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