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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)