Diff of /src/foreign/vigra/numerictraits.hxx [da984f] .. [8f0f49] Maximize Restore

Repo status: analyzing...

  Switch to side-by-side view

--- a/src/foreign/vigra/numerictraits.hxx
+++ b/src/foreign/vigra/numerictraits.hxx
@@ -4,19 +4,34 @@
 /*       Cognitive Systems Group, University of Hamburg, Germany        */
 /*                                                                      */
 /*    This file is part of the VIGRA computer vision library.           */
-/*    ( Version 1.2.0, Aug 07 2003 )                                    */
-/*    You may use, modify, and distribute this software according       */
-/*    to the terms stated in the LICENSE file included in               */
-/*    the VIGRA distribution.                                           */
-/*                                                                      */
+/*    ( Version 1.4.0, Dec 21 2005 )                                    */
 /*    The VIGRA Website is                                              */
 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
 /*    Please direct questions, bug reports, and contributions to        */
-/*        koethe@informatik.uni-hamburg.de                              */
+/*        koethe@informatik.uni-hamburg.de          or                  */
+/*        vigra@kogs1.informatik.uni-hamburg.de                         */
 /*                                                                      */
-/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
-/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
-/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
+/*    Permission is hereby granted, free of charge, to any person       */
+/*    obtaining a copy of this software and associated documentation    */
+/*    files (the "Software"), to deal in the Software without           */
+/*    restriction, including without limitation the rights to use,      */
+/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
+/*    sell copies of the Software, and to permit persons to whom the    */
+/*    Software is furnished to do so, subject to the following          */
+/*    conditions:                                                       */
+/*                                                                      */
+/*    The above copyright notice and this permission notice shall be    */
+/*    included in all copies or substantial portions of the             */
+/*    Software.                                                         */
+/*                                                                      */
+/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
+/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
+/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
+/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
+/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
+/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
+/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
+/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
 /*                                                                      */
 /************************************************************************/
 
@@ -26,7 +41,9 @@
 
 #include <limits.h>
 #include <cfloat>
+#include <complex>
 #include "vigra/metaprogramming.hxx"
+#include "vigra/sized_int.hxx"
 
 /********************************************************/
 /*                                                      */
@@ -48,6 +65,12 @@
     <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
     \ref PromoteTraits
     <DD><em>Binary traits for promotion of arithmetic objects</em>
+    <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 
+    \ref SquareRootTraits
+    <DD><em>Unary traits for the calculation of the square root of arithmetic objects</em>
+    <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> 
+    \ref NormTraits
+    <DD><em>Unary traits for the calculation of the norm and squared norm of arithmetic objects</em>
     </DL>
 
     These traits classes contain information that is used by generic
@@ -134,8 +157,14 @@
     <b> <TT>NumericTraits<ArithmeticType></TT></b>:
 
     <table>
-    <tr>
-    <td>
+    <tr><td>
+    <b> <TT>typedef ... Type;</TT></b>
+    </td><td>
+    
+            the type itself 
+        
+    </td></tr>
+    <tr><td>
     <b> <TT>typedef ... Promote;</TT></b>
     </td><td>
 
@@ -145,10 +174,25 @@
     <tr><td>
     <b> <TT>typedef ... RealPromote;</TT></b>
     </td><td>
-            promote type for multiplication and division
+            promote type for multiplication and division with a real number
 
     (only defined if <TT>ArithmeticType</TT> supports these operations)
 
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... ComplexPromote;</TT></b>
+    </td><td>
+    
+            promote type for complex arithmetic 
+        
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... ValueType;</TT></b>
+    </td><td>
+    
+            for scalar types: the type itself<br>
+            otherwise: typename Type::value_type (if defined)
+        
     </td></tr>
     <tr><td>
     <b> <TT>static Promote toPromote(ArithmeticType v);</TT></b>
@@ -206,6 +250,24 @@
 
     </td></tr>
     <tr><td>
