imgtools/imglib/boostlibrary/boost/detail/limits.hpp
changeset 2 39c28ec933dd
equal deleted inserted replaced
1:820b22e13ff1 2:39c28ec933dd
       
     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