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

details vigra/numerictraits.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.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)