VIGRA - VIGRA: vigra/numerictraits.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | 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.6.0, Aug 13 2008 )                                    */
    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 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@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     <UL style="list-style-image:url(documents/bullet.gif)">
    00060     <LI> \ref NumericTraits
    00061          <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for promotion, conversion, creation of arithmetic objects</em>
    00062     <LI> \ref PromoteTraits
    00063          <BR>&nbsp;&nbsp;&nbsp;<em>Binary traits for promotion of arithmetic objects</em>
    00064     <LI> \ref SquareRootTraits
    00065          <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the square root of arithmetic objects</em>
    00066     <LI> \ref NormTraits
    00067          <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the norm and squared norm of arithmetic objects</em>
    00068     </UL>
    00069
    00070     These traits classes contain information that is used by generic
    00071     algorithms and data structures to determine intermediate and result
    00072     types of numerical calculations, to convert between different
    00073     representations of arithmetic types, and to create certain important
    00074     constants of each type. Thus, algorithms and data structures
    00075     operating that need arithmetic operations can be made more
    00076     independent from the actual data representation.
    00077
    00078     NumericTraits are implemented as template specializations of one
    00079     arithmetic type, while PromoteTraits are specialized for a pair of
    00080     arithmetic types that shall be combined in one operation.
    00081 */
    00082
    00083 /** \page NumericTraits template<> struct NumericTraits<ArithmeticType>
    00084
    00085     Unary traits for promotion, conversion, creation of arithmetic objects.
    00086
    00087     <b>\#include</b>
    00088     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00089
    00090     This traits class is used derive important properties of
    00091     an arithmetic type. Consider the following algorithm:
    00092
    00093     \code
    00094     // calculate the sum of a sequence of bytes
    00095     int sumBytes(unsigned char * begin, unsigned char * end)
    00096     {
    00097         int result = 0;
    00098         for(; begin != end; ++begin)  result += *begin;
    00099         return result;
    00100     }
    00101     \endcode
    00102
    00103     The return type of this function can not be 'unsigned char' because
    00104     the summation would very likely overflow. Since we know the source
    00105     type, we can easily choose 'int' as an appropriate return type.
    00106     Likewise, we would have choosen 'float' if we had to sum a
    00107     sequence of floats. If we want to make this
    00108     algorithm generic, we would like to derive the appropriate return
    00109     type automatically. This can be done with NumericTraits.
    00110     The code would look like this (we use \ref DataAccessors to
    00111     read the data from the sequence):
    00112
    00113     \code
    00114     // calculate the sum of any sequence
    00115     template <class Iterator, class Accessor>
    00116     typename vigra::NumericTraits<typename Accessor::value_type>::Promote
    00117     sumSequence(Iterator begin, Iterator end, Accessor a)
    00118     {
    00119         // an abbreviation
    00120         typedef vigra::NumericTraits<typename Accessor::value_type>  SrcTraits;
    00121
    00122         // find out result type
    00123         typedef typename SrcTraits::Promote ResultType;
    00124
    00125         // init result to zero
    00126         ResultType result = vigra::NumericTraits<ResultType>::zero();
    00127
    00128         for(; begin != end; ++begin)
    00129         {
    00130             // cast current item to ResultType and add
    00131             result += SrcTraits::toPromote(a(begin));
    00132         }
    00133
    00134         return result;
    00135     }
    00136     \endcode
    00137
    00138     In this example NumericTraits is not only used to deduce the
    00139     ReturnType of the operation, but also to initialize it with the
    00140     constant 'zero'. This is necessary since we do not know in general,
    00141     which expression must be used to obtain a zero of some arbitrary
    00142     type - '<TT>ResultType result = 0;</TT>' would only work if the
    00143     ResultType had an constructor taking an '<TT>int</TT>' argument, and we
    00144     would not even have any guarantee as to what the semantics of this
    00145     constructor are. In addition, the traits are used to cast the
    00146     source type into the promote type.
    00147
    00148     Similarly, an algorithm that needs multiplication would use the
    00149     return type <TT>RealPromote</TT> and the functions <TT>one()</TT> and
    00150     <TT>toRealPromote()</TT>. The following members are defined in
    00151     <b> <TT>NumericTraits<ArithmeticType></TT></b>:
    00152
    00153     <table>
    00154     <tr><td>
    00155     <b> <TT>typedef ... Type;</TT></b>
    00156     </td><td>
    00157
    00158             the type itself
    00159
    00160     </td></tr>
    00161     <tr><td>
    00162     <b> <TT>typedef ... Promote;</TT></b>
    00163     </td><td>
    00164
    00165             promote type for addition and subtraction
    00166
    00167     </td></tr>
    00168     <tr><td>
    00169     <b> <TT>typedef ... RealPromote;</TT></b>
    00170     </td><td>
    00171             promote type for multiplication and division with a real number
    00172
    00173     (only defined if <TT>ArithmeticType</TT> supports these operations)
    00174
    00175     </td></tr>
    00176     <tr><td>
    00177     <b> <TT>typedef ... ComplexPromote;</TT></b>
    00178     </td><td>
    00179
    00180             promote type for complex arithmetic
    00181
    00182     </td></tr>
    00183     <tr><td>
    00184     <b> <TT>typedef ... ValueType;</TT></b>
    00185     </td><td>
    00186
    00187             for scalar types: the type itself<br>
    00188             otherwise: typename Type::value_type (if defined)
    00189
    00190     </td></tr>
    00191     <tr><td>
    00192     <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
    00193     </td><td>
    00194         convert to <TT>Promote</TT> type
    00195
    00196     </td></tr>
    00197     <tr><td>
    00198     <b> <TT>static RealPromote toRealPromote(ArithmeticType v);</TT></b>
    00199     </td><td>
    00200         convert to <TT>RealPromote</TT> type
    00201
    00202     (only defined if <TT>ArithmeticType</TT> supports multiplication)
    00203
    00204     </td></tr>
    00205     <tr><td>
    00206     <b> <TT>static ArithmeticType fromPromote(Promote v);</TT></b>
    00207     </td><td>
    00208         convert from <TT>Promote</TT> type
    00209
    00210     if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped;
    00211
    00212     </td></tr>
    00213     <tr><td>
    00214     <b> <TT>static ArithmeticType fromRealPromote(RealPromote v);</TT></b>
    00215     </td><td>
    00216         convert from <TT>RealPromote</TT> type
    00217
    00218     (only defined if
    00219     <TT>ArithmeticType</TT> supports multiplication)
    00220
    00221     if <TT>ArithmeticType</TT> is an integral type, the result is rounded
    00222
    00223     if <TT>v</TT> is outside the range of <TT>ArithmeticType</TT> it is clipped
    00224
    00225     </td></tr>
    00226     <tr><td>
    00227     <b> <TT>static ArithmeticType zero();</TT></b>
    00228     </td><td>
    00229     create neutral element of addition
    00230
    00231     i.e. <TT>(ArithmeticType a = ...,</TT>
    00232     <TT>  a + NumericTraits<ArithmeticType>::zero() == a)</TT>
    00233     must always yield <TT>true</TT>
    00234
    00235     </td></tr>
    00236     <tr><td>
    00237     <b> <TT>static ArithmeticType nonZero();</TT></b>
    00238     </td><td>
    00239     create a non-zero element (if multiplication is defined, this yields one())
    00240
    00241     i.e. <TT>(ArithmeticType a = ...,</TT>
    00242     <TT>  a + NumericTraits<ArithmeticType>::nonZero() == a)</TT>
    00243     must always yield <TT>false</TT>
    00244
    00245     </td></tr>
    00246     <tr><td>
    00247     <b> <TT>static ArithmeticType min();</TT></b>
    00248     </td><td>
    00249     the smallest number representable in this type.<br>
    00250     Only available if isOrdered is VigraTrueType. For integral types,
    00251     this equals <TT>INT_MIN</TT> etc., for real valued types it is <TT>-FLT_MAX</TT>
    00252     etc. (<b>not</b> <TT>FLT_MIN</TT> -- this is the smallest positive <tt>float</tt>)
    00253
    00254     </td></tr>
    00255     <tr><td>
    00256     <b> <TT>static ArithmeticType max();</TT></b>
    00257     </td><td>
    00258     the largest number representable in this type.<br>
    00259     Only available if isOrdered is VigraTrueType. For integral types,
    00260     this equals <TT>INT_MAX</TT> etc., for real valued types it is <TT>FLT_MAX</TT>
    00261     etc.
    00262
    00263     </td></tr>
    00264     <tr><td>
    00265     <b> <TT>static ArithmeticType one();</TT></b>
    00266     </td><td>
    00267     create neutral element of multiplication
    00268
    00269     (only defined if <TT>ArithmeticType</TT> supports multiplication)
    00270
    00271     i.e. <TT>(ArithmeticType a = ...,</TT>
    00272     <TT>  a * NumericTraits<ArithmeticType>::one() == a)</TT>
    00273     must always yield <TT>true</TT>
    00274
    00275     </td></tr>
    00276     <tr><td>
    00277     <b> <TT>typedef ... isIntegral;</TT></b>
    00278     </td><td>
    00279         VigraTrueType if <TT>ArithmeticType</TT> is an integral type,
    00280         VigraFalseType otherwise
    00281
    00282     </td></tr>
    00283     <tr><td>
    00284     <b> <TT>typedef ... isScalar;</TT></b>
    00285     </td><td>
    00286         VigraTrueType if <TT>ArithmeticType</TT> is a scalar type,
    00287         VigraFalseType otherwise
    00288
    00289     </td></tr>
    00290     <tr><td>
    00291     <tr><td>
    00292     <b> <TT>typedef ... isSigned;</TT></b>
    00293     </td><td>
    00294         VigraTrueType if <TT>ArithmeticType</TT> is a signed type,
    00295         VigraFalseType otherwise
    00296
    00297     </td></tr>
    00298     <tr><td>
    00299     <tr><td>
    00300     <b> <TT>typedef ... isOrdered;</TT></b>
    00301     </td><td>
    00302         VigraTrueType if <TT>ArithmeticType</TT> supports operator<(),
    00303         VigraFalseType otherwise
    00304
    00305     </td></tr>
    00306     <tr><td>
    00307     <b> <TT>typedef ... isComplex;</TT></b>
    00308     </td><td>
    00309         VigraTrueType if <TT>ArithmeticType</TT> is a complex number,
    00310         VigraFalseType otherwise
    00311
    00312     </td></tr>
    00313     <tr><td>
    00314     </table>
    00315
    00316     NumericTraits for the built-in types are defined in <b>\#include</b>
    00317     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00318
    00319     Namespace: vigra
    00320
    00321 */
    00322
    00323 /** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, ArithmeticType2>
    00324
    00325     Binary traits for promotion of arithmetic objects.
    00326
    00327     <b>\#include</b>
    00328     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00329
    00330     This traits class is used to determine the appropriate result type
    00331     of arithmetic expressions which depend of two arguments. Consider
    00332     the following function:
    00333
    00334     \code
    00335     template <class T>
    00336     T min(T t1, T t2)
    00337     {
    00338         return (t1 < t2) ? t1 : t2;
    00339     }
    00340     \endcode
    00341
    00342     This template is only applicable if both arguments have the same
    00343     type. However, sometimes we may want to use the function in cases
    00344     where the argument types differ. The we can deduce the approrpiate
    00345     return type by using <TT>PromoteTraits</TT>:
    00346
    00347     \code
    00348     template <class T1, class T2>
    00349     typename vigra::PromoteTraits<T1, T2>::Promote
    00350     min(T1 t1, T2 t2)
    00351     {
    00352         return (t1 < t2) ? vigra::PromoteTraits<T1, T2>::toPromote(t1) :
    00353                            vigra::PromoteTraits<T1, T2>::toPromote(t2);
    00354     }
    00355     \endcode
    00356
    00357     In addition, the traits class provide static functions to cast the
    00358     arguments to the promote type. For example, if <TT>T1</TT> were <TT>int</TT> and
    00359     <TT>T2</TT> were <TT>float</TT>, the <TT>Promote</TT> type would be <TT>float</TT>.
    00360     The following members are defined in
    00361     <b> <TT>PromoteTraits<ArithmeticType1, ArithmeticType2></TT></b>:
    00362
    00363     <table>
    00364     <tr>
    00365     <td>
    00366     <b> <TT>typedef ... Promote;</TT></b>
    00367     </td><td>
    00368             promote type
    00369     </td></tr>
    00370     <tr><td>
    00371     <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b>
    00372
    00373     <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
    00374     </td><td>
    00375         convert to <TT>Promote</TT> type
    00376     </td></tr>
    00377     </table>
    00378
    00379     PromoteTraits for the built-in types are defined in <b>\#include</b>
    00380     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00381
    00382     Namespace: vigra
    00383 */
    00384
    00385 /** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticType>
    00386
    00387     Unary traits for the calculation of the square root of arithmetic objects.
    00388
    00389     <b>\#include</b>
    00390     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00391
    00392     This traits class is used to determine appropriate argument and result types
    00393     for the function sqrt(). These traits are typically used like this:
    00394
    00395     \code
    00396     ArithmeticType t = ...;
    00397     SquareRootTraits<ArithmeticType>::SquareRootResult r =
    00398           sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
    00399     \endcode
    00400
    00401     This approach avoids 'ambigouos overload errors' when taking the square root of
    00402     an integer type. It also takes care of determining the proper result of the
    00403     sqrt() function of \ref vigra::FixedPoint and of the norm() function, when
    00404     it is implemented via sqrt(squaredNorm(x)).
    00405     The following members are defined in <b> <TT>SquareRootTraits<ArithmeticType></TT></b>:
    00406
    00407     <table>
    00408     <tr><td>
    00409     <b> <TT>typedef ArithmeticType Type;</TT></b>
    00410     </td><td>
    00411             the type itself
    00412     </td></tr>
    00413     <tr><td>
    00414     <b> <TT>typedef ... SquareRootArgument;</TT></b>
    00415     </td><td>
    00416             required argument type for srqt(), i.e. <tt>sqrt((SquareRootArgument)x)</tt>
    00417     </td></tr>
    00418     <tr><td>
    00419     <b> <TT>typedef ... SquareRootResult;</TT></b>
    00420     </td><td>
    00421             result of <tt>sqrt((SquareRootArgument)x)</tt>
    00422     </td></tr>
    00423     </table>
    00424
    00425     NormTraits for the built-in types are defined in <b>\#include</b>
    00426     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00427
    00428     Namespace: vigra
    00429 */
    00430
    00431 /** \page NormTraits template<> struct NormTraits<ArithmeticType>
    00432
    00433     Unary traits for the calculation of the norm and squared norm of arithmetic objects.
    00434
    00435     <b>\#include</b>
    00436     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00437
    00438     This traits class is used to determine appropriate result types
    00439     for the functions norm() and squaredNorm(). These functions are always
    00440     declared like this (where <tt>ArithmeticType</tt> is a type thats supports a norm):
    00441
    00442     \code
    00443     NormTraits<ArithmeticType>::NormType        norm(ArithmeticType const & t);
    00444     NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
    00445     \endcode
    00446
    00447     The following members are defined in <b> <TT>NormTraits<ArithmeticType></TT></b>:
    00448
    00449     <table>
    00450     <tr><td>
    00451     <b> <TT>typedef ArithmeticType Type;</TT></b>
    00452     </td><td>
    00453             the type itself
    00454     </td></tr>
    00455     <tr><td>
    00456     <b> <TT>typedef ... SquaredNormType;</TT></b>
    00457     </td><td>
    00458             result of <tt>squaredNorm(ArithmeticType)</tt>
    00459     </td></tr>
    00460     <tr><td>
    00461     <b> <TT>typedef ... NormType;</TT></b>
    00462     </td><td>
    00463             result of <tt>norm(ArithmeticType)</tt><br>
    00464             Usually equal to <tt>SquareRootTraits<SquaredNormType>::SquareRootResult</tt>
    00465     </td></tr>
    00466     </table>
    00467
    00468     NormTraits for the built-in types are defined in <b>\#include</b>
    00469     <<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>>
    00470
    00471     Namespace: vigra
    00472 */
    00473
    00474 namespace vigra {
    00475
    00476 struct Error_NumericTraits_not_specialized_for_this_case { };
    00477 struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char { };
    00478
    00479 template<class A>
    00480 struct NumericTraits
    00481 {
    00482     typedef Error_NumericTraits_not_specialized_for_this_case Type;
    00483     typedef Error_NumericTraits_not_specialized_for_this_case Promote;
    00484     typedef Error_NumericTraits_not_specialized_for_this_case UnsignedPromote;
    00485     typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
    00486     typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromote;
    00487     typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
    00488
    00489     typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
    00490     typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
    00491     typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
    00492     typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
    00493     typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
    00494 };
    00495
    00496 template<>
    00497 struct NumericTraits<char>
    00498 {
    00499     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Type;
    00500     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Promote;
    00501     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char UnsignedPromote;
    00502     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char RealPromote;
    00503     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ComplexPromote;
    00504     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ValueType;
    00505
    00506     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isScalar;
    00507     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isIntegral;
    00508     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isSigned;
    00509     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isOrdered;
    00510     typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isComplex;
    00511 };
    00512
    00513 #ifndef NO_BOOL
    00514 template<>
    00515 struct NumericTraits<bool>
    00516 {
    00517     typedef bool Type;
    00518     typedef int Promote;
    00519     typedef unsigned int UnsignedPromote;
    00520     typedef double RealPromote;
    00521     typedef std::complex<RealPromote> ComplexPromote;
    00522     typedef Type ValueType;
    00523
    00524     typedef VigraTrueType isIntegral;
    00525     typedef VigraTrueType isScalar;
    00526     typedef VigraFalseType isSigned;
    00527     typedef VigraTrueType isOrdered;
    00528     typedef VigraFalseType isComplex;
    00529
    00530     static bool zero() { return false; }
    00531     static bool one() { return true; }
    00532     static bool nonZero() { return true; }
    00533     static bool min() { return false; }
    00534     static bool max() { return true; }
    00535
    00536 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00537     enum { minConst = false , maxConst = true };
    00538 #else
    00539     static const bool minConst = false;
    00540     static const bool maxConst = true;
    00541 #endif
    00542
    00543     static Promote toPromote(bool v) { return v ? 1 : 0; }
    00544     static RealPromote toRealPromote(bool v) { return v ? 1.0 : 0.0; }
    00545     static bool fromPromote(Promote v) {
    00546         return (v == 0) ? false : true;
    00547     }
    00548     static bool fromRealPromote(RealPromote v) {
    00549         return (v == 0.0) ? false : true;
    00550     }
    00551 };
    00552 #endif
    00553
    00554 template<>
    00555 struct NumericTraits<signed char>
    00556 {
    00557     typedef signed char Type;
    00558     typedef int Promote;
    00559     typedef unsigned int UnsignedPromote;
    00560     typedef double RealPromote;
    00561     typedef std::complex<RealPromote> ComplexPromote;
    00562     typedef Type ValueType;
    00563
    00564     typedef VigraTrueType isIntegral;
    00565     typedef VigraTrueType isScalar;
    00566     typedef VigraTrueType isSigned;
    00567     typedef VigraTrueType isOrdered;
    00568     typedef VigraFalseType isComplex;
    00569
    00570     static signed char zero() { return 0; }
    00571     static signed char one() { return 1; }
    00572     static signed char nonZero() { return 1; }
    00573     static signed char min() { return SCHAR_MIN; }
    00574     static signed char max() { return SCHAR_MAX; }
    00575
    00576 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00577     enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
    00578 #else
    00579     static const signed char minConst = SCHAR_MIN;
    00580     static const signed char maxConst = SCHAR_MIN;
    00581 #endif
    00582
    00583     static Promote toPromote(signed char v) { return v; }
    00584     static RealPromote toRealPromote(signed char v) { return v; }
    00585     static signed char fromPromote(Promote v) {
    00586         return ((v < SCHAR_MIN) ? SCHAR_MIN : (v > SCHAR_MAX) ? SCHAR_MAX : v);
    00587     }
    00588     static signed char fromRealPromote(RealPromote v) {
    00589         return ((v < 0.0)
    00590                    ? ((v < (RealPromote)SCHAR_MIN)
    00591                        ? SCHAR_MIN
    00592                        : static_cast<signed char>(v - 0.5))
    00593                    : (v > (RealPromote)SCHAR_MAX)
    00594                        ? SCHAR_MAX
    00595                        : static_cast<signed char>(v + 0.5));
    00596     }
    00597 };
    00598
    00599 template<>
    00600 struct NumericTraits<unsigned char>
    00601 {
    00602     typedef unsigned char Type;
    00603     typedef int Promote;
    00604     typedef unsigned int UnsignedPromote;
    00605     typedef double RealPromote;
    00606     typedef std::complex<RealPromote> ComplexPromote;
    00607     typedef Type ValueType;
    00608
    00609     typedef VigraTrueType isIntegral;
    00610     typedef VigraTrueType isScalar;
    00611     typedef VigraFalseType isSigned;
    00612     typedef VigraTrueType isOrdered;
    00613     typedef VigraFalseType isComplex;
    00614
    00615     static unsigned char zero() { return 0; }
    00616     static unsigned char one() { return 1; }
    00617     static unsigned char nonZero() { return 1; }
    00618     static unsigned char min() { return 0; }
    00619     static unsigned char max() { return UCHAR_MAX; }
    00620
    00621 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00622     enum { minConst = 0, maxConst = UCHAR_MAX };
    00623 #else
    00624     static const unsigned char minConst = 0;
    00625     static const unsigned char maxConst = UCHAR_MAX;
    00626 #endif
    00627
    00628     static Promote toPromote(unsigned char v) { return v; }
    00629     static RealPromote toRealPromote(unsigned char v) { return v; }
    00630     static unsigned char fromPromote(Promote const & v) {
    00631         return Type((v < 0)
    00632              ? 0
    00633              : (v > (Promote)UCHAR_MAX)
    00634                     ? UCHAR_MAX
    00635                     : v);
    00636     }
    00637     static unsigned char fromRealPromote(RealPromote const & v) {
    00638             return Type((v < 0.0)
    00639                      ? 0
    00640                      : ((v > (RealPromote)UCHAR_MAX)
    00641                          ? UCHAR_MAX
    00642                          : v + 0.5));
    00643     }
    00644 };
    00645
    00646 template<>
    00647 struct NumericTraits<short int>
    00648 {
    00649     typedef short int Type;
    00650     typedef int Promote;
    00651     typedef unsigned int UnsignedPromote;
    00652     typedef double RealPromote;
    00653     typedef std::complex<RealPromote> ComplexPromote;
    00654     typedef Type ValueType;
    00655
    00656     typedef VigraTrueType isIntegral;
    00657     typedef VigraTrueType isScalar;
    00658     typedef VigraTrueType isSigned;
    00659     typedef VigraTrueType isOrdered;
    00660     typedef VigraFalseType isComplex;
    00661
    00662     static short int zero() { return 0; }
    00663     static short int one() { return 1; }
    00664     static short int nonZero() { return 1; }
    00665     static short int min() { return SHRT_MIN; }
    00666     static short int max() { return SHRT_MAX; }
    00667
    00668 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00669     enum { minConst = SHRT_MIN, maxConst = SHRT_MAX };
    00670 #else
    00671     static const short int minConst = SHRT_MIN;
    00672     static const short int maxConst = SHRT_MAX;
    00673 #endif
    00674
    00675     static Promote toPromote(short int v) { return v; }
    00676     static RealPromote toRealPromote(short int v) { return v; }
    00677     static short int fromPromote(Promote v) {
    00678         return ((v < SHRT_MIN) ? SHRT_MIN :
    00679                 (v > SHRT_MAX) ? SHRT_MAX : v);
    00680     }
    00681     static short int fromRealPromote(RealPromote v) {
    00682         return ((v < 0.0)
    00683                  ? ((v < (RealPromote)SHRT_MIN)
    00684                      ? SHRT_MIN
    00685                      : static_cast<short int>(v - 0.5))
    00686                  : ((v > (RealPromote)SHRT_MAX)
    00687                      ? SHRT_MAX
    00688                      : static_cast<short int>(v + 0.5)));
    00689     }
    00690 };
    00691
    00692 template<>
    00693 struct NumericTraits<short unsigned int>
    00694 {
    00695     typedef short unsigned int Type;
    00696     typedef int Promote;
    00697     typedef unsigned int UnsignedPromote;
    00698     typedef double RealPromote;
    00699     typedef std::complex<RealPromote> ComplexPromote;
    00700     typedef Type ValueType;
    00701
    00702     typedef VigraTrueType isIntegral;
    00703     typedef VigraTrueType isScalar;
    00704     typedef VigraFalseType isSigned;
    00705     typedef VigraTrueType isOrdered;
    00706     typedef VigraFalseType isComplex;
    00707
    00708     static short unsigned int zero() { return 0; }
    00709     static short unsigned int one() { return 1; }
    00710     static short unsigned int nonZero() { return 1; }
    00711     static short unsigned int min() { return 0; }
    00712     static short unsigned int max() { return USHRT_MAX; }
    00713
    00714 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00715     enum { minConst = 0, maxConst = USHRT_MAX };
    00716 #else
    00717     static const short unsigned int minConst = 0;
    00718     static const short unsigned int maxConst = USHRT_MAX;
    00719 #endif
    00720
    00721     static Promote toPromote(short unsigned int v) { return v; }
    00722     static RealPromote toRealPromote(short unsigned int v) { return v; }
    00723     static short unsigned int fromPromote(Promote v) {
    00724         return Type((v < 0)
    00725               ? 0
    00726               : (v > USHRT_MAX)
    00727                    ? USHRT_MAX
    00728                    : v);
    00729     }
    00730     static short unsigned int fromRealPromote(RealPromote v) {
    00731             return Type((v < 0.0)
    00732                      ? 0
    00733                      : ((v > (RealPromote)USHRT_MAX)
    00734                          ? USHRT_MAX
    00735                          : v + 0.5));
    00736     }
    00737 };
    00738
    00739 template<>
    00740 struct NumericTraits<int>
    00741 {
    00742     typedef int Type;
    00743     typedef int Promote;
    00744     typedef unsigned int UnsignedPromote;
    00745     typedef double RealPromote;
    00746     typedef std::complex<RealPromote> ComplexPromote;
    00747     typedef Type ValueType;
    00748
    00749     typedef VigraTrueType isIntegral;
    00750     typedef VigraTrueType isScalar;
    00751     typedef VigraTrueType isSigned;
    00752     typedef VigraTrueType isOrdered;
    00753     typedef VigraFalseType isComplex;
    00754
    00755     static int zero() { return 0; }
    00756     static int one() { return 1; }
    00757     static int nonZero() { return 1; }
    00758     static int min() { return INT_MIN; }
    00759     static int max() { return INT_MAX; }
    00760
    00761 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00762     enum { minConst = INT_MIN, maxConst = INT_MAX };
    00763 #else
    00764     static const int minConst = INT_MIN;
    00765     static const int maxConst = INT_MAX;
    00766 #endif
    00767
    00768     static Promote toPromote(int v) { return v; }
    00769     static RealPromote toRealPromote(int v) { return v; }
    00770     static int fromPromote(Promote v) { return v; }
    00771     static int fromRealPromote(RealPromote v) {
    00772         return ((v < 0.0)
    00773                  ? ((v < (RealPromote)INT_MIN)
    00774                      ? INT_MIN
    00775                      : static_cast<int>(v - 0.5))
    00776                  : ((v > (RealPromote)INT_MAX)
    00777                      ? INT_MAX
    00778                      : static_cast<int>(v + 0.5)));
    00779     }
    00780 };
    00781
    00782 template<>
    00783 struct NumericTraits<unsigned int>
    00784 {
    00785     typedef unsigned int Type;
    00786     typedef unsigned int Promote;
    00787     typedef unsigned int UnsignedPromote;
    00788     typedef double RealPromote;
    00789     typedef std::complex<RealPromote> ComplexPromote;
    00790     typedef Type ValueType;
    00791
    00792     typedef VigraTrueType isIntegral;
    00793     typedef VigraTrueType isScalar;
    00794     typedef VigraFalseType isSigned;
    00795     typedef VigraTrueType isOrdered;
    00796     typedef VigraFalseType isComplex;
    00797
    00798     static unsigned int zero() { return 0; }
    00799     static unsigned int one() { return 1; }
    00800     static unsigned int nonZero() { return 1; }
    00801     static unsigned int min() { return 0; }
    00802     static unsigned int max() { return UINT_MAX; }
    00803
    00804 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00805     enum { minConst = 0, maxConst = UINT_MAX };
    00806 #else
    00807     static const unsigned int minConst = 0;
    00808     static const unsigned int maxConst = UINT_MAX;
    00809 #endif
    00810
    00811     static Promote toPromote(unsigned int v) { return v; }
    00812     static RealPromote toRealPromote(unsigned int v) { return v; }
    00813     static unsigned int fromPromote(Promote v) { return v; }
    00814     static unsigned int fromRealPromote(RealPromote v) {
    00815             return ((v < 0.0)
    00816                      ? 0
    00817                      : ((v > (RealPromote)UINT_MAX)
    00818                          ? UINT_MAX
    00819                          : static_cast<unsigned int>(v + 0.5)));
    00820     }
    00821 };
    00822
    00823 template<>
    00824 struct NumericTraits<long>
    00825 {
    00826     typedef long Type;
    00827     typedef long Promote;
    00828     typedef unsigned long UnsignedPromote;
    00829     typedef double RealPromote;
    00830     typedef std::complex<RealPromote> ComplexPromote;
    00831     typedef Type ValueType;
    00832
    00833     typedef VigraTrueType isIntegral;
    00834     typedef VigraTrueType isScalar;
    00835     typedef VigraTrueType isSigned;
    00836     typedef VigraTrueType isOrdered;
    00837     typedef VigraFalseType isComplex;
    00838
    00839     static long zero() { return 0; }
    00840     static long one() { return 1; }
    00841     static long nonZero() { return 1; }
    00842     static long min() { return LONG_MIN; }
    00843     static long max() { return LONG_MAX; }
    00844
    00845 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00846     enum { minConst = LONG_MIN, maxConst = LONG_MAX };
    00847 #else
    00848     static const long minConst = LONG_MIN;
    00849     static const long maxConst = LONG_MAX;
    00850 #endif
    00851
    00852     static Promote toPromote(long v) { return v; }
    00853     static RealPromote toRealPromote(long v) { return v; }
    00854     static long fromPromote(Promote v) { return v; }
    00855     static long fromRealPromote(RealPromote v) {
    00856         return ((v < 0.0)
    00857                  ? ((v < (RealPromote)LONG_MIN)
    00858                      ? LONG_MIN
    00859                      : static_cast<long>(v - 0.5))
    00860                  : ((v > (RealPromote)LONG_MAX)
    00861                      ? LONG_MAX
    00862                      : static_cast<long>(v + 0.5)));
    00863     }
    00864 };
    00865
    00866 template<>
    00867 struct NumericTraits<unsigned long>
    00868 {
    00869     typedef unsigned long Type;
    00870     typedef unsigned long Promote;
    00871     typedef unsigned long UnsignedPromote;
    00872     typedef double RealPromote;
    00873     typedef std::complex<RealPromote> ComplexPromote;
    00874     typedef Type ValueType;
    00875
    00876     typedef VigraTrueType isIntegral;
    00877     typedef VigraTrueType isScalar;
    00878     typedef VigraFalseType isSigned;
    00879     typedef VigraTrueType isOrdered;
    00880     typedef VigraFalseType isComplex;
    00881
    00882     static unsigned long zero() { return 0; }
    00883     static unsigned long one() { return 1; }
    00884     static unsigned long nonZero() { return 1; }
    00885     static unsigned long min() { return 0; }
    00886     static unsigned long max() { return ULONG_MAX; }
    00887
    00888 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00889     enum { minConst = 0, maxConst = ULONG_MAX };
    00890 #else
    00891     static const unsigned long minConst = 0;
    00892     static const unsigned long maxConst = ULONG_MAX;
    00893 #endif
    00894
    00895     static Promote toPromote(unsigned long v) { return v; }
    00896     static RealPromote toRealPromote(unsigned long v) { return v; }
    00897     static unsigned long fromPromote(Promote v) { return v; }
    00898     static unsigned long fromRealPromote(RealPromote v) {
    00899             return ((v < 0.0)
    00900                      ? 0
    00901                      : ((v > (RealPromote)ULONG_MAX)
    00902                          ? ULONG_MAX
    00903                          : static_cast<unsigned long>(v + 0.5)));
    00904     }
    00905 };
    00906
    00907 #ifdef LLONG_MAX
    00908 template<>
    00909 struct NumericTraits<long long>
    00910 {
    00911     typedef long long Type;
    00912     typedef long long Promote;
    00913     typedef unsigned long long UnsignedPromote;
    00914     typedef double RealPromote;
    00915     typedef std::complex<RealPromote> ComplexPromote;
    00916     typedef Type ValueType;
    00917
    00918     typedef VigraTrueType isIntegral;
    00919     typedef VigraTrueType isScalar;
    00920     typedef VigraTrueType isSigned;
    00921     typedef VigraTrueType isOrdered;
    00922     typedef VigraFalseType isComplex;
    00923
    00924     static long long zero() { return 0; }
    00925     static long long one() { return 1; }
    00926     static long long nonZero() { return 1; }
    00927     static long long min() { return LLONG_MIN; }
    00928     static long long max() { return LLONG_MAX; }
    00929
    00930 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00931     enum { minConst = LLONG_MIN, maxConst = LLONG_MAX };
    00932 #else
    00933     static const long long minConst = LLONG_MIN;
    00934     static const long long maxConst = LLONG_MAX;
    00935 #endif
    00936
    00937     static Promote toPromote(long long v) { return v; }
    00938     static RealPromote toRealPromote(long long v) { return v; }
    00939     static long long fromPromote(Promote v) { return v; }
    00940     static long long fromRealPromote(RealPromote v) {
    00941         return ((v < 0.0)
    00942                  ? ((v < (RealPromote)LLONG_MIN)
    00943                      ? LLONG_MIN
    00944                      : static_cast<long long>(v - 0.5))
    00945                  : ((v > (RealPromote)LLONG_MAX)
    00946                      ? LLONG_MAX
    00947                      : static_cast<long long>(v + 0.5)));
    00948     }
    00949 };
    00950
    00951 template<>
    00952 struct NumericTraits<unsigned long long>
    00953 {
    00954     typedef unsigned long long Type;
    00955     typedef unsigned long long Promote;
    00956     typedef unsigned long long UnsignedPromote;
    00957     typedef double RealPromote;
    00958     typedef std::complex<RealPromote> ComplexPromote;
    00959     typedef Type ValueType;
    00960
    00961     typedef VigraTrueType isIntegral;
    00962     typedef VigraTrueType isScalar;
    00963     typedef VigraFalseType isSigned;
    00964     typedef VigraTrueType isOrdered;
    00965     typedef VigraFalseType isComplex;
    00966
    00967     static unsigned long long zero() { return 0; }
    00968     static unsigned long long one() { return 1; }
    00969     static unsigned long long nonZero() { return 1; }
    00970     static unsigned long long min() { return 0; }
    00971     static unsigned long long max() { return ULLONG_MAX; }
    00972
    00973 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
    00974     enum { minConst = 0, maxConst = ULLONG_MAX };
    00975 #else
    00976     static const unsigned long long minConst = 0;
    00977     static const unsigned long long maxConst = ULLONG_MAX;
    00978 #endif
    00979
    00980     static Promote toPromote(unsigned long long v) { return v; }
    00981     static RealPromote toRealPromote(unsigned long long v) { return v; }
    00982     static unsigned long long fromPromote(Promote v) { return v; }
    00983     static unsigned long long fromRealPromote(RealPromote v) {
    00984             return ((v < 0.0)
    00985                      ? 0
    00986                      : ((v > (RealPromote)ULLONG_MAX)
    00987                          ? ULONG_MAX
    00988                          : static_cast<unsigned long long>(v + 0.5)));
    00989     }
    00990 };
    00991 #endif // LLONG_MAX
    00992
    00993 template<>
    00994 struct NumericTraits<float>
    00995 {
    00996     typedef float Type;
    00997     typedef float Promote;
    00998     typedef float UnsignedPromote;
    00999     typedef float RealPromote;
    01000     typedef std::complex<RealPromote> ComplexPromote;
    01001     typedef Type ValueType;
    01002
    01003     typedef VigraFalseType isIntegral;
    01004     typedef VigraTrueType isScalar;
    01005     typedef VigraTrueType isSigned;
    01006     typedef VigraTrueType isOrdered;
    01007     typedef VigraFalseType isComplex;
    01008
    01009     static float zero() { return 0.0; }
    01010     static float one() { return 1.0; }
    01011     static float nonZero() { return 1.0; }
    01012     static float epsilon() { return FLT_EPSILON; }
    01013     static float smallestPositive() { return FLT_MIN; }
    01014     static float min() { return -FLT_MAX; }
    01015     static float max() { return FLT_MAX; }
    01016
    01017     static Promote toPromote(float v) { return v; }
    01018     static RealPromote toRealPromote(float v) { return v; }
    01019     static float fromPromote(Promote v) { return v; }
    01020     static float fromRealPromote(RealPromote v) { return v; }
    01021 };
    01022
    01023 template<>
    01024 struct NumericTraits<double>
    01025 {
    01026     typedef double Type;
    01027     typedef double Promote;
    01028     typedef double UnsignedPromote;
    01029     typedef double RealPromote;
    01030     typedef std::complex<RealPromote> ComplexPromote;
    01031     typedef Type ValueType;
    01032
    01033     typedef VigraFalseType isIntegral;
    01034     typedef VigraTrueType isScalar;
    01035     typedef VigraTrueType isSigned;
    01036     typedef VigraTrueType isOrdered;
    01037     typedef VigraFalseType isComplex;
    01038
    01039     static double zero() { return 0.0; }
    01040     static double one() { return 1.0; }
    01041     static double nonZero() { return 1.0; }
    01042     static double epsilon() { return DBL_EPSILON; }
    01043     static double smallestPositive() { return DBL_MIN; }
    01044     static double min() { return -DBL_MAX; }
    01045     static double max() { return DBL_MAX; }
    01046
    01047     static Promote toPromote(double v) { return v; }
    01048     static RealPromote toRealPromote(double v) { return v; }
    01049     static double fromPromote(Promote v) { return v; }
    01050     static double fromRealPromote(RealPromote v) { return v; }
    01051 };
    01052
    01053 template<>
    01054 struct NumericTraits<long double>
    01055 {
    01056     typedef long double Type;
    01057     typedef long double Promote;
    01058     typedef long double UnsignedPromote;
    01059     typedef long double RealPromote;
    01060     typedef std::complex<RealPromote> ComplexPromote;
    01061     typedef Type ValueType;
    01062
    01063     typedef VigraFalseType isIntegral;
    01064     typedef VigraTrueType isScalar;
    01065     typedef VigraTrueType isSigned;
    01066     typedef VigraTrueType isOrdered;
    01067     typedef VigraFalseType isComplex;
    01068
    01069     static long double zero() { return 0.0; }
    01070     static long double one() { return 1.0; }
    01071     static long double nonZero() { return 1.0; }
    01072     static long double epsilon() { return LDBL_EPSILON; }
    01073     static long double smallestPositive() { return LDBL_MIN; }
    01074     static long double min() { return -LDBL_MAX; }
    01075     static long double max() { return LDBL_MAX; }
    01076
    01077     static Promote toPromote(long double v) { return v; }
    01078     static RealPromote toRealPromote(long double v) { return v; }
    01079     static long double fromPromote(Promote v) { return v; }
    01080     static long double fromRealPromote(RealPromote v) { return v; }
    01081 };
    01082
    01083 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01084
    01085 template<class T>
    01086 struct NumericTraits<std::complex<T> >
    01087 {
    01088     typedef std::complex<T> Type;
    01089     typedef std::complex<typename NumericTraits<T>::Promote> Promote;
    01090     typedef std::complex<typename NumericTraits<T>::UnsignedPromote> UnsignedPromote;
    01091     typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromote;
    01092     typedef std::complex<RealPromote> ComplexPromote;
    01093     typedef T ValueType;
    01094
    01095     typedef VigraFalseType isIntegral;
    01096     typedef VigraFalseType isScalar;
    01097     typedef typename NumericTraits<T>::isSigned isSigned;
    01098     typedef VigraFalseType isOrdered;
    01099     typedef VigraTrueType isComplex;
    01100
    01101     static Type zero() { return Type(0.0); }
    01102     static Type one() { return Type(1.0); }
    01103     static Type nonZero() { return one(); }
    01104     static Type epsilon() { return Type(NumericTraits<T>::epsilon()); }
    01105     static Type smallestPositive() { return Type(NumericTraits<T>::smallestPositive()); }
    01106
    01107     static Promote toPromote(Type const & v) { return v; }
    01108     static Type fromPromote(Promote const & v) { return v; }
    01109     static Type fromRealPromote(RealPromote v) { return Type(v); }
    01110 };
    01111
    01112 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01113
    01114 /********************************************************/
    01115 /*                                                      */
    01116 /*                    SquareRootTraits                  */
    01117 /*                                                      */
    01118 /********************************************************/
    01119
    01120 template<class T>
    01121 struct SquareRootTraits
    01122 {
    01123     typedef T                                                    Type;
    01124     typedef typename NumericTraits<T>::RealPromote               SquareRootResult;
    01125     typedef typename NumericTraits<T>::RealPromote               SquareRootArgument;
    01126 };
    01127
    01128
    01129 /********************************************************/
    01130 /*                                                      */
    01131 /*                       NormTraits                     */
    01132 /*                                                      */
    01133 /********************************************************/
    01134
    01135 struct Error_NormTraits_not_specialized_for_this_case { };
    01136
    01137 template<class T>
    01138 struct NormTraits
    01139 {
    01140     typedef T                                                Type;
    01141     typedef Error_NormTraits_not_specialized_for_this_case   SquaredNormType;
    01142     typedef Error_NormTraits_not_specialized_for_this_case   NormType;
    01143 };
    01144
    01145 #define VIGRA_DEFINE_NORM_TRAITS(T) \
    01146     template <> struct NormTraits<T> { \
    01147         typedef T Type; \
    01148         typedef NumericTraits<T>::Promote SquaredNormType; \
    01149         typedef T NormType; \
    01150     };
    01151
    01152 VIGRA_DEFINE_NORM_TRAITS(bool)
    01153 VIGRA_DEFINE_NORM_TRAITS(signed char)
    01154 VIGRA_DEFINE_NORM_TRAITS(unsigned char)
    01155 VIGRA_DEFINE_NORM_TRAITS(short)
    01156 VIGRA_DEFINE_NORM_TRAITS(unsigned short)
    01157 VIGRA_DEFINE_NORM_TRAITS(int)
    01158 VIGRA_DEFINE_NORM_TRAITS(unsigned int)
    01159 VIGRA_DEFINE_NORM_TRAITS(long)
    01160 VIGRA_DEFINE_NORM_TRAITS(unsigned long)
    01161 VIGRA_DEFINE_NORM_TRAITS(float)
    01162 VIGRA_DEFINE_NORM_TRAITS(double)
    01163 VIGRA_DEFINE_NORM_TRAITS(long double)
    01164
    01165 #ifdef LLONG_MAX
    01166 VIGRA_DEFINE_NORM_TRAITS(long long)
    01167 VIGRA_DEFINE_NORM_TRAITS(unsigned long long)
    01168 #endif // LLONG_MAX
    01169
    01170 #undef VIGRA_DEFINE_NORM_TRAITS
    01171
    01172 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01173
    01174 template<class T>
    01175 struct NormTraits<std::complex<T> >
    01176 {
    01177     typedef std::complex<T>                                              Type;
    01178     typedef typename NormTraits<T>::SquaredNormType                      SquaredNormType;
    01179     typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
    01180 };
    01181
    01182 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01183
    01184 /********************************************************/
    01185 /*                                                      */
    01186 /*                      PromoteTraits                   */
    01187 /*                                                      */
    01188 /********************************************************/
    01189
    01190 namespace detail {
    01191
    01192 template <class T, class U>
    01193 struct PromoteType
    01194 {
    01195     static T & t();
    01196     static U & u();
    01197     // let C++ figure out the promote type by adding a T and an U
    01198     typedef typename SizeToType<sizeof(*typeToSize(t() + u()))>::result Promote;
    01199     static Promote toPromote(T t) { return Promote(t); }
    01200     static Promote toPromote(U u) { return Promote(u); }
    01201 };
    01202
    01203
    01204 template <class T>
    01205 struct PromoteType<T, T>
    01206 {
    01207     static T & t();
    01208     // let C++ figure out the promote type by adding two Ts
    01209     typedef typename SizeToType<sizeof(*typeToSize(t() + t()))>::result Promote;
    01210     static Promote toPromote(T t) { return Promote(t); }
    01211 };
    01212
    01213 } // namespace detail
    01214
    01215 struct Error_PromoteTraits_not_specialized_for_this_case { };
    01216
    01217 template<class A, class B>
    01218 struct PromoteTraits
    01219 {
    01220     typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
    01221 };
    01222
    01223 #include "promote_traits.hxx"
    01224
    01225 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01226
    01227 template <class T>
    01228 struct PromoteTraits<std::complex<T>, std::complex<T> >
    01229 {
    01230     typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
    01231     static Promote toPromote(std::complex<T> const & v) { return v; }
    01232 };
    01233
    01234 template <class T1, class T2>
    01235 struct PromoteTraits<std::complex<T1>, std::complex<T2> >
    01236 {
    01237     typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
    01238     static Promote toPromote(std::complex<T1> const & v) { return v; }
    01239     static Promote toPromote(std::complex<T2> const & v) { return v; }
    01240 };
    01241
    01242 template <class T1, class T2>
    01243 struct PromoteTraits<std::complex<T1>, T2 >
    01244 {
    01245     typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
    01246     static Promote toPromote(std::complex<T1> const & v) { return v; }
    01247     static Promote toPromote(T2 const & v) { return Promote(v); }
    01248 };
    01249
    01250 template <class T1, class T2>
    01251 struct PromoteTraits<T1, std::complex<T2> >
    01252 {
    01253     typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
    01254     static Promote toPromote(T1 const & v) { return Promote(v); }
    01255     static Promote toPromote(std::complex<T2> const & v) { return v; }
    01256 };
    01257
    01258 #endif
    01259
    01260 namespace detail {
    01261
    01262 template <class T>
    01263 struct RequiresExplicitCast {
    01264     template <class U>
    01265     static U const & cast(U const & v)
    01266         { return v; }
    01267 };
    01268
    01269 #if !defined(_MSC_VER) || _MSC_VER >= 1300
    01270 #  define VIGRA_SPECIALIZED_CAST(type) \
    01271     template <> \
    01272     struct RequiresExplicitCast<type> { \
    01273         static type cast(float v) \
    01274             { return NumericTraits<type>::fromRealPromote(v); } \
    01275         static type cast(double v) \
    01276             { return NumericTraits<type>::fromRealPromote(v); } \
    01277         static type cast(type v) \
    01278             { return v; } \
    01279         template <class U> \
    01280         static type cast(U v) \
    01281             { return static_cast<type>(v); } \
    01282  \
    01283     };
    01284 #else
    01285 #  define VIGRA_SPECIALIZED_CAST(type) \
    01286     template <> \
    01287     struct RequiresExplicitCast<type> { \
    01288         static type cast(float v) \
    01289             { return NumericTraits<type>::fromRealPromote(v); } \
    01290         static type cast(double v) \
    01291             { return NumericTraits<type>::fromRealPromote(v); } \
    01292         static type cast(signed char v) \
    01293             { return v; } \
    01294         static type cast(unsigned char v) \
    01295             { return v; } \
    01296         static type cast(short v) \
    01297             { return v; } \
    01298         static type cast(unsigned short v) \
    01299             { return v; } \
    01300         static type cast(int v) \
    01301             { return v; } \
    01302         static type cast(unsigned int v) \
    01303             { return v; } \
    01304         static type cast(long v) \
    01305             { return v; } \
    01306         static type cast(unsigned long v) \
    01307             { return v; } \
    01308     };
    01309 #endif
    01310
    01311
    01312 VIGRA_SPECIALIZED_CAST(signed char)
    01313 VIGRA_SPECIALIZED_CAST(unsigned char)
    01314 VIGRA_SPECIALIZED_CAST(short)
    01315 VIGRA_SPECIALIZED_CAST(unsigned short)
    01316 VIGRA_SPECIALIZED_CAST(int)
    01317 VIGRA_SPECIALIZED_CAST(unsigned int)
    01318 VIGRA_SPECIALIZED_CAST(long)
    01319 VIGRA_SPECIALIZED_CAST(unsigned long)
    01320
    01321 template <>
    01322 struct RequiresExplicitCast<float> {
    01323     template <class U>
    01324     static U cast(U v)
    01325         { return v; }
    01326 };
    01327
    01328 template <>
    01329 struct RequiresExplicitCast<double> {
    01330     template <class U>
    01331     static U cast(U v)
    01332         { return v; }
    01333 };
    01334
    01335 #undef VIGRA_SPECIALIZED_CAST
    01336
    01337 } // namespace detail
    01338
    01339
    01340
    01341 } // namespace vigra
    01342
    01343 #endif // VIGRA_NUMERICTRAITS_HXX
    01344

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)