/extlibs/Boost/include/boost/detail/limits.hpp
C++ Header | 449 lines | 304 code | 77 blank | 68 comment | 6 complexity | 04e9b82732ce56b825c97520897b47ec MD5 | raw file
1// Copyright 2001 John Maddock 2// Distributed under the Boost Software License, Version 1.0. (See accompany- 3// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5/* 6 * Copyright (c) 1997 7 * Silicon Graphics Computer Systems, Inc. 8 * 9 * Permission to use, copy, modify, distribute and sell this software 10 * and its documentation for any purpose is hereby granted without fee, 11 * provided that the above copyright notice appear in all copies and 12 * that both that copyright notice and this permission notice appear 13 * in supporting documentation. Silicon Graphics makes no 14 * representations about the suitability of this software for any 15 * purpose. It is provided "as is" without express or implied warranty. 16 */ 17 18/* NOTE: This is not portable code. Parts of numeric_limits<> are 19 * inherently machine-dependent, and this file is written for the MIPS 20 * architecture and the SGI MIPSpro C++ compiler. Parts of it (in 21 * particular, some of the characteristics of floating-point types) 22 * are almost certainly incorrect for any other platform. 23 */ 24 25/* The above comment is almost certainly out of date. This file works 26 * on systems other than SGI MIPSpro C++ now. 27 */ 28 29/* 30 * Revision history: 31 * 21 Sep 2001: 32 * Only include <cwchar> if BOOST_NO_CWCHAR is defined. (Darin Adler) 33 * 10 Aug 2001: 34 * Added MIPS (big endian) to the big endian family. (Jens Maurer) 35 * 13 Apr 2001: 36 * Added powerpc to the big endian family. (Jeremy Siek) 37 * 5 Apr 2001: 38 * Added sparc (big endian) processor support (John Maddock). 39 * Initial sub: 40 * Modified by Jens Maurer for gcc 2.95 on x86. 41 */ 42 43#ifndef BOOST_SGI_CPP_LIMITS 44#define BOOST_SGI_CPP_LIMITS 45 46#include <climits> 47#include <cfloat> 48#include <boost/config.hpp> 49#include <boost/detail/endian.hpp> 50 51#ifndef BOOST_NO_CWCHAR 52#include <cwchar> // for WCHAR_MIN and WCHAR_MAX 53#endif 54 55namespace std { 56 57enum float_round_style { 58 round_indeterminate = -1, 59 round_toward_zero = 0, 60 round_to_nearest = 1, 61 round_toward_infinity = 2, 62 round_toward_neg_infinity = 3 63}; 64 65enum float_denorm_style { 66 denorm_indeterminate = -1, 67 denorm_absent = 0, 68 denorm_present = 1 69}; 70 71// The C++ standard (section 18.2.1) requires that some of the members of 72// numeric_limits be static const data members that are given constant- 73// initializers within the class declaration. On compilers where the 74// BOOST_NO_INCLASS_MEMBER_INITIALIZATION macro is defined, it is impossible to write 75// a standard-conforming numeric_limits class. 76// 77// There are two possible workarounds: either initialize the data 78// members outside the class, or change them from data members to 79// enums. Neither workaround is satisfactory: the former makes it 80// impossible to use the data members in constant-expressions, and the 81// latter means they have the wrong type and that it is impossible to 82// take their addresses. We choose the former workaround. 83 84#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION 85# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ 86 enum { __mem_name = __mem_value } 87#else /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ 88# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ 89 static const __mem_type __mem_name = __mem_value 90#endif /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ 91 92// Base class for all specializations of numeric_limits. 93template <class __number> 94class _Numeric_limits_base { 95public: 96 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false); 97 98 static __number min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } 99 static __number max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } 100 101 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0); 102 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0); 103 104 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false); 105 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false); 106 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false); 107 108 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0); 109 110 static __number epsilon() throw() { return __number(); } 111 static __number round_error() throw() { return __number(); } 112 113 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0); 114 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0); 115 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0); 116 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0); 117 118 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false); 119 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false); 120 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false); 121 BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, 122 has_denorm, 123 denorm_absent); 124 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); 125 126 static __number infinity() throw() { return __number(); } 127 static __number quiet_NaN() throw() { return __number(); } 128 static __number signaling_NaN() throw() { return __number(); } 129 static __number denorm_min() throw() { return __number(); } 130 131 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false); 132 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false); 133 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false); 134 135 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false); 136 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); 137 BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, 138 round_style, 139 round_toward_zero); 140}; 141 142// Base class for integers. 143 144template <class _Int, 145 _Int __imin, 146 _Int __imax, 147 int __idigits = -1> 148class _Integer_limits : public _Numeric_limits_base<_Int> 149{ 150public: 151 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); 152 153 static _Int min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imin; } 154 static _Int max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imax; } 155 156 BOOST_STL_DECLARE_LIMITS_MEMBER(int, 157 digits, 158 (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT) 159 - (__imin == 0 ? 0 : 1) 160 : __idigits); 161 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000); 162 // log 2 = 0.301029995664... 163 164 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0); 165 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true); 166 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true); 167 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); 168 169 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); 170 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true); 171}; 172 173#if defined(BOOST_BIG_ENDIAN) 174 175 template<class Number, unsigned int Word> 176 struct float_helper{ 177 static Number get_word() throw() { 178 // sizeof(long double) == 16 179 const unsigned int _S_word[4] = { Word, 0, 0, 0 }; 180 return *reinterpret_cast<const Number*>(&_S_word); 181 } 182}; 183 184#else 185 186 template<class Number, unsigned int Word> 187 struct float_helper{ 188 static Number get_word() throw() { 189 // sizeof(long double) == 12, but only 10 bytes significant 190 const unsigned int _S_word[4] = { 0, 0, 0, Word }; 191 return *reinterpret_cast<const Number*>( 192 reinterpret_cast<const char *>(&_S_word)+16- 193 (sizeof(Number) == 12 ? 10 : sizeof(Number))); 194 } 195}; 196 197#endif 198 199// Base class for floating-point numbers. 200template <class __number, 201 int __Digits, int __Digits10, 202 int __MinExp, int __MaxExp, 203 int __MinExp10, int __MaxExp10, 204 unsigned int __InfinityWord, 205 unsigned int __QNaNWord, unsigned int __SNaNWord, 206 bool __IsIEC559, 207 float_round_style __RoundStyle> 208class _Floating_limits : public _Numeric_limits_base<__number> 209{ 210public: 211 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); 212 213 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits); 214 BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10); 215 216 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true); 217 218 BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); 219 220 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp); 221 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp); 222 BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10); 223 BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10); 224 225 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true); 226 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true); 227 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true); 228 BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, 229 has_denorm, 230 denorm_indeterminate); 231 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); 232 233 234 static __number infinity() throw() { 235 return float_helper<__number, __InfinityWord>::get_word(); 236 } 237 static __number quiet_NaN() throw() { 238 return float_helper<__number,__QNaNWord>::get_word(); 239 } 240 static __number signaling_NaN() throw() { 241 return float_helper<__number,__SNaNWord>::get_word(); 242 } 243 244 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559); 245 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); 246 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false /* was: true */ ); 247 BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); 248 249 BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle); 250}; 251 252// Class numeric_limits 253 254// The unspecialized class. 255 256template<class T> 257class numeric_limits : public _Numeric_limits_base<T> {}; 258 259// Specializations for all built-in integral types. 260 261template<> 262class numeric_limits<bool> 263 : public _Integer_limits<bool, false, true, 0> 264{}; 265 266template<> 267class numeric_limits<char> 268 : public _Integer_limits<char, CHAR_MIN, CHAR_MAX> 269{}; 270 271template<> 272class numeric_limits<signed char> 273 : public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX> 274{}; 275 276template<> 277class numeric_limits<unsigned char> 278 : public _Integer_limits<unsigned char, 0, UCHAR_MAX> 279{}; 280 281#ifndef BOOST_NO_INTRINSIC_WCHAR_T 282template<> 283class numeric_limits<wchar_t> 284#if !defined(WCHAR_MAX) || !defined(WCHAR_MIN) 285#if defined(_WIN32) || defined(__CYGWIN__) 286 : public _Integer_limits<wchar_t, 0, USHRT_MAX> 287#elif defined(__hppa) 288// wchar_t has "unsigned int" as the underlying type 289 : public _Integer_limits<wchar_t, 0, UINT_MAX> 290#else 291// assume that wchar_t has "int" as the underlying type 292 : public _Integer_limits<wchar_t, INT_MIN, INT_MAX> 293#endif 294#else 295// we have WCHAR_MIN and WCHAR_MAX defined, so use it 296 : public _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX> 297#endif 298{}; 299#endif 300 301template<> 302class numeric_limits<short> 303 : public _Integer_limits<short, SHRT_MIN, SHRT_MAX> 304{}; 305 306template<> 307class numeric_limits<unsigned short> 308 : public _Integer_limits<unsigned short, 0, USHRT_MAX> 309{}; 310 311template<> 312class numeric_limits<int> 313 : public _Integer_limits<int, INT_MIN, INT_MAX> 314{}; 315 316template<> 317class numeric_limits<unsigned int> 318 : public _Integer_limits<unsigned int, 0, UINT_MAX> 319{}; 320 321template<> 322class numeric_limits<long> 323 : public _Integer_limits<long, LONG_MIN, LONG_MAX> 324{}; 325 326template<> 327class numeric_limits<unsigned long> 328 : public _Integer_limits<unsigned long, 0, ULONG_MAX> 329{}; 330 331#ifdef __GNUC__ 332 333// Some compilers have long long, but don't define the 334// LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This 335// assumes that long long is 64 bits. 336#if !defined(LONGLONG_MAX) && !defined(ULONGLONG_MAX) 337 338# define ULONGLONG_MAX 0xffffffffffffffffLLU 339# define LONGLONG_MAX 0x7fffffffffffffffLL 340 341#endif 342 343#if !defined(LONGLONG_MIN) 344# define LONGLONG_MIN (-LONGLONG_MAX - 1) 345#endif 346 347 348#if !defined(ULONGLONG_MIN) 349# define ULONGLONG_MIN 0 350#endif 351 352#endif /* __GNUC__ */ 353 354// Specializations for all built-in floating-point type. 355 356template<> class numeric_limits<float> 357 : public _Floating_limits<float, 358 FLT_MANT_DIG, // Binary digits of precision 359 FLT_DIG, // Decimal digits of precision 360 FLT_MIN_EXP, // Minimum exponent 361 FLT_MAX_EXP, // Maximum exponent 362 FLT_MIN_10_EXP, // Minimum base 10 exponent 363 FLT_MAX_10_EXP, // Maximum base 10 exponent 364#if defined(BOOST_BIG_ENDIAN) 365 0x7f80 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity 366 0x7f81 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN 367 0x7fc1 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN 368#else 369 0x7f800000u, // Last word of +infinity 370 0x7f810000u, // Last word of quiet NaN 371 0x7fc10000u, // Last word of signaling NaN 372#endif 373 true, // conforms to iec559 374 round_to_nearest> 375{ 376public: 377 static float min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MIN; } 378 static float denorm_min() throw() { return FLT_MIN; } 379 static float max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MAX; } 380 static float epsilon() throw() { return FLT_EPSILON; } 381 static float round_error() throw() { return 0.5f; } // Units: ulps. 382}; 383 384template<> class numeric_limits<double> 385 : public _Floating_limits<double, 386 DBL_MANT_DIG, // Binary digits of precision 387 DBL_DIG, // Decimal digits of precision 388 DBL_MIN_EXP, // Minimum exponent 389 DBL_MAX_EXP, // Maximum exponent 390 DBL_MIN_10_EXP, // Minimum base 10 exponent 391 DBL_MAX_10_EXP, // Maximum base 10 exponent 392#if defined(BOOST_BIG_ENDIAN) 393 0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity 394 0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN 395 0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN 396#else 397 0x7ff00000u, // Last word of +infinity 398 0x7ff10000u, // Last word of quiet NaN 399 0x7ff90000u, // Last word of signaling NaN 400#endif 401 true, // conforms to iec559 402 round_to_nearest> 403{ 404public: 405 static double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MIN; } 406 static double denorm_min() throw() { return DBL_MIN; } 407 static double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MAX; } 408 static double epsilon() throw() { return DBL_EPSILON; } 409 static double round_error() throw() { return 0.5; } // Units: ulps. 410}; 411 412template<> class numeric_limits<long double> 413 : public _Floating_limits<long double, 414 LDBL_MANT_DIG, // Binary digits of precision 415 LDBL_DIG, // Decimal digits of precision 416 LDBL_MIN_EXP, // Minimum exponent 417 LDBL_MAX_EXP, // Maximum exponent 418 LDBL_MIN_10_EXP,// Minimum base 10 exponent 419 LDBL_MAX_10_EXP,// Maximum base 10 exponent 420#if defined(BOOST_BIG_ENDIAN) 421 0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity 422 0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN 423 0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN 424#else 425 0x7fff8000u, // Last word of +infinity 426 0x7fffc000u, // Last word of quiet NaN 427 0x7fff9000u, // Last word of signaling NaN 428#endif 429 false, // Doesn't conform to iec559 430 round_to_nearest> 431{ 432public: 433 static long double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MIN; } 434 static long double denorm_min() throw() { return LDBL_MIN; } 435 static long double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MAX; } 436 static long double epsilon() throw() { return LDBL_EPSILON; } 437 static long double round_error() throw() { return 4; } // Units: ulps. 438}; 439 440} // namespace std 441 442#endif /* BOOST_SGI_CPP_LIMITS */ 443 444// Local Variables: 445// mode:C++ 446// End: 447 448 449