vigra - vigra/numerictraits.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

numerictraits.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36
37 #ifndef VIGRA_NUMERICTRAITS_HXX
38 #define VIGRA_NUMERICTRAITS_HXX
39
40 #include <climits>
41 #include <limits>
42 #include <cfloat>
43 #include <complex>
44 #include "metaprogramming.hxx"
45 #include "sized_int.hxx"
46
47 /********************************************************/
48 /* */
49 /* NumericTraits */
50 /* */
51 /********************************************************/
52
53
54 /** \page NumericPromotionTraits Numeric and Promotion Traits
55
56 Meta-information about arithmetic types.
57
58 <UL style="list-style-image:url(documents/bullet.gif)">
59 <LI> \ref NumericTraits
60 <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for promotion, conversion, creation of arithmetic objects</em>
61 <LI> \ref PromoteTraits
62 <BR>&nbsp;&nbsp;&nbsp;<em>Binary traits for promotion of arithmetic objects</em>
63 <LI> \ref SquareRootTraits
64 <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the square root of arithmetic objects</em>
65 <LI> \ref NormTraits
66 <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the norm and squared norm of arithmetic objects</em>
67 </UL>
68
69 These traits classes contain information that is used by generic
70 algorithms and data structures to determine intermediate and result
71 types of numerical calculations, to convert between different
72 representations of arithmetic types, and to create certain important
73 constants of each type. Thus, algorithms and data structures
74 operating that need arithmetic operations can be made more
75 independent from the actual data representation.
76
77 NumericTraits are implemented as template specializations of one
78 arithmetic type, while PromoteTraits are specialized for a pair of
79 arithmetic types that shall be combined in one operation.
80 */
81
82 /** \page NumericTraits template<> struct NumericTraits<ArithmeticType>
83
84 Unary traits for promotion, conversion, creation of arithmetic objects.
85
86 <b>\#include</b> <vigra/numerictraits.hxx>
87
88 This traits class is used derive important properties of
89 an arithmetic type. Consider the following algorithm:
90
91 \code
92 // calculate the sum of a sequence of bytes
93 int sumBytes(unsigned char * begin, unsigned char * end)
94 {
95 int result = 0;
96 for(; begin != end; ++begin) result += *begin;
97 return result;
98 }
99 \endcode
100
101 The return type of this function can not be 'unsigned char' because
102 the summation would very likely overflow. Since we know the source
103 type, we can easily choose 'int' as an appropriate return type.
104 Likewise, we would have chosen 'float' if we had to sum a
105 sequence of floats. If we want to make this
106 algorithm generic, we would like to derive the appropriate return
107 type automatically. This can be done with NumericTraits.
108 The code would look like this (we use \ref DataAccessors to
109 read the data from the sequence):
110
111 \code
112 // calculate the sum of any sequence
113 template <class Iterator, class Accessor>
114 typename vigra::NumericTraits<typename Accessor::value_type>::Promote
115 sumSequence(Iterator begin, Iterator end, Accessor a)
116 {
117 // an abbreviation
118 typedef vigra::NumericTraits<typename Accessor::value_type> SrcTraits;
119
120 // find out result type
121 typedef typename SrcTraits::Promote ResultType;
122
123 // init result to zero
124 ResultType result = vigra::NumericTraits<ResultType>::zero();
125
126 for(; begin != end; ++begin)
127 {
128 // cast current item to ResultType and add
129 result += SrcTraits::toPromote(a(begin));
130 }
131
132 return result;
133 }
134 \endcode
135
136 In this example NumericTraits is not only used to deduce the
137 ReturnType of the operation, but also to initialize it with the
138 constant 'zero'. This is necessary since we do not know in general,
139 which expression must be used to obtain a zero of some arbitrary
140 type - '<TT>ResultType result = 0;</TT>' would only work if the
141 ResultType had an constructor taking an '<TT>int</TT>' argument, and we
142 would not even have any guarantee as to what the semantics of this
143 constructor are. In addition, the traits are used to cast the
144 source type into the promote type.
145
146 Similarly, an algorithm that needs multiplication would use the
147 return type <TT>RealPromote</TT> and the functions <TT>one()</TT> and
148 <TT>toRealPromote()</TT>. The following members are defined in
149 <b> <TT>NumericTraits<ArithmeticType></TT></b>:
150
151 <table>
152 <tr><td>
153 <b> <TT>typedef ... Type;</TT></b>
154 </td><td>
155
156 the type itself
157
158 </td></tr>
159 <tr><td>
160 <b> <TT>typedef ... Promote;</TT></b>
161 </td><td>
162
163 promote type for addition and subtraction
164
165 </td></tr>
166 <tr><td>
167 <b> <TT>typedef ... RealPromote;</TT></b>
168 </td><td>
169 promote type for multiplication and division with a real number
170
171 (only defined if <TT>ArithmeticType</TT> supports these operations)
172
173 </td></tr>
174 <tr><td>
175 <b> <TT>typedef ... ComplexPromote;</TT></b>
176 </td><td>
177
178 promote type for complex arithmetic
179
180 </td></tr>
181 <tr><td>
182 <b> <TT>typedef ... ValueType;</TT></b>
183 </td><td>
184
185 for scalar types: the type itself<br>
186 otherwise: typename Type::value_type (if defined)
187
188 </td></tr>
189 <tr><td>
190 <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
191 </td><td>
192 convert to <TT>Promote</TT> type
193
194 </td></tr>
195 <tr><td>
196 <b> <TT>static RealPromote toRealPromote(ArithmeticType v);</TT></b>
197 </td><td>
198 convert to <TT>RealPromote</TT> type
199
200 (only defined if <TT>ArithmeticType</TT> supports multiplication)
201
202 </td></tr>
203 <tr><td>
204 <b> <TT>static ArithmeticType fromPromote(Promote v);</TT></b>
205 </td><td>
206 convert from <TT>Promote</TT> type
207
208 if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped;
209
210 </td></tr>
211 <tr><td>
212 <b> <TT>static ArithmeticType fromRealPromote(RealPromote v);</TT></b>
213 </td><td>
214 convert from <TT>RealPromote</TT> type
215
216 (only defined if
217 <TT>ArithmeticType</TT> supports multiplication)
218
219 if <TT>ArithmeticType</TT> is an integral type, the result is rounded
220
221 if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped
222
223 </td></tr>
224 <tr><td>
225 <b> <TT>static ArithmeticType zero();</TT></b>
226 </td><td>
227 create neutral element of addition
228
229 i.e. <TT>(ArithmeticType a = ...,</TT>
230 <TT> a + NumericTraits<ArithmeticType>::zero() == a)</TT>
231 must always yield <TT>true</TT>
232
233 </td></tr>
234 <tr><td>
235 <b> <TT>static ArithmeticType nonZero();</TT></b>
236 </td><td>
237 create a non-zero element (if multiplication is defined, this yields one())
238
239 i.e. <TT>(ArithmeticType a = ...,</TT>
240 <TT> a + NumericTraits<ArithmeticType>::nonZero() == a)</TT>
241 must always yield <TT>false</TT>
242
243 </td></tr>
244 <tr><td>
245 <b> <TT>static ArithmeticType min();</TT></b>
246 </td><td>
247 the smallest number representable in this type.<br>
248 Only available if isOrdered is VigraTrueType. For integral types,
249 this equals <TT>INT_MIN</TT> etc., for real valued types it is <TT>-FLT_MAX</TT>
250 etc. (<b>not</b> <TT>FLT_MIN</TT> -- this is the smallest positive <tt>float</tt>)
251
252 </td></tr>
253 <tr><td>
254 <b> <TT>static ArithmeticType max();</TT></b>
255 </td><td>
256 the largest number representable in this type.<br>
257 Only available if isOrdered is VigraTrueType. For integral types,
258 this equals <TT>INT_MAX</TT> etc., for real valued types it is <TT>FLT_MAX</TT>
259 etc.
260
261 </td></tr>
262 <tr><td>
263 <b> <TT>static ArithmeticType one();</TT></b>
264 </td><td>
265 create neutral element of multiplication
266
267 (only defined if <TT>ArithmeticType</TT> supports multiplication)
268
269 i.e. <TT>(ArithmeticType a = ...,</TT>
270 <TT> a * NumericTraits<ArithmeticType>::one() == a)</TT>
271 must always yield <TT>true</TT>
272
273 </td></tr>
274 <tr><td>
275 <b> <TT>typedef ... isIntegral;</TT></b>
276 </td><td>
277 VigraTrueType if <TT>ArithmeticType</TT> is an integral type,
278 VigraFalseType otherwise
279
280 </td></tr>
281 <tr><td>
282 <b> <TT>typedef ... isScalar;</TT></b>
283 </td><td>
284 VigraTrueType if <TT>ArithmeticType</TT> is a scalar type,
285 VigraFalseType otherwise
286
287 </td></tr>
288 <tr><td>
289 <tr><td>
290 <b> <TT>typedef ... isSigned;</TT></b>
291 </td><td>
292 VigraTrueType if <TT>ArithmeticType</TT> is a signed type,
293 VigraFalseType otherwise
294
295 </td></tr>
296 <tr><td>
297 <tr><td>
298 <b> <TT>typedef ... isOrdered;</TT></b>
299 </td><td>
300 VigraTrueType if <TT>ArithmeticType</TT> supports operator<(),
301 VigraFalseType otherwise
302
303 </td></tr>
304 <tr><td>
305 <b> <TT>typedef ... isComplex;</TT></b>
306 </td><td>
307 VigraTrueType if <TT>ArithmeticType</TT> is a complex number,
308 VigraFalseType otherwise
309
310 </td></tr>
311 <tr><td>
312 </table>
313
314 NumericTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
315
316 Namespace: vigra
317
318 */
319
320 /** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, ArithmeticType2>
321
322 Binary traits for promotion of arithmetic objects.
323
324 <b>\#include</b> <vigra/numerictraits.hxx>
325
326 This traits class is used to determine the appropriate result type
327 of arithmetic expressions which depend of two arguments. Consider
328 the following function:
329
330 \code
331 template <class T>
332 T min(T t1, T t2)
333 {
334 return (t1 < t2) ? t1 : t2;
335 }
336 \endcode
337
338 This template is only applicable if both arguments have the same
339 type. However, sometimes we may want to use the function in cases
340 where the argument types differ. Then we can deduce the appropriate
341 return type by using <TT>PromoteTraits</TT>:
342
343 \code
344 template <class T1, class T2>
345 typename vigra::PromoteTraits<T1, T2>::Promote
346 min(T1 t1, T2 t2)
347 {
348 return (t1 < t2) ? vigra::PromoteTraits<T1, T2>::toPromote(t1) :
349 vigra::PromoteTraits<T1, T2>::toPromote(t2);
350 }
351 \endcode
352
353 In addition, the traits class provide static functions to cast the
354 arguments to the promote type. For example, if <TT>T1</TT> were <TT>int</TT> and
355 <TT>T2</TT> were <TT>float</TT>, the <TT>Promote</TT> type would be <TT>float</TT>.
356 The following members are defined in
357 <b> <TT>PromoteTraits<ArithmeticType1, ArithmeticType2></TT></b>:
358
359 <table>
360 <tr>
361 <td>
362 <b> <TT>typedef ... Promote;</TT></b>
363 </td><td>
364 promote type
365 </td></tr>
366 <tr><td>
367 <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b>
368
369 <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
370 </td><td>
371 convert to <TT>Promote</TT> type
372 </td></tr>
373 </table>
374
375 PromoteTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
376
377 Namespace: vigra
378 */
379
380 /** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticType>
381
382 Unary traits for the calculation of the square root of arithmetic objects.
383
384 <b>\#include</b> <vigra/numerictraits.hxx>
385
386 This traits class is used to determine appropriate argument and result types
387 for the function sqrt(). These traits are typically used like this:
388
389 \code
390 ArithmeticType t = ...;
391 SquareRootTraits<ArithmeticType>::SquareRootResult r =
392 sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
393 \endcode
394
395 This approach avoids 'ambiguous overload errors' when taking the square root of
396 an integer type. It also takes care of determining the proper result of the
397 sqrt() function of \ref vigra::FixedPoint and of the norm() function, when
398 it is implemented via sqrt(squaredNorm(x)).
399 The following members are defined in <b> <TT>SquareRootTraits<ArithmeticType></TT></b>:
400
401 <table>
402 <tr><td>
403 <b> <TT>typedef ArithmeticType Type;</TT></b>
404 </td><td>
405 the type itself
406 </td></tr>
407 <tr><td>
408 <b> <TT>typedef ... SquareRootArgument;</TT></b>
409 </td><td>
410 required argument type for srqt(), i.e. <tt>sqrt((SquareRootArgument)x)</tt>
411 </td></tr>
412 <tr><td>
413 <b> <TT>typedef ... SquareRootResult;</TT></b>
414 </td><td>
415 result of <tt>sqrt((SquareRootArgument)x)</tt>
416 </td></tr>
417 </table>
418
419 NormTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
420
421 Namespace: vigra
422 */
423
424 /** \page NormTraits template<> struct NormTraits<ArithmeticType>
425
426 Unary traits for the calculation of the norm and squared norm of arithmetic objects.
427
428 <b>\#include</b> <vigra/numerictraits.hxx>
429
430 This traits class is used to determine appropriate result types
431 for the functions norm() and squaredNorm(). These functions are always
432 declared like this (where <tt>ArithmeticType</tt> is a type that supports a norm):
433
434 \code
435 NormTraits<ArithmeticType>::NormType norm(ArithmeticType const & t);
436 NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
437 \endcode
438
439 The following members are defined in <b> <TT>NormTraits<ArithmeticType></TT></b>:
440
441 <table>
442 <tr><td>
443 <b> <TT>typedef ArithmeticType Type;</TT></b>
444 </td><td>
445 the type itself
446 </td></tr>
447 <tr><td>
448 <b> <TT>typedef ... SquaredNormType;</TT></b>
449 </td><td>
450 result of <tt>squaredNorm(ArithmeticType)</tt>
451 </td></tr>
452 <tr><td>
453 <b> <TT>typedef ... NormType;</TT></b>
454 </td><td>
455 result of <tt>norm(ArithmeticType)</tt><br>
456 Usually equal to <tt>SquareRootTraits<SquaredNormType>::SquareRootResult</tt>
457 </td></tr>
458 </table>
459
460 NormTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
461
462 Namespace: vigra
463 */
464
465
466 namespace vigra {
467 namespace detail {
468 template <typename s, typename t>
469 inline static t clamp_integer_to_unsigned(s value, t maximum) {
470 return
471 value <= s() ?
472 t() :
473 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
474 }
475
476 template <typename s, typename t>
477 inline static t clamp_integer_to_signed(s value, t minimum, t maximum) {
478 return
479 value <= static_cast<s>(minimum) ?
480 minimum :
481 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
482 }
483
484 template <typename s, typename t>
485 inline static t clamp_float_to_unsigned(s value, t maximum) {
486 return
487 value <= s() ?
488 t() :
489 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5));
490 }
491
492 template <typename s, typename t>
493 inline static t clamp_float_to_signed(s value, t minimum, t maximum) {
494 if (value >= s()) {
495 return value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5);
496 } else {
497 return value <= static_cast<s>(minimum) ? minimum : static_cast<t>(value - 0.5);
498 }
499 }
500 } // end namespace detail
501
502 struct Error_NumericTraits_not_specialized_for_this_case { };
503 struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char { };
504
505 template<class A>
506 struct NumericTraits
507 {
508 typedef Error_NumericTraits_not_specialized_for_this_case Type;
509 typedef Error_NumericTraits_not_specialized_for_this_case Promote;
510 typedef Error_NumericTraits_not_specialized_for_this_case UnsignedPromote;
511 typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
512 typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromote;
513 typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
514
515 typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
516 typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
517 typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
518 typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
519 typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
520 };
521
522 template<>
523 struct NumericTraits<char>
524 {
525 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Type;
526 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Promote;
527 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char UnsignedPromote;
528 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char RealPromote;
529 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ComplexPromote;
530 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ValueType;
531
532 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isScalar;
533 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isIntegral;
534 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isSigned;
535 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isOrdered;
536 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isComplex;
537 };
538
539 #ifndef NO_BOOL
540 template<>
541 struct NumericTraits<bool>
542 {
543 typedef bool Type;
544 typedef int Promote;
545 typedef unsigned int UnsignedPromote;
546 typedef double RealPromote;
547 typedef std::complex<RealPromote> ComplexPromote;
548 typedef Type ValueType;
549
550 typedef VigraTrueType isIntegral;
551 typedef VigraTrueType isScalar;
552 typedef VigraFalseType isSigned;
553 typedef VigraTrueType isOrdered;
554 typedef VigraFalseType isComplex;
555
556 static bool zero() { return false; }
557 static bool one() { return true; }
558 static bool nonZero() { return true; }
559 static bool min() { return false; }
560 static bool max() { return true; }
561
562 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
563 enum { minConst = false , maxConst = true };
564 #else
565 static const bool minConst = false;
566 static const bool maxConst = true;
567 #endif
568
569 static Promote toPromote(bool v) { return v ? 1 : 0; }
570 static RealPromote toRealPromote(bool v) { return v ? 1.0 : 0.0; }
571 static bool fromPromote(Promote v) {
572 return (v == 0) ? false : true;
573 }
574 static bool fromRealPromote(RealPromote v) {
575 return (v == 0.0) ? false : true;
576 }
577 };
578 #endif
579
580 template<>
581 struct NumericTraits<signed char>
582 {
583 typedef signed char Type;
584 typedef int Promote;
585 typedef unsigned int UnsignedPromote;
586 typedef double RealPromote;
587 typedef std::complex<RealPromote> ComplexPromote;
588 typedef Type ValueType;
589
590 typedef VigraTrueType isIntegral;
591 typedef VigraTrueType isScalar;
592 typedef VigraTrueType isSigned;
593 typedef VigraTrueType isOrdered;
594 typedef VigraFalseType isComplex;
595
596 static signed char zero() { return 0; }
597 static signed char one() { return 1; }
598 static signed char nonZero() { return 1; }
599 static signed char min() { return SCHAR_MIN; }
600 static signed char max() { return SCHAR_MAX; }
601
602 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
603 enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
604 #else
605 static const signed char minConst = SCHAR_MIN;
606 static const signed char maxConst = SCHAR_MIN;
607 #endif
608
609 static Promote toPromote(signed char v) { return v; }
610 static RealPromote toRealPromote(signed char v) { return v; }
611 static signed char fromPromote(Promote v) {
612 return detail::clamp_integer_to_signed<Promote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
613 }
614 static signed char fromRealPromote(RealPromote v) {
615 return detail::clamp_float_to_signed<RealPromote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
616 }
617 };
618
619 template<>
620 struct NumericTraits<unsigned char>
621 {
622 typedef unsigned char Type;
623 typedef int Promote;
624 typedef unsigned int UnsignedPromote;
625 typedef double RealPromote;
626 typedef std::complex<RealPromote> ComplexPromote;
627 typedef Type ValueType;
628
629 typedef VigraTrueType isIntegral;
630 typedef VigraTrueType isScalar;
631 typedef VigraFalseType isSigned;
632 typedef VigraTrueType isOrdered;
633 typedef VigraFalseType isComplex;
634
635 static unsigned char zero() { return 0; }
636 static unsigned char one() { return 1; }
637 static unsigned char nonZero() { return 1; }
638 static unsigned char min() { return 0; }
639 static unsigned char max() { return UCHAR_MAX; }
640
641 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
642 enum { minConst = 0, maxConst = UCHAR_MAX };
643 #else
644 static const unsigned char minConst = 0;
645 static const unsigned char maxConst = UCHAR_MAX;
646 #endif
647
648 static Promote toPromote(unsigned char v) { return v; }
649 static RealPromote toRealPromote(unsigned char v) { return v; }
650 static unsigned char fromPromote(Promote v) {
651 return detail::clamp_integer_to_unsigned<Promote, unsigned char>(v, UCHAR_MAX);
652 }
653 static unsigned char fromRealPromote(RealPromote v) {
654 return detail::clamp_float_to_unsigned<RealPromote, unsigned char>(v, UCHAR_MAX);
655 }
656 };
657
658 template<>
659 struct NumericTraits<short int>
660 {
661 typedef short int Type;
662 typedef int Promote;
663 typedef unsigned int UnsignedPromote;
664 typedef double RealPromote;
665 typedef std::complex<RealPromote> ComplexPromote;
666 typedef Type ValueType;
667
668 typedef VigraTrueType isIntegral;
669 typedef VigraTrueType isScalar;
670 typedef VigraTrueType isSigned;
671 typedef VigraTrueType isOrdered;
672 typedef VigraFalseType isComplex;
673
674 static short int zero() { return 0; }
675 static short int one() { return 1; }
676 static short int nonZero() { return 1; }
677 static short int min() { return SHRT_MIN; }
678 static short int max() { return SHRT_MAX; }
679
680 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
681 enum { minConst = SHRT_MIN, maxConst = SHRT_MAX };
682 #else
683 static const short int minConst = SHRT_MIN;
684 static const short int maxConst = SHRT_MAX;
685 #endif
686
687 static Promote toPromote(short int v) { return v; }
688 static RealPromote toRealPromote(short int v) { return v; }
689 static short int fromPromote(Promote v) {
690 return detail::clamp_integer_to_signed<Promote, short int>(v, SHRT_MIN, SHRT_MAX);
691 }
692 static short int fromRealPromote(RealPromote v) {
693 return detail::clamp_float_to_signed<RealPromote, short int>(v, SHRT_MIN, SHRT_MAX);
694 }
695 };
696
697 template<>
698 struct NumericTraits<short unsigned int>
699 {
700 typedef short unsigned int Type;
701 typedef int Promote;
702 typedef unsigned int UnsignedPromote;
703 typedef double RealPromote;
704 typedef std::complex<RealPromote> ComplexPromote;
705 typedef Type ValueType;
706
707 typedef VigraTrueType isIntegral;
708 typedef VigraTrueType isScalar;
709 typedef VigraFalseType isSigned;
710 typedef VigraTrueType isOrdered;
711 typedef VigraFalseType isComplex;
712
713 static short unsigned int zero() { return 0; }
714 static short unsigned int one() { return 1; }
715 static short unsigned int nonZero() { return 1; }
716 static short unsigned int min() { return 0; }
717 static short unsigned int max() { return USHRT_MAX; }
718
719 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
720 enum { minConst = 0, maxConst = USHRT_MAX };
721 #else
722 static const short unsigned int minConst = 0;
723 static const short unsigned int maxConst = USHRT_MAX;
724 #endif
725
726 static Promote toPromote(short unsigned int v) { return v; }
727 static RealPromote toRealPromote(short unsigned int v) { return v; }
728 static short unsigned int fromPromote(Promote v) {
729 return detail::clamp_integer_to_unsigned<Promote, short unsigned int>(v, USHRT_MAX);
730 }
731 static short unsigned int fromRealPromote(RealPromote v) {
732 return detail::clamp_float_to_unsigned<RealPromote, short unsigned int>(v, USHRT_MAX);
733 }
734 };
735
736 template<>
737 struct NumericTraits<int>
738 {
739 typedef int Type;
740 typedef int Promote;
741 typedef unsigned int UnsignedPromote;
742 typedef double RealPromote;
743 typedef std::complex<RealPromote> ComplexPromote;
744 typedef Type ValueType;
745
746 typedef VigraTrueType isIntegral;
747 typedef VigraTrueType isScalar;
748 typedef VigraTrueType isSigned;
749 typedef VigraTrueType isOrdered;
750 typedef VigraFalseType isComplex;
751
752 static int zero() { return 0; }
753 static int one() { return 1; }
754 static int nonZero() { return 1; }
755 static int min() { return INT_MIN; }
756 static int max() { return INT_MAX; }
757
758 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
759 enum { minConst = INT_MIN, maxConst = INT_MAX };
760 #else
761 static const int minConst = INT_MIN;
762 static const int maxConst = INT_MAX;
763 #endif
764
765 static Promote toPromote(int v) { return v; }
766 static RealPromote toRealPromote(int v) { return v; }
767 static int fromPromote(Promote v) { return v; }
768 static int fromRealPromote(RealPromote v) {
769 return detail::clamp_float_to_signed<RealPromote, int>(v, INT_MIN, INT_MAX);
770 }
771 };
772
773 template<>
774 struct NumericTraits<unsigned int>
775 {
776 typedef unsigned int Type;
777 typedef unsigned int Promote;
778 typedef unsigned int UnsignedPromote;
779 typedef double RealPromote;
780 typedef std::complex<RealPromote> ComplexPromote;
781 typedef Type ValueType;
782
783 typedef VigraTrueType isIntegral;
784 typedef VigraTrueType isScalar;
785 typedef VigraFalseType isSigned;
786 typedef VigraTrueType isOrdered;
787 typedef VigraFalseType isComplex;
788
789 static unsigned int zero() { return 0; }
790 static unsigned int one() { return 1; }
791 static unsigned int nonZero() { return 1; }
792 static unsigned int min() { return 0; }
793 static unsigned int max() { return UINT_MAX; }
794
795 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
796 enum { minConst = 0, maxConst = UINT_MAX };
797 #else
798 static const unsigned int minConst = 0;
799 static const unsigned int maxConst = UINT_MAX;
800 #endif
801
802 static Promote toPromote(unsigned int v) { return v; }
803 static RealPromote toRealPromote(unsigned int v) { return v; }
804 static unsigned int fromPromote(Promote v) { return v; }
805 static unsigned int fromRealPromote(RealPromote v) {
806 return detail::clamp_float_to_unsigned<RealPromote, unsigned int>(v, UINT_MAX);
807 }
808 };
809
810 template<>
811 struct NumericTraits<long>
812 {
813 typedef long Type;
814 typedef long Promote;
815 typedef unsigned long UnsignedPromote;
816 typedef double RealPromote;
817 typedef std::complex<RealPromote> ComplexPromote;
818 typedef Type ValueType;
819
820 typedef VigraTrueType isIntegral;
821 typedef VigraTrueType isScalar;
822 typedef VigraTrueType isSigned;
823 typedef VigraTrueType isOrdered;
824 typedef VigraFalseType isComplex;
825
826 static long zero() { return 0; }
827 static long one() { return 1; }
828 static long nonZero() { return 1; }
829 static long min() { return LONG_MIN; }
830 static long max() { return LONG_MAX; }
831
832 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
833 enum { minConst = LONG_MIN, maxConst = LONG_MAX };
834 #else
835 static const long minConst = LONG_MIN;
836 static const long maxConst = LONG_MAX;
837 #endif
838
839 static Promote toPromote(long v) { return v; }
840 static RealPromote toRealPromote(long v) { return static_cast<RealPromote>(v); }
841 static long fromPromote(Promote v) { return v; }
842 static long fromRealPromote(RealPromote v) {
843 return detail::clamp_float_to_signed<RealPromote, long>(v, LONG_MIN, LONG_MAX);
844 }
845 };
846
847 template<>
848 struct NumericTraits<unsigned long>
849 {
850 typedef unsigned long Type;
851 typedef unsigned long Promote;
852 typedef unsigned long UnsignedPromote;
853 typedef double RealPromote;
854 typedef std::complex<RealPromote> ComplexPromote;
855 typedef Type ValueType;
856
857 typedef VigraTrueType isIntegral;
858 typedef VigraTrueType isScalar;
859 typedef VigraFalseType isSigned;
860 typedef VigraTrueType isOrdered;
861 typedef VigraFalseType isComplex;
862
863 static unsigned long zero() { return 0; }
864 static unsigned long one() { return 1; }
865 static unsigned long nonZero() { return 1; }
866 static unsigned long min() { return 0; }
867 static unsigned long max() { return ULONG_MAX; }
868
869 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
870 enum { minConst = 0, maxConst = ULONG_MAX };
871 #else
872 static const unsigned long minConst = 0;
873 static const unsigned long maxConst = ULONG_MAX;
874 #endif
875
876 static Promote toPromote(unsigned long v) { return v; }
877 static RealPromote toRealPromote(unsigned long v) { return static_cast<RealPromote>(v); }
878 static unsigned long fromPromote(Promote v) { return v; }
879 static unsigned long fromRealPromote(RealPromote v) {
880 return detail::clamp_float_to_unsigned<RealPromote, unsigned long>(v, ULONG_MAX);
881 }
882 };
883
884 #ifdef LLONG_MAX
885 template<>
886 struct NumericTraits<long long>
887 {
888 typedef long long Type;
889 typedef long long Promote;
890 typedef unsigned long long UnsignedPromote;
891 typedef double RealPromote;
892 typedef std::complex<RealPromote> ComplexPromote;
893 typedef Type ValueType;
894
895 typedef VigraTrueType isIntegral;
896 typedef VigraTrueType isScalar;
897 typedef VigraTrueType isSigned;
898 typedef VigraTrueType isOrdered;
899 typedef VigraFalseType isComplex;
900
901 static long long zero() { return 0; }
902 static long long one() { return 1; }
903 static long long nonZero() { return 1; }
904 static long long min() { return LLONG_MIN; }
905 static long long max() { return LLONG_MAX; }
906
907 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
908 enum { minConst = LLONG_MIN, maxConst = LLONG_MAX };
909 #else
910 static const long long minConst = LLONG_MIN;
911 static const long long maxConst = LLONG_MAX;
912 #endif
913
914 static Promote toPromote(long long v) { return v; }
915 static RealPromote toRealPromote(long long v) { return (RealPromote)v; }
916 static long long fromPromote(Promote v) { return v; }
917 static long long fromRealPromote(RealPromote v) {
918 return detail::clamp_float_to_signed<RealPromote, long long>(v, LLONG_MIN, LLONG_MAX);
919 }
920 };
921
922 template<>
923 struct NumericTraits<unsigned long long>
924 {
925 typedef unsigned long long Type;
926 typedef unsigned long long Promote;
927 typedef unsigned long long UnsignedPromote;
928 typedef double RealPromote;
929 typedef std::complex<RealPromote> ComplexPromote;
930 typedef Type ValueType;
931
932 typedef VigraTrueType isIntegral;
933 typedef VigraTrueType isScalar;
934 typedef VigraFalseType isSigned;
935 typedef VigraTrueType isOrdered;
936 typedef VigraFalseType isComplex;
937
938 static unsigned long long zero() { return 0; }
939 static unsigned long long one() { return 1; }
940 static unsigned long long nonZero() { return 1; }
941 static unsigned long long min() { return 0; }
942 static unsigned long long max() { return ULLONG_MAX; }
943
944 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
945 enum { minConst = 0, maxConst = ULLONG_MAX };
946 #else
947 static const unsigned long long minConst = 0;
948 static const unsigned long long maxConst = ULLONG_MAX;
949 #endif
950
951 static Promote toPromote(unsigned long long v) { return v; }
952 static RealPromote toRealPromote(unsigned long long v) { return (RealPromote)v; }
953 static unsigned long long fromPromote(Promote v) { return v; }
954 static unsigned long long fromRealPromote(RealPromote v) {
955 return detail::clamp_float_to_unsigned<RealPromote, unsigned long long>(v, ULLONG_MAX);
956 }
957 };
958 #endif // LLONG_MAX
959
960 template<>
961 struct NumericTraits<float>
962 {
963 typedef float Type;
964 typedef float Promote;
965 typedef float UnsignedPromote;
966 typedef float RealPromote;
967 typedef std::complex<RealPromote> ComplexPromote;
968 typedef Type ValueType;
969
970 typedef VigraFalseType isIntegral;
971 typedef VigraTrueType isScalar;
972 typedef VigraTrueType isSigned;
973 typedef VigraTrueType isOrdered;
974 typedef VigraFalseType isComplex;
975
976 static float zero() { return 0.0; }
977 static float one() { return 1.0; }
978 static float nonZero() { return 1.0; }
979 static float epsilon() { return FLT_EPSILON; }
980 static float smallestPositive() { return FLT_MIN; }
981 static float min() { return -FLT_MAX; }
982 static float max() { return FLT_MAX; }
983
984 static Promote toPromote(float v) { return v; }
985 static RealPromote toRealPromote(float v) { return v; }
986 static float fromPromote(Promote v) { return v; }
987 static float fromRealPromote(RealPromote v) { return v; }
988 };
989
990 template<>
991 struct NumericTraits<double>
992 {
993 typedef double Type;
994 typedef double Promote;
995 typedef double UnsignedPromote;
996 typedef double RealPromote;
997 typedef std::complex<RealPromote> ComplexPromote;
998 typedef Type ValueType;
999
1000 typedef VigraFalseType isIntegral;
1001 typedef VigraTrueType isScalar;
1002 typedef VigraTrueType isSigned;
1003 typedef VigraTrueType isOrdered;
1004 typedef VigraFalseType isComplex;
1005
1006 static double zero() { return 0.0; }
1007 static double one() { return 1.0; }
1008 static double nonZero() { return 1.0; }
1009 static double epsilon() { return DBL_EPSILON; }
1010 static double smallestPositive() { return DBL_MIN; }
1011 static double min() { return -DBL_MAX; }
1012 static double max() { return DBL_MAX; }
1013
1014 static Promote toPromote(double v) { return v; }
1015 static RealPromote toRealPromote(double v) { return v; }
1016 static double fromPromote(Promote v) { return v; }
1017 static double fromRealPromote(RealPromote v) { return v; }
1018 };
1019
1020 template<>
1021 struct NumericTraits<long double>
1022 {
1023 typedef long double Type;
1024 typedef long double Promote;
1025 typedef long double UnsignedPromote;
1026 typedef long double RealPromote;
1027 typedef std::complex<RealPromote> ComplexPromote;
1028 typedef Type ValueType;
1029
1030 typedef VigraFalseType isIntegral;
1031 typedef VigraTrueType isScalar;
1032 typedef VigraTrueType isSigned;
1033 typedef VigraTrueType isOrdered;
1034 typedef VigraFalseType isComplex;
1035
1036 static long double zero() { return 0.0; }
1037 static long double one() { return 1.0; }
1038 static long double nonZero() { return 1.0; }
1039 static long double epsilon() { return LDBL_EPSILON; }
1040 static long double smallestPositive() { return LDBL_MIN; }
1041 static long double min() { return -LDBL_MAX; }
1042 static long double max() { return LDBL_MAX; }
1043
1044 static Promote toPromote(long double v) { return v; }
1045 static RealPromote toRealPromote(long double v) { return v; }
1046 static long double fromPromote(Promote v) { return v; }
1047 static long double fromRealPromote(RealPromote v) { return v; }
1048 };
1049
1050 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1051
1052 template<class T>
1053 struct NumericTraits<std::complex<T> >
1054 {
1055 typedef std::complex<T> Type;
1056 typedef std::complex<typename NumericTraits<T>::Promote> Promote;
1057 typedef std::complex<typename NumericTraits<T>::UnsignedPromote> UnsignedPromote;
1058 typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromote;
1059 typedef std::complex<RealPromote> ComplexPromote;
1060 typedef T ValueType;
1061
1062 typedef VigraFalseType isIntegral;
1063 typedef VigraFalseType isScalar;
1064 typedef typename NumericTraits<T>::isSigned isSigned;
1065 typedef VigraFalseType isOrdered;
1066 typedef VigraTrueType isComplex;
1067
1068 static Type zero() { return Type(0.0); }
1069 static Type one() { return Type(1.0); }
1070 static Type nonZero() { return one(); }
1071 static Type epsilon() { return Type(NumericTraits<T>::epsilon()); }
1072 static Type smallestPositive() { return Type(NumericTraits<T>::smallestPositive()); }
1073
1074 static Promote toPromote(Type const & v) { return v; }
1075 static Type fromPromote(Promote const & v) { return v; }
1076 static Type fromRealPromote(RealPromote v) { return Type(v); }
1077 };
1078
1079 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1080
1081 /********************************************************/
1082 /* */
1083 /* SquareRootTraits */
1084 /* */
1085 /********************************************************/
1086
1087 template<class T>
1088 struct SquareRootTraits
1089 {
1090 typedef T Type;
1091 typedef typename NumericTraits<T>::RealPromote SquareRootResult;
1092 typedef typename NumericTraits<T>::RealPromote SquareRootArgument;
1093 };
1094
1095
1096 /********************************************************/
1097 /* */
1098 /* NormTraits */
1099 /* */
1100 /********************************************************/
1101
1102 struct Error_NormTraits_not_specialized_for_this_case { };
1103
1104 template<class T>
1105 struct NormTraits
1106 {
1107 typedef T Type;
1108 typedef Error_NormTraits_not_specialized_for_this_case SquaredNormType;
1109 typedef Error_NormTraits_not_specialized_for_this_case NormType;
1110 };
1111
1112 #define VIGRA_DEFINE_NORM_TRAITS(T) \
1113 template <> struct NormTraits<T> { \
1114 typedef T Type; \
1115 typedef NumericTraits<T>::Promote SquaredNormType; \
1116 typedef T NormType; \
1117 };
1118
1119 VIGRA_DEFINE_NORM_TRAITS(bool)
1120 VIGRA_DEFINE_NORM_TRAITS(signed char)
1121 VIGRA_DEFINE_NORM_TRAITS(unsigned char)
1122 VIGRA_DEFINE_NORM_TRAITS(short)
1123 VIGRA_DEFINE_NORM_TRAITS(unsigned short)
1124 VIGRA_DEFINE_NORM_TRAITS(int)
1125 VIGRA_DEFINE_NORM_TRAITS(unsigned int)
1126 VIGRA_DEFINE_NORM_TRAITS(long)
1127 VIGRA_DEFINE_NORM_TRAITS(unsigned long)
1128 VIGRA_DEFINE_NORM_TRAITS(float)
1129 VIGRA_DEFINE_NORM_TRAITS(double)
1130 VIGRA_DEFINE_NORM_TRAITS(long double)
1131
1132 #ifdef LLONG_MAX
1133 VIGRA_DEFINE_NORM_TRAITS(long long)
1134 VIGRA_DEFINE_NORM_TRAITS(unsigned long long)
1135 #endif // LLONG_MAX
1136
1137 #undef VIGRA_DEFINE_NORM_TRAITS
1138
1139 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1140
1141 template<class T>
1142 struct NormTraits<std::complex<T> >
1143 {
1144 typedef std::complex<T> Type;
1145 typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
1146 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
1147 };
1148
1149 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1150
1151 /********************************************************/
1152 /* */
1153 /* PromoteTraits */
1154 /* */
1155 /********************************************************/
1156
1157 namespace detail {
1158
1159 template <class T, class U>
1160 struct PromoteType
1161 {
1162 static T & t();
1163 static U & u();
1164 // let C++ figure out the promote type by adding a T and an U
1165 typedef typename SizeToType<sizeof(*typeToSize(t() + u()))>::result Promote;
1166 static Promote toPromote(T t) { return Promote(t); }
1167 static Promote toPromote(U u) { return Promote(u); }
1168 };
1169
1170
1171 template <class T>
1172 struct PromoteType<T, T>
1173 {
1174 static T & t();
1175 // let C++ figure out the promote type by adding two Ts
1176 typedef typename SizeToType<sizeof(*typeToSize(t() + t()))>::result Promote;
1177 static Promote toPromote(T t) { return Promote(t); }
1178 };
1179
1180 } // namespace detail
1181
1182 struct Error_PromoteTraits_not_specialized_for_this_case { };
1183
1184 template<class A, class B>
1185 struct PromoteTraits
1186 {
1187 typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
1188 };
1189
1190 #include "promote_traits.hxx"
1191
1192 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1193
1194 template <class T>
1195 struct PromoteTraits<std::complex<T>, std::complex<T> >
1196 {
1197 typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
1198 static Promote toPromote(std::complex<T> const & v) { return v; }
1199 };
1200
1201 template <class T1, class T2>
1202 struct PromoteTraits<std::complex<T1>, std::complex<T2> >
1203 {
1204 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1205 static Promote toPromote(std::complex<T1> const & v) { return v; }
1206 static Promote toPromote(std::complex<T2> const & v) { return v; }
1207 };
1208
1209 template <class T1, class T2>
1210 struct PromoteTraits<std::complex<T1>, T2 >
1211 {
1212 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1213 static Promote toPromote(std::complex<T1> const & v) { return v; }
1214 static Promote toPromote(T2 const & v) { return Promote(v); }
1215 };
1216
1217 template <class T1, class T2>
1218 struct PromoteTraits<T1, std::complex<T2> >
1219 {
1220 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1221 static Promote toPromote(T1 const & v) { return Promote(v); }
1222 static Promote toPromote(std::complex<T2> const & v) { return v; }
1223 };
1224
1225 #endif
1226
1227 namespace detail {
1228
1229 template <class T>
1230 struct RequiresExplicitCast {
1231 template <class U>
1232 static U const & cast(U const & v)
1233 { return v; }
1234 };
1235
1236 #if !defined(_MSC_VER) || _MSC_VER >= 1300
1237 # define VIGRA_SPECIALIZED_CAST(type) \
1238 template <> \
1239 struct RequiresExplicitCast<type> { \
1240 static type cast(float v) \
1241 { return NumericTraits<type>::fromRealPromote(v); } \
1242 static type cast(double v) \
1243 { return NumericTraits<type>::fromRealPromote(v); } \
1244 static type cast(type v) \
1245 { return v; } \
1246 template <class U> \
1247 static type cast(U v) \
1248 { return static_cast<type>(v); } \
1249 \
1250 };
1251 #else
1252 # define VIGRA_SPECIALIZED_CAST(type) \
1253 template <> \
1254 struct RequiresExplicitCast<type> { \
1255 static type cast(float v) \
1256 { return NumericTraits<type>::fromRealPromote(v); } \
1257 static type cast(double v) \
1258 { return NumericTraits<type>::fromRealPromote(v); } \
1259 static type cast(signed char v) \
1260 { return v; } \
1261 static type cast(unsigned char v) \
1262 { return v; } \
1263 static type cast(short v) \
1264 { return v; } \
1265 static type cast(unsigned short v) \
1266 { return v; } \
1267 static type cast(int v) \
1268 { return v; } \
1269 static type cast(unsigned int v) \
1270 { return v; } \
1271 static type cast(long v) \
1272 { return v; } \
1273 static type cast(unsigned long v) \
1274 { return v; } \
1275 };
1276 #endif
1277
1278
1279 VIGRA_SPECIALIZED_CAST(signed char)
1280 VIGRA_SPECIALIZED_CAST(unsigned char)
1281 VIGRA_SPECIALIZED_CAST(short)
1282 VIGRA_SPECIALIZED_CAST(unsigned short)
1283 VIGRA_SPECIALIZED_CAST(int)
1284 VIGRA_SPECIALIZED_CAST(unsigned int)
1285 VIGRA_SPECIALIZED_CAST(long)
1286 VIGRA_SPECIALIZED_CAST(unsigned long)
1287
1288 template <>
1289 struct RequiresExplicitCast<bool> {
1290 template <class U>
1291 static bool cast(U v)
1292 { return v == NumericTraits<U>::zero()
1293 ? false
1294 : true; }
1295 };
1296
1297 template <>
1298 struct RequiresExplicitCast<float> {
1299 static float cast(int v)
1300 { return (float)v; }
1301
1302 static float cast(unsigned int v)
1303 { return (float)v; }
1304
1305 static float cast(long v)
1306 { return (float)v; }
1307
1308 static float cast(unsigned long v)
1309 { return (float)v; }
1310
1311 static float cast(long long v)
1312 { return (float)v; }
1313
1314 static float cast(unsigned long long v)
1315 { return (float)v; }
1316
1317 static float cast(double v)
1318 { return (float)v; }
1319
1320 static float cast(long double v)
1321 { return (float)v; }
1322
1323 template <class U>
1324 static U cast(U v)
1325 { return v; }
1326 };
1327
1328 template <>
1329 struct RequiresExplicitCast<double> {
1330 static double cast(Int64 v)
1331 { return (double)v; }
1332
1333 static double cast(UInt64 v)
1334 { return (double)v; }
1335
1336 template <class U>
1337 static U cast(U v)
1338 { return v; }
1339 };
1340
1341 #undef VIGRA_SPECIALIZED_CAST
1342
1343 } // namespace detail
1344
1345
1346
1347 } // namespace vigra
1348
1349 #endif // VIGRA_NUMERICTRAITS_HXX
1350

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.10.0 (Mon Nov 18 2013)