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

numerictraits.hxx VIGRA

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 
detail::SelectIntegerType< 64, detail::SignedIntTypes >::type Int64
64-bit signed int
Definition: sized_int.hxx:177
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.10.0 (Fri Feb 21 2014)