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

vigra/numerictraits.hxx |

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

© 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.7.1 (3 Dec 2010)