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