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

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

html generated using doxygen and Python
VIGRA 1.3.2 (27 Jan 2005)