+    <b> <TT>static ArithmeticType min();</TT></b>
+    </td><td>
+    the smallest number representable in this type.<br>
+    Only available if isOrdered is VigraTrueType. For integral types,
+    this equals <TT>INT_MIN</TT> etc., for real valued types it is <TT>-FLT_MAX</TT>
+    etc. (<b>not</b> <TT>FLT_MIN</TT> -- this is the smallest positive <tt>float</tt>)
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>static ArithmeticType max();</TT></b>
+    </td><td>
+    the largest number representable in this type.<br>
+    Only available if isOrdered is VigraTrueType. For integral types,
+    this equals <TT>INT_MAX</TT> etc., for real valued types it is <TT>FLT_MAX</TT>
+    etc.
+    
+    </td></tr>
+    <tr><td>
     <b> <TT>static ArithmeticType one();</TT></b>
     </td><td>
     create neutral element of multiplication
@@ -218,15 +280,40 @@
 
     </td></tr>
     <tr><td>
-    <b> <TT>static const bool is_integral;</TT></b>
-    </td><td>
-        true if <TT>ArithmeticType</TT> is an integral type, false otherwise
-
-    </td></tr>
-    <tr><td>
-    <b> <TT>static const bool is_scalar;</TT></b>
-    </td><td>
-        true if <TT>ArithmeticType</TT> is a scalar type, false otherwise
+    <b> <TT>typedef ... isIntegral;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is an integral type, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... isScalar;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a scalar type, 
+        VigraFalseType otherwise 
+
+    </td></tr>
+    <tr><td>
+    <tr><td>
+    <b> <TT>typedef ... isSigned;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a signed type, 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <tr><td>
+    <b> <TT>typedef ... isOrdered;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> supports operator<(), 
+        VigraFalseType otherwise 
+    
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... isComplex;</TT></b>
+    </td><td>
+        VigraTrueType if <TT>ArithmeticType</TT> is a complex number, 
+        VigraFalseType otherwise 
 
     </td></tr>
     <tr><td>
@@ -301,19 +388,130 @@
     Namespace: vigra
 */
 
