00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef BOOST_SGI_CPP_LIMITS
00044 #define BOOST_SGI_CPP_LIMITS
00045
00046 #include <climits>
00047 #include <cfloat>
00048 #include <boost/config.hpp>
00049 #include <boost/detail/endian.hpp>
00050
00051 #ifndef BOOST_NO_CWCHAR
00052 #include <cwchar>
00053 #endif
00054
00055 namespace std {
00056
00057 enum float_round_style {
00058 round_indeterminate = -1,
00059 round_toward_zero = 0,
00060 round_to_nearest = 1,
00061 round_toward_infinity = 2,
00062 round_toward_neg_infinity = 3
00063 };
00064
00065 enum float_denorm_style {
00066 denorm_indeterminate = -1,
00067 denorm_absent = 0,
00068 denorm_present = 1
00069 };
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
00085 # define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
00086 enum { __mem_name = __mem_value }
00087 #else
00088 # define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
00089 static const __mem_type __mem_name = __mem_value
00090 #endif
00091
00092
00093 template <class __number>
00094 class _Numeric_limits_base {
00095 public:
00096 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false);
00097
00098 static __number min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); }
00099 static __number max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); }
00100
00101 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0);
00102 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0);
00103
00104 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false);
00105 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false);
00106 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false);
00107
00108 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0);
00109
00110 static __number epsilon() throw() { return __number(); }
00111 static __number round_error() throw() { return __number(); }
00112
00113 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0);
00114 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0);
00115 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0);
00116 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0);
00117
00118 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false);
00119 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false);
00120 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false);
00121 BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
00122 has_denorm,
00123 denorm_absent);
00124 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
00125
00126 static __number infinity() throw() { return __number(); }
00127 static __number quiet_NaN() throw() { return __number(); }
00128 static __number signaling_NaN() throw() { return __number(); }
00129 static __number denorm_min() throw() { return __number(); }
00130
00131 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false);
00132 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false);
00133 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false);
00134
00135 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false);
00136 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
00137 BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style,
00138 round_style,
00139 round_toward_zero);
00140 };
00141
00142
00143
00144 template <class _Int,
00145 _Int __imin,
00146 _Int __imax,
00147 int __idigits = -1>
00148 class _Integer_limits : public _Numeric_limits_base<_Int>
00149 {
00150 public:
00151 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
00152
00153 static _Int min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imin; }
00154 static _Int max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imax; }
00155
00156 BOOST_STL_DECLARE_LIMITS_MEMBER(int,
00157 digits,
00158 (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT)
00159 - (__imin == 0 ? 0 : 1)
00160 : __idigits);
00161 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000);
00162
00163
00164 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0);
00165 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true);
00166 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true);
00167 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
00168
00169 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
00170 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true);
00171 };
00172
00173 #if defined(BOOST_BIG_ENDIAN)
00174
00175 template<class Number, unsigned int Word>
00176 struct float_helper{
00177 static Number get_word() throw() {
00178
00179 const unsigned int _S_word[4] = { Word, 0, 0, 0 };
00180 return *reinterpret_cast<const Number*>(&_S_word);
00181 }
00182 };
00183
00184 #else
00185
00186 template<class Number, unsigned int Word>
00187 struct float_helper{
00188 static Number get_word() throw() {
00189
00190 const unsigned int _S_word[4] = { 0, 0, 0, Word };
00191 return *reinterpret_cast<const Number*>(
00192 reinterpret_cast<const char *>(&_S_word)+16-
00193 (sizeof(Number) == 12 ? 10 : sizeof(Number)));
00194 }
00195 };
00196
00197 #endif
00198
00199
00200 template <class __number,
00201 int __Digits, int __Digits10,
00202 int __MinExp, int __MaxExp,
00203 int __MinExp10, int __MaxExp10,
00204 unsigned int __InfinityWord,
00205 unsigned int __QNaNWord, unsigned int __SNaNWord,
00206 bool __IsIEC559,
00207 float_round_style __RoundStyle>
00208 class _Floating_limits : public _Numeric_limits_base<__number>
00209 {
00210 public:
00211 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
00212
00213 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits);
00214 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10);
00215
00216 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true);
00217
00218 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
00219
00220 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp);
00221 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp);
00222 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10);
00223 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10);
00224
00225 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true);
00226 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true);
00227 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true);
00228 BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
00229 has_denorm,
00230 denorm_indeterminate);
00231 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
00232
00233
00234 static __number infinity() throw() {
00235 return float_helper<__number, __InfinityWord>::get_word();
00236 }
00237 static __number quiet_NaN() throw() {
00238 return float_helper<__number,__QNaNWord>::get_word();
00239 }
00240 static __number signaling_NaN() throw() {
00241 return float_helper<__number,__SNaNWord>::get_word();
00242 }
00243
00244 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559);
00245 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
00246 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false );
00247 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
00248
00249 BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle);
00250 };
00251
00252
00253
00254
00255
00256 template<class T>
00257 class numeric_limits : public _Numeric_limits_base<T> {};
00258
00259
00260
00261 template<>
00262 class numeric_limits<bool>
00263 : public _Integer_limits<bool, false, true, 0>
00264 {};
00265
00266 template<>
00267 class numeric_limits<char>
00268 : public _Integer_limits<char, CHAR_MIN, CHAR_MAX>
00269 {};
00270
00271 template<>
00272 class numeric_limits<signed char>
00273 : public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX>
00274 {};
00275
00276 template<>
00277 class numeric_limits<unsigned char>
00278 : public _Integer_limits<unsigned char, 0, UCHAR_MAX>
00279 {};
00280
00281 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
00282 template<>
00283 class numeric_limits<wchar_t>
00284 #if !defined(WCHAR_MAX) || !defined(WCHAR_MIN)
00285 #if defined(_WIN32) || defined(__CYGWIN__)
00286 : public _Integer_limits<wchar_t, 0, USHRT_MAX>
00287 #elif defined(__hppa)
00288
00289 : public _Integer_limits<wchar_t, 0, UINT_MAX>
00290 #else
00291
00292 : public _Integer_limits<wchar_t, INT_MIN, INT_MAX>
00293 #endif
00294 #else
00295
00296 : public _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX>
00297 #endif
00298 {};
00299 #endif
00300
00301 template<>
00302 class numeric_limits<short>
00303 : public _Integer_limits<short, SHRT_MIN, SHRT_MAX>
00304 {};
00305
00306 template<>
00307 class numeric_limits<unsigned short>
00308 : public _Integer_limits<unsigned short, 0, USHRT_MAX>
00309 {};
00310
00311 template<>
00312 class numeric_limits<int>
00313 : public _Integer_limits<int, INT_MIN, INT_MAX>
00314 {};
00315
00316 template<>
00317 class numeric_limits<unsigned int>
00318 : public _Integer_limits<unsigned int, 0, UINT_MAX>
00319 {};
00320
00321 template<>
00322 class numeric_limits<long>
00323 : public _Integer_limits<long, LONG_MIN, LONG_MAX>
00324 {};
00325
00326 template<>
00327 class numeric_limits<unsigned long>
00328 : public _Integer_limits<unsigned long, 0, ULONG_MAX>
00329 {};
00330
00331 #ifdef __GNUC__
00332
00333
00334
00335
00336 #if !defined(LONGLONG_MAX) && !defined(ULONGLONG_MAX)
00337
00338 # define ULONGLONG_MAX 0xffffffffffffffffLLU
00339 # define LONGLONG_MAX 0x7fffffffffffffffLL
00340
00341 #endif
00342
00343 #if !defined(LONGLONG_MIN)
00344 # define LONGLONG_MIN (-LONGLONG_MAX - 1)
00345 #endif
00346
00347
00348 #if !defined(ULONGLONG_MIN)
00349 # define ULONGLONG_MIN 0
00350 #endif
00351
00352 #endif
00353
00354
00355
00356 template<> class numeric_limits<float>
00357 : public _Floating_limits<float,
00358 FLT_MANT_DIG,
00359 FLT_DIG,
00360 FLT_MIN_EXP,
00361 FLT_MAX_EXP,
00362 FLT_MIN_10_EXP,
00363 FLT_MAX_10_EXP,
00364 #if defined(BOOST_BIG_ENDIAN)
00365 0x7f80 << (sizeof(int)*CHAR_BIT-16),
00366 0x7f81 << (sizeof(int)*CHAR_BIT-16),
00367 0x7fc1 << (sizeof(int)*CHAR_BIT-16),
00368 #else
00369 0x7f800000u,
00370 0x7f810000u,
00371 0x7fc10000u,
00372 #endif
00373 true,
00374 round_to_nearest>
00375 {
00376 public:
00377 static float min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MIN; }
00378 static float denorm_min() throw() { return FLT_MIN; }
00379 static float max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MAX; }
00380 static float epsilon() throw() { return FLT_EPSILON; }
00381 static float round_error() throw() { return 0.5f; }
00382 };
00383
00384 template<> class numeric_limits<double>
00385 : public _Floating_limits<double,
00386 DBL_MANT_DIG,
00387 DBL_DIG,
00388 DBL_MIN_EXP,
00389 DBL_MAX_EXP,
00390 DBL_MIN_10_EXP,
00391 DBL_MAX_10_EXP,
00392 #if defined(BOOST_BIG_ENDIAN)
00393 0x7ff0 << (sizeof(int)*CHAR_BIT-16),
00394 0x7ff1 << (sizeof(int)*CHAR_BIT-16),
00395 0x7ff9 << (sizeof(int)*CHAR_BIT-16),
00396 #else
00397 0x7ff00000u,
00398 0x7ff10000u,
00399 0x7ff90000u,
00400 #endif
00401 true,
00402 round_to_nearest>
00403 {
00404 public:
00405 static double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MIN; }
00406 static double denorm_min() throw() { return DBL_MIN; }
00407 static double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MAX; }
00408 static double epsilon() throw() { return DBL_EPSILON; }
00409 static double round_error() throw() { return 0.5; }
00410 };
00411
00412 template<> class numeric_limits<long double>
00413 : public _Floating_limits<long double,
00414 LDBL_MANT_DIG,
00415 LDBL_DIG,
00416 LDBL_MIN_EXP,
00417 LDBL_MAX_EXP,
00418 LDBL_MIN_10_EXP,
00419 LDBL_MAX_10_EXP,
00420 #if defined(BOOST_BIG_ENDIAN)
00421 0x7ff0 << (sizeof(int)*CHAR_BIT-16),
00422 0x7ff1 << (sizeof(int)*CHAR_BIT-16),
00423 0x7ff9 << (sizeof(int)*CHAR_BIT-16),
00424 #else
00425 0x7fff8000u,
00426 0x7fffc000u,
00427 0x7fff9000u,
00428 #endif
00429 false,
00430 round_to_nearest>
00431 {
00432 public:
00433 static long double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MIN; }
00434 static long double denorm_min() throw() { return LDBL_MIN; }
00435 static long double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MAX; }
00436 static long double epsilon() throw() { return LDBL_EPSILON; }
00437 static long double round_error() throw() { return 4; }
00438 };
00439
00440 }
00441
00442 #endif
00443
00444
00445
00446
00447
00448
00449