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