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