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

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

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)