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

| vigra/numerictraits.hxx |
--- | --- | ---

    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)