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

details vigra/numerictraits.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.2.0, Aug 07 2003 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022  
00023  
00024 #ifndef VIGRA_NUMERICTRAITS_HXX
00025 #define VIGRA_NUMERICTRAITS_HXX
00026 
00027 #include <limits.h>
00028 #include <cfloat>
00029 #include "vigra/metaprogramming.hxx"
00030 
00031 /********************************************************/
00032 /*                                                      */
00033 /*                      NumericTraits                   */
00034 /*                                                      */
00035 /********************************************************/
00036 
00037 
00038 /** \page NumericPromotionTraits Numeric and Promotion Traits
00039 
00040     Meta-information about arithmetic types.
00041     
00042     <DL>
00043     <DT>
00044     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 
00045     \ref NumericTraits
00046     <DD><em>Unary traits for promotion, conversion, creation of arithmetic objects</em>
00047     <DT>
00048     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 
00049     \ref PromoteTraits
00050     <DD><em>Binary traits for promotion of arithmetic objects</em>
00051     </DL>
00052     
00053     These traits classes contain information that is used by generic
00054     algorithms and data structures to determine intermediate and result
00055     types of numerical calculations, to convert between different 
00056     representations of arithmetic types, and to create certain important
00057     constants of each type. Thus, algorithms and data structures
00058     operating that need arithmetic operations can be made more
00059     independent from the actual data representation.
00060     
00061     NumericTraits are implemented as template specializations of one
00062     arithmetic type, while PromoteTraits are specialized for a pair of
00063     arithmetic types that shall be combined in one operation.    
00064 */
00065 
00066 /** \page NumericTraits template<> struct NumericTraits<ArithmeticType>
00067 
00068     Unary traits for promotion, conversion, creation of arithmetic objects.
00069 
00070     <b>\#include</b> 
00071     "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
00072 
00073     This traits class is used derive important properties of
00074     an arithmetic type. Consider the following algorithm:
00075     
00076     \code
00077     // calculate the sum of a sequence of bytes
00078     int sumBytes(unsigned char * begin, unsigned char * end)
00079     {
00080         int result = 0;
00081         for(; begin != end; ++begin)  result += *begin;
00082         return result;
00083     }
00084     \endcode 
00085     
00086     The return type of this function can not be 'unsigned char' because
00087     the summation would very likely overflow. Since we know the source
00088     type, we can easily choose 'int' as an appropriate return type.
00089     Likewise, we would have choosen 'float' if we had to sum a 
00090     sequence of floats. If we want to make this 
00091     algorithm generic, we would like to derive the appropriate return 
00092     type automatically. This can be done with NumericTraits. 
00093     The code would look like this (we use \ref DataAccessors to 
00094     read the data from the sequence):
00095     
00096     \code
00097     // calculate the sum of any sequence
00098     template <class Iterator, class Accessor>
00099     typename vigra::NumericTraits<typename Accessor::value_type>::Promote
00100     sumSequence(Iterator begin, Iterator end, Accessor a)
00101     {
00102         // an abbreviation
00103         typedef vigra::NumericTraits<typename Accessor::value_type>  SrcTraits;
00104         
00105         // find out result type
00106         typedef typename SrcTraits::Promote ResultType;
00107       
00108         // init result to zero
00109         ResultType result = vigra::NumericTraits<ResultType>::zero();
00110     
00111         for(; begin != end; ++begin)
00112         {  
00113             // cast current item to ResultType and add
00114             result += SrcTraits::toPromote(a(begin));
00115         }
00116         
00117         return result;
00118     }
00119     \endcode
00120     
00121     In this example NumericTraits is not only used to deduce the 
00122     ReturnType of the operation, but also to initialize it with the
00123     constant 'zero'. This is necessary since we do not know in general,
00124     which expression must be used to obtain a zero of some arbitrary
00125     type - '<TT>ResultType result = 0;</TT>' would only work if the 
00126     ResultType had an constructor taking an '<TT>int</TT>' argument, and we 
00127     would not even have any guarantee as to what the semantics of this
00128     constructor are. In addition, the traits are used to cast the 
00129     source type into the promote type.
00130     
00131     Similarly, an algorithm that needs multiplication would use the 
00132     return type <TT>RealPromote</TT> and the functions <TT>one()</TT> and
00133     <TT>toRealPromote()</TT>. The following members are defined in 
00134     <b> <TT>NumericTraits<ArithmeticType></TT></b>:
00135     
00136     <table>
00137     <tr>
00138     <td>
00139     <b> <TT>typedef ... Promote;</TT></b>
00140     </td><td>
00141     
00142             promote type for addition and subtraction 
00143         
00144     </td></tr>
00145     <tr><td>
00146     <b> <TT>typedef ... RealPromote;</TT></b>
00147     </td><td>
00148             promote type for multiplication and division
00149     
00150     (only defined if <TT>ArithmeticType</TT> supports these operations) 
00151     
00152     </td></tr>
00153     <tr><td>
00154     <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
00155     </td><td>
00156         convert to <TT>Promote</TT> type 
00157     
00158     </td></tr>
00159     <tr><td>
00160     <b> <TT>static RealPromote toRealPromote(ArithmeticType v);</TT></b>
00161     </td><td>
00162         convert to <TT>RealPromote</TT> type 
00163 
00164     (only defined if <TT>ArithmeticType</TT> supports multiplication) 
00165     
00166     </td></tr>
00167     <tr><td>
00168     <b> <TT>static ArithmeticType fromPromote(Promote v);</TT></b> 
00169     </td><td>
00170         convert from <TT>Promote</TT> type
00171     
00172     if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped;
00173 
00174     </td></tr>
00175     <tr><td>
00176     <b> <TT>static ArithmeticType fromRealPromote(RealPromote v);</TT></b>
00177     </td><td>
00178         convert from <TT>RealPromote</TT> type 
00179     
00180     (only defined if 
00181     <TT>ArithmeticType</TT> supports multiplication)
00182     
00183     if <TT>ArithmeticType</TT> is an integral type, the result is rounded 
00184     
00185     if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped
00186     
00187     </td></tr>
00188     <tr><td>
00189     <b> <TT>static ArithmeticType zero();</TT></b>
00190     </td><td>
00191     create neutral element of addition
00192     
00193     i.e. <TT>(ArithmeticType a = ...,</TT> 
00194     <TT>  a + NumericTraits<ArithmeticType>::zero() == a)</TT> 
00195     must always yield <TT>true</TT> 
00196     
00197     </td></tr>
00198     <tr><td>
00199     <b> <TT>static ArithmeticType nonZero();</TT></b>
00200     </td><td>
00201     create a non-zero element (if multiplication is defined, this yields one())
00202     
00203     i.e. <TT>(ArithmeticType a = ...,</TT> 
00204     <TT>  a + NumericTraits<ArithmeticType>::nonZero() == a)</TT> 
00205     must always yield <TT>false</TT> 
00206     
00207     </td></tr>
00208     <tr><td>
00209     <b> <TT>static ArithmeticType one();</TT></b>
00210     </td><td>
00211     create neutral element of multiplication 
00212     
00213     (only defined if <TT>ArithmeticType</TT> supports multiplication)
00214     
00215     i.e. <TT>(ArithmeticType a = ...,</TT> 
00216     <TT>  a * NumericTraits<ArithmeticType>::one() == a)</TT> 
00217     must always yield <TT>true</TT> 
00218     
00219     </td></tr>
00220     <tr><td>
00221     <b> <TT>static const bool is_integral;</TT></b>
00222     </td><td>
00223         true if <TT>ArithmeticType</TT> is an integral type, false otherwise 
00224     
00225     </td></tr>
00226     <tr><td>
00227     <b> <TT>static const bool is_scalar;</TT></b>
00228     </td><td>
00229         true if <TT>ArithmeticType</TT> is a scalar type, false otherwise 
00230     
00231     </td></tr>
00232     <tr><td>
00233     </table>
00234     
00235     NumericTraits for the built-in types are defined in <b>\#include</b> 
00236     "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
00237     
00238     Namespace: vigra
00239     
00240 */
00241 
00242 /** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, ArithmeticType2>
00243 
00244     Binary traits for promotion of arithmetic objects.
00245     
00246     <b>\#include</b> 
00247     "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
00248 
00249     This traits class is used to determine the appropriate result type
00250     of arithmetic expressions which depend of two arguments. Consider
00251     the following function:
00252     
00253     \code
00254     template <class T>
00255     T min(T t1, T t2)
00256     {
00257         return (t1 < t2) ? t1 : t2;
00258     }
00259     \endcode
00260     
00261     This template is only applicable if both arguments have the same
00262     type. However, sometimes we may want to use the function in cases
00263     where the argument types differ. The we can deduce the approrpiate
00264     return type by using <TT>PromoteTraits</TT>:
00265     
00266     \code
00267     template <class T1, class T2>
00268     typename vigra::PromoteTraits<T1, T2>::Promote
00269     min(T1 t1, T2 t2)
00270     {
00271         return (t1 < t2) ? vigra::PromoteTraits<T1, T2>::toPromote(t1) : 
00272                            vigra::PromoteTraits<T1, T2>::toPromote(t2);
00273     }    
00274     \endcode
00275     
00276     In addition, the traits class provide static functions to cast the
00277     arguments to the promote type. For example, if <TT>T1</TT> were <TT>int</TT> and 
00278     <TT>T2</TT> were <TT>float</TT>, the <TT>Promote</TT> type would be <TT>float</TT>. 
00279     The following members are defined in 
00280     <b> <TT>PromoteTraits<ArithmeticType1, ArithmeticType2></TT></b>:
00281     
00282     <table>
00283     <tr>
00284     <td>
00285     <b> <TT>typedef ... Promote;</TT></b>
00286     </td><td>
00287             promote type 
00288     </td></tr>
00289     <tr><td>
00290     <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b> 
00291     
00292     <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
00293     </td><td>
00294         convert to <TT>Promote</TT> type 
00295     </td></tr>
00296     </table>
00297     
00298     PromoteTraits for the built-in types are defined in <b>\#include</b> 
00299     "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
00300     
00301     Namespace: vigra
00302 */
00303 
00304 namespace vigra {
00305 
00306 struct Error_NumericTraits_not_specialized_for_this_case { };
00307 
00308 template<class A>
00309 struct NumericTraits
00310 {
00311     typedef Error_NumericTraits_not_specialized_for_this_case Promote;
00312     typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
00313     typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
00314     typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
00315     typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
00316 };
00317 
00318 #ifndef NO_BOOL
00319 template<>
00320 struct NumericTraits<bool>
00321 {
00322     typedef bool Type;
00323     typedef int Promote;
00324     typedef double RealPromote;
00325     typedef VigraTrueType isIntegral;
00326     typedef VigraTrueType isScalar;
00327     typedef VigraTrueType isOrdered;
00328     
00329     static bool zero() { return false; }
00330     static bool one() { return true; }
00331     static bool nonZero() { return true; }
00332     static bool min() { return false; }
00333     static bool max() { return true; }
00334     
00335 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00336     enum { minConst = false , maxConst = true };
00337 #else
00338     static const bool minConst = false;
00339     static const bool maxConst = true;
00340 #endif
00341     
00342     static Promote toPromote(bool v) { return v ? 1 : 0; }
00343     static RealPromote toRealPromote(bool v) { return v ? 1.0 : 0.0; }
00344     static bool fromPromote(Promote v) { 
00345         return (v == 0) ? false : true; 
00346     }
00347     static bool fromRealPromote(RealPromote v) {
00348         return (v == 0.0) ? false : true; 
00349     }
00350 };
00351 #endif
00352 
00353 template<>
00354 struct NumericTraits<signed char>
00355 {
00356     typedef signed char Type;
00357     typedef int Promote;
00358     typedef double RealPromote;
00359     typedef VigraTrueType isIntegral;
00360     typedef VigraTrueType isScalar;
00361     typedef VigraTrueType isOrdered;
00362     
00363     static signed char zero() { return 0; }
00364     static signed char one() { return 1; }
00365     static signed char nonZero() { return 1; }
00366     static signed char min() { return SCHAR_MIN; }
00367     static signed char max() { return SCHAR_MAX; }
00368     
00369 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00370     enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
00371 #else
00372     static const signed char minConst = SCHAR_MIN;
00373     static const signed char maxConst = SCHAR_MIN;
00374 #endif
00375     
00376     static Promote toPromote(signed char v) { return v; }
00377     static RealPromote toRealPromote(signed char v) { return v; }
00378     static signed char fromPromote(Promote v) { 
00379         return ((v < SCHAR_MIN) ? SCHAR_MIN : (v > SCHAR_MAX) ? SCHAR_MAX : v); 
00380     }
00381     static signed char fromRealPromote(RealPromote v) {
00382         return ((v < 0.0) ? ((v < (float)SCHAR_MIN) ? SCHAR_MIN : static_cast<signed char>(v - 0.5)) : 
00383                 (v > SCHAR_MAX) ? SCHAR_MAX : static_cast<signed char>(v + 0.5)); 
00384     }
00385 };
00386 
00387 template<>
00388 struct NumericTraits<unsigned char>
00389 {
00390     typedef unsigned char Type;
00391     typedef int Promote;
00392     typedef double RealPromote;
00393     typedef VigraTrueType isIntegral;
00394     typedef VigraTrueType isScalar;
00395     typedef VigraTrueType isOrdered;
00396     
00397     static unsigned char zero() { return 0; }
00398     static unsigned char one() { return 1; }
00399     static unsigned char nonZero() { return 1; }
00400     static unsigned char min() { return 0; }
00401     static unsigned char max() { return UCHAR_MAX; }
00402     
00403 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00404     enum { minConst = 0, maxConst = UCHAR_MAX };
00405 #else
00406     static const unsigned char minConst = 0;
00407     static const unsigned char maxConst = UCHAR_MAX;
00408 #endif
00409     
00410     static Promote toPromote(unsigned char v) { return v; }
00411     static RealPromote toRealPromote(unsigned char v) { return v; }
00412     static unsigned char fromPromote(Promote const & v) { 
00413         return ((v < 0) ? 0 : (v > UCHAR_MAX) ? UCHAR_MAX : v); 
00414     }
00415     static unsigned char fromRealPromote(RealPromote const & v) {
00416             return ((v < 0.0) ? 0 : ((v > (float)UCHAR_MAX) ? UCHAR_MAX : static_cast<unsigned char>(v + 0.5)));
00417     }
00418 };
00419 
00420 template<>
00421 struct NumericTraits<short int>
00422 {
00423     typedef short int Type;
00424     typedef int Promote;
00425     typedef double RealPromote;
00426     typedef VigraTrueType isIntegral;
00427     typedef VigraTrueType isScalar;
00428     typedef VigraTrueType isOrdered;
00429     
00430     static short int zero() { return 0; }
00431     static short int one() { return 1; }
00432     static short int nonZero() { return 1; }
00433     static short int min() { return SHRT_MIN; }
00434     static short int max() { return SHRT_MAX; }
00435     
00436 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00437     enum { minConst = SHRT_MIN, maxConst = SHRT_MAX };
00438 #else
00439     static const short int minConst = SHRT_MIN;
00440     static const short int maxConst = SHRT_MAX;
00441 #endif
00442     
00443     static Promote toPromote(short int v) { return v; }
00444     static RealPromote toRealPromote(short int v) { return v; }
00445     static short int fromPromote(Promote v) { 
00446         return ((v < SHRT_MIN) ? SHRT_MIN : 
00447                 (v > SHRT_MAX) ? SHRT_MAX : v); 
00448     }
00449     static short int fromRealPromote(RealPromote v) {
00450         return ((v < 0.0) ? 
00451                 ((v < (float)SHRT_MIN) ? SHRT_MIN : static_cast<short int>(v - 0.5)) : 
00452                 ((v > (float)SHRT_MAX) ? SHRT_MAX : static_cast<short int>(v + 0.5))); 
00453     }
00454 };
00455 
00456 template<>
00457 struct NumericTraits<short unsigned int>
00458 {
00459     typedef short unsigned int Type;
00460     typedef int Promote;
00461     typedef double RealPromote;
00462 
00463     typedef VigraTrueType isIntegral;
00464     typedef VigraTrueType isScalar;
00465     typedef VigraTrueType isOrdered;
00466 
00467     static short unsigned int zero() { return 0; }
00468     static short unsigned int one() { return 1; }
00469     static short unsigned int nonZero() { return 1; }
00470     static short unsigned int min() { return 0; }
00471     static short unsigned int max() { return USHRT_MAX; }
00472     
00473 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00474     enum { minConst = 0, maxConst = USHRT_MAX };
00475 #else
00476     static const short unsigned int minConst = 0;
00477     static const short unsigned int maxConst = USHRT_MAX;
00478 #endif
00479 
00480     static Promote toPromote(short unsigned int v) { return v; }
00481     static RealPromote toRealPromote(short unsigned int v) { return v; }
00482     static short unsigned int fromPromote(Promote v) { 
00483         return ((v < 0) ? 0 : (v > USHRT_MAX) ? USHRT_MAX : v); 
00484     }
00485     static short unsigned int fromRealPromote(RealPromote v) {
00486             return ((v < 0.0) ? 
00487               0 : ((v > (float)USHRT_MAX) ? USHRT_MAX : static_cast<short unsigned int>(v + 0.5)));
00488     }
00489 };
00490 
00491 template<>
00492 struct NumericTraits<int>
00493 {
00494     typedef int Type;
00495     typedef int Promote;
00496     typedef double RealPromote;
00497     typedef VigraTrueType isIntegral;
00498     typedef VigraTrueType isScalar;
00499     typedef VigraTrueType isOrdered;
00500 
00501     static int zero() { return 0; }
00502     static int one() { return 1; }
00503     static int nonZero() { return 1; }
00504     static int min() { return INT_MIN; }
00505     static int max() { return INT_MAX; }
00506     
00507 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00508     enum { minConst = INT_MIN, maxConst = INT_MAX };
00509 #else
00510     static const int minConst = INT_MIN;
00511     static const int maxConst = INT_MAX;
00512 #endif
00513 
00514     static Promote toPromote(int v) { return v; }
00515     static RealPromote toRealPromote(int v) { return v; }
00516     static int fromPromote(Promote v) { return v; }
00517     static int fromRealPromote(RealPromote v) {
00518         return ((v < 0.0) ? 
00519                 ((v < (float)INT_MIN) ? INT_MIN : static_cast<int>(v - 0.5)) : 
00520                 ((v > (float)INT_MAX) ? INT_MAX : static_cast<int>(v + 0.5))); 
00521     }
00522 };
00523 
00524 template<>
00525 struct NumericTraits<unsigned int>
00526 {
00527     typedef unsigned int Type;
00528     typedef unsigned int Promote;
00529     typedef double RealPromote;
00530     typedef VigraTrueType isIntegral;
00531     typedef VigraTrueType isScalar;
00532     typedef VigraTrueType isOrdered;
00533     
00534     static unsigned int zero() { return 0; }
00535     static unsigned int one() { return 1; }
00536     static unsigned int nonZero() { return 1; }
00537     static unsigned int min() { return 0; }
00538     static unsigned int max() { return UINT_MAX; }
00539     
00540 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00541     enum { minConst = 0, maxConst = UINT_MAX };
00542 #else
00543     static const unsigned int minConst = 0;
00544     static const unsigned int maxConst = UINT_MAX;
00545 #endif
00546 
00547     static Promote toPromote(unsigned int v) { return v; }
00548     static RealPromote toRealPromote(unsigned int v) { return v; }
00549     static unsigned int fromPromote(Promote v) { return v; }
00550     static unsigned int fromRealPromote(RealPromote v) {
00551             return ((v < 0.0) ? 0 : 
00552                ((v > (float)UINT_MAX) ? 
00553                          UINT_MAX : static_cast<unsigned int>(v + 0.5)));
00554     }
00555 };
00556 
00557 template<>
00558 struct NumericTraits<long>
00559 {
00560     typedef long Type;
00561     typedef long Promote;
00562     typedef double RealPromote;
00563     typedef VigraTrueType isIntegral;
00564     typedef VigraTrueType isScalar;
00565     typedef VigraTrueType isOrdered;
00566     
00567     static long zero() { return 0; }
00568     static long one() { return 1; }
00569     static long nonZero() { return 1; }
00570     static long min() { return LONG_MIN; }
00571     static long max() { return LONG_MAX; }
00572     
00573 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00574     enum { minConst = LONG_MIN, maxConst = LONG_MAX };
00575 #else
00576     static const long minConst = LONG_MIN;
00577     static const long maxConst = LONG_MAX;
00578 #endif
00579 
00580     static Promote toPromote(long v) { return v; }
00581     static RealPromote toRealPromote(long v) { return v; }
00582     static long fromPromote(Promote v) { return v; }
00583     static long fromRealPromote(RealPromote v) {
00584         return ((v < 0.0) ? 
00585                 ((v < (float)LONG_MIN) ? LONG_MIN : static_cast<long>(v - 0.5)) : 
00586                 ((v > (float)LONG_MAX) ? LONG_MAX : static_cast<long>(v + 0.5))); 
00587     }
00588 };
00589 
00590 template<>
00591 struct NumericTraits<unsigned long>
00592 {
00593     typedef unsigned long Type;
00594     typedef unsigned long Promote;
00595     typedef double RealPromote;
00596     typedef VigraTrueType isIntegral;
00597     typedef VigraTrueType isScalar;
00598     typedef VigraTrueType isOrdered;
00599     
00600     static unsigned long zero() { return 0; }
00601     static unsigned long one() { return 1; }
00602     static unsigned long nonZero() { return 1; }
00603     static unsigned long min() { return 0; }
00604     static unsigned long max() { return ULONG_MAX; }
00605     
00606 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
00607     enum { minConst = 0, maxConst = ULONG_MAX };
00608 #else
00609     static const unsigned long minConst = 0;
00610     static const unsigned long maxConst = ULONG_MAX;
00611 #endif
00612 
00613     static Promote toPromote(unsigned long v) { return v; }
00614     static RealPromote toRealPromote(unsigned long v) { return v; }
00615     static unsigned long fromPromote(Promote v) { return v; }
00616     static unsigned long fromRealPromote(RealPromote v) {
00617             return ((v < 0.0) ? 0 : 
00618                ((v > (float)ULONG_MAX) ? 
00619                             ULONG_MAX : static_cast<unsigned long>(v + 0.5)));
00620     }
00621 };
00622 
00623 template<>
00624 struct NumericTraits<float>
00625 {
00626     typedef float Type;
00627     typedef float Promote;
00628     typedef float RealPromote;
00629     typedef VigraFalseType isIntegral;
00630     typedef VigraTrueType isScalar;
00631     typedef VigraTrueType isOrdered;
00632     
00633     static float zero() { return 0.0; }
00634     static float one() { return 1.0; }
00635     static float nonZero() { return 1.0; }
00636     static float epsilon() { return FLT_EPSILON; }
00637     static float smallestPositive() { return FLT_MIN; }
00638     static float min() { return -FLT_MAX; }
00639     static float max() { return FLT_MAX; }
00640     
00641     static Promote toPromote(float v) { return v; }
00642     static RealPromote toRealPromote(float v) { return v; }
00643     static float fromPromote(Promote v) { return v; }
00644     static float fromRealPromote(RealPromote v) { return v; }
00645 };
00646 
00647 template<>
00648 struct NumericTraits<double>
00649 {
00650     typedef double Type;
00651     typedef double Promote;
00652     typedef double RealPromote;
00653     typedef VigraFalseType isIntegral;
00654     typedef VigraTrueType isScalar;
00655     typedef VigraTrueType isOrdered;
00656     
00657     static double zero() { return 0.0; }
00658     static double one() { return 1.0; }
00659     static double nonZero() { return 1.0; }
00660     static double epsilon() { return DBL_EPSILON; }
00661     static double smallestPositive() { return DBL_MIN; }
00662     static double min() { return -DBL_MAX; }
00663     static double max() { return DBL_MAX; }
00664 
00665     static Promote toPromote(double v) { return v; }
00666     static RealPromote toRealPromote(double v) { return v; }
00667     static double fromPromote(Promote v) { return v; }
00668     static double fromRealPromote(RealPromote v) { return v; }
00669 };
00670 
00671 template<>
00672 struct NumericTraits<long double>
00673 {
00674     typedef long double Type;
00675     typedef long double Promote;
00676     typedef long double RealPromote;
00677     typedef VigraFalseType isIntegral;
00678     typedef VigraTrueType isScalar;
00679     typedef VigraTrueType isOrdered;
00680     
00681     static long double zero() { return 0.0; }
00682     static long double one() { return 1.0; }
00683     static long double nonZero() { return 1.0; }
00684     static long double epsilon() { return LDBL_EPSILON; }
00685     static long double smallestPositive() { return LDBL_MIN; }
00686     static long double min() { return -LDBL_MAX; }
00687     static long double max() { return LDBL_MAX; }
00688 
00689     static Promote toPromote(long double v) { return v; }
00690     static RealPromote toRealPromote(long double v) { return v; }
00691     static long double fromPromote(Promote v) { return v; }
00692     static long double fromRealPromote(RealPromote v) { return v; }
00693 };
00694 
00695 /********************************************************/
00696 /*                                                      */
00697 /*                      PromoteTraits                  */
00698 /*                                                      */
00699 /********************************************************/
00700 
00701 struct Error_PromoteTraits_not_specialized_for_this_case { };
00702 
00703 template<class A, class B>
00704 struct PromoteTraits
00705 {
00706         typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
00707 };
00708 
00709 template<>
00710 struct PromoteTraits<char, char>
00711 {
00712     typedef int Promote;
00713     static Promote toPromote(char v) { return v; }
00714 };
00715 
00716 template<>
00717 struct PromoteTraits<char, unsigned char>
00718 {
00719     typedef int Promote;
00720     static Promote toPromote(char v) { return v; }
00721     static Promote toPromote(unsigned char v) { return v; }
00722 };
00723 
00724 template<>
00725 struct PromoteTraits<char, short int>
00726 {
00727     typedef int Promote;
00728     static Promote toPromote(char v) { return v; }
00729     static Promote toPromote(short int v) { return v; }
00730 };
00731 
00732 template<>
00733 struct PromoteTraits<char, short unsigned int>
00734 {
00735     typedef unsigned int Promote;
00736     static Promote toPromote(char v) { return v; }
00737     static Promote toPromote(short unsigned int v) { return v; }
00738 };
00739 
00740 template<>
00741 struct PromoteTraits<char, int>
00742 {
00743     typedef int Promote;
00744     static Promote toPromote(char v) { return v; }
00745     static Promote toPromote(int v) { return v; }
00746 };
00747 
00748 template<>
00749 struct PromoteTraits<char, unsigned int>
00750 {
00751     typedef unsigned int Promote;
00752     static Promote toPromote(char v) { return v; }
00753     static Promote toPromote(unsigned int v) { return v; }
00754 };
00755 
00756 template<>
00757 struct PromoteTraits<char, long>
00758 {
00759     typedef long Promote;
00760     static Promote toPromote(char v) { return v; }
00761     static Promote toPromote(long v) { return v; }
00762 };
00763 
00764 template<>
00765 struct PromoteTraits<char, unsigned long>
00766 {
00767     typedef unsigned long Promote;
00768     static Promote toPromote(char v) { return v; }
00769     static Promote toPromote(unsigned long v) { return v; }
00770 };
00771 
00772 template<>
00773 struct PromoteTraits<char, float>
00774 {
00775     typedef float Promote;
00776     static Promote toPromote(char v) { return v; }
00777     static Promote toPromote(float v) { return v; }
00778 };
00779 
00780 template<>
00781 struct PromoteTraits<char, double>
00782 {
00783     typedef double Promote;
00784     static Promote toPromote(char v) { return v; }
00785     static Promote toPromote(double v) { return v; }
00786 };
00787 
00788 template<>
00789 struct PromoteTraits<char, long double>
00790 {
00791     typedef long double Promote;
00792     static Promote toPromote(char v) { return v; }
00793     static Promote toPromote(long double v) { return v; }
00794 };
00795 
00796 template<>
00797 struct PromoteTraits<unsigned char, char>
00798 {
00799     typedef int Promote;
00800     static Promote toPromote(unsigned char v) { return v; }
00801     static Promote toPromote(char v) { return v; }
00802 };
00803 
00804 template<>
00805 struct PromoteTraits<unsigned char, unsigned char>
00806 {
00807     typedef int Promote;
00808     static Promote toPromote(unsigned char v) { return v; }
00809 };
00810 
00811 template<>
00812 struct PromoteTraits<unsigned char, short int>
00813 {
00814     typedef int Promote;
00815     static Promote toPromote(unsigned char v) { return v; }
00816     static Promote toPromote(short int v) { return v; }
00817 };
00818 
00819 template<>
00820 struct PromoteTraits<unsigned char, short unsigned int>
00821 {
00822     typedef unsigned int Promote;
00823     static Promote toPromote(unsigned char v) { return v; }
00824     static Promote toPromote(short unsigned int v) { return v; }
00825 };
00826 
00827 template<>
00828 struct PromoteTraits<unsigned char, int>
00829 {
00830     typedef int Promote;
00831     static Promote toPromote(unsigned char v) { return v; }
00832     static Promote toPromote(int v) { return v; }
00833 };
00834 
00835 template<>
00836 struct PromoteTraits<unsigned char, unsigned int>
00837 {
00838     typedef unsigned int Promote;
00839     static Promote toPromote(unsigned char v) { return v; }
00840     static Promote toPromote(unsigned int v) { return v; }
00841 };
00842 
00843 template<>
00844 struct PromoteTraits<unsigned char, long>
00845 {
00846     typedef long Promote;
00847     static Promote toPromote(unsigned char v) { return v; }
00848     static Promote toPromote(long v) { return v; }
00849 };
00850 
00851 template<>
00852 struct PromoteTraits<unsigned char, unsigned long>
00853 {
00854     typedef unsigned long Promote;
00855     static Promote toPromote(unsigned char v) { return v; }
00856     static Promote toPromote(unsigned long v) { return v; }
00857 };
00858 
00859 template<>
00860 struct PromoteTraits<unsigned char, float>
00861 {
00862     typedef float Promote;
00863     static Promote toPromote(unsigned char v) { return v; }
00864     static Promote toPromote(float v) { return v; }
00865 };
00866 
00867 template<>
00868 struct PromoteTraits<unsigned char, double>
00869 {
00870     typedef double Promote;
00871     static Promote toPromote(unsigned char v) { return v; }
00872     static Promote toPromote(double v) { return v; }
00873 };
00874 
00875 template<>
00876 struct PromoteTraits<unsigned char, long double>
00877 {
00878     typedef long double Promote;
00879     static Promote toPromote(unsigned char v) { return v; }
00880     static Promote toPromote(long double v) { return v; }
00881 };
00882 
00883 template<>
00884 struct PromoteTraits<short int, char>
00885 {
00886     typedef int Promote;
00887     static Promote toPromote(short int v) { return v; }
00888     static Promote toPromote(char v) { return v; }
00889 };
00890 
00891 template<>
00892 struct PromoteTraits<short int, unsigned char>
00893 {
00894     typedef int Promote;
00895     static Promote toPromote(short int v) { return v; }
00896     static Promote toPromote(unsigned char v) { return v; }
00897 };
00898 
00899 template<>
00900 struct PromoteTraits<short int, short int>
00901 {
00902     typedef int Promote;
00903     static Promote toPromote(short int v) { return v; }
00904 };
00905 
00906 template<>
00907 struct PromoteTraits<short int, short unsigned int>
00908 {
00909     typedef unsigned int Promote;
00910     static Promote toPromote(short int v) { return v; }
00911     static Promote toPromote(short unsigned int v) { return v; }
00912 };
00913 
00914 template<>
00915 struct PromoteTraits<short int, int>
00916 {
00917     typedef int Promote;
00918     static Promote toPromote(short int v) { return v; }
00919     static Promote toPromote(int v) { return v; }
00920 };
00921 
00922 template<>
00923 struct PromoteTraits<short int, unsigned int>
00924 {
00925     typedef unsigned int Promote;
00926     static Promote toPromote(short int v) { return v; }
00927     static Promote toPromote(unsigned int v) { return v; }
00928 };
00929 
00930 template<>
00931 struct PromoteTraits<short int, long>
00932 {
00933     typedef long Promote;
00934     static Promote toPromote(short int v) { return v; }
00935     static Promote toPromote(long v) { return v; }
00936 };
00937 
00938 template<>
00939 struct PromoteTraits<short int, unsigned long>
00940 {
00941     typedef unsigned long Promote;
00942     static Promote toPromote(short int v) { return v; }
00943     static Promote toPromote(unsigned long v) { return v; }
00944 };
00945 
00946 template<>
00947 struct PromoteTraits<short int, float>
00948 {
00949     typedef float Promote;
00950     static Promote toPromote(short int v) { return v; }
00951     static Promote toPromote(float v) { return v; }
00952 };
00953 
00954 template<>
00955 struct PromoteTraits<short int, double>
00956 {
00957     typedef double Promote;
00958     static Promote toPromote(short int v) { return v; }
00959     static Promote toPromote(double v) { return v; }
00960 };
00961 
00962 template<>
00963 struct PromoteTraits<short int, long double>
00964 {
00965     typedef long double Promote;
00966     static Promote toPromote(short int v) { return v; }
00967     static Promote toPromote(long double v) { return v; }
00968 };
00969 
00970 template<>
00971 struct PromoteTraits<short unsigned int, char>
00972 {
00973     typedef unsigned int Promote;
00974     static Promote toPromote(short unsigned int v) { return v; }
00975     static Promote toPromote(char v) { return v; }
00976 };
00977 
00978 template<>
00979 struct PromoteTraits<short unsigned int, unsigned char>
00980 {
00981     typedef unsigned int Promote;
00982     static Promote toPromote(short unsigned int v) { return v; }
00983     static Promote toPromote(unsigned char v) { return v; }
00984 };
00985 
00986 template<>
00987 struct PromoteTraits<short unsigned int, short int>
00988 {
00989     typedef unsigned int Promote;
00990     static Promote toPromote(short unsigned int v) { return v; }
00991     static Promote toPromote(short int v) { return v; }
00992 };
00993 
00994 template<>
00995 struct PromoteTraits<short unsigned int, short unsigned int>
00996 {
00997     typedef unsigned int Promote;
00998     static Promote toPromote(short unsigned int v) { return v; }
00999 };
01000 
01001 template<>
01002 struct PromoteTraits<short unsigned int, int>
01003 {
01004     typedef unsigned int Promote;
01005     static Promote toPromote(short unsigned int v) { return v; }
01006     static Promote toPromote(int v) { return v; }
01007 };
01008 
01009 template<>
01010 struct PromoteTraits<short unsigned int, unsigned int>
01011 {
01012     typedef unsigned int Promote;
01013     static Promote toPromote(short unsigned int v) { return v; }
01014     static Promote toPromote(unsigned int v) { return v; }
01015 };
01016 
01017 template<>
01018 struct PromoteTraits<short unsigned int, long>
01019 {
01020     typedef long Promote;
01021     static Promote toPromote(short unsigned int v) { return v; }
01022     static Promote toPromote(long v) { return v; }
01023 };
01024 
01025 template<>
01026 struct PromoteTraits<short unsigned int, unsigned long>
01027 {
01028     typedef unsigned long Promote;
01029     static Promote toPromote(short unsigned int v) { return v; }
01030     static Promote toPromote(unsigned long v) { return v; }
01031 };
01032 
01033 template<>
01034 struct PromoteTraits<short unsigned int, float>
01035 {
01036     typedef float Promote;
01037     static Promote toPromote(short unsigned int v) { return v; }
01038     static Promote toPromote(float v) { return v; }
01039 };
01040 
01041 template<>
01042 struct PromoteTraits<short unsigned int, double>
01043 {
01044     typedef double Promote;
01045     static Promote toPromote(short unsigned int v) { return v; }
01046     static Promote toPromote(double v) { return v; }
01047 };
01048 
01049 template<>
01050 struct PromoteTraits<short unsigned int, long double>
01051 {
01052     typedef long double Promote;
01053     static Promote toPromote(short unsigned int v) { return v; }
01054     static Promote toPromote(long double v) { return v; }
01055 };
01056 
01057 template<>
01058 struct PromoteTraits<int, char>
01059 {
01060     typedef int Promote;
01061     static Promote toPromote(int v) { return v; }
01062     static Promote toPromote(char v) { return v; }
01063 };
01064 
01065 template<>
01066 struct PromoteTraits<int, unsigned char>
01067 {
01068     typedef int Promote;
01069     static Promote toPromote(int v) { return v; }
01070     static Promote toPromote(unsigned char v) { return v; }
01071 };
01072 
01073 template<>
01074 struct PromoteTraits<int, short int>
01075 {
01076     typedef int Promote;
01077     static Promote toPromote(int v) { return v; }
01078     static Promote toPromote(short int v) { return v; }
01079 };
01080 
01081 template<>
01082 struct PromoteTraits<int, short unsigned int>
01083 {
01084     typedef unsigned int Promote;
01085     static Promote toPromote(int v) { return v; }
01086     static Promote toPromote(short unsigned int v) { return v; }
01087 };
01088 
01089 template<>
01090 struct PromoteTraits<int, int>
01091 {
01092     typedef int Promote;
01093     static Promote toPromote(int v) { return v; }
01094 };
01095 
01096 template<>
01097 struct PromoteTraits<int, unsigned int>
01098 {
01099     typedef unsigned int Promote;
01100     static Promote toPromote(int v) { return v; }
01101     static Promote toPromote(unsigned int v) { return v; }
01102 };
01103 
01104 template<>
01105 struct PromoteTraits<int, long>
01106 {
01107     typedef long Promote;
01108     static Promote toPromote(int v) { return v; }
01109     static Promote toPromote(long v) { return v; }
01110 };
01111 
01112 template<>
01113 struct PromoteTraits<int, unsigned long>
01114 {
01115     typedef unsigned long Promote;
01116     static Promote toPromote(int v) { return v; }
01117     static Promote toPromote(unsigned long v) { return v; }
01118 };
01119 
01120 template<>
01121 struct PromoteTraits<int, float>
01122 {
01123     typedef float Promote;
01124     static Promote toPromote(int v) { return v; }
01125     static Promote toPromote(float v) { return v; }
01126 };
01127 
01128 template<>
01129 struct PromoteTraits<int, double>
01130 {
01131     typedef double Promote;
01132     static Promote toPromote(int v) { return v; }
01133     static Promote toPromote(double v) { return v; }
01134 };
01135 
01136 template<>
01137 struct PromoteTraits<int, long double>
01138 {
01139     typedef long double Promote;
01140     static Promote toPromote(int v) { return v; }
01141     static Promote toPromote(long double v) { return v; }
01142 };
01143 
01144 template<>
01145 struct PromoteTraits<unsigned int, char>
01146 {
01147     typedef unsigned int Promote;
01148     static Promote toPromote(unsigned int v) { return v; }
01149     static Promote toPromote(char v) { return v; }
01150 };
01151 
01152 template<>
01153 struct PromoteTraits<unsigned int, unsigned char>
01154 {
01155     typedef unsigned int Promote;
01156     static Promote toPromote(unsigned int v) { return v; }
01157     static Promote toPromote(unsigned char v) { return v; }
01158 };
01159 
01160 template<>
01161 struct PromoteTraits<unsigned int, short int>
01162 {
01163     typedef unsigned int Promote;
01164     static Promote toPromote(unsigned int v) { return v; }
01165     static Promote toPromote(short int v) { return v; }
01166 };
01167 
01168 template<>
01169 struct PromoteTraits<unsigned int, short unsigned int>
01170 {
01171     typedef unsigned int Promote;
01172     static Promote toPromote(unsigned int v) { return v; }
01173     static Promote toPromote(short unsigned int v) { return v; }
01174 };
01175 
01176 template<>
01177 struct PromoteTraits<unsigned int, int>
01178 {
01179     typedef unsigned int Promote;
01180     static Promote toPromote(unsigned int v) { return v; }
01181     static Promote toPromote(int v) { return v; }
01182 };
01183 
01184 template<>
01185 struct PromoteTraits<unsigned int, unsigned int>
01186 {
01187     typedef unsigned int Promote;
01188     static Promote toPromote(unsigned int v) { return v; }
01189 };
01190 
01191 template<>
01192 struct PromoteTraits<unsigned int, long>
01193 {
01194     typedef long Promote;
01195     static Promote toPromote(unsigned int v) { return v; }
01196     static Promote toPromote(long v) { return v; }
01197 };
01198 
01199 template<>
01200 struct PromoteTraits<unsigned int, unsigned long>
01201 {
01202     typedef unsigned long Promote;
01203     static Promote toPromote(unsigned int v) { return v; }
01204     static Promote toPromote(unsigned long v) { return v; }
01205 };
01206 
01207 template<>
01208 struct PromoteTraits<unsigned int, float>
01209 {
01210     typedef float Promote;
01211     static Promote toPromote(unsigned int v) { return v; }
01212     static Promote toPromote(float v) { return v; }
01213 };
01214 
01215 template<>
01216 struct PromoteTraits<unsigned int, double>
01217 {
01218     typedef double Promote;
01219     static Promote toPromote(unsigned int v) { return v; }
01220     static Promote toPromote(double v) { return v; }
01221 };
01222 
01223 template<>
01224 struct PromoteTraits<unsigned int, long double>
01225 {
01226     typedef long double Promote;
01227     static Promote toPromote(unsigned int v) { return v; }
01228     static Promote toPromote(long double v) { return v; }
01229 };
01230 
01231 template<>
01232 struct PromoteTraits<long, char>
01233 {
01234     typedef long Promote;
01235     static Promote toPromote(long v) { return v; }
01236     static Promote toPromote(char v) { return v; }
01237 };
01238 
01239 template<>
01240 struct PromoteTraits<long, unsigned char>
01241 {
01242     typedef long Promote;
01243     static Promote toPromote(long v) { return v; }
01244     static Promote toPromote(unsigned char v) { return v; }
01245 };
01246 
01247 template<>
01248 struct PromoteTraits<long, short int>
01249 {
01250     typedef long Promote;
01251     static Promote toPromote(long v) { return v; }
01252     static Promote toPromote(short int v) { return v; }
01253 };
01254 
01255 template<>
01256 struct PromoteTraits<long, short unsigned int>
01257 {
01258     typedef long Promote;
01259     static Promote toPromote(long v) { return v; }
01260     static Promote toPromote(short unsigned int v) { return v; }
01261 };
01262 
01263 template<>
01264 struct PromoteTraits<long, int>
01265 {
01266     typedef long Promote;
01267     static Promote toPromote(long v) { return v; }
01268     static Promote toPromote(int v) { return v; }
01269 };
01270 
01271 template<>
01272 struct PromoteTraits<long, unsigned int>
01273 {
01274     typedef long Promote;
01275     static Promote toPromote(long v) { return v; }
01276     static Promote toPromote(unsigned int v) { return v; }
01277 };
01278 
01279 template<>
01280 struct PromoteTraits<long, long>
01281 {
01282     typedef long Promote;
01283     static Promote toPromote(long v) { return v; }
01284 };
01285 
01286 template<>
01287 struct PromoteTraits<long, unsigned long>
01288 {
01289     typedef unsigned long Promote;
01290     static Promote toPromote(long v) { return v; }
01291     static Promote toPromote(unsigned long v) { return v; }
01292 };
01293 
01294 template<>
01295 struct PromoteTraits<long, float>
01296 {
01297     typedef float Promote;
01298     static Promote toPromote(long v) { return v; }
01299     static Promote toPromote(float v) { return v; }
01300 };
01301 
01302 template<>
01303 struct PromoteTraits<long, double>
01304 {
01305     typedef double Promote;
01306     static Promote toPromote(long v) { return v; }
01307     static Promote toPromote(double v) { return v; }
01308 };
01309 
01310 template<>
01311 struct PromoteTraits<long, long double>
01312 {
01313     typedef long double Promote;
01314     static Promote toPromote(long v) { return v; }
01315     static Promote toPromote(long double v) { return v; }
01316 };
01317 
01318 template<>
01319 struct PromoteTraits<unsigned long, char>
01320 {
01321     typedef unsigned long Promote;
01322     static Promote toPromote(unsigned long v) { return v; }
01323     static Promote toPromote(char v) { return v; }
01324 };
01325 
01326 template<>
01327 struct PromoteTraits<unsigned long, unsigned char>
01328 {
01329     typedef unsigned long Promote;
01330     static Promote toPromote(unsigned long v) { return v; }
01331     static Promote toPromote(unsigned char v) { return v; }
01332 };
01333 
01334 template<>
01335 struct PromoteTraits<unsigned long, short int>
01336 {
01337     typedef unsigned long Promote;
01338     static Promote toPromote(unsigned long v) { return v; }
01339     static Promote toPromote(short int v) { return v; }
01340 };
01341 
01342 template<>
01343 struct PromoteTraits<unsigned long, short unsigned int>
01344 {
01345     typedef unsigned long Promote;
01346     static Promote toPromote(unsigned long v) { return v; }
01347     static Promote toPromote(short unsigned int v) { return v; }
01348 };
01349 
01350 template<>
01351 struct PromoteTraits<unsigned long, int>
01352 {
01353     typedef unsigned long Promote;
01354     static Promote toPromote(unsigned long v) { return v; }
01355     static Promote toPromote(int v) { return v; }
01356 };
01357 
01358 template<>
01359 struct PromoteTraits<unsigned long, unsigned int>
01360 {
01361     typedef unsigned long Promote;
01362     static Promote toPromote(unsigned long v) { return v; }
01363     static Promote toPromote(unsigned int v) { return v; }
01364 };
01365 
01366 template<>
01367 struct PromoteTraits<unsigned long, long>
01368 {
01369     typedef unsigned long Promote;
01370     static Promote toPromote(unsigned long v) { return v; }
01371     static Promote toPromote(long v) { return v; }
01372 };
01373 
01374 template<>
01375 struct PromoteTraits<unsigned long, unsigned long>
01376 {
01377     typedef unsigned long Promote;
01378     static Promote toPromote(unsigned long v) { return v; }
01379 };
01380 
01381 template<>
01382 struct PromoteTraits<unsigned long, float>
01383 {
01384     typedef float Promote;
01385     static Promote toPromote(unsigned long v) { return v; }
01386     static Promote toPromote(float v) { return v; }
01387 };
01388 
01389 template<>
01390 struct PromoteTraits<unsigned long, double>
01391 {
01392     typedef double Promote;
01393     static Promote toPromote(unsigned long v) { return v; }
01394     static Promote toPromote(double v) { return v; }
01395 };
01396 
01397 template<>
01398 struct PromoteTraits<unsigned long, long double>
01399 {
01400     typedef long double Promote;
01401     static Promote toPromote(unsigned long v) { return v; }
01402     static Promote toPromote(long double v) { return v; }
01403 };
01404 
01405 template<>
01406 struct PromoteTraits<float, char>
01407 {
01408     typedef float Promote;
01409     static Promote toPromote(float v) { return v; }
01410     static Promote toPromote(char v) { return v; }
01411 };
01412 
01413 template<>
01414 struct PromoteTraits<float, unsigned char>
01415 {
01416     typedef float Promote;
01417     static Promote toPromote(float v) { return v; }
01418     static Promote toPromote(unsigned char v) { return v; }
01419 };
01420 
01421 template<>
01422 struct PromoteTraits<float, short int>
01423 {
01424     typedef float Promote;
01425     static Promote toPromote(float v) { return v; }
01426     static Promote toPromote(short int v) { return v; }
01427 };
01428 
01429 template<>
01430 struct PromoteTraits<float, short unsigned int>
01431 {
01432     typedef float Promote;
01433     static Promote toPromote(float v) { return v; }
01434     static Promote toPromote(short unsigned int v) { return v; }
01435 };
01436 
01437 template<>
01438 struct PromoteTraits<float, int>
01439 {
01440     typedef float Promote;
01441     static Promote toPromote(float v) { return v; }
01442     static Promote toPromote(int v) { return v; }
01443 };
01444 
01445 template<>
01446 struct PromoteTraits<float, unsigned int>
01447 {
01448     typedef float Promote;
01449     static Promote toPromote(float v) { return v; }
01450     static Promote toPromote(unsigned int v) { return v; }
01451 };
01452 
01453 template<>
01454 struct PromoteTraits<float, long>
01455 {
01456     typedef float Promote;
01457     static Promote toPromote(float v) { return v; }
01458     static Promote toPromote(long v) { return v; }
01459 };
01460 
01461 template<>
01462 struct PromoteTraits<float, unsigned long>
01463 {
01464     typedef float Promote;
01465     static Promote toPromote(float v) { return v; }
01466     static Promote toPromote(unsigned long v) { return v; }
01467 };
01468 
01469 template<>
01470 struct PromoteTraits<float, float>
01471 {
01472     typedef float Promote;
01473     static Promote toPromote(float v) { return v; }
01474 };
01475 
01476 template<>
01477 struct PromoteTraits<float, double>
01478 {
01479     typedef double Promote;
01480     static Promote toPromote(float v) { return v; }
01481     static Promote toPromote(double v) { return v; }
01482 };
01483 
01484 template<>
01485 struct PromoteTraits<float, long double>
01486 {
01487     typedef long double Promote;
01488     static Promote toPromote(float v) { return v; }
01489     static Promote toPromote(long double v) { return v; }
01490 };
01491 
01492 template<>
01493 struct PromoteTraits<double, char>
01494 {
01495     typedef double Promote;
01496     static Promote toPromote(double v) { return v; }
01497     static Promote toPromote(char v) { return v; }
01498 };
01499 
01500 template<>
01501 struct PromoteTraits<double, unsigned char>
01502 {
01503     typedef double Promote;
01504     static Promote toPromote(double v) { return v; }
01505     static Promote toPromote(unsigned char v) { return v; }
01506 };
01507 
01508 template<>
01509 struct PromoteTraits<double, short int>
01510 {
01511     typedef double Promote;
01512     static Promote toPromote(double v) { return v; }
01513     static Promote toPromote(short int v) { return v; }
01514 };
01515 
01516 template<>
01517 struct PromoteTraits<double, short unsigned int>
01518 {
01519     typedef double Promote;
01520     static Promote toPromote(double v) { return v; }
01521     static Promote toPromote(short unsigned int v) { return v; }
01522 };
01523 
01524 template<>
01525 struct PromoteTraits<double, int>
01526 {
01527     typedef double Promote;
01528     static Promote toPromote(double v) { return v; }
01529     static Promote toPromote(int v) { return v; }
01530 };
01531 
01532 template<>
01533 struct PromoteTraits<double, unsigned int>
01534 {
01535     typedef double Promote;
01536     static Promote toPromote(double v) { return v; }
01537     static Promote toPromote(unsigned int v) { return v; }
01538 };
01539 
01540 template<>
01541 struct PromoteTraits<double, long>
01542 {
01543     typedef double Promote;
01544     static Promote toPromote(double v) { return v; }
01545     static Promote toPromote(long v) { return v; }
01546 };
01547 
01548 template<>
01549 struct PromoteTraits<double, unsigned long>
01550 {
01551     typedef double Promote;
01552     static Promote toPromote(double v) { return v; }
01553     static Promote toPromote(unsigned long v) { return v; }
01554 };
01555 
01556 template<>
01557 struct PromoteTraits<double, float>
01558 {
01559     typedef double Promote;
01560     static Promote toPromote(double v) { return v; }
01561     static Promote toPromote(float v) { return v; }
01562 };
01563 
01564 template<>
01565 struct PromoteTraits<double, double>
01566 {
01567     typedef double Promote;
01568     static Promote toPromote(double v) { return v; }
01569 };
01570 
01571 template<>
01572 struct PromoteTraits<double, long double>
01573 {
01574     typedef long double Promote;
01575     static Promote toPromote(double v) { return v; }
01576     static Promote toPromote(long double v) { return v; }
01577 };
01578 
01579 template<>
01580 struct PromoteTraits<long double, char>
01581 {
01582     typedef long double Promote;
01583     static Promote toPromote(long double v) { return v; }
01584     static Promote toPromote(char v) { return v; }
01585 };
01586 
01587 template<>
01588 struct PromoteTraits<long double, unsigned char>
01589 {
01590     typedef long double Promote;
01591     static Promote toPromote(long double v) { return v; }
01592     static Promote toPromote(unsigned char v) { return v; }
01593 };
01594 
01595 template<>
01596 struct PromoteTraits<long double, short int>
01597 {
01598     typedef long double Promote;
01599     static Promote toPromote(long double v) { return v; }
01600     static Promote toPromote(short int v) { return v; }
01601 };
01602 
01603 template<>
01604 struct PromoteTraits<long double, short unsigned int>
01605 {
01606     typedef long double Promote;
01607     static Promote toPromote(long double v) { return v; }
01608     static Promote toPromote(short unsigned int v) { return v; }
01609 };
01610 
01611 template<>
01612 struct PromoteTraits<long double, int>
01613 {
01614     typedef long double Promote;
01615     static Promote toPromote(long double v) { return v; }
01616     static Promote toPromote(int v) { return v; }
01617 };
01618 
01619 template<>
01620 struct PromoteTraits<long double, unsigned int>
01621 {
01622     typedef long double Promote;
01623     static Promote toPromote(long double v) { return v; }
01624     static Promote toPromote(unsigned int v) { return v; }
01625 };
01626 
01627 template<>
01628 struct PromoteTraits<long double, long>
01629 {
01630     typedef long double Promote;
01631     static Promote toPromote(long double v) { return v; }
01632     static Promote toPromote(long v) { return v; }
01633 };
01634 
01635 template<>
01636 struct PromoteTraits<long double, unsigned long>
01637 {
01638     typedef long double Promote;
01639     static Promote toPromote(long double v) { return v; }
01640     static Promote toPromote(unsigned long v) { return v; }
01641 };
01642 
01643 template<>
01644 struct PromoteTraits<long double, float>
01645 {
01646     typedef long double Promote;
01647     static Promote toPromote(long double v) { return v; }
01648     static Promote toPromote(float v) { return v; }
01649 };
01650 
01651 template<>
01652 struct PromoteTraits<long double, double>
01653 {
01654     typedef long double Promote;
01655     static Promote toPromote(long double v) { return v; }
01656     static Promote toPromote(double v) { return v; }
01657 };
01658 
01659 template<>
01660 struct PromoteTraits<long double, long double>
01661 {
01662     typedef long double Promote;
01663     static Promote toPromote(long double v) { return v; }
01664 };
01665 
01666 namespace detail {
01667 
01668 template <class T>
01669 struct RequiresExplicitCast {
01670     template <class U>
01671     static U const & cast(U const & v)
01672         { return v; }
01673 };
01674 
01675 #if !defined(_MSC_VER) || _MSC_VER >= 1300
01676 #  define VIGRA_SPECIALIZED_CAST(type) \
01677     template <> \
01678     struct RequiresExplicitCast<type> { \
01679         static type cast(float v) \
01680             { return NumericTraits<type>::fromRealPromote(v); } \
01681         static type cast(double v) \
01682             { return NumericTraits<type>::fromRealPromote(v); } \
01683         template <class U> \
01684         static type cast(U v) \
01685             { return v; } \
01686  \
01687     };
01688 #else
01689 #  define VIGRA_SPECIALIZED_CAST(type) \
01690     template <> \
01691     struct RequiresExplicitCast<type> { \
01692         static type cast(float v) \
01693             { return NumericTraits<type>::fromRealPromote(v); } \
01694         static type cast(double v) \
01695             { return NumericTraits<type>::fromRealPromote(v); } \
01696         static type cast(signed char v) \
01697             { return v; } \
01698         static type cast(unsigned char v) \
01699             { return v; } \
01700         static type cast(short v) \
01701             { return v; } \
01702         static type cast(unsigned short v) \
01703             { return v; } \
01704         static type cast(int v) \
01705             { return v; } \
01706         static type cast(unsigned int v) \
01707             { return v; } \
01708         static type cast(long v) \
01709             { return v; } \
01710         static type cast(unsigned long v) \
01711             { return v; } \
01712     };
01713 #endif
01714 
01715 
01716 VIGRA_SPECIALIZED_CAST(signed char)
01717 VIGRA_SPECIALIZED_CAST(unsigned char)
01718 VIGRA_SPECIALIZED_CAST(short)
01719 VIGRA_SPECIALIZED_CAST(unsigned short)
01720 VIGRA_SPECIALIZED_CAST(int)
01721 VIGRA_SPECIALIZED_CAST(unsigned int)
01722 VIGRA_SPECIALIZED_CAST(long)
01723 VIGRA_SPECIALIZED_CAST(unsigned long)
01724 
01725 template <>
01726 struct RequiresExplicitCast<float> {
01727     template <class U>
01728     static U cast(U v)
01729         { return v; }
01730 };
01731 
01732 template <>
01733 struct RequiresExplicitCast<double> {
01734     template <class U>
01735     static U cast(U v)
01736         { return v; }
01737 };
01738 
01739 #undef VIGRA_SPECIALIZED_CAST
01740 
01741 } // namespace detail
01742 
01743 
01744 
01745 } // namespace vigra
01746 
01747 #endif // VIGRA_NUMERICTRAITS_HXX
01748 

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.2.0 (7 Aug 2003)