+/** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticType>
+
+    Unary traits for the calculation of the square root of arithmetic objects.
+    
+    <b>\#include</b> 
+    "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
+
+    This traits class is used to determine appropriate argument and result types
+    for the function sqrt(). These traits are typically used like this:
+    
+    \code
+    ArithmeticType t = ...;
+    SquareRootTraits<ArithmeticType>::SquareRootResult r = 
+          sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
+    \endcode
+    
+    This approach avoids 'ambigouos overload errors' when taking the square root of 
+    an integer type. It also takes care of determining the proper result of the
+    sqrt() function of \ref vigra::FixedPoint and of the norm() function, when
+    it is implemented via sqrt(squaredNorm(x)).
+    The following members are defined in <b> <TT>SquareRootTraits<ArithmeticType></TT></b>:
+    
+    <table>
+    <tr><td>
+    <b> <TT>typedef ArithmeticType Type;</TT></b>
+    </td><td>
+            the type itself
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquareRootArgument;</TT></b>
+    </td><td>
+            required argument type for srqt(), i.e. <tt>sqrt((SquareRootArgument)x)</tt>
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquareRootResult;</TT></b>
+    </td><td>
+            result of <tt>sqrt((SquareRootArgument)x)</tt>
+    </td></tr>
+    </table>
+    
+    NormTraits for the built-in types are defined in <b>\#include</b> 
+    "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
+    
+    Namespace: vigra
+*/
+
+/** \page NormTraits template<> struct NormTraits<ArithmeticType>
+
+    Unary traits for the calculation of the norm and squared norm of arithmetic objects.
+    
+    <b>\#include</b> 
+    "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
+
+    This traits class is used to determine appropriate result types
+    for the functions norm() and squaredNorm(). These functions are always 
+    declared like this (where <tt>ArithmeticType</tt> is a type thats supports a norm):
+    
+    \code
+    NormTraits<ArithmeticType>::NormType        norm(ArithmeticType const & t);
+    NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
+    \endcode
+    
+    The following members are defined in <b> <TT>NormTraits<ArithmeticType></TT></b>:
+    
+    <table>
+    <tr><td>
+    <b> <TT>typedef ArithmeticType Type;</TT></b>
+    </td><td>
+            the type itself
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... SquaredNormType;</TT></b>
+    </td><td>
+            result of <tt>squaredNorm(ArithmeticType)</tt>
+    </td></tr>
+    <tr><td>
+    <b> <TT>typedef ... NormType;</TT></b>
+    </td><td>
+            result of <tt>norm(ArithmeticType)</tt><br>
+            Usually equal to <tt>SquareRootTraits&lt;SquaredNormType&gt;::SquareRootResult
+    </td></tr>
+    </table>
+    
+    NormTraits for the built-in types are defined in <b>\#include</b> 
+    "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>"
+    
+    Namespace: vigra
+*/
+
 namespace vigra {
 
 struct Error_NumericTraits_not_specialized_for_this_case { };
+struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char { };
 
 template<class A>
 struct NumericTraits
 {
+    typedef Error_NumericTraits_not_specialized_for_this_case Type;
     typedef Error_NumericTraits_not_specialized_for_this_case Promote;
     typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
+    typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromote;
+    typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
+
     typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
     typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
+    typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
     typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
-    typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
+    typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
+};
+
+template<>
+struct NumericTraits<char>
+{
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Type;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char Promote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char RealPromote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ComplexPromote;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char ValueType;
+
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isScalar;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isIntegral;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isSigned;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isOrdered;
+    typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_unsigned_char isComplex;
 };
 
 #ifndef NO_BOOL
@@ -323,10 +521,14 @@
     typedef bool Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraFalseType isSigned;
+    typedef VigraFalseType isComplex;
 
     static bool zero() { return false; }
     static bool one() { return true; }
@@ -358,10 +560,14 @@
     typedef signed char Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static signed char zero() { return 0; }
     static signed char one() { return 1; }
@@ -382,8 +588,13 @@
         return ((v < SCHAR_MIN) ? SCHAR_MIN : (v > SCHAR_MAX) ? SCHAR_MAX : v);
     }
     static signed char fromRealPromote(RealPromote v) {
-        return ((v < 0.0) ? ((v < (float)SCHAR_MIN) ? SCHAR_MIN : static_cast<signed char>(v - 0.5)) :
-                (v > SCHAR_MAX) ? SCHAR_MAX : static_cast<signed char>(v + 0.5));
+        return ((v < 0.0) 
+                   ? ((v < (RealPromote)SCHAR_MIN) 
+                       ? SCHAR_MIN 
+                       : static_cast<signed char>(v - 0.5)) 
+                   : (v > (RealPromote)SCHAR_MAX) 
+                       ? SCHAR_MAX 
+                       : static_cast<signed char>(v + 0.5)); 
     }
 };
 
@@ -393,10 +604,14 @@
     typedef unsigned char Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraFalseType isSigned;
+    typedef VigraFalseType isComplex;
 
     static unsigned char zero() { return 0; }
     static unsigned char one() { return 1; }
@@ -417,7 +632,11 @@
         return ((v < 0) ? 0 : (v > UCHAR_MAX) ? UCHAR_MAX : v);
     }
     static unsigned char fromRealPromote(RealPromote const & v) {
-            return ((v < 0.0) ? 0 : ((v > (float)UCHAR_MAX) ? UCHAR_MAX : static_cast<unsigned char>(v + 0.5)));
+            return ((v < 0.0) 
+                     ? 0 
+                     : ((v > (RealPromote)UCHAR_MAX) 
+                         ? UCHAR_MAX 
+                         : static_cast<unsigned char>(v + 0.5)));
     }
 };
 
@@ -427,10 +646,14 @@
     typedef short int Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static short int zero() { return 0; }
     static short int one() { return 1; }
@@ -452,9 +675,13 @@
                 (v > SHRT_MAX) ? SHRT_MAX : v);
     }
     static short int fromRealPromote(RealPromote v) {
-        return ((v < 0.0) ?
-                ((v < (float)SHRT_MIN) ? SHRT_MIN : static_cast<short int>(v - 0.5)) :
-                ((v > (float)SHRT_MAX) ? SHRT_MAX : static_cast<short int>(v + 0.5)));
+        return ((v < 0.0) 
+                 ? ((v < (RealPromote)SHRT_MIN) 
+                     ? SHRT_MIN 
+                     : static_cast<short int>(v - 0.5)) 
+                 : ((v > (RealPromote)SHRT_MAX) 
+                     ? SHRT_MAX 
+                     : static_cast<short int>(v + 0.5))); 
     }
 };
 
@@ -464,11 +691,14 @@
     typedef short unsigned int Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
 
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraFalseType isSigned;
+    typedef VigraFalseType isComplex;
 
     static short unsigned int zero() { return 0; }
     static short unsigned int one() { return 1; }
@@ -489,8 +719,11 @@
         return ((v < 0) ? 0 : (v > USHRT_MAX) ? USHRT_MAX : v);
     }
     static short unsigned int fromRealPromote(RealPromote v) {
-            return ((v < 0.0) ?
-              0 : ((v > (float)USHRT_MAX) ? USHRT_MAX : static_cast<short unsigned int>(v + 0.5)));
+            return ((v < 0.0) 
+                     ? 0 
+                     : ((v > (RealPromote)USHRT_MAX) 
+                         ? USHRT_MAX 
+                         : static_cast<short unsigned int>(v + 0.5)));
     }
 };
 
@@ -500,10 +733,14 @@
     typedef int Type;
     typedef int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static int zero() { return 0; }
     static int one() { return 1; }
@@ -522,9 +759,13 @@
     static RealPromote toRealPromote(int v) { return v; }
     static int fromPromote(Promote v) { return v; }
     static int fromRealPromote(RealPromote v) {
-        return ((v < 0.0) ?
-                ((v < (float)INT_MIN) ? INT_MIN : static_cast<int>(v - 0.5)) :
-                ((v > (float)INT_MAX) ? INT_MAX : static_cast<int>(v + 0.5)));
+        return ((v < 0.0) 
+                 ? ((v < (RealPromote)INT_MIN) 
+                     ? INT_MIN 
+                     : static_cast<int>(v - 0.5)) 
+                 : ((v > (RealPromote)INT_MAX) 
+                     ? INT_MAX 
+                     : static_cast<int>(v + 0.5))); 
     }
 };
 
@@ -534,10 +775,14 @@
     typedef unsigned int Type;
     typedef unsigned int Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraFalseType isSigned;
+    typedef VigraFalseType isComplex;
 
     static unsigned int zero() { return 0; }
     static unsigned int one() { return 1; }
@@ -556,9 +801,11 @@
     static RealPromote toRealPromote(unsigned int v) { return v; }
     static unsigned int fromPromote(Promote v) { return v; }
     static unsigned int fromRealPromote(RealPromote v) {
-            return ((v < 0.0) ? 0 :
-               ((v > (float)UINT_MAX) ?
-                         UINT_MAX : static_cast<unsigned int>(v + 0.5)));
+            return ((v < 0.0) 
+                     ? 0 
+                     : ((v > (RealPromote)UINT_MAX) 
+                         ? UINT_MAX 
+                         : static_cast<unsigned int>(v + 0.5)));
     }
 };
 
@@ -568,10 +815,14 @@
     typedef long Type;
     typedef long Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static long zero() { return 0; }
     static long one() { return 1; }
@@ -590,9 +841,13 @@
     static RealPromote toRealPromote(long v) { return v; }
     static long fromPromote(Promote v) { return v; }
     static long fromRealPromote(RealPromote v) {
-        return ((v < 0.0) ?
-                ((v < (float)LONG_MIN) ? LONG_MIN : static_cast<long>(v - 0.5)) :
-                ((v > (float)LONG_MAX) ? LONG_MAX : static_cast<long>(v + 0.5)));
+        return ((v < 0.0) 
+                 ? ((v < (RealPromote)LONG_MIN) 
+                     ? LONG_MIN 
+                     : static_cast<long>(v - 0.5)) 
+                 : ((v > (RealPromote)LONG_MAX) 
+                     ? LONG_MAX 
+                     : static_cast<long>(v + 0.5))); 
     }
 };
 
@@ -602,10 +857,14 @@
     typedef unsigned long Type;
     typedef unsigned long Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraTrueType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraFalseType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraFalseType isSigned;
+    typedef VigraFalseType isComplex;
 
     static unsigned long zero() { return 0; }
     static unsigned long one() { return 1; }
@@ -624,9 +883,11 @@
     static RealPromote toRealPromote(unsigned long v) { return v; }
     static unsigned long fromPromote(Promote v) { return v; }
     static unsigned long fromRealPromote(RealPromote v) {
-            return ((v < 0.0) ? 0 :
-               ((v > (float)ULONG_MAX) ?
-                            ULONG_MAX : static_cast<unsigned long>(v + 0.5)));
+            return ((v < 0.0) 
+                     ? 0 
+                     : ((v > (RealPromote)ULONG_MAX) 
+                         ? ULONG_MAX 
+                         : static_cast<unsigned long>(v + 0.5)));
     }
 };
 
@@ -636,10 +897,14 @@
     typedef float Type;
     typedef float Promote;
     typedef float RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+    
     typedef VigraFalseType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static float zero() { return 0.0; }
     static float one() { return 1.0; }
@@ -661,10 +926,14 @@
     typedef double Type;
     typedef double Promote;
     typedef double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraFalseType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static double zero() { return 0.0; }
     static double one() { return 1.0; }
@@ -686,10 +955,14 @@
     typedef long double Type;
     typedef long double Promote;
     typedef long double RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef Type ValueType;
+
     typedef VigraFalseType isIntegral;
     typedef VigraTrueType isScalar;
+    typedef VigraTrueType isSigned;
     typedef VigraTrueType isOrdered;
-    typedef VigraTrueType isSigned;
+    typedef VigraFalseType isComplex;
 
     static long double zero() { return 0.0; }
     static long double one() { return 1.0; }
@@ -705,6 +978,101 @@
     static long double fromRealPromote(RealPromote v) { return v; }
 };
 
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+struct NumericTraits<std::complex<T> >
+{
+    typedef std::complex<T> Type;
+    typedef std::complex<typename NumericTraits<T>::Promote> Promote;
+    typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromote;
+    typedef std::complex<RealPromote> ComplexPromote;
+    typedef T ValueType;
+
+    typedef VigraFalseType isIntegral;
+    typedef VigraFalseType isScalar;
+    typedef typename NumericTraits<T>::isSigned isSigned;
+    typedef VigraFalseType isOrdered;
+    typedef VigraTrueType isComplex;
+    
+    static Type zero() { return Type(0.0); }
+    static Type one() { return Type(1.0); }
+    static Type nonZero() { return one(); }
+    static Type epsilon() { return Type(NumericTraits<T>::epsilon()); }
+    static Type smallestPositive() { return Type(NumericTraits<T>::smallestPositive()); }
+
+    static Promote toPromote(Type const & v) { return v; }
+    static Type fromPromote(Promote const & v) { return v; }
+    static Type fromRealPromote(RealPromote v) { return Type(v); }
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+/********************************************************/
+/*                                                      */
+/*                    SquareRootTraits                  */
+/*                                                      */
+/********************************************************/
+
+template<class T>
+struct SquareRootTraits
+{
+    typedef T                                                    Type;
+    typedef typename NumericTraits<T>::RealPromote               SquareRootResult;
+    typedef typename NumericTraits<T>::RealPromote               SquareRootArgument;
+};
+
+
+/********************************************************/
+/*                                                      */
+/*                       NormTraits                     */
+/*                                                      */
+/********************************************************/
+
+struct Error_NormTraits_not_specialized_for_this_case { };
+
+template<class T>
+struct NormTraits
+{
+    typedef T                                                            Type;
+    typedef typename T::SquaredNormType                                  SquaredNormType;
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
+};
+
+#define VIGRA_DEFINE_NORM_TRAITS(T) \
+    template <> struct NormTraits<T> { \
+        typedef T Type; \
+        typedef NumericTraits<T>::Promote SquaredNormType; \
+        typedef T NormType; \
+    };
+
+VIGRA_DEFINE_NORM_TRAITS(bool)
+VIGRA_DEFINE_NORM_TRAITS(signed char)
+VIGRA_DEFINE_NORM_TRAITS(unsigned char)
+VIGRA_DEFINE_NORM_TRAITS(short)
+VIGRA_DEFINE_NORM_TRAITS(unsigned short)
+VIGRA_DEFINE_NORM_TRAITS(int)
+VIGRA_DEFINE_NORM_TRAITS(unsigned int)
+VIGRA_DEFINE_NORM_TRAITS(long)
+VIGRA_DEFINE_NORM_TRAITS(unsigned long)
+VIGRA_DEFINE_NORM_TRAITS(float)
+VIGRA_DEFINE_NORM_TRAITS(double)
+VIGRA_DEFINE_NORM_TRAITS(long double)
+
+#undef VIGRA_DEFINE_NORM_TRAITS
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template<class T>
+struct NormTraits<std::complex<T> >
+{
+    typedef std::complex<T>                                              Type;
+    typedef typename NormTraits<T>::SquaredNormType                      SquaredNormType;
+    typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
+};
+
+#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
 /********************************************************/
 /*                                                      */
 /*                      PromoteTraits                  */
@@ -720,98 +1088,98 @@
 };
 
 template<>
