[ 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 the type itself
156
157 </td></tr>
158 <tr><td>
159 <b> <TT>typedef ... Promote;</TT></b>
160 </td><td>
161 promote type for addition and subtraction
162
163 </td></tr>
164 <tr><td>
165 <b> <TT>typedef ... RealPromote;</TT></b>
166 </td><td>
167 promote type for multiplication and division with a real number
168
169 (only defined if <TT>ArithmeticType</TT> supports these operations)
170
171 </td></tr>
172 <tr><td>
173 <b> <TT>typedef ... ComplexPromote;</TT></b>
174 </td><td>
175 promote type for complex arithmetic
176
177 </td></tr>
178 <tr><td>
179 <b> <TT>typedef ... ValueType;</TT></b>
180 </td><td>
181 for scalar types: the type itself<br>
182 otherwise: typename Type::value_type (if defined)
183
184 </td></tr>
185 <tr><td>
186 <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
187 </td><td>
188 convert to <TT>Promote</TT> type
189
190 </td></tr>
191 <tr><td>
192 <b> <TT>static RealPromote toRealPromote(ArithmeticType v);</TT></b>
193 </td><td>
194 convert to <TT>RealPromote</TT> type
195
196 (only defined if <TT>ArithmeticType</TT> supports multiplication)
197
198 </td></tr>
199 <tr><td>
200 <b> <TT>static ArithmeticType fromPromote(Promote v);</TT></b>
201 </td><td>
202 convert from <TT>Promote</TT> type
203
204 if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped;
205
206 </td></tr>
207 <tr><td>
208 <b> <TT>static ArithmeticType fromRealPromote(RealPromote v);</TT></b>
209 </td><td>
210 convert from <TT>RealPromote</TT> type
211
212 (only defined if
213 <TT>ArithmeticType</TT> supports multiplication)
214
215 if <TT>ArithmeticType</TT> is an integral type, the result is rounded
216
217 if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped
218
219 </td></tr>
220 <tr><td>
221 <b> <TT>static ArithmeticType zero();</TT></b>
222 </td><td>
223 create neutral element of addition
224
225 i.e. <TT>(ArithmeticType a = ...,</TT>
226 <TT> a + NumericTraits<ArithmeticType>::zero() == a)</TT>
227 must always yield <TT>true</TT>
228
229 </td></tr>
230 <tr><td>
231 <b> <TT>static ArithmeticType nonZero();</TT></b>
232 </td><td>
233 create a non-zero element (if multiplication is defined, this yields one())
234
235 i.e. <TT>(ArithmeticType a = ...,</TT>
236 <TT> a + NumericTraits<ArithmeticType>::nonZero() == a)</TT>
237 must always yield <TT>false</TT>
238
239 </td></tr>
240 <tr><td>
241 <b> <TT>static ArithmeticType min();</TT></b>
242 </td><td>
243 the smallest number representable in this type.<br>
244 Only available if isOrdered is VigraTrueType. For integral types,
245 this equals <TT>INT_MIN</TT> etc., for real valued types it is <TT>-FLT_MAX</TT>
246 etc. (<b>not</b> <TT>FLT_MIN</TT> -- this is the smallest positive <tt>float</tt>)
247
248 </td></tr>
249 <tr><td>
250 <b> <TT>static ArithmeticType max();</TT></b>
251 </td><td>
252 the largest number representable in this type.<br>
253 Only available if isOrdered is VigraTrueType. For integral types,
254 this equals <TT>INT_MAX</TT> etc., for real valued types it is <TT>FLT_MAX</TT>
255 etc.
256
257 </td></tr>
258 <tr><td>
259 <b> <TT>static ArithmeticType one();</TT></b>
260 </td><td>
261 create neutral element of multiplication
262
263 (only defined if <TT>ArithmeticType</TT> supports multiplication)
264
265 i.e. <TT>(ArithmeticType a = ...,</TT>
266 <TT> a * NumericTraits<ArithmeticType>::one() == a)</TT>
267 must always yield <TT>true</TT>
268
269 </td></tr>
270 <tr><td>
271 <b> <TT>typedef ... isIntegral;</TT></b>
272 </td><td>
273 VigraTrueType if <TT>ArithmeticType</TT> is an integral type,
274 VigraFalseType otherwise
275
276 </td></tr>
277 <tr><td>
278 <b> <TT>typedef ... isScalar;</TT></b>
279 </td><td>
280 VigraTrueType if <TT>ArithmeticType</TT> is a scalar type,
281 VigraFalseType otherwise
282
283 </td></tr>
284 <tr><td>
285 <tr><td>
286 <b> <TT>typedef ... isSigned;</TT></b>
287 </td><td>
288 VigraTrueType if <TT>ArithmeticType</TT> is a signed type,
289 VigraFalseType otherwise
290
291 </td></tr>
292 <tr><td>
293 <tr><td>
294 <b> <TT>typedef ... isOrdered;</TT></b>
295 </td><td>
296 VigraTrueType if <TT>ArithmeticType</TT> supports operator<(),
297 VigraFalseType otherwise
298
299 </td></tr>
300 <tr><td>
301 <b> <TT>typedef ... isComplex;</TT></b>
302 </td><td>
303 VigraTrueType if <TT>ArithmeticType</TT> is a complex number,
304 VigraFalseType otherwise
305
306 </td></tr>
307 <tr><td>
308 </table>
309
310 NumericTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
311
312 Namespace: vigra
313
314 */
315
316 /** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, ArithmeticType2>
317
318 Binary traits for promotion of arithmetic objects.
319
320 <b>\#include</b> <vigra/numerictraits.hxx>
321
322 This traits class is used to determine the appropriate result type
323 of arithmetic expressions which depend of two arguments. Consider
324 the following function:
325
326 \code
327 template <class T>
328 T min(T t1, T t2)
329 {
330 return (t1 < t2) ? t1 : t2;
331 }
332 \endcode
333
334 This template is only applicable if both arguments have the same
335 type. However, sometimes we may want to use the function in cases
336 where the argument types differ. Then we can deduce the appropriate
337 return type by using <TT>PromoteTraits</TT>:
338
339 \code
340 template <class T1, class T2>
341 typename vigra::PromoteTraits<T1, T2>::Promote
342 min(T1 t1, T2 t2)
343 {
344 return (t1 < t2) ? vigra::PromoteTraits<T1, T2>::toPromote(t1) :
345 vigra::PromoteTraits<T1, T2>::toPromote(t2);
346 }
347 \endcode
348
349 In addition, the traits class provide static functions to cast the
350 arguments to the promote type. For example, if <TT>T1</TT> were <TT>int</TT> and
351 <TT>T2</TT> were <TT>float</TT>, the <TT>Promote</TT> type would be <TT>float</TT>.
352 The following members are defined in
353 <b> <TT>PromoteTraits<ArithmeticType1, ArithmeticType2></TT></b>:
354
355 <table>
356 <tr>
357 <td>
358 <b> <TT>typedef ... Promote;</TT></b>
359 </td><td>
360 promote type
361 </td></tr>
362 <tr><td>
363 <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b>
364
365 <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
366 </td><td>
367 convert to <TT>Promote</TT> type
368 </td></tr>
369 </table>
370
371 PromoteTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
372
373 Namespace: vigra
374 */
375
376 /** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticType>
377
378 Unary traits for the calculation of the square root of arithmetic objects.
379
380 <b>\#include</b> <vigra/numerictraits.hxx>
381
382 This traits class is used to determine appropriate argument and result types
383 for the function sqrt(). These traits are typically used like this:
384
385 \code
386 ArithmeticType t = ...;
387 SquareRootTraits<ArithmeticType>::SquareRootResult r =
388 sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
389 \endcode
390
391 This approach avoids 'ambiguous overload errors' when taking the square root of
392 an integer type. It also takes care of determining the proper result of the
393 sqrt() function of \ref vigra::FixedPoint and of the norm() function, when
394 it is implemented via sqrt(squaredNorm(x)).
395 The following members are defined in <b> <TT>SquareRootTraits<ArithmeticType></TT></b>:
396
397 <table>
398 <tr><td>
399 <b> <TT>typedef ArithmeticType Type;</TT></b>
400 </td><td>
401 the type itself
402 </td></tr>
403 <tr><td>
404 <b> <TT>typedef ... SquareRootArgument;</TT></b>
405 </td><td>
406 required argument type for srqt(), i.e. <tt>sqrt((SquareRootArgument)x)</tt>
407 </td></tr>
408 <tr><td>
409 <b> <TT>typedef ... SquareRootResult;</TT></b>
410 </td><td>
411 result of <tt>sqrt((SquareRootArgument)x)</tt>
412 </td></tr>
413 </table>
414
415 NormTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
416
417 Namespace: vigra
418 */
419
420 /** \page NormTraits template<> struct NormTraits<ArithmeticType>
421
422 Unary traits for the calculation of the norm and squared norm of arithmetic objects.
423
424 <b>\#include</b> <vigra/numerictraits.hxx>
425
426 This traits class is used to determine appropriate result types
427 for the functions norm() and squaredNorm(). These functions are always
428 declared like this (where <tt>ArithmeticType</tt> is a type that supports a norm):
429
430 \code
431 NormTraits<ArithmeticType>::NormType norm(ArithmeticType const & t);
432 NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
433 \endcode
434
435 The following members are defined in <b> <TT>NormTraits<ArithmeticType></TT></b>:
436
437 <table>
438 <tr><td>
439 <b> <TT>typedef ArithmeticType Type;</TT></b>
440 </td><td>
441 the type itself
442 </td></tr>
443 <tr><td>
444 <b> <TT>typedef ... SquaredNormType;</TT></b>
445 </td><td>
446 result of <tt>squaredNorm(ArithmeticType)</tt>
447 </td></tr>
448 <tr><td>
449 <b> <TT>typedef ... NormType;</TT></b>
450 </td><td>
451 result of <tt>norm(ArithmeticType)</tt><br>
452 Usually equal to <tt>SquareRootTraits<SquaredNormType>::SquareRootResult</tt>
453 </td></tr>
454 </table>
455
456 NormTraits for the built-in types are defined in <b>\#include</b> <vigra/numerictraits.hxx>
457
458 Namespace: vigra
459 */
460
461
462 namespace vigra {
463 namespace detail {
464 template <typename s, typename t>
465 inline static t clamp_integer_to_unsigned(s value, t maximum) {
466 return
467 value <= s() ?
468 t() :
469 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
470 }
471
472 template <typename s, typename t>
473 inline static t clamp_integer_to_signed(s value, t minimum, t maximum) {
474 return
475 value <= static_cast<s>(minimum) ?
476 minimum :
477 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value));
478 }
479
480 template <typename s, typename t>
481 inline static t clamp_float_to_unsigned(s value, t maximum) {
482 return
483 value <= s() ?
484 t() :
485 (value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5));
486 }
487
488 template <typename s, typename t>
489 inline static t clamp_float_to_signed(s value, t minimum, t maximum) {
490 if (value >= s()) {
491 return value >= static_cast<s>(maximum) ? maximum : static_cast<t>(value + 0.5);
492 } else {
493 return value <= static_cast<s>(minimum) ? minimum : static_cast<t>(value - 0.5);
494 }
495 }
496 } // end namespace detail
497
498 struct Error_NumericTraits_not_specialized_for_this_case { };
499 struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char { };
500
501 template<class A>
502 struct NumericTraits
503 {
504 typedef Error_NumericTraits_not_specialized_for_this_case Type;
505 typedef Error_NumericTraits_not_specialized_for_this_case Promote;
506 typedef Error_NumericTraits_not_specialized_for_this_case UnsignedPromote;
507 typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
508 typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromote;
509 typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
510
511 typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
512 typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
513 typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
514 typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
515 typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
516 };
517
518 template<>
519 struct NumericTraits<char>
520 {
521 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Type;
522 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Promote;
523 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char UnsignedPromote;
524 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char RealPromote;
525 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ComplexPromote;
526 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ValueType;
527
528 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isScalar;
529 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isIntegral;
530 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isSigned;
531 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isOrdered;
532 typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isComplex;
533 };
534
535 #ifndef NO_BOOL
536 template<>
537 struct NumericTraits<bool>
538 {
539 typedef bool Type;
540 typedef int Promote;
541 typedef unsigned int UnsignedPromote;
542 typedef double RealPromote;
543 typedef std::complex<RealPromote> ComplexPromote;
544 typedef Type ValueType;
545
546 typedef VigraTrueType isIntegral;
547 typedef VigraTrueType isScalar;
548 typedef VigraFalseType isSigned;
549 typedef VigraTrueType isOrdered;
550 typedef VigraFalseType isComplex;
551
552 static bool zero() { return false; }
553 static bool one() { return true; }
554 static bool nonZero() { return true; }
555 static bool min() { return false; }
556 static bool max() { return true; }
557
558 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
559 enum { minConst = false , maxConst = true };
560 #else
561 static const bool minConst = false;
562 static const bool maxConst = true;
563 #endif
564
565 static Promote toPromote(bool v) { return v ? 1 : 0; }
566 static RealPromote toRealPromote(bool v) { return v ? 1.0 : 0.0; }
567 static bool fromPromote(Promote v) {
568 return (v == 0) ? false : true;
569 }
570 static bool fromRealPromote(RealPromote v) {
571 return (v == 0.0) ? false : true;
572 }
573 };
574 #endif
575
576 template<>
577 struct NumericTraits<signed char>
578 {
579 typedef signed char Type;
580 typedef int Promote;
581 typedef unsigned int UnsignedPromote;
582 typedef double RealPromote;
583 typedef std::complex<RealPromote> ComplexPromote;
584 typedef Type ValueType;
585
586 typedef VigraTrueType isIntegral;
587 typedef VigraTrueType isScalar;
588 typedef VigraTrueType isSigned;
589 typedef VigraTrueType isOrdered;
590 typedef VigraFalseType isComplex;
591
592 static signed char zero() { return 0; }
593 static signed char one() { return 1; }
594 static signed char nonZero() { return 1; }
595 static signed char min() { return SCHAR_MIN; }
596 static signed char max() { return SCHAR_MAX; }
597
598 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
599 enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
600 #else
601 static const signed char minConst = SCHAR_MIN;
602 static const signed char maxConst = SCHAR_MIN;
603 #endif
604
605 static Promote toPromote(signed char v) { return v; }
606 static RealPromote toRealPromote(signed char v) { return v; }
607 static signed char fromPromote(Promote v) {
608 return detail::clamp_integer_to_signed<Promote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
609 }
610 static signed char fromRealPromote(RealPromote v) {
611 return detail::clamp_float_to_signed<RealPromote, signed char>(v, SCHAR_MIN, SCHAR_MAX);
612 }
613 };
614
615 template<>
616 struct NumericTraits<unsigned char>
617 {
618 typedef unsigned char Type;
619 typedef int Promote;
620 typedef unsigned int UnsignedPromote;
621 typedef double RealPromote;
622 typedef std::complex<RealPromote> ComplexPromote;
623 typedef Type ValueType;
624
625 typedef VigraTrueType isIntegral;
626 typedef VigraTrueType isScalar;
627 typedef VigraFalseType isSigned;
628 typedef VigraTrueType isOrdered;
629 typedef VigraFalseType isComplex;
630
631 static unsigned char zero() { return 0; }
632 static unsigned char one() { return 1; }
633 static unsigned char nonZero() { return 1; }
634 static unsigned char min() { return 0; }
635 static unsigned char max() { return UCHAR_MAX; }
636
637 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
638 enum { minConst = 0, maxConst = UCHAR_MAX };
639 #else
640 static const unsigned char minConst = 0;
641 static const unsigned char maxConst = UCHAR_MAX;
642 #endif
643
644 static Promote toPromote(unsigned char v) { return v; }
645 static RealPromote toRealPromote(unsigned char v) { return v; }
646 static unsigned char fromPromote(Promote v) {
647 return detail::clamp_integer_to_unsigned<Promote, unsigned char>(v, UCHAR_MAX);
648 }
649 static unsigned char fromRealPromote(RealPromote v) {
650 return detail::clamp_float_to_unsigned<RealPromote, unsigned char>(v, UCHAR_MAX);
651 }
652 };
653
654 template<>
655 struct NumericTraits<short int>
656 {
657 typedef short int Type;
658 typedef int Promote;
659 typedef unsigned int UnsignedPromote;
660 typedef double RealPromote;
661 typedef std::complex<RealPromote> ComplexPromote;
662 typedef Type ValueType;
663
664 typedef VigraTrueType isIntegral;
665 typedef VigraTrueType isScalar;
666 typedef VigraTrueType isSigned;
667 typedef VigraTrueType isOrdered;
668 typedef VigraFalseType isComplex;
669
670 static short int zero() { return 0; }
671 static short int one() { return 1; }
672 static short int nonZero() { return 1; }
673 static short int min() { return SHRT_MIN; }
674 static short int max() { return SHRT_MAX; }
675
676 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
677 enum { minConst = SHRT_MIN, maxConst = SHRT_MAX };
678 #else
679 static const short int minConst = SHRT_MIN;
680 static const short int maxConst = SHRT_MAX;
681 #endif
682
683 static Promote toPromote(short int v) { return v; }
684 static RealPromote toRealPromote(short int v) { return v; }
685 static short int fromPromote(Promote v) {
686 return detail::clamp_integer_to_signed<Promote, short int>(v, SHRT_MIN, SHRT_MAX);
687 }
688 static short int fromRealPromote(RealPromote v) {
689 return detail::clamp_float_to_signed<RealPromote, short int>(v, SHRT_MIN, SHRT_MAX);
690 }
691 };
692
693 template<>
694 struct NumericTraits<short unsigned int>
695 {
696 typedef short unsigned int Type;
697 typedef int Promote;
698 typedef unsigned int UnsignedPromote;
699 typedef double RealPromote;
700 typedef std::complex<RealPromote> ComplexPromote;
701 typedef Type ValueType;
702
703 typedef VigraTrueType isIntegral;
704 typedef VigraTrueType isScalar;
705 typedef VigraFalseType isSigned;
706 typedef VigraTrueType isOrdered;
707 typedef VigraFalseType isComplex;
708
709 static short unsigned int zero() { return 0; }
710 static short unsigned int one() { return 1; }
711 static short unsigned int nonZero() { return 1; }
712 static short unsigned int min() { return 0; }
713 static short unsigned int max() { return USHRT_MAX; }
714
715 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
716 enum { minConst = 0, maxConst = USHRT_MAX };
717 #else
718 static const short unsigned int minConst = 0;
719 static const short unsigned int maxConst = USHRT_MAX;
720 #endif
721
722 static Promote toPromote(short unsigned int v) { return v; }
723 static RealPromote toRealPromote(short unsigned int v) { return v; }
724 static short unsigned int fromPromote(Promote v) {
725 return detail::clamp_integer_to_unsigned<Promote, short unsigned int>(v, USHRT_MAX);
726 }
727 static short unsigned int fromRealPromote(RealPromote v) {
728 return detail::clamp_float_to_unsigned<RealPromote, short unsigned int>(v, USHRT_MAX);
729 }
730 };
731
732 template<>
733 struct NumericTraits<int>
734 {
735 typedef int Type;
736 typedef int Promote;
737 typedef unsigned int UnsignedPromote;
738 typedef double RealPromote;
739 typedef std::complex<RealPromote> ComplexPromote;
740 typedef Type ValueType;
741
742 typedef VigraTrueType isIntegral;
743 typedef VigraTrueType isScalar;
744 typedef VigraTrueType isSigned;
745 typedef VigraTrueType isOrdered;
746 typedef VigraFalseType isComplex;
747
748 static int zero() { return 0; }
749 static int one() { return 1; }
750 static int nonZero() { return 1; }
751 static int min() { return INT_MIN; }
752 static int max() { return INT_MAX; }
753
754 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
755 enum { minConst = INT_MIN, maxConst = INT_MAX };
756 #else
757 static const int minConst = INT_MIN;
758 static const int maxConst = INT_MAX;
759 #endif
760
761 static Promote toPromote(int v) { return v; }
762 static RealPromote toRealPromote(int v) { return v; }
763 static int fromPromote(Promote v) { return v; }
764 static int fromRealPromote(RealPromote v) {
765 return detail::clamp_float_to_signed<RealPromote, int>(v, INT_MIN, INT_MAX);
766 }
767 };
768
769 template<>
770 struct NumericTraits<unsigned int>
771 {
772 typedef unsigned int Type;
773 typedef unsigned int Promote;
774 typedef unsigned int UnsignedPromote;
775 typedef double RealPromote;
776 typedef std::complex<RealPromote> ComplexPromote;
777 typedef Type ValueType;
778
779 typedef VigraTrueType isIntegral;
780 typedef VigraTrueType isScalar;
781 typedef VigraFalseType isSigned;
782 typedef VigraTrueType isOrdered;
783 typedef VigraFalseType isComplex;
784
785 static unsigned int zero() { return 0; }
786 static unsigned int one() { return 1; }
787 static unsigned int nonZero() { return 1; }
788 static unsigned int min() { return 0; }
789 static unsigned int max() { return UINT_MAX; }
790
791 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
792 enum { minConst = 0, maxConst = UINT_MAX };
793 #else
794 static const unsigned int minConst = 0;
795 static const unsigned int maxConst = UINT_MAX;
796 #endif
797
798 static Promote toPromote(unsigned int v) { return v; }
799 static RealPromote toRealPromote(unsigned int v) { return v; }
800 static unsigned int fromPromote(Promote v) { return v; }
801 static unsigned int fromRealPromote(RealPromote v) {
802 return detail::clamp_float_to_unsigned<RealPromote, unsigned int>(v, UINT_MAX);
803 }
804 };
805
806 template<>
807 struct NumericTraits<long>
808 {
809 typedef long Type;
810 typedef long Promote;
811 typedef unsigned long UnsignedPromote;
812 typedef double RealPromote;
813 typedef std::complex<RealPromote> ComplexPromote;
814 typedef Type ValueType;
815
816 typedef VigraTrueType isIntegral;
817 typedef VigraTrueType isScalar;
818 typedef VigraTrueType isSigned;
819 typedef VigraTrueType isOrdered;
820 typedef VigraFalseType isComplex;
821
822 static long zero() { return 0; }
823 static long one() { return 1; }
824 static long nonZero() { return 1; }
825 static long min() { return LONG_MIN; }
826 static long max() { return LONG_MAX; }
827
828 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
829 enum { minConst = LONG_MIN, maxConst = LONG_MAX };
830 #else
831 static const long minConst = LONG_MIN;
832 static const long maxConst = LONG_MAX;
833 #endif
834
835 static Promote toPromote(long v) { return v; }
836 static RealPromote toRealPromote(long v) { return static_cast<RealPromote>(v); }
837 static long fromPromote(Promote v) { return v; }
838 static long fromRealPromote(RealPromote v) {
839 return detail::clamp_float_to_signed<RealPromote, long>(v, LONG_MIN, LONG_MAX);
840 }
841 };
842
843 template<>
844 struct NumericTraits<unsigned long>
845 {
846 typedef unsigned long Type;
847 typedef unsigned long Promote;
848 typedef unsigned long UnsignedPromote;
849 typedef double RealPromote;
850 typedef std::complex<RealPromote> ComplexPromote;
851 typedef Type ValueType;
852
853 typedef VigraTrueType isIntegral;
854 typedef VigraTrueType isScalar;
855 typedef VigraFalseType isSigned;
856 typedef VigraTrueType isOrdered;
857 typedef VigraFalseType isComplex;
858
859 static unsigned long zero() { return 0; }
860 static unsigned long one() { return 1; }
861 static unsigned long nonZero() { return 1; }
862 static unsigned long min() { return 0; }
863 static unsigned long max() { return ULONG_MAX; }
864
865 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
866 enum { minConst = 0, maxConst = ULONG_MAX };
867 #else
868 static const unsigned long minConst = 0;
869 static const unsigned long maxConst = ULONG_MAX;
870 #endif
871
872 static Promote toPromote(unsigned long v) { return v; }
873 static RealPromote toRealPromote(unsigned long v) { return static_cast<RealPromote>(v); }
874 static unsigned long fromPromote(Promote v) { return v; }
875 static unsigned long fromRealPromote(RealPromote v) {
876 return detail::clamp_float_to_unsigned<RealPromote, unsigned long>(v, ULONG_MAX);
877 }
878 };
879
880 #ifdef LLONG_MAX
881 template<>
882 struct NumericTraits<long long>
883 {
884 typedef long long Type;
885 typedef long long Promote;
886 typedef unsigned long long UnsignedPromote;
887 typedef double RealPromote;
888 typedef std::complex<RealPromote> ComplexPromote;
889 typedef Type ValueType;
890
891 typedef VigraTrueType isIntegral;
892 typedef VigraTrueType isScalar;
893 typedef VigraTrueType isSigned;
894 typedef VigraTrueType isOrdered;
895 typedef VigraFalseType isComplex;
896
897 static long long zero() { return 0; }
898 static long long one() { return 1; }
899 static long long nonZero() { return 1; }
900 static long long min() { return LLONG_MIN; }
901 static long long max() { return LLONG_MAX; }
902
903 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
904 enum { minConst = LLONG_MIN, maxConst = LLONG_MAX };
905 #else
906 static const long long minConst = LLONG_MIN;
907 static const long long maxConst = LLONG_MAX;
908 #endif
909
910 static Promote toPromote(long long v) { return v; }
911 static RealPromote toRealPromote(long long v) { return (RealPromote)v; }
912 static long long fromPromote(Promote v) { return v; }
913 static long long fromRealPromote(RealPromote v) {
914 return detail::clamp_float_to_signed<RealPromote, long long>(v, LLONG_MIN, LLONG_MAX);
915 }
916 };
917
918 template<>
919 struct NumericTraits<unsigned long long>
920 {
921 typedef unsigned long long Type;
922 typedef unsigned long long Promote;
923 typedef unsigned long long UnsignedPromote;
924 typedef double RealPromote;
925 typedef std::complex<RealPromote> ComplexPromote;
926 typedef Type ValueType;
927
928 typedef VigraTrueType isIntegral;
929 typedef VigraTrueType isScalar;
930 typedef VigraFalseType isSigned;
931 typedef VigraTrueType isOrdered;
932 typedef VigraFalseType isComplex;
933
934 static unsigned long long zero() { return 0; }
935 static unsigned long long one() { return 1; }
936 static unsigned long long nonZero() { return 1; }
937 static unsigned long long min() { return 0; }
938 static unsigned long long max() { return ULLONG_MAX; }
939
940 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
941 enum { minConst = 0, maxConst = ULLONG_MAX };
942 #else
943 static const unsigned long long minConst = 0;
944 static const unsigned long long maxConst = ULLONG_MAX;
945 #endif
946
947 static Promote toPromote(unsigned long long v) { return v; }
948 static RealPromote toRealPromote(unsigned long long v) { return (RealPromote)v; }
949 static unsigned long long fromPromote(Promote v) { return v; }
950 static unsigned long long fromRealPromote(RealPromote v) {
951 return detail::clamp_float_to_unsigned<RealPromote, unsigned long long>(v, ULLONG_MAX);
952 }
953 };
954 #endif // LLONG_MAX
955
956 template<>
957 struct NumericTraits<float>
958 {
959 typedef float Type;
960 typedef float Promote;
961 typedef float UnsignedPromote;
962 typedef float RealPromote;
963 typedef std::complex<RealPromote> ComplexPromote;
964 typedef Type ValueType;
965
966 typedef VigraFalseType isIntegral;
967 typedef VigraTrueType isScalar;
968 typedef VigraTrueType isSigned;
969 typedef VigraTrueType isOrdered;
970 typedef VigraFalseType isComplex;
971
972 static float zero() { return 0.0; }
973 static float one() { return 1.0; }
974 static float nonZero() { return 1.0; }
975 static float epsilon() { return FLT_EPSILON; }
976 static float smallestPositive() { return FLT_MIN; }
977 static float min() { return -FLT_MAX; }
978 static float max() { return FLT_MAX; }
979
980 static Promote toPromote(float v) { return v; }
981 static RealPromote toRealPromote(float v) { return v; }
982 static float fromPromote(Promote v) { return v; }
983 static float fromRealPromote(RealPromote v) { return v; }
984 };
985
986 template<>
987 struct NumericTraits<double>
988 {
989 typedef double Type;
990 typedef double Promote;
991 typedef double UnsignedPromote;
992 typedef double RealPromote;
993 typedef std::complex<RealPromote> ComplexPromote;
994 typedef Type ValueType;
995
996 typedef VigraFalseType isIntegral;
997 typedef VigraTrueType isScalar;
998 typedef VigraTrueType isSigned;
999 typedef VigraTrueType isOrdered;
1000 typedef VigraFalseType isComplex;
1001
1002 static double zero() { return 0.0; }
1003 static double one() { return 1.0; }
1004 static double nonZero() { return 1.0; }
1005 static double epsilon() { return DBL_EPSILON; }
1006 static double smallestPositive() { return DBL_MIN; }
1007 static double min() { return -DBL_MAX; }
1008 static double max() { return DBL_MAX; }
1009
1010 static Promote toPromote(double v) { return v; }
1011 static RealPromote toRealPromote(double v) { return v; }
1012 static double fromPromote(Promote v) { return v; }
1013 static double fromRealPromote(RealPromote v) { return v; }
1014 };
1015
1016 template<>
1017 struct NumericTraits<long double>
1018 {
1019 typedef long double Type;
1020 typedef long double Promote;
1021 typedef long double UnsignedPromote;
1022 typedef long double RealPromote;
1023 typedef std::complex<RealPromote> ComplexPromote;
1024 typedef Type ValueType;
1025
1026 typedef VigraFalseType isIntegral;
1027 typedef VigraTrueType isScalar;
1028 typedef VigraTrueType isSigned;
1029 typedef VigraTrueType isOrdered;
1030 typedef VigraFalseType isComplex;
1031
1032 static long double zero() { return 0.0; }
1033 static long double one() { return 1.0; }
1034 static long double nonZero() { return 1.0; }
1035 static long double epsilon() { return LDBL_EPSILON; }
1036 static long double smallestPositive() { return LDBL_MIN; }
1037 static long double min() { return -LDBL_MAX; }
1038 static long double max() { return LDBL_MAX; }
1039
1040 static Promote toPromote(long double v) { return v; }
1041 static RealPromote toRealPromote(long double v) { return v; }
1042 static long double fromPromote(Promote v) { return v; }
1043 static long double fromRealPromote(RealPromote v) { return v; }
1044 };
1045
1046 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1047
1048 template<class T>
1049 struct NumericTraits<std::complex<T> >
1050 {
1051 typedef std::complex<T> Type;
1052 typedef std::complex<typename NumericTraits<T>::Promote> Promote;
1053 typedef std::complex<typename NumericTraits<T>::UnsignedPromote> UnsignedPromote;
1054 typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromote;
1055 typedef std::complex<RealPromote> ComplexPromote;
1056 typedef T ValueType;
1057
1058 typedef VigraFalseType isIntegral;
1059 typedef VigraFalseType isScalar;
1060 typedef typename NumericTraits<T>::isSigned isSigned;
1061 typedef VigraFalseType isOrdered;
1062 typedef VigraTrueType isComplex;
1063
1064 static Type zero() { return Type(0.0); }
1065 static Type one() { return Type(1.0); }
1066 static Type nonZero() { return one(); }
1067 static Type epsilon() { return Type(NumericTraits<T>::epsilon()); }
1068 static Type smallestPositive() { return Type(NumericTraits<T>::smallestPositive()); }
1069
1070 static Promote toPromote(Type const & v) { return v; }
1071 static Type fromPromote(Promote const & v) { return v; }
1072 static Type fromRealPromote(RealPromote v) { return Type(v); }
1073 };
1074
1075 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1076
1077 /********************************************************/
1078 /* */
1079 /* SquareRootTraits */
1080 /* */
1081 /********************************************************/
1082
1083 template<class T>
1084 struct SquareRootTraits
1085 {
1086 typedef T Type;
1087 typedef typename NumericTraits<T>::RealPromote SquareRootResult;
1088 typedef typename NumericTraits<T>::RealPromote SquareRootArgument;
1089 };
1090
1091
1092 /********************************************************/
1093 /* */
1094 /* NormTraits */
1095 /* */
1096 /********************************************************/
1097
1098 struct Error_NormTraits_not_specialized_for_this_case { };
1099
1100 template<class T>
1101 struct NormTraits
1102 {
1103 typedef T Type;
1104 typedef Error_NormTraits_not_specialized_for_this_case SquaredNormType;
1105 typedef Error_NormTraits_not_specialized_for_this_case NormType;
1106 };
1107
1108 #define VIGRA_DEFINE_NORM_TRAITS(T) \
1109 template <> struct NormTraits<T> { \
1110 typedef T Type; \
1111 typedef NumericTraits<T>::Promote SquaredNormType; \
1112 typedef T NormType; \
1113 };
1114
1115 VIGRA_DEFINE_NORM_TRAITS(bool)
1116 VIGRA_DEFINE_NORM_TRAITS(signed char)
1117 VIGRA_DEFINE_NORM_TRAITS(unsigned char)
1118 VIGRA_DEFINE_NORM_TRAITS(short)
1119 VIGRA_DEFINE_NORM_TRAITS(unsigned short)
1120 VIGRA_DEFINE_NORM_TRAITS(int)
1121 VIGRA_DEFINE_NORM_TRAITS(unsigned int)
1122 VIGRA_DEFINE_NORM_TRAITS(long)
1123 VIGRA_DEFINE_NORM_TRAITS(unsigned long)
1124 VIGRA_DEFINE_NORM_TRAITS(float)
1125 VIGRA_DEFINE_NORM_TRAITS(double)
1126 VIGRA_DEFINE_NORM_TRAITS(long double)
1127
1128 #ifdef LLONG_MAX
1129 VIGRA_DEFINE_NORM_TRAITS(long long)
1130 VIGRA_DEFINE_NORM_TRAITS(unsigned long long)
1131 #endif // LLONG_MAX
1132
1133 #undef VIGRA_DEFINE_NORM_TRAITS
1134
1135 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1136
1137 template<class T>
1138 struct NormTraits<std::complex<T> >
1139 {
1140 typedef std::complex<T> Type;
1141 typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
1142 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
1143 };
1144
1145 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1146
1147 /********************************************************/
1148 /* */
1149 /* PromoteTraits */
1150 /* */
1151 /********************************************************/
1152
1153 namespace detail {
1154
1155 template <class T, class U>
1156 struct PromoteType
1157 {
1158 static T & t();
1159 static U & u();
1160 // let C++ figure out the promote type by adding a T and an U
1161 typedef typename SizeToType<sizeof(*typeToSize(t() + u()))>::result Promote;
1162 static Promote toPromote(T t) { return Promote(t); }
1163 static Promote toPromote(U u) { return Promote(u); }
1164 };
1165
1166
1167 template <class T>
1168 struct PromoteType<T, T>
1169 {
1170 static T & t();
1171 // let C++ figure out the promote type by adding two Ts
1172 typedef typename SizeToType<sizeof(*typeToSize(t() + t()))>::result Promote;
1173 static Promote toPromote(T t) { return Promote(t); }
1174 };
1175
1176 } // namespace detail
1177
1178 struct Error_PromoteTraits_not_specialized_for_this_case { };
1179
1180 template<class A, class B>
1181 struct PromoteTraits
1182 {
1183 typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
1184 };
1185
1186 #include "promote_traits.hxx"
1187
1188 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
1189
1190 template <class T>
1191 struct PromoteTraits<std::complex<T>, std::complex<T> >
1192 {
1193 typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
1194 static Promote toPromote(std::complex<T> const & v) { return v; }
1195 };
1196
1197 template <class T1, class T2>
1198 struct PromoteTraits<std::complex<T1>, std::complex<T2> >
1199 {
1200 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1201 static Promote toPromote(std::complex<T1> const & v) { return v; }
1202 static Promote toPromote(std::complex<T2> const & v) { return v; }
1203 };
1204
1205 template <class T1, class T2>
1206 struct PromoteTraits<std::complex<T1>, T2 >
1207 {
1208 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1209 static Promote toPromote(std::complex<T1> const & v) { return v; }
1210 static Promote toPromote(T2 const & v) { return Promote(v); }
1211 };
1212
1213 template <class T1, class T2>
1214 struct PromoteTraits<T1, std::complex<T2> >
1215 {
1216 typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
1217 static Promote toPromote(T1 const & v) { return Promote(v); }
1218 static Promote toPromote(std::complex<T2> const & v) { return v; }
1219 };
1220
1221 #endif
1222
1223 namespace detail {
1224
1225 template <class T>
1226 struct RequiresExplicitCast {
1227 template <class U>
1228 static U const & cast(U const & v)
1229 { return v; }
1230 };
1231
1232 #if !defined(_MSC_VER) || _MSC_VER >= 1300
1233 # define VIGRA_SPECIALIZED_CAST(type) \
1234 template <> \
1235 struct RequiresExplicitCast<type> { \
1236 static type cast(float v) \
1237 { return NumericTraits<type>::fromRealPromote(v); } \
1238 static type cast(double v) \
1239 { return NumericTraits<type>::fromRealPromote(v); } \
1240 static type cast(type v) \
1241 { return v; } \
1242 template <class U> \
1243 static type cast(U v) \
1244 { return static_cast<type>(v); } \
1245 \
1246 };
1247 #else
1248 # define VIGRA_SPECIALIZED_CAST(type) \
1249 template <> \
1250 struct RequiresExplicitCast<type> { \
1251 static type cast(float v) \
1252 { return NumericTraits<type>::fromRealPromote(v); } \
1253 static type cast(double v) \
1254 { return NumericTraits<type>::fromRealPromote(v); } \
1255 static type cast(signed char v) \
1256 { return v; } \
1257 static type cast(unsigned char v) \
1258 { return v; } \
1259 static type cast(short v) \
1260 { return v; } \
1261 static type cast(unsigned short v) \
1262 { return v; } \
1263 static type cast(int v) \
1264 { return v; } \
1265 static type cast(unsigned int v) \
1266 { return v; } \
1267 static type cast(long v) \
1268 { return v; } \
1269 static type cast(unsigned long v) \
1270 { return v; } \
1271 };
1272 #endif
1273
1274
1275 VIGRA_SPECIALIZED_CAST(signed char)
1276 VIGRA_SPECIALIZED_CAST(unsigned char)
1277 VIGRA_SPECIALIZED_CAST(short)
1278 VIGRA_SPECIALIZED_CAST(unsigned short)
1279 VIGRA_SPECIALIZED_CAST(int)
1280 VIGRA_SPECIALIZED_CAST(unsigned int)
1281 VIGRA_SPECIALIZED_CAST(long)
1282 VIGRA_SPECIALIZED_CAST(unsigned long)
1283
1284 template <>
1285 struct RequiresExplicitCast<bool> {
1286 template <class U>
1287 static bool cast(U v)
1288 { return v == NumericTraits<U>::zero()
1289 ? false
1290 : true; }
1291 };
1292
1293 template <>
1294 struct RequiresExplicitCast<float> {
1295 static float cast(int v)
1296 { return (float)v; }
1297
1298 static float cast(unsigned int v)
1299 { return (float)v; }
1300
1301 static float cast(long v)
1302 { return (float)v; }
1303
1304 static float cast(unsigned long v)
1305 { return (float)v; }
1306
1307 static float cast(long long v)
1308 { return (float)v; }
1309
1310 static float cast(unsigned long long v)
1311 { return (float)v; }
1312
1313 static float cast(double v)
1314 { return (float)v; }
1315
1316 static float cast(long double v)
1317 { return (float)v; }
1318
1319 template <class U>
1320 static U cast(U v)
1321 { return v; }
1322 };
1323
1324 template <>
1325 struct RequiresExplicitCast<double> {
1326 static double cast(Int64 v)
1327 { return (double)v; }
1328
1329 static double cast(UInt64 v)
1330 { return (double)v; }
1331
1332 template <class U>
1333 static U cast(U v)
1334 { return v; }
1335 };
1336
1337 #undef VIGRA_SPECIALIZED_CAST
1338
1339 } // namespace detail
1340
1341
1342
1343 } // namespace vigra
1344
1345 #endif // VIGRA_NUMERICTRAITS_HXX
1346
vigra::Int64
detail::SelectIntegerType< 64, detail::SignedIntTypes >::type Int64
64-bit signed int
Definition: sized_int.hxx:177
vigra::UInt64
detail::SelectIntegerType< 64, detail::UnsignedIntTypes >::type UInt64
64-bit unsigned int
Definition: sized_int.hxx:185

© 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.11.1 (Fri May 19 2017)