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