williamr@4: /* williamr@4: * Copyright (c) 1997 williamr@4: * Silicon Graphics Computer Systems, Inc. williamr@4: * williamr@4: * Copyright (c) 1999 williamr@4: * Boris Fomitchev williamr@4: * williamr@4: * This material is provided "as is", with absolutely no warranty expressed williamr@4: * or implied. Any use is at your own risk. williamr@4: * williamr@4: * Permission to use or copy this software for any purpose is hereby granted williamr@4: * without fee, provided the above notices are retained on all copies. williamr@4: * Permission to modify the code and to distribute modified code is granted, williamr@4: * provided the above notices are retained, and a notice that the code was williamr@4: * modified is included with the above copyright notice. williamr@4: * williamr@4: */ williamr@4: williamr@4: /* NOTE: This may be not portable code. Parts of numeric_limits<> are williamr@4: * inherently machine-dependent. At present this file is suitable williamr@4: * for the MIPS, SPARC, Alpha and ia32 architectures. williamr@4: */ williamr@4: williamr@4: #ifndef _STLP_INTERNAL_LIMITS williamr@4: #define _STLP_INTERNAL_LIMITS williamr@4: williamr@4: #ifndef _STLP_CLIMITS williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #ifndef _STLP_CFLOAT williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_INTERNAL_CWCHAR) williamr@4: # include williamr@4: #endif williamr@4: williamr@4: _STLP_BEGIN_NAMESPACE williamr@4: williamr@4: enum float_round_style { williamr@4: round_indeterminate = -1, williamr@4: round_toward_zero = 0, williamr@4: round_to_nearest = 1, williamr@4: round_toward_infinity = 2, williamr@4: round_toward_neg_infinity = 3 williamr@4: }; williamr@4: williamr@4: enum float_denorm_style { williamr@4: denorm_indeterminate = -1, williamr@4: denorm_absent = 0, williamr@4: denorm_present = 1 williamr@4: }; williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: // Base class for all specializations of numeric_limits. williamr@4: template williamr@4: class _Numeric_limits_base { williamr@4: public: williamr@4: williamr@4: static __number (_STLP_CALL min)() _STLP_NOTHROW { return __number(); } williamr@4: static __number (_STLP_CALL max)() _STLP_NOTHROW { return __number(); } williamr@4: williamr@4: #if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: enum { williamr@4: #else williamr@4: static const int williamr@4: #endif williamr@4: williamr@4: digits = 0, williamr@4: digits10 = 0, williamr@4: radix = 0, williamr@4: min_exponent = 0, williamr@4: min_exponent10 = 0, williamr@4: max_exponent = 0, williamr@4: max_exponent10 = 0 williamr@4: williamr@4: #if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: , williamr@4: has_denorm = denorm_absent, williamr@4: round_style = round_toward_zero, williamr@4: #else williamr@4: ; williamr@4: static const float_denorm_style has_denorm = denorm_absent; williamr@4: static const float_round_style round_style = round_toward_zero; williamr@4: static const bool williamr@4: #endif williamr@4: williamr@4: is_specialized = false, williamr@4: is_signed = false, williamr@4: is_integer = false, williamr@4: is_exact = false, williamr@4: has_infinity = false, williamr@4: has_quiet_NaN = false, williamr@4: has_signaling_NaN = false, williamr@4: has_denorm_loss = false, williamr@4: is_iec559 = false, williamr@4: is_bounded = false, williamr@4: is_modulo = false, williamr@4: traps = false, williamr@4: tinyness_before = false williamr@4: #if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: } williamr@4: #endif williamr@4: ; williamr@4: williamr@4: static __number _STLP_CALL epsilon() _STLP_NOTHROW { return __number(); } williamr@4: static __number _STLP_CALL round_error() _STLP_NOTHROW { return __number(); } williamr@4: williamr@4: static __number _STLP_CALL infinity() _STLP_NOTHROW { return __number(); } williamr@4: static __number _STLP_CALL quiet_NaN() _STLP_NOTHROW { return __number(); } williamr@4: static __number _STLP_CALL signaling_NaN() _STLP_NOTHROW { return __number(); } williamr@4: static __number _STLP_CALL denorm_min() _STLP_NOTHROW { return __number(); } williamr@4: }; williamr@4: williamr@4: // Base class for integers. williamr@4: williamr@4: #ifdef _STLP_LIMITED_DEFAULT_TEMPLATES williamr@4: # ifdef _STLP_LONG_LONG williamr@4: # define _STLP_LIMITS_MIN_TYPE _STLP_LONG_LONG williamr@4: # define _STLP_LIMITS_MAX_TYPE unsigned _STLP_LONG_LONG williamr@4: # else williamr@4: # define _STLP_LIMITS_MIN_TYPE long williamr@4: # define _STLP_LIMITS_MAX_TYPE unsigned long williamr@4: # endif williamr@4: #else williamr@4: # define _STLP_LIMITS_MIN_TYPE _Int williamr@4: # define _STLP_LIMITS_MAX_TYPE _Int williamr@4: #endif /* _STLP_LIMITED_DEFAULT_TEMPLATES */ williamr@4: williamr@4: template williamr@4: class _Integer_limits : public _Numeric_limits_base<_Int> { williamr@4: public: williamr@4: williamr@4: static _Int (_STLP_CALL min) () _STLP_NOTHROW { return (_Int)__imin; } williamr@4: static _Int (_STLP_CALL max) () _STLP_NOTHROW { return (_Int)__imax; } williamr@4: williamr@4: #if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: enum { williamr@4: #else williamr@4: static const int williamr@4: #endif williamr@4: digits = (__idigits < 0) ? williamr@4: ((int)((sizeof(_Int) * (CHAR_BIT))) - ((__imin == 0) ? 0 : 1)) williamr@4: : (__idigits), williamr@4: digits10 = (digits * 301UL) / 1000, williamr@4: radix = 2 williamr@4: #if !defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: ; williamr@4: static const bool williamr@4: #else williamr@4: , williamr@4: #endif williamr@4: is_specialized = true, williamr@4: is_signed = (__imin != 0), williamr@4: is_integer = true, williamr@4: is_exact = true, williamr@4: is_bounded = true, williamr@4: is_modulo = __ismod williamr@4: #if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: } williamr@4: #endif williamr@4: ; williamr@4: }; williamr@4: williamr@4: // Base class for floating-point numbers. williamr@4: template williamr@4: class _Floating_limits : public _Numeric_limits_base<__number> { williamr@4: public: williamr@4: williamr@4: #if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: enum { williamr@4: #else williamr@4: static const int williamr@4: #endif williamr@4: williamr@4: digits = __Digits, williamr@4: digits10 = __Digits10, williamr@4: williamr@4: radix = ( FLT_RADIX /* 2 */ ), williamr@4: min_exponent = __MinExp, williamr@4: max_exponent = __MaxExp, williamr@4: min_exponent10 = __MinExp10, williamr@4: max_exponent10 = __MaxExp10 williamr@4: williamr@4: #if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: , williamr@4: has_denorm = denorm_indeterminate, williamr@4: round_style = __RoundStyle, williamr@4: #else williamr@4: ; williamr@4: static const float_denorm_style has_denorm = denorm_indeterminate; williamr@4: static const float_round_style round_style = __RoundStyle; williamr@4: static const bool williamr@4: #endif williamr@4: williamr@4: is_specialized = true, williamr@4: is_signed = true, williamr@4: williamr@4: //IEC 559 specify the floating point representation of williamr@4: //infinity, quiet and signaling Not a Number. Not supporting williamr@4: //it is consider as not being able to grant those values. williamr@4: #if (defined (_STLP_MSVC) && (_STLP_MSVC < 1300)) williamr@4: //MSVC 6 do not fully support IEC 599 but grant a good infinity value. williamr@4: has_infinity = true, williamr@4: #else williamr@4: has_infinity = __IsIEC559, williamr@4: #endif williamr@4: has_quiet_NaN = __IsIEC559, williamr@4: has_signaling_NaN = __IsIEC559, williamr@4: williamr@4: has_denorm_loss = false, williamr@4: is_iec559 = __IsIEC559, williamr@4: is_bounded = true, williamr@4: traps = true, williamr@4: tinyness_before= false williamr@4: williamr@4: #if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: } williamr@4: #endif williamr@4: ; williamr@4: }; williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: // Class numeric_limits williamr@4: williamr@4: // The unspecialized class. williamr@4: williamr@4: template williamr@4: class numeric_limits : public _STLP_PRIV _Numeric_limits_base<_Tp> {}; williamr@4: williamr@4: // Specializations for all built-in integral types. williamr@4: williamr@4: #if !defined (_STLP_NO_BOOL) williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: #endif /* _STLP_NO_BOOL */ williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: #if !defined (_STLP_NO_SIGNED_BUILTINS) williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: #endif williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: #if !(defined (_STLP_NO_WCHAR_T) || defined (_STLP_WCHAR_T_IS_USHORT)) williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: #endif williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: #if defined (__xlC__) && (__xlC__ == 0x500) williamr@4: # undef INT_MIN williamr@4: # define INT_MIN -2147483648 williamr@4: #endif williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: williamr@4: #if defined (_STLP_LONG_LONG) williamr@4: williamr@4: # if defined (_STLP_MSVC) || defined (__BORLANDC__) williamr@4: # define LONGLONG_MAX 0x7fffffffffffffffi64 williamr@4: # define LONGLONG_MIN (-LONGLONG_MAX-1i64) williamr@4: # define ULONGLONG_MAX 0xffffffffffffffffUi64 williamr@4: # else williamr@4: # ifndef LONGLONG_MAX williamr@4: # define LONGLONG_MAX 0x7fffffffffffffffLL williamr@4: # endif williamr@4: # ifndef LONGLONG_MIN williamr@4: # define LONGLONG_MIN (-LONGLONG_MAX-1LL) williamr@4: # endif williamr@4: # ifndef ULONGLONG_MAX williamr@4: # define ULONGLONG_MAX 0xffffffffffffffffULL williamr@4: # endif williamr@4: # endif williamr@4: williamr@4: # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ <= 96) williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits<_STLP_LONG_LONG> williamr@4: : public _STLP_PRIV _Integer_limits<_STLP_LONG_LONG, LONGLONG_MIN, LONGLONG_MAX, -1, true> williamr@4: {}; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Integer_limits williamr@4: {}; williamr@4: # else /* gcc 2.97 (after 2000-11-01), 2.98, 3.0 */ williamr@4: /* williamr@4: newest gcc has new mangling scheme, that has problem williamr@4: with generating name [instantiated] of template specialization like williamr@4: _Integer_limits<_STLP_LONG_LONG, LONGLONG_MIN, LONGLONG_MAX, -1, true> williamr@4: ~~~~~~~~~~~~ ~~~~~~~~~~~~ williamr@4: Below is code that solve this problem. williamr@4: - ptr williamr@4: */ williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits<_STLP_LONG_LONG> williamr@4: : public _STLP_PRIV _Numeric_limits_base<_STLP_LONG_LONG> { williamr@4: public: williamr@4: williamr@4: static _STLP_LONG_LONG (_STLP_CALL min) () _STLP_NOTHROW { return LONGLONG_MIN; } williamr@4: static _STLP_LONG_LONG (_STLP_CALL max) () _STLP_NOTHROW { return LONGLONG_MAX; } williamr@4: williamr@4: # if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: enum { williamr@4: # else williamr@4: static const int williamr@4: # endif williamr@4: digits = ((int)((sizeof(_STLP_LONG_LONG) * (CHAR_BIT))) - 1), williamr@4: digits10 = (digits * 301UL) / 1000, williamr@4: radix = 2 williamr@4: # if ! defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: ; williamr@4: static const bool williamr@4: # else williamr@4: , williamr@4: # endif williamr@4: is_specialized = true, williamr@4: is_signed = true, williamr@4: is_integer = true, williamr@4: is_exact = true, williamr@4: is_bounded = true, williamr@4: is_modulo = true williamr@4: # if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: } williamr@4: # endif williamr@4: ; williamr@4: }; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Numeric_limits_base { williamr@4: public: williamr@4: williamr@4: static unsigned _STLP_LONG_LONG (_STLP_CALL min) () _STLP_NOTHROW { return 0ULL; } williamr@4: static unsigned _STLP_LONG_LONG (_STLP_CALL max) () _STLP_NOTHROW { return ULONGLONG_MAX; } williamr@4: williamr@4: # if defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: enum { williamr@4: # else williamr@4: static const int williamr@4: # endif williamr@4: digits = ((int)((sizeof(unsigned _STLP_LONG_LONG) * (CHAR_BIT)))), williamr@4: digits10 = (digits * 301UL) / 1000, williamr@4: radix = 2 williamr@4: # if ! defined (_STLP_STATIC_CONST_INIT_BUG) williamr@4: ; williamr@4: static const bool williamr@4: # else williamr@4: , williamr@4: # endif williamr@4: is_specialized = true, williamr@4: is_signed = false, williamr@4: is_integer = true, williamr@4: is_exact = true, williamr@4: is_bounded = true, williamr@4: is_modulo = true williamr@4: # if defined ( _STLP_STATIC_CONST_INIT_BUG) williamr@4: } williamr@4: # endif williamr@4: ; williamr@4: }; williamr@4: williamr@4: # endif /* __GNUC__ > 2000-11-01 */ williamr@4: williamr@4: #endif /* _STLP_LONG_LONG */ williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: // Specializations for all built-in floating-point types. williamr@4: template williamr@4: class _LimG { williamr@4: public: williamr@4: static float _STLP_CALL get_F_inf(); williamr@4: static float _STLP_CALL get_F_qNaN(); williamr@4: static float _STLP_CALL get_F_sNaN(); williamr@4: static double _STLP_CALL get_D_inf(); williamr@4: static double _STLP_CALL get_D_qNaN(); williamr@4: static double _STLP_CALL get_D_sNaN(); williamr@4: williamr@4: #if !defined (_STLP_NO_LONG_DOUBLE) williamr@4: static long double _STLP_CALL get_LD_inf(); williamr@4: static long double _STLP_CALL get_LD_qNaN(); williamr@4: static long double _STLP_CALL get_LD_sNaN(); williamr@4: #endif williamr@4: }; williamr@4: williamr@4: #if defined (_STLP_USE_TEMPLATE_EXPORT) williamr@4: _STLP_EXPORT_TEMPLATE_CLASS _LimG; williamr@4: #endif williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Floating_limits { williamr@4: public: williamr@4: static float (_STLP_CALL min) () _STLP_NOTHROW { return FLT_MIN; } williamr@4: static float _STLP_CALL denorm_min() _STLP_NOTHROW { return FLT_MIN; } williamr@4: static float (_STLP_CALL max) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return FLT_MAX; } williamr@4: static float _STLP_CALL epsilon() _STLP_NOTHROW { return FLT_EPSILON; } williamr@4: static float _STLP_CALL round_error() _STLP_NOTHROW { return 0.5f; } // Units: ulps. williamr@4: static float _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_F_inf(); } williamr@4: static float _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_F_qNaN(); } williamr@4: static float _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_F_sNaN(); } williamr@4: }; williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Floating_limits { williamr@4: public: williamr@4: static double (_STLP_CALL min)() _STLP_NOTHROW { return DBL_MIN; } williamr@4: static double _STLP_CALL denorm_min() _STLP_NOTHROW { return DBL_MIN; } williamr@4: static double (_STLP_CALL max)() _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return DBL_MAX; } williamr@4: static double _STLP_CALL epsilon() _STLP_NOTHROW { return DBL_EPSILON; } williamr@4: static double _STLP_CALL round_error() _STLP_NOTHROW { return 0.5; } // Units: ulps. williamr@4: static double _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_D_inf(); } williamr@4: static double _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_D_qNaN(); } williamr@4: static double _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_D_sNaN(); } williamr@4: }; williamr@4: williamr@4: #if !defined (_STLP_NO_LONG_DOUBLE) williamr@4: williamr@4: _STLP_TEMPLATE_NULL williamr@4: class numeric_limits williamr@4: : public _STLP_PRIV _Floating_limits { williamr@4: public: williamr@4: static long double (_STLP_CALL min) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MIN; } williamr@4: static long double _STLP_CALL denorm_min() _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MIN; } williamr@4: static long double (_STLP_CALL max) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MAX; } williamr@4: static long double _STLP_CALL epsilon() _STLP_NOTHROW { return LDBL_EPSILON; } williamr@4: static long double _STLP_CALL round_error() _STLP_NOTHROW { return 4; } // Units: ulps. williamr@4: static long double _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_LD_inf(); } williamr@4: static long double _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_LD_qNaN(); } williamr@4: static long double _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG::get_LD_sNaN(); } williamr@4: }; williamr@4: williamr@4: #endif williamr@4: williamr@4: // We write special values (Inf and NaN) as bit patterns and williamr@4: // cast the the appropriate floating-point types. williamr@4: _STLP_END_NAMESPACE williamr@4: williamr@4: #if !defined (_STLP_LINK_TIME_INSTANTIATION) williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #endif williamr@4: williamr@4: // Local Variables: williamr@4: // mode:C++ williamr@4: // End: