3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
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.
19 /* NOTE: This may be not portable code. Parts of numeric_limits<> are
20 * inherently machine-dependent. At present this file is suitable
21 * for the MIPS, SPARC, Alpha and ia32 architectures.
24 #ifndef _STLP_INTERNAL_LIMITS
25 #define _STLP_INTERNAL_LIMITS
35 #if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_INTERNAL_CWCHAR)
36 # include <stl/_cwchar.h>
41 enum float_round_style {
42 round_indeterminate = -1,
43 round_toward_zero = 0,
45 round_toward_infinity = 2,
46 round_toward_neg_infinity = 3
49 enum float_denorm_style {
50 denorm_indeterminate = -1,
55 _STLP_MOVE_TO_PRIV_NAMESPACE
57 // Base class for all specializations of numeric_limits.
58 template <class __number>
59 class _Numeric_limits_base {
62 static __number (_STLP_CALL min)() _STLP_NOTHROW { return __number(); }
63 static __number (_STLP_CALL max)() _STLP_NOTHROW { return __number(); }
65 #if defined ( _STLP_STATIC_CONST_INIT_BUG)
79 #if defined ( _STLP_STATIC_CONST_INIT_BUG)
81 has_denorm = denorm_absent,
82 round_style = round_toward_zero,
85 static const float_denorm_style has_denorm = denorm_absent;
86 static const float_round_style round_style = round_toward_zero;
90 is_specialized = false,
95 has_quiet_NaN = false,
96 has_signaling_NaN = false,
97 has_denorm_loss = false,
102 tinyness_before = false
103 #if defined ( _STLP_STATIC_CONST_INIT_BUG)
108 static __number _STLP_CALL epsilon() _STLP_NOTHROW { return __number(); }
109 static __number _STLP_CALL round_error() _STLP_NOTHROW { return __number(); }
111 static __number _STLP_CALL infinity() _STLP_NOTHROW { return __number(); }
112 static __number _STLP_CALL quiet_NaN() _STLP_NOTHROW { return __number(); }
113 static __number _STLP_CALL signaling_NaN() _STLP_NOTHROW { return __number(); }
114 static __number _STLP_CALL denorm_min() _STLP_NOTHROW { return __number(); }
117 // Base class for integers.
119 #ifdef _STLP_LIMITED_DEFAULT_TEMPLATES
120 # ifdef _STLP_LONG_LONG
121 # define _STLP_LIMITS_MIN_TYPE _STLP_LONG_LONG
122 # define _STLP_LIMITS_MAX_TYPE unsigned _STLP_LONG_LONG
124 # define _STLP_LIMITS_MIN_TYPE long
125 # define _STLP_LIMITS_MAX_TYPE unsigned long
128 # define _STLP_LIMITS_MIN_TYPE _Int
129 # define _STLP_LIMITS_MAX_TYPE _Int
130 #endif /* _STLP_LIMITED_DEFAULT_TEMPLATES */
132 template <class _Int,
133 _STLP_LIMITS_MIN_TYPE __imin,
134 _STLP_LIMITS_MAX_TYPE __imax,
135 int __idigits, bool __ismod>
136 class _Integer_limits : public _Numeric_limits_base<_Int> {
139 static _Int (_STLP_CALL min) () _STLP_NOTHROW { return (_Int)__imin; }
140 static _Int (_STLP_CALL max) () _STLP_NOTHROW { return (_Int)__imax; }
142 #if defined (_STLP_STATIC_CONST_INIT_BUG)
147 digits = (__idigits < 0) ?
148 ((int)((sizeof(_Int) * (CHAR_BIT))) - ((__imin == 0) ? 0 : 1))
150 digits10 = (digits * 301UL) / 1000,
152 #if !defined (_STLP_STATIC_CONST_INIT_BUG)
158 is_specialized = true,
159 is_signed = (__imin != 0),
164 #if defined ( _STLP_STATIC_CONST_INIT_BUG)
170 // Base class for floating-point numbers.
171 template <class __number,
172 int __Digits, int __Digits10,
173 int __MinExp, int __MaxExp,
174 int __MinExp10, int __MaxExp10,
176 float_round_style __RoundStyle>
177 class _Floating_limits : public _Numeric_limits_base<__number> {
180 #if defined (_STLP_STATIC_CONST_INIT_BUG)
187 digits10 = __Digits10,
189 radix = ( FLT_RADIX /* 2 */ ),
190 min_exponent = __MinExp,
191 max_exponent = __MaxExp,
192 min_exponent10 = __MinExp10,
193 max_exponent10 = __MaxExp10
195 #if defined (_STLP_STATIC_CONST_INIT_BUG)
197 has_denorm = denorm_indeterminate,
198 round_style = __RoundStyle,
201 static const float_denorm_style has_denorm = denorm_indeterminate;
202 static const float_round_style round_style = __RoundStyle;
206 is_specialized = true,
209 //IEC 559 specify the floating point representation of
210 //infinity, quiet and signaling Not a Number. Not supporting
211 //it is consider as not being able to grant those values.
212 #if (defined (_STLP_MSVC) && (_STLP_MSVC < 1300))
213 //MSVC 6 do not fully support IEC 599 but grant a good infinity value.
216 has_infinity = __IsIEC559,
218 has_quiet_NaN = __IsIEC559,
219 has_signaling_NaN = __IsIEC559,
221 has_denorm_loss = false,
222 is_iec559 = __IsIEC559,
225 tinyness_before= false
227 #if defined (_STLP_STATIC_CONST_INIT_BUG)
233 _STLP_MOVE_TO_STD_NAMESPACE
235 // Class numeric_limits
237 // The unspecialized class.
240 class numeric_limits : public _STLP_PRIV _Numeric_limits_base<_Tp> {};
242 // Specializations for all built-in integral types.
244 #if !defined (_STLP_NO_BOOL)
246 class numeric_limits<bool>
247 : public _STLP_PRIV _Integer_limits<bool, false, true, 1, false>
249 #endif /* _STLP_NO_BOOL */
252 class numeric_limits<char>
253 : public _STLP_PRIV _Integer_limits<char, CHAR_MIN, CHAR_MAX, -1, true>
256 #if !defined (_STLP_NO_SIGNED_BUILTINS)
258 class numeric_limits<signed char>
259 : public _STLP_PRIV _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX, -1, true>
264 class numeric_limits<unsigned char>
265 : public _STLP_PRIV _Integer_limits<unsigned char, 0, UCHAR_MAX, -1, true>
268 #if !(defined (_STLP_NO_WCHAR_T) || defined (_STLP_WCHAR_T_IS_USHORT))
271 class numeric_limits<wchar_t>
272 : public _STLP_PRIV _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX, -1, true>
278 class numeric_limits<short>
279 : public _STLP_PRIV _Integer_limits<short, SHRT_MIN, SHRT_MAX, -1, true>
283 class numeric_limits<unsigned short>
284 : public _STLP_PRIV _Integer_limits<unsigned short, 0, USHRT_MAX, -1, true>
287 #if defined (__xlC__) && (__xlC__ == 0x500)
289 # define INT_MIN -2147483648
293 class numeric_limits<int>
294 : public _STLP_PRIV _Integer_limits<int, INT_MIN, INT_MAX, -1, true>
298 class numeric_limits<unsigned int>
299 : public _STLP_PRIV _Integer_limits<unsigned int, 0, UINT_MAX, -1, true>
303 class numeric_limits<long>
304 : public _STLP_PRIV _Integer_limits<long, LONG_MIN, LONG_MAX, -1, true>
308 class numeric_limits<unsigned long>
309 : public _STLP_PRIV _Integer_limits<unsigned long, 0, ULONG_MAX, -1, true>
312 #if defined (_STLP_LONG_LONG)
314 # if defined (_STLP_MSVC) || defined (__BORLANDC__)
315 # define LONGLONG_MAX 0x7fffffffffffffffi64
316 # define LONGLONG_MIN (-LONGLONG_MAX-1i64)
317 # define ULONGLONG_MAX 0xffffffffffffffffUi64
319 # ifndef LONGLONG_MAX
320 # define LONGLONG_MAX 0x7fffffffffffffffLL
322 # ifndef LONGLONG_MIN
323 # define LONGLONG_MIN (-LONGLONG_MAX-1LL)
325 # ifndef ULONGLONG_MAX
326 # define ULONGLONG_MAX 0xffffffffffffffffULL
330 # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ <= 96)
333 class numeric_limits<_STLP_LONG_LONG>
334 : public _STLP_PRIV _Integer_limits<_STLP_LONG_LONG, LONGLONG_MIN, LONGLONG_MAX, -1, true>
338 class numeric_limits<unsigned _STLP_LONG_LONG>
339 : public _STLP_PRIV _Integer_limits<unsigned _STLP_LONG_LONG, 0, ULONGLONG_MAX, -1, true>
341 # else /* gcc 2.97 (after 2000-11-01), 2.98, 3.0 */
343 newest gcc has new mangling scheme, that has problem
344 with generating name [instantiated] of template specialization like
345 _Integer_limits<_STLP_LONG_LONG, LONGLONG_MIN, LONGLONG_MAX, -1, true>
346 ~~~~~~~~~~~~ ~~~~~~~~~~~~
347 Below is code that solve this problem.
351 class numeric_limits<_STLP_LONG_LONG>
352 : public _STLP_PRIV _Numeric_limits_base<_STLP_LONG_LONG> {
355 static _STLP_LONG_LONG (_STLP_CALL min) () _STLP_NOTHROW { return LONGLONG_MIN; }
356 static _STLP_LONG_LONG (_STLP_CALL max) () _STLP_NOTHROW { return LONGLONG_MAX; }
358 # if defined ( _STLP_STATIC_CONST_INIT_BUG)
363 digits = ((int)((sizeof(_STLP_LONG_LONG) * (CHAR_BIT))) - 1),
364 digits10 = (digits * 301UL) / 1000,
366 # if ! defined (_STLP_STATIC_CONST_INIT_BUG)
372 is_specialized = true,
378 # if defined (_STLP_STATIC_CONST_INIT_BUG)
385 class numeric_limits<unsigned _STLP_LONG_LONG>
386 : public _STLP_PRIV _Numeric_limits_base<unsigned _STLP_LONG_LONG> {
389 static unsigned _STLP_LONG_LONG (_STLP_CALL min) () _STLP_NOTHROW { return 0ULL; }
390 static unsigned _STLP_LONG_LONG (_STLP_CALL max) () _STLP_NOTHROW { return ULONGLONG_MAX; }
392 # if defined (_STLP_STATIC_CONST_INIT_BUG)
397 digits = ((int)((sizeof(unsigned _STLP_LONG_LONG) * (CHAR_BIT)))),
398 digits10 = (digits * 301UL) / 1000,
400 # if ! defined (_STLP_STATIC_CONST_INIT_BUG)
406 is_specialized = true,
412 # if defined ( _STLP_STATIC_CONST_INIT_BUG)
418 # endif /* __GNUC__ > 2000-11-01 */
420 #endif /* _STLP_LONG_LONG */
422 _STLP_MOVE_TO_PRIV_NAMESPACE
424 // Specializations for all built-in floating-point types.
425 template <class __dummy>
428 static float _STLP_CALL get_F_inf();
429 static float _STLP_CALL get_F_qNaN();
430 static float _STLP_CALL get_F_sNaN();
431 static double _STLP_CALL get_D_inf();
432 static double _STLP_CALL get_D_qNaN();
433 static double _STLP_CALL get_D_sNaN();
435 #if !defined (_STLP_NO_LONG_DOUBLE)
436 static long double _STLP_CALL get_LD_inf();
437 static long double _STLP_CALL get_LD_qNaN();
438 static long double _STLP_CALL get_LD_sNaN();
442 #if defined (_STLP_USE_TEMPLATE_EXPORT)
443 _STLP_EXPORT_TEMPLATE_CLASS _LimG<bool>;
446 _STLP_MOVE_TO_STD_NAMESPACE
449 class numeric_limits<float>
450 : public _STLP_PRIV _Floating_limits<float,
451 FLT_MANT_DIG, // Binary digits of precision
452 FLT_DIG, // Decimal digits of precision
453 FLT_MIN_EXP, // Minimum exponent
454 FLT_MAX_EXP, // Maximum exponent
455 FLT_MIN_10_EXP, // Minimum base 10 exponent
456 FLT_MAX_10_EXP, // Maximum base 10 exponent
457 #if defined (_STLP_NO_IEC559_SUPPORT)
458 false, // do not conform to iec559
460 true, // conforms to iec559
464 static float (_STLP_CALL min) () _STLP_NOTHROW { return FLT_MIN; }
465 static float _STLP_CALL denorm_min() _STLP_NOTHROW { return FLT_MIN; }
466 static float (_STLP_CALL max) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return FLT_MAX; }
467 static float _STLP_CALL epsilon() _STLP_NOTHROW { return FLT_EPSILON; }
468 static float _STLP_CALL round_error() _STLP_NOTHROW { return 0.5f; } // Units: ulps.
469 static float _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_F_inf(); }
470 static float _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_F_qNaN(); }
471 static float _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_F_sNaN(); }
475 class numeric_limits<double>
476 : public _STLP_PRIV _Floating_limits<double,
477 DBL_MANT_DIG, // Binary digits of precision
478 DBL_DIG, // Decimal digits of precision
479 DBL_MIN_EXP, // Minimum exponent
480 DBL_MAX_EXP, // Maximum exponent
481 DBL_MIN_10_EXP, // Minimum base 10 exponent
482 DBL_MAX_10_EXP, // Maximum base 10 exponent
483 #if defined (_STLP_NO_IEC559_SUPPORT)
484 false, // do not conform to iec559
486 true, // conforms to iec559
490 static double (_STLP_CALL min)() _STLP_NOTHROW { return DBL_MIN; }
491 static double _STLP_CALL denorm_min() _STLP_NOTHROW { return DBL_MIN; }
492 static double (_STLP_CALL max)() _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return DBL_MAX; }
493 static double _STLP_CALL epsilon() _STLP_NOTHROW { return DBL_EPSILON; }
494 static double _STLP_CALL round_error() _STLP_NOTHROW { return 0.5; } // Units: ulps.
495 static double _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_D_inf(); }
496 static double _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_D_qNaN(); }
497 static double _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_D_sNaN(); }
500 #if !defined (_STLP_NO_LONG_DOUBLE)
503 class numeric_limits<long double>
504 : public _STLP_PRIV _Floating_limits<long double,
505 LDBL_MANT_DIG, // Binary digits of precision
506 LDBL_DIG, // Decimal digits of precision
507 LDBL_MIN_EXP, // Minimum exponent
508 LDBL_MAX_EXP, // Maximum exponent
509 LDBL_MIN_10_EXP,// Minimum base 10 exponent
510 LDBL_MAX_10_EXP,// Maximum base 10 exponent
511 false, // do not conform to iec559
514 static long double (_STLP_CALL min) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MIN; }
515 static long double _STLP_CALL denorm_min() _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MIN; }
516 static long double (_STLP_CALL max) () _STLP_NOTHROW { _STLP_USING_VENDOR_CSTD return LDBL_MAX; }
517 static long double _STLP_CALL epsilon() _STLP_NOTHROW { return LDBL_EPSILON; }
518 static long double _STLP_CALL round_error() _STLP_NOTHROW { return 4; } // Units: ulps.
519 static long double _STLP_CALL infinity() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_LD_inf(); }
520 static long double _STLP_CALL quiet_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_LD_qNaN(); }
521 static long double _STLP_CALL signaling_NaN() _STLP_NOTHROW { return _STLP_PRIV _LimG<bool>::get_LD_sNaN(); }
526 // We write special values (Inf and NaN) as bit patterns and
527 // cast the the appropriate floating-point types.
530 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
531 # include <stl/_limits.c>