Home | History | Annotate | Download | only in stl
      1 /*
      2  * Copyright (c) 1998,1999
      3  * Silicon Graphics Computer Systems, Inc.
      4  *
      5  * Copyright (c) 1999
      6  * Boris Fomitchev
      7  *
      8  * This material is provided "as is", with absolutely no warranty expressed
      9  * or implied. Any use is at your own risk.
     10  *
     11  * Permission to use or copy this software for any purpose is hereby granted
     12  * without fee, provided the above notices are retained on all copies.
     13  * Permission to modify the code and to distribute modified code is granted,
     14  * provided the above notices are retained, and a notice that the code was
     15  * modified is included with the above copyright notice.
     16  *
     17  */
     18 
     19 #ifndef _STLP_LIMITS_C
     20 #define _STLP_LIMITS_C
     21 
     22 #ifndef _STLP_INTERNAL_LIMITS
     23 #  include <stl/_limits.h>
     24 #endif
     25 
     26 //==========================================================
     27 //  numeric_limits static members
     28 //==========================================================
     29 
     30 _STLP_BEGIN_NAMESPACE
     31 
     32 _STLP_MOVE_TO_PRIV_NAMESPACE
     33 
     34 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
     35 
     36 #  define __declare_numeric_base_member(__type, __mem) \
     37 template <class __number> \
     38   const __type _Numeric_limits_base<__number>:: __mem
     39 
     40 __declare_numeric_base_member(bool, is_specialized);
     41 __declare_numeric_base_member(int, digits);
     42 __declare_numeric_base_member(int, digits10);
     43 __declare_numeric_base_member(bool, is_signed);
     44 __declare_numeric_base_member(bool, is_integer);
     45 __declare_numeric_base_member(bool, is_exact);
     46 __declare_numeric_base_member(int, radix);
     47 __declare_numeric_base_member(int, min_exponent);
     48 __declare_numeric_base_member(int, max_exponent);
     49 __declare_numeric_base_member(int, min_exponent10);
     50 __declare_numeric_base_member(int, max_exponent10);
     51 __declare_numeric_base_member(bool, has_infinity);
     52 __declare_numeric_base_member(bool, has_quiet_NaN);
     53 __declare_numeric_base_member(bool, has_signaling_NaN);
     54 __declare_numeric_base_member(float_denorm_style, has_denorm);
     55 __declare_numeric_base_member(bool, has_denorm_loss);
     56 __declare_numeric_base_member(bool, is_iec559);
     57 __declare_numeric_base_member(bool, is_bounded);
     58 __declare_numeric_base_member(bool, is_modulo);
     59 __declare_numeric_base_member(bool, traps);
     60 __declare_numeric_base_member(bool, tinyness_before);
     61 __declare_numeric_base_member(float_round_style, round_style);
     62 
     63 #  undef __declare_numeric_base_member
     64 
     65 #  define __declare_integer_limits_member(__type, __mem) \
     66 template <class _Int, _STLP_LIMITS_MIN_TYPE __imin, _STLP_LIMITS_MAX_TYPE __imax, int __idigits, bool __ismod> \
     67   const __type _Integer_limits<_Int, __imin, __imax, __idigits, __ismod>:: __mem
     68 
     69 __declare_integer_limits_member(bool, is_specialized);
     70 __declare_integer_limits_member(int, digits);
     71 __declare_integer_limits_member(int, digits10);
     72 __declare_integer_limits_member(bool, is_signed);
     73 __declare_integer_limits_member(bool, is_integer);
     74 __declare_integer_limits_member(bool, is_exact);
     75 __declare_integer_limits_member(int, radix);
     76 __declare_integer_limits_member(bool, is_bounded);
     77 __declare_integer_limits_member(bool, is_modulo);
     78 #  undef __declare_integer_limits_member
     79 
     80 #  if defined (__GNUC__) && (__GNUC__ != 2 || __GNUC_MINOR__ > 96) && (__GNUC__ != 3 || __GNUC_MINOR__ == 0) && (__GNUC__ <= 3)
     81 _STLP_MOVE_TO_STD_NAMESPACE
     82 
     83 #    define __declare_numeric_limits_member(__integer) \
     84   _STLP_TEMPLATE_NULL const int numeric_limits<__integer>::digits; \
     85   _STLP_TEMPLATE_NULL const int numeric_limits<__integer>::digits10; \
     86   _STLP_TEMPLATE_NULL const int numeric_limits<__integer>::radix; \
     87   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_specialized; \
     88   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_signed; \
     89   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_integer; \
     90   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_exact; \
     91   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_bounded; \
     92   _STLP_TEMPLATE_NULL const bool numeric_limits<__integer>::is_modulo
     93 
     94 __declare_numeric_limits_member(_STLP_LONG_LONG);
     95 __declare_numeric_limits_member(unsigned _STLP_LONG_LONG);
     96 
     97 #    undef __declare_numeric_limits_member
     98 
     99 _STLP_MOVE_TO_PRIV_NAMESPACE
    100 #  endif
    101 
    102 #  define __declare_float_limits_member(__type, __mem) \
    103 template <class __number,  \
    104          int __Digits, int __Digits10,    \
    105          int __MinExp, int __MaxExp,      \
    106          int __MinExp10, int __MaxExp10,  \
    107          bool __IsIEC559, \
    108          float_denorm_style __DenormStyle, \
    109          float_round_style __RoundStyle> \
    110 const __type _Floating_limits< __number, __Digits, __Digits10,    \
    111          __MinExp, __MaxExp, __MinExp10, __MaxExp10,  \
    112          __IsIEC559, __DenormStyle, __RoundStyle>::\
    113          __mem
    114 
    115 __declare_float_limits_member(bool, is_specialized);
    116 __declare_float_limits_member(int, digits);
    117 __declare_float_limits_member(int, digits10);
    118 __declare_float_limits_member(bool, is_signed);
    119 __declare_float_limits_member(int, radix);
    120 __declare_float_limits_member(int, min_exponent);
    121 __declare_float_limits_member(int, max_exponent);
    122 __declare_float_limits_member(int, min_exponent10);
    123 __declare_float_limits_member(int, max_exponent10);
    124 __declare_float_limits_member(bool, has_infinity);
    125 __declare_float_limits_member(bool, has_quiet_NaN);
    126 __declare_float_limits_member(bool, has_signaling_NaN);
    127 __declare_float_limits_member(float_denorm_style, has_denorm);
    128 __declare_float_limits_member(bool, has_denorm_loss);
    129 __declare_float_limits_member(bool, is_iec559);
    130 __declare_float_limits_member(bool, is_bounded);
    131 __declare_float_limits_member(bool, traps);
    132 __declare_float_limits_member(bool, tinyness_before);
    133 __declare_float_limits_member(float_round_style, round_style);
    134 #  undef __declare_float_limits_member
    135 
    136 #endif
    137 
    138 
    139 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
    140 
    141 #  if defined (__GNUC__) || defined (__BORLANDC__)
    142 #    define _STLP_ADDITIONAL_OPEN_BRACKET {
    143 #    define _STLP_ADDITIONAL_CLOSE_BRACKET }
    144 #  else
    145 #    define _STLP_ADDITIONAL_OPEN_BRACKET
    146 #    define _STLP_ADDITIONAL_CLOSE_BRACKET
    147 #  endif
    148 
    149 /* The following code has been extracted from the boost libraries (www.boost.org) and
    150  * adapted with the STLport portability macros. Advantage on previous technique is that
    151  * computation of infinity and NaN values is only based on big/little endianess, compiler
    152  * float, double or long double representation is taken into account thanks to the sizeof
    153  * operator. */
    154 template<class _Number, unsigned short _Word>
    155 struct float_helper {
    156   union _WordsNumber {
    157     unsigned short _Words[8];
    158     _Number _num;
    159   };
    160   static _Number get_word_higher() _STLP_NOTHROW {
    161     _WordsNumber __tmp = { _STLP_ADDITIONAL_OPEN_BRACKET _Word, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
    162     return __tmp._num;
    163   }
    164   static _Number get_word_lower() _STLP_NOTHROW {
    165     _WordsNumber __tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
    166     __tmp._Words[(sizeof(_Number) >= 12 ? 10 : sizeof(_Number)) / sizeof(unsigned short) - 1] = _Word;
    167     return __tmp._num;
    168   }
    169   static _Number get_from_last_word() _STLP_NOTHROW {
    170 #  if defined (_STLP_BIG_ENDIAN)
    171     return get_word_higher();
    172 #  else /* _STLP_LITTLE_ENDIAN */
    173     return get_word_lower();
    174 #  endif
    175   }
    176   static _Number get_from_first_word() _STLP_NOTHROW {
    177 #  if defined (_STLP_BIG_ENDIAN)
    178     return get_word_lower();
    179 #  else /* _STLP_LITTLE_ENDIAN */
    180     return get_word_higher();
    181 #  endif
    182   }
    183 };
    184 
    185 #  if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_BIG_ENDIAN)
    186 template<class _Number, unsigned short _Word1, unsigned short _Word2>
    187 struct float_helper2 {
    188   union _WordsNumber {
    189     unsigned short _Words[8];
    190     _Number _num;
    191   };
    192   //static _Number get_word_higher() _STLP_NOTHROW {
    193   //  _WordsNumber __tmp = { _STLP_ADDITIONAL_OPEN_BRACKET _Word1, _Word2, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
    194   //  return __tmp._num;
    195   //}
    196   static _Number get_word_lower() _STLP_NOTHROW {
    197     _WordsNumber __tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
    198     __tmp._Words[(sizeof(_Number) >= 12 ? 10 : sizeof(_Number)) / sizeof(unsigned short) - 2] = _Word1;
    199     __tmp._Words[(sizeof(_Number) >= 12 ? 10 : sizeof(_Number)) / sizeof(unsigned short) - 1] = _Word2;
    200     return __tmp._num;
    201   }
    202   static _Number get_from_last_word() _STLP_NOTHROW {
    203 //#    if defined (_STLP_BIG_ENDIAN)
    204 //    return get_word_higher();
    205 //#    else /* _STLP_LITTLE_ENDIAN */
    206     return get_word_lower();
    207 //#    endif
    208   }
    209 };
    210 #  endif
    211 
    212 /* Former values kept in case moving to boost code has introduce a regression on
    213  * some platform. */
    214 #if 0
    215 #  if defined (_STLP_BIG_ENDIAN)
    216 #    if defined (__OS400__)
    217 #      define _STLP_FLOAT_INF_REP { 0x7f80, 0 }
    218 #      define _STLP_FLOAT_QNAN_REP { 0xffc0, 0 }
    219 #      define _STLP_FLOAT_SNAN_REP { 0xff80, 0 }
    220 #      define _STLP_DOUBLE_INF_REP { 0x7ff0, 0, 0, 0 }
    221 #      define _STLP_DOUBLE_QNAN_REP { 0xfff8, 0, 0, 0 }
    222 #      define _STLP_DOUBLE_SNAN_REP { 0xfff0, 0, 0, 0 }
    223 #      define _STLP_LDOUBLE_INF_REP { 0x7ff0, 0, 0, 0, 0, 0, 0, 0 }
    224 #      define _STLP_LDOUBLE_QNAN_REP { 0xfff8, 0, 0, 0, 0, 0, 0, 0 }
    225 #      define _STLP_LDOUBLE_SNAN_REP { 0xfff0, 0, 0, 0, 0, 0, 0, 0 }
    226 #    else /* __OS400__ */
    227 #      define _STLP_FLOAT_INF_REP   { 0x7f80, 0 }
    228 #      define _STLP_FLOAT_QNAN_REP  { 0x7fc1, 0 }
    229 #      define _STLP_FLOAT_SNAN_REP  { 0x7f81, 0 }
    230 #      define _STLP_DOUBLE_INF_REP  { 0x7ff0, 0, 0, 0 }
    231 #      define _STLP_DOUBLE_QNAN_REP { 0x7ff9, 0, 0, 0 }
    232 #      define _STLP_DOUBLE_SNAN_REP { 0x7ff1, 0, 0, 0 }
    233 #      define _STLP_LDOUBLE_INF_REP { 0x7ff0, 0, 0, 0, 0, 0, 0, 0 }
    234 #      define _STLP_LDOUBLE_QNAN_REP { 0x7ff1, 0, 0, 0, 0, 0, 0, 0 }
    235 #      define _STLP_LDOUBLE_SNAN_REP { 0x7ff9, 0, 0, 0, 0, 0, 0, 0 }
    236 #    endif /* __OS400__ */
    237 #  else /* _STLP_LITTLE_ENDIAN */
    238 #    if defined(__DECCXX)
    239 #      define _STLP_FLOAT_INF_REP { 0, 0x7f80 }
    240 #      define _STLP_FLOAT_QNAN_REP { 0, 0xffc0 }
    241 #      define _STLP_FLOAT_SNAN_REP { 0x5555, 0x7f85 }
    242 #      define _STLP_DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 }
    243 #      define _STLP_DOUBLE_QNAN_REP { 0, 0, 0, 0xfff8 }
    244 #      define _STLP_DOUBLE_SNAN_REP { 0x5555, 0x5555, 0x5555, 0x7ff5 }
    245 #      define _STLP_LDOUBLE_INF_REP { 0, 0, 0, 0, 0, 0, 0, 0x7fff }
    246 #      define _STLP_LDOUBLE_QNAN_REP { 0, 0, 0, 0, 0, 0, 0x8000, 0xffff }
    247 #      define _STLP_LDOUBLE_SNAN_REP { 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x7fff}
    248 #    else
    249 #      define _STLP_FLOAT_INF_REP { 0, 0x7f80 }
    250 #      define _STLP_FLOAT_QNAN_REP { 0, 0x7fc0 }
    251 #      define _STLP_FLOAT_SNAN_REP { 0, 0x7fa0 }
    252 #      define _STLP_DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 }
    253 #      define _STLP_DOUBLE_QNAN_REP { 0, 0, 0, 0x7ff8 }
    254 #      define _STLP_DOUBLE_SNAN_REP { 0, 0, 0, 0x7ff4 }
    255 #      if defined (_STLP_MSVC) || defined (__ICL)
    256 #        define _STLP_LDOUBLE_INF_REP { 0, 0, 0, 0x7FF0, 0 }
    257 #        define _STLP_LDOUBLE_QNAN_REP { 0, 0, 0, 0xFFF8, 0 }
    258 #        define _STLP_LDOUBLE_SNAN_REP { 0, 0, 0, 0xFFF8, 0 }
    259 #      elif defined (__BORLANDC__)
    260 #        define _STLP_LDOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff }
    261 #        define _STLP_LDOUBLE_QNAN_REP { 0, 0, 0, 0xc000, 0x7fff }
    262 #        define _STLP_LDOUBLE_SNAN_REP { 0, 0, 0, 0xa000, 0x7fff }
    263 #      else
    264 #        define _STLP_LDOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff, 0 }
    265 #        define _STLP_LDOUBLE_QNAN_REP { 0, 0, 0, 0xa000, 0x7fff, 0 }
    266 #        define _STLP_LDOUBLE_SNAN_REP { 0, 0, 0, 0xc000, 0x7fff, 0 }
    267 #      endif
    268 #    endif
    269 #  endif
    270 
    271 union _F_rep {
    272   unsigned short rep[2];
    273   float val;
    274 };
    275 union _D_rep {
    276   unsigned short rep[4];
    277   double val;
    278 };
    279 
    280 #  ifndef _STLP_NO_LONG_DOUBLE
    281 union _LD_rep {
    282   unsigned short rep[8];
    283   long double val;
    284 };
    285 #  endif
    286 #endif
    287 
    288 template <class __dummy>
    289 float _STLP_CALL _LimG<__dummy>::get_F_inf() {
    290   typedef float_helper<float, 0x7f80u> _FloatHelper;
    291   return _FloatHelper::get_from_last_word();
    292 }
    293 template <class __dummy>
    294 float _STLP_CALL _LimG<__dummy>::get_F_qNaN() {
    295   typedef float_helper<float, 0x7f81u> _FloatHelper;
    296   return _FloatHelper::get_from_last_word();
    297 }
    298 template <class __dummy>
    299 float _STLP_CALL _LimG<__dummy>::get_F_sNaN() {
    300   typedef float_helper<float, 0x7fc1u> _FloatHelper;
    301   return _FloatHelper::get_from_last_word();
    302 }
    303 template <class __dummy>
    304 float _STLP_CALL _LimG<__dummy>::get_F_denormMin() {
    305   typedef float_helper<float, 0x0001u> _FloatHelper;
    306   return _FloatHelper::get_from_first_word();
    307 }
    308 
    309 template <int __use_double_limits>
    310 class _NumericLimitsAccess;
    311 
    312 _STLP_TEMPLATE_NULL
    313 class _NumericLimitsAccess<1> {
    314 public:
    315   static double get_inf() {
    316     typedef float_helper<double, 0x7ff0u> _FloatHelper;
    317     return _FloatHelper::get_from_last_word();
    318   }
    319   static double get_qNaN() {
    320     typedef float_helper<double, 0x7ff1u> _FloatHelper;
    321     return _FloatHelper::get_from_last_word();
    322   }
    323   static double get_sNaN() {
    324     typedef float_helper<double, 0x7ff9u> _FloatHelper;
    325     return _FloatHelper::get_from_last_word();
    326   }
    327 };
    328 
    329 template <class __dummy>
    330 double _STLP_CALL _LimG<__dummy>::get_D_inf()
    331 { return _NumericLimitsAccess<1>::get_inf(); }
    332 template <class __dummy>
    333 double _STLP_CALL _LimG<__dummy>::get_D_qNaN()
    334 { return _NumericLimitsAccess<1>::get_qNaN(); }
    335 template <class __dummy>
    336 double _STLP_CALL _LimG<__dummy>::get_D_sNaN()
    337 { return _NumericLimitsAccess<1>::get_sNaN(); }
    338 template <class __dummy>
    339 double _STLP_CALL _LimG<__dummy>::get_D_denormMin() {
    340   typedef float_helper<double, 0x0001u> _FloatHelper;
    341   return _FloatHelper::get_from_first_word();
    342 }
    343 
    344 #  if !defined (_STLP_NO_LONG_DOUBLE)
    345 _STLP_TEMPLATE_NULL
    346 class _NumericLimitsAccess<0> {
    347 public:
    348   static long double get_inf() {
    349 #    if defined (_STLP_BIG_ENDIAN)
    350     typedef float_helper<long double, 0x7ff0u> _FloatHelper;
    351 #    else
    352     typedef float_helper2<long double, 0x8000u, 0x7fffu> _FloatHelper;
    353 #    endif
    354     return _FloatHelper::get_from_last_word();
    355   }
    356   static long double get_qNaN() {
    357 #    if defined (_STLP_BIG_ENDIAN)
    358     typedef float_helper<long double, 0x7ff1u> _FloatHelper;
    359 #    else
    360     typedef float_helper2<long double, 0xc000u, 0x7fffu> _FloatHelper;
    361 #    endif
    362     return _FloatHelper::get_from_last_word();
    363   }
    364   static long double get_sNaN() {
    365 #    if defined (_STLP_BIG_ENDIAN)
    366     typedef float_helper<long double, 0x7ff9u> _FloatHelper;
    367 #    else
    368     typedef float_helper2<long double, 0x9000u, 0x7fffu> _FloatHelper;
    369 #    endif
    370     return _FloatHelper::get_from_last_word();
    371   }
    372 };
    373 
    374 template <class __dummy>
    375 long double _STLP_CALL _LimG<__dummy>::get_LD_inf() {
    376   const int __use_double_limits = sizeof(double) == sizeof(long double) ? 1 : 0;
    377   return _NumericLimitsAccess<__use_double_limits>::get_inf();
    378 }
    379 template <class __dummy>
    380 long double _STLP_CALL _LimG<__dummy>::get_LD_qNaN() {
    381   const int __use_double_limits = sizeof(double) == sizeof(long double) ? 1 : 0;
    382   return _NumericLimitsAccess<__use_double_limits>::get_qNaN();
    383 }
    384 template <class __dummy>
    385 long double _STLP_CALL _LimG<__dummy>::get_LD_sNaN() {
    386   const int __use_double_limits = sizeof(double) == sizeof(long double) ? 1 : 0;
    387   return _NumericLimitsAccess<__use_double_limits>::get_sNaN();
    388 }
    389 template <class __dummy>
    390 long double _STLP_CALL _LimG<__dummy>::get_LD_denormMin() {
    391   typedef float_helper<long double, 0x0001u> _FloatHelper;
    392   return _FloatHelper::get_from_first_word();
    393 }
    394 #  endif
    395 
    396 #endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */
    397 
    398 #undef _STLP_LIMITS_MIN_TYPE
    399 #undef _STLP_LIMITS_MAX_TYPE
    400 
    401 _STLP_MOVE_TO_STD_NAMESPACE
    402 
    403 _STLP_END_NAMESPACE
    404 
    405 #endif /* _STLP_LIMITS_C_INCLUDED */
    406