os/ossrv/ossrv_pub/boost_apis/boost/detail/limits.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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 
    55 namespace std {
    56 
    57 enum 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 
    65 enum 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.
    93 template <class __number>
    94 class _Numeric_limits_base {
    95 public:
    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 
   144 template <class _Int,
   145           _Int __imin,
   146           _Int __imax,
   147           int __idigits = -1>
   148 class _Integer_limits : public _Numeric_limits_base<_Int> 
   149 {
   150 public:
   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.
   200 template <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>
   208 class _Floating_limits : public _Numeric_limits_base<__number>
   209 {
   210 public:
   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 
   256 template<class T> 
   257 class numeric_limits : public _Numeric_limits_base<T> {};
   258 
   259 // Specializations for all built-in integral types.
   260 
   261 template<>
   262 class numeric_limits<bool>
   263   : public _Integer_limits<bool, false, true, 0>
   264 {};
   265 
   266 template<>
   267 class numeric_limits<char>
   268   : public _Integer_limits<char, CHAR_MIN, CHAR_MAX>
   269 {};
   270 
   271 template<>
   272 class numeric_limits<signed char>
   273   : public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX>
   274 {};
   275 
   276 template<>
   277 class numeric_limits<unsigned char>
   278   : public _Integer_limits<unsigned char, 0, UCHAR_MAX>
   279 {};
   280 
   281 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
   282 template<>
   283 class 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 
   301 template<>
   302 class numeric_limits<short>
   303   : public _Integer_limits<short, SHRT_MIN, SHRT_MAX>
   304 {};
   305 
   306 template<>
   307 class numeric_limits<unsigned short>
   308   : public _Integer_limits<unsigned short, 0, USHRT_MAX>
   309 {};
   310 
   311 template<>
   312 class numeric_limits<int>
   313   : public _Integer_limits<int, INT_MIN, INT_MAX>
   314 {};
   315 
   316 template<>
   317 class numeric_limits<unsigned int>
   318   : public _Integer_limits<unsigned int, 0, UINT_MAX>
   319 {};
   320 
   321 template<>
   322 class numeric_limits<long>
   323   : public _Integer_limits<long, LONG_MIN, LONG_MAX>
   324 {};
   325 
   326 template<>
   327 class 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 
   356 template<> 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 {
   376 public:
   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 
   384 template<> 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 {
   404 public:
   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 
   412 template<> 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 {
   432 public:
   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