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