-struct PromoteTraits<char, char>
+struct PromoteTraits<signed char, signed char>
 {
     typedef int Promote;
-    static Promote toPromote(char v) { return v; }
-};
-
-template<>
-struct PromoteTraits<char, unsigned char>
+    static Promote toPromote(signed char v) { return v; }
+};
+
+template<>
+struct PromoteTraits<signed char, unsigned char>
 {
     typedef int Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(unsigned char v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, short int>
+struct PromoteTraits<signed char, short int>
 {
     typedef int Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(short int v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, short unsigned int>
+struct PromoteTraits<signed char, short unsigned int>
 {
     typedef unsigned int Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(short unsigned int v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, int>
+struct PromoteTraits<signed char, int>
 {
     typedef int Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(int v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, unsigned int>
+struct PromoteTraits<signed char, unsigned int>
 {
     typedef unsigned int Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(unsigned int v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, long>
+struct PromoteTraits<signed char, long>
 {
     typedef long Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(long v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, unsigned long>
+struct PromoteTraits<signed char, unsigned long>
 {
     typedef unsigned long Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(unsigned long v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, float>
+struct PromoteTraits<signed char, float>
 {
     typedef float Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(float v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, double>
+struct PromoteTraits<signed char, double>
 {
     typedef double Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(double v) { return v; }
 };
 
 template<>
-struct PromoteTraits<char, long double>
+struct PromoteTraits<signed char, long double>
 {
     typedef long double Promote;
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
     static Promote toPromote(long double v) { return v; }
 };
 
 template<>
-struct PromoteTraits<unsigned char, char>
+struct PromoteTraits<unsigned char, signed char>
 {
     typedef int Promote;
     static Promote toPromote(unsigned char v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -894,11 +1262,11 @@
 };
 
 template<>
-struct PromoteTraits<short int, char>
+struct PromoteTraits<short int, signed char>
 {
     typedef int Promote;
     static Promote toPromote(short int v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -981,11 +1349,11 @@
 };
 
 template<>
-struct PromoteTraits<short unsigned int, char>
+struct PromoteTraits<short unsigned int, signed char>
 {
     typedef unsigned int Promote;
     static Promote toPromote(short unsigned int v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1068,11 +1436,11 @@
 };
 
 template<>
-struct PromoteTraits<int, char>
+struct PromoteTraits<int, signed char>
 {
     typedef int Promote;
     static Promote toPromote(int v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1134,7 +1502,7 @@
 struct PromoteTraits<int, float>
 {
     typedef float Promote;
-    static Promote toPromote(int v) { return v; }
+    static Promote toPromote(int v) { return static_cast<Promote>(v); }
     static Promote toPromote(float v) { return v; }
 };
 
@@ -1155,11 +1523,11 @@
 };
 
 template<>
-struct PromoteTraits<unsigned int, char>
+struct PromoteTraits<unsigned int, signed char>
 {
     typedef unsigned int Promote;
     static Promote toPromote(unsigned int v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1221,7 +1589,7 @@
 struct PromoteTraits<unsigned int, float>
 {
     typedef float Promote;
-    static Promote toPromote(unsigned int v) { return v; }
+    static Promote toPromote(unsigned int v) { return static_cast<Promote>(v); }
     static Promote toPromote(float v) { return v; }
 };
 
@@ -1242,11 +1610,11 @@
 };
 
 template<>
-struct PromoteTraits<long, char>
+struct PromoteTraits<long, signed char>
 {
     typedef long Promote;
     static Promote toPromote(long v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1308,7 +1676,7 @@
 struct PromoteTraits<long, float>
 {
     typedef float Promote;
-    static Promote toPromote(long v) { return v; }
+    static Promote toPromote(long v) { return static_cast<Promote>(v); }
     static Promote toPromote(float v) { return v; }
 };
 
@@ -1329,11 +1697,11 @@
 };
 
 template<>
-struct PromoteTraits<unsigned long, char>
+struct PromoteTraits<unsigned long, signed char>
 {
     typedef unsigned long Promote;
     static Promote toPromote(unsigned long v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1395,7 +1763,7 @@
 struct PromoteTraits<unsigned long, float>
 {
     typedef float Promote;
-    static Promote toPromote(unsigned long v) { return v; }
+    static Promote toPromote(unsigned long v) { return static_cast<Promote>(v); }
     static Promote toPromote(float v) { return v; }
 };
 
@@ -1416,11 +1784,11 @@
 };
 
 template<>
-struct PromoteTraits<float, char>
+struct PromoteTraits<float, signed char>
 {
     typedef float Promote;
     static Promote toPromote(float v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1452,7 +1820,7 @@
 {
     typedef float Promote;
     static Promote toPromote(float v) { return v; }
-    static Promote toPromote(int v) { return v; }
+    static Promote toPromote(int v) { return static_cast<Promote>(v); }
 };
 
 template<>
@@ -1460,7 +1828,7 @@
 {
     typedef float Promote;
     static Promote toPromote(float v) { return v; }
-    static Promote toPromote(unsigned int v) { return v; }
+    static Promote toPromote(unsigned int v) { return static_cast<Promote>(v); }
 };
 
 template<>
@@ -1468,7 +1836,7 @@
 {
     typedef float Promote;
     static Promote toPromote(float v) { return v; }
-    static Promote toPromote(long v) { return v; }
+    static Promote toPromote(long v) { return static_cast<Promote>(v); }
 };
 
 template<>
@@ -1476,7 +1844,7 @@
 {
     typedef float Promote;
     static Promote toPromote(float v) { return v; }
-    static Promote toPromote(unsigned long v) { return v; }
+    static Promote toPromote(unsigned long v) { return static_cast<Promote>(v); }
 };
 
 template<>
@@ -1503,11 +1871,11 @@
 };
 
 template<>
-struct PromoteTraits<double, char>
+struct PromoteTraits<double, signed char>
 {
     typedef double Promote;
     static Promote toPromote(double v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1590,11 +1958,11 @@
 };
 
 template<>
-struct PromoteTraits<long double, char>
+struct PromoteTraits<long double, signed char>
 {
     typedef long double Promote;
     static Promote toPromote(long double v) { return v; }
-    static Promote toPromote(char v) { return v; }
+    static Promote toPromote(signed char v) { return v; }
 };
 
 template<>
@@ -1675,6 +2043,41 @@
     typedef long double Promote;
     static Promote toPromote(long double v) { return v; }
 };
+
+#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class T>
+struct PromoteTraits<std::complex<T>, std::complex<T> >
+{
+    typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
+    static Promote toPromote(std::complex<T> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<std::complex<T1>, std::complex<T2> >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(std::complex<T1> const & v) { return v; }
+    static Promote toPromote(std::complex<T2> const & v) { return v; }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<std::complex<T1>, T2 >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(std::complex<T1> const & v) { return v; }
+    static Promote toPromote(T2 const & v) { return Promote(v); }
+};
+
+template <class T1, class T2>
+struct PromoteTraits<T1, std::complex<T2> >
+{
+    typedef std::complex<typename PromoteTraits<T1, T2>::Promote> Promote;
+    static Promote toPromote(T1 const & v) { return Promote(v); }
+    static Promote toPromote(std::complex<T2> const & v) { return v; }
+};
+
+#endif
 
 namespace detail {
 
@@ -1693,9 +2096,11 @@
             { return NumericTraits<type>::fromRealPromote(v); } \
         static type cast(double v) \
             { return NumericTraits<type>::fromRealPromote(v); } \
+        static type cast(type v) \
+            { return v; } \
         template <class U> \
         static type cast(U v) \
-            { return v; } \
+            { return static_cast<type>(v); } \
  \
     };
 #else