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,
62 _STLP_MOVE_TO_PRIV_NAMESPACE
64 // Base class for all specializations of numeric_limits.
65 template <class __number
>
66 class _Numeric_limits_base
{
69 static __number _STLP_CALL
min() _STLP_NOTHROW
{ return __number(); }
70 static __number _STLP_CALL
max() _STLP_NOTHROW
{ return __number(); }
72 _STLP_STATIC_CONSTANT(int, digits
= 0);
73 _STLP_STATIC_CONSTANT(int, digits10
= 0);
74 _STLP_STATIC_CONSTANT(int, radix
= 0);
75 _STLP_STATIC_CONSTANT(int, min_exponent
= 0);
76 _STLP_STATIC_CONSTANT(int, min_exponent10
= 0);
77 _STLP_STATIC_CONSTANT(int, max_exponent
= 0);
78 _STLP_STATIC_CONSTANT(int, max_exponent10
= 0);
80 _STLP_STATIC_CONSTANT(float_denorm_style
, has_denorm
= denorm_absent
);
81 _STLP_STATIC_CONSTANT(float_round_style
, round_style
= round_toward_zero
);
83 _STLP_STATIC_CONSTANT(bool, is_specialized
= false);
84 _STLP_STATIC_CONSTANT(bool, is_signed
= false);
85 _STLP_STATIC_CONSTANT(bool, is_integer
= false);
86 _STLP_STATIC_CONSTANT(bool, is_exact
= false);
87 _STLP_STATIC_CONSTANT(bool, has_infinity
= false);
88 _STLP_STATIC_CONSTANT(bool, has_quiet_NaN
= false);
89 _STLP_STATIC_CONSTANT(bool, has_signaling_NaN
= false);
90 _STLP_STATIC_CONSTANT(bool, has_denorm_loss
= false);
91 _STLP_STATIC_CONSTANT(bool, is_iec559
= false);
92 _STLP_STATIC_CONSTANT(bool, is_bounded
= false);
93 _STLP_STATIC_CONSTANT(bool, is_modulo
= false);
94 _STLP_STATIC_CONSTANT(bool, traps
= false);
95 _STLP_STATIC_CONSTANT(bool, tinyness_before
= false);
97 static __number _STLP_CALL
epsilon() _STLP_NOTHROW
{ return __number(); }
98 static __number _STLP_CALL
round_error() _STLP_NOTHROW
{ return __number(); }
100 static __number _STLP_CALL
infinity() _STLP_NOTHROW
{ return __number(); }
101 static __number _STLP_CALL
quiet_NaN() _STLP_NOTHROW
{ return __number(); }
102 static __number _STLP_CALL
signaling_NaN() _STLP_NOTHROW
{ return __number(); }
103 static __number _STLP_CALL
denorm_min() _STLP_NOTHROW
{ return __number(); }
106 // Base class for integers.
108 #ifdef _STLP_LIMITED_DEFAULT_TEMPLATES
109 # ifdef _STLP_LONG_LONG
110 # define _STLP_LIMITS_MIN_TYPE _STLP_LONG_LONG
111 # define _STLP_LIMITS_MAX_TYPE unsigned _STLP_LONG_LONG
113 # define _STLP_LIMITS_MIN_TYPE long
114 # define _STLP_LIMITS_MAX_TYPE unsigned long
117 # define _STLP_LIMITS_MIN_TYPE _Int
118 # define _STLP_LIMITS_MAX_TYPE _Int
119 #endif /* _STLP_LIMITED_DEFAULT_TEMPLATES */
121 template <class _Int
,
122 _STLP_LIMITS_MIN_TYPE __imin
,
123 _STLP_LIMITS_MAX_TYPE __imax
,
124 int __idigits
, bool __ismod
>
125 class _Integer_limits
: public _Numeric_limits_base
<_Int
> {
128 static _Int _STLP_CALL
min () _STLP_NOTHROW
{ return (_Int
)__imin
; }
129 static _Int _STLP_CALL
max () _STLP_NOTHROW
{ return (_Int
)__imax
; }
131 _STLP_STATIC_CONSTANT(int, digits
= (__idigits
< 0) ? ((int)((sizeof(_Int
) * (CHAR_BIT
))) - ((__imin
== 0) ? 0 : 1)) : (__idigits
));
132 _STLP_STATIC_CONSTANT(int, digits10
= (digits
* 301UL) / 1000);
133 _STLP_STATIC_CONSTANT(int, radix
= 2);
134 _STLP_STATIC_CONSTANT(bool, is_specialized
= true);
135 _STLP_STATIC_CONSTANT(bool, is_signed
= (__imin
!= 0));
136 _STLP_STATIC_CONSTANT(bool, is_integer
= true);
137 _STLP_STATIC_CONSTANT(bool, is_exact
= true);
138 _STLP_STATIC_CONSTANT(bool, is_bounded
= true);
139 _STLP_STATIC_CONSTANT(bool, is_modulo
= __ismod
);
142 // Base class for floating-point numbers.
143 template <class __number
,
144 int __Digits
, int __Digits10
,
145 int __MinExp
, int __MaxExp
,
146 int __MinExp10
, int __MaxExp10
,
148 float_denorm_style __DenormStyle
,
149 float_round_style __RoundStyle
>
150 class _Floating_limits
: public _Numeric_limits_base
<__number
> {
153 _STLP_STATIC_CONSTANT(int, digits
= __Digits
);
154 _STLP_STATIC_CONSTANT(int, digits10
= __Digits10
);
155 _STLP_STATIC_CONSTANT(int, radix
= FLT_RADIX
);
156 _STLP_STATIC_CONSTANT(int, min_exponent
= __MinExp
);
157 _STLP_STATIC_CONSTANT(int, max_exponent
= __MaxExp
);
158 _STLP_STATIC_CONSTANT(int, min_exponent10
= __MinExp10
);
159 _STLP_STATIC_CONSTANT(int, max_exponent10
= __MaxExp10
);
161 _STLP_STATIC_CONSTANT(float_denorm_style
, has_denorm
= __DenormStyle
);
162 _STLP_STATIC_CONSTANT(float_round_style
, round_style
= __RoundStyle
);
164 _STLP_STATIC_CONSTANT(bool, is_specialized
= true);
165 _STLP_STATIC_CONSTANT(bool, is_signed
= true);
167 _STLP_STATIC_CONSTANT(bool, has_infinity
= true);
168 #if (!defined (_STLP_MSVC) || (_STLP_MSVC > 1300)) && \
169 (!defined (__BORLANDC__) || (__BORLANDC__ >= 0x590)) && \
170 (!defined (_CRAY) || defined (_CRAYIEEE))
171 _STLP_STATIC_CONSTANT(bool, has_quiet_NaN
= true);
172 _STLP_STATIC_CONSTANT(bool, has_signaling_NaN
= true);
174 _STLP_STATIC_CONSTANT(bool, has_quiet_NaN
= false);
175 _STLP_STATIC_CONSTANT(bool, has_signaling_NaN
= false);
178 _STLP_STATIC_CONSTANT(bool, is_iec559
= __IsIEC559
&& has_infinity
&& has_quiet_NaN
&& has_signaling_NaN
&& (has_denorm
== denorm_present
));
179 _STLP_STATIC_CONSTANT(bool, has_denorm_loss
= false);
180 _STLP_STATIC_CONSTANT(bool, is_bounded
= true);
181 _STLP_STATIC_CONSTANT(bool, traps
= true);
182 _STLP_STATIC_CONSTANT(bool, tinyness_before
= false);
185 _STLP_MOVE_TO_STD_NAMESPACE
187 // Class numeric_limits
189 // The unspecialized class.
192 class numeric_limits
: public _STLP_PRIV _Numeric_limits_base
<_Tp
> {};
194 // Specializations for all built-in integral types.
196 #if !defined (_STLP_NO_BOOL)
198 class numeric_limits
<bool>
199 : public _STLP_PRIV _Integer_limits
<bool, false, true, 1, false>
201 #endif /* _STLP_NO_BOOL */
204 class numeric_limits
<char>
205 : public _STLP_PRIV _Integer_limits
<char, CHAR_MIN
, CHAR_MAX
, -1, true>
208 #if !defined (_STLP_NO_SIGNED_BUILTINS)
210 class numeric_limits
<signed char>
211 : public _STLP_PRIV _Integer_limits
<signed char, SCHAR_MIN
, SCHAR_MAX
, -1, true>
216 class numeric_limits
<unsigned char>
217 : public _STLP_PRIV _Integer_limits
<unsigned char, 0, UCHAR_MAX
, -1, true>
220 #if !(defined (_STLP_NO_WCHAR_T) || defined (_STLP_WCHAR_T_IS_USHORT))
223 class numeric_limits
<wchar_t>
224 : public _STLP_PRIV _Integer_limits
<wchar_t, WCHAR_MIN
, WCHAR_MAX
, -1, true>
230 class numeric_limits
<short>
231 : public _STLP_PRIV _Integer_limits
<short, SHRT_MIN
, SHRT_MAX
, -1, true>
235 class numeric_limits
<unsigned short>
236 : public _STLP_PRIV _Integer_limits
<unsigned short, 0, USHRT_MAX
, -1, true>
239 #if defined (__xlC__) && (__xlC__ == 0x500)
241 # define INT_MIN -2147483648
245 class numeric_limits
<int>
246 : public _STLP_PRIV _Integer_limits
<int, INT_MIN
, INT_MAX
, -1, true>
250 class numeric_limits
<unsigned int>
251 : public _STLP_PRIV _Integer_limits
<unsigned int, 0, UINT_MAX
, -1, true>
255 class numeric_limits
<long>
256 : public _STLP_PRIV _Integer_limits
<long, LONG_MIN
, LONG_MAX
, -1, true>
260 class numeric_limits
<unsigned long>
261 : public _STLP_PRIV _Integer_limits
<unsigned long, 0, ULONG_MAX
, -1, true>
264 #if defined (_STLP_LONG_LONG)
266 # if defined (_STLP_MSVC) || defined (__BORLANDC__)
267 # define LONGLONG_MAX 0x7fffffffffffffffi64
268 # define LONGLONG_MIN (-LONGLONG_MAX-1i64)
269 # define ULONGLONG_MAX 0xffffffffffffffffUi64
271 # ifndef LONGLONG_MAX
272 # define LONGLONG_MAX 0x7fffffffffffffffLL
274 # ifndef LONGLONG_MIN
275 # define LONGLONG_MIN (-LONGLONG_MAX-1LL)
277 # ifndef ULONGLONG_MAX
278 # define ULONGLONG_MAX 0xffffffffffffffffULL
282 # if !defined (__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ <= 96) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 3)
285 class numeric_limits
<_STLP_LONG_LONG
>
286 : public _STLP_PRIV _Integer_limits
<_STLP_LONG_LONG
, LONGLONG_MIN
, LONGLONG_MAX
, -1, true>
290 class numeric_limits
<unsigned _STLP_LONG_LONG
>
291 : public _STLP_PRIV _Integer_limits
<unsigned _STLP_LONG_LONG
, 0, ULONGLONG_MAX
, -1, true>
293 # else /* gcc 2.97 (after 2000-11-01), 2.98, 3.0 */
295 newest gcc has new mangling scheme, that has problem
296 with generating name [instantiated] of template specialization like
297 _Integer_limits<_STLP_LONG_LONG, LONGLONG_MIN, LONGLONG_MAX, -1, true>
298 ~~~~~~~~~~~~ ~~~~~~~~~~~~
299 Below is code that solve this problem.
303 class numeric_limits
<_STLP_LONG_LONG
>
304 : public _STLP_PRIV _Numeric_limits_base
<_STLP_LONG_LONG
> {
307 static _STLP_LONG_LONG (_STLP_CALL min
) () _STLP_NOTHROW
{ return LONGLONG_MIN
; }
308 static _STLP_LONG_LONG (_STLP_CALL max
) () _STLP_NOTHROW
{ return LONGLONG_MAX
; }
310 _STLP_STATIC_CONSTANT(int, digits
= ((int)((sizeof(_STLP_LONG_LONG
) * (CHAR_BIT
))) - 1));
311 _STLP_STATIC_CONSTANT(int, digits10
= (digits
* 301UL) / 1000);
312 _STLP_STATIC_CONSTANT(int, radix
= 2);
313 _STLP_STATIC_CONSTANT(bool, is_specialized
= true);
314 _STLP_STATIC_CONSTANT(bool, is_signed
= true);
315 _STLP_STATIC_CONSTANT(bool, is_integer
= true);
316 _STLP_STATIC_CONSTANT(bool, is_exact
= true);
317 _STLP_STATIC_CONSTANT(bool, is_bounded
= true);
318 _STLP_STATIC_CONSTANT(bool, is_modulo
= true);
322 class numeric_limits
<unsigned _STLP_LONG_LONG
>
323 : public _STLP_PRIV _Numeric_limits_base
<unsigned _STLP_LONG_LONG
> {
326 static unsigned _STLP_LONG_LONG (_STLP_CALL min
) () _STLP_NOTHROW
{ return 0ULL; }
327 static unsigned _STLP_LONG_LONG (_STLP_CALL max
) () _STLP_NOTHROW
{ return ULONGLONG_MAX
; }
329 _STLP_STATIC_CONSTANT(int, digits
= ((int)((sizeof(unsigned _STLP_LONG_LONG
) * (CHAR_BIT
)))));
330 _STLP_STATIC_CONSTANT(int, digits10
= (digits
* 301UL) / 1000);
331 _STLP_STATIC_CONSTANT(int, radix
= 2);
332 _STLP_STATIC_CONSTANT(bool, is_specialized
= true);
333 _STLP_STATIC_CONSTANT(bool, is_signed
= false);
334 _STLP_STATIC_CONSTANT(bool, is_integer
= true);
335 _STLP_STATIC_CONSTANT(bool, is_exact
= true);
336 _STLP_STATIC_CONSTANT(bool, is_bounded
= true);
337 _STLP_STATIC_CONSTANT(bool, is_modulo
= true);
340 # endif /* __GNUC__ > 2000-11-01 */
342 #endif /* _STLP_LONG_LONG */
344 _STLP_MOVE_TO_PRIV_NAMESPACE
346 // Specializations for all built-in floating-point types.
347 template <class __dummy
>
350 static float _STLP_CALL
get_F_inf();
351 static float _STLP_CALL
get_F_qNaN();
352 static float _STLP_CALL
get_F_sNaN();
353 static float _STLP_CALL
get_F_denormMin();
354 static double _STLP_CALL
get_D_inf();
355 static double _STLP_CALL
get_D_qNaN();
356 static double _STLP_CALL
get_D_sNaN();
357 static double _STLP_CALL
get_D_denormMin();
359 #if !defined (_STLP_NO_LONG_DOUBLE)
360 static long double _STLP_CALL
get_LD_inf();
361 static long double _STLP_CALL
get_LD_qNaN();
362 static long double _STLP_CALL
get_LD_sNaN();
363 static long double _STLP_CALL
get_LD_denormMin();
367 #if defined (_STLP_USE_TEMPLATE_EXPORT)
368 _STLP_EXPORT_TEMPLATE_CLASS _LimG
<bool>;
371 #if defined (__GNUC__)
372 # if defined (__FLT_DENORM_MIN__)
373 # define _STLP_FLT_DENORM_MIN __FLT_DENORM_MIN__
375 # define _STLP_FLT_DENORM_STYLE denorm_absent
377 # if defined (__DBL_DENORM_MIN__)
378 # define _STLP_DBL_DENORM_MIN __DBL_DENORM_MIN__
380 # define _STLP_DBL_DENORM_STYLE denorm_absent
382 # if defined (__LDBL_DENORM_MIN__)
383 # define _STLP_LDBL_DENORM_MIN __LDBL_DENORM_MIN__
385 # define _STLP_LDBL_DENORM_STYLE denorm_absent
389 /* If compiler do not expose thanks to some macro its status regarding
390 * denormalized floating point numbers, we consider that denormalization
391 * is present. Unit tests will tell us if compiler do not support them. */
392 #if !defined (_STLP_FLT_DENORM_STYLE)
393 # define _STLP_FLT_DENORM_STYLE denorm_present
396 #if !defined (_STLP_DBL_DENORM_STYLE)
397 # define _STLP_DBL_DENORM_STYLE denorm_present
400 #if !defined (_STLP_LDBL_DENORM_STYLE)
401 # define _STLP_LDBL_DENORM_STYLE denorm_present
404 _STLP_MOVE_TO_STD_NAMESPACE
407 class numeric_limits
<float>
408 : public _STLP_PRIV _Floating_limits
<float,
409 FLT_MANT_DIG
, // Binary digits of precision
410 FLT_DIG
, // Decimal digits of precision
411 FLT_MIN_EXP
, // Minimum exponent
412 FLT_MAX_EXP
, // Maximum exponent
413 FLT_MIN_10_EXP
, // Minimum base 10 exponent
414 FLT_MAX_10_EXP
, // Maximum base 10 exponent
416 _STLP_FLT_DENORM_STYLE
,
419 static float (_STLP_CALL min
) () _STLP_NOTHROW
{ return FLT_MIN
; }
420 static float _STLP_CALL
denorm_min() _STLP_NOTHROW
421 #if defined (_STLP_FLT_DENORM_MIN)
422 { return _STLP_FLT_DENORM_MIN
; }
424 { return _STLP_FLT_DENORM_STYLE
? _STLP_PRIV _LimG
<bool>::get_F_denormMin() : FLT_MIN
; }
426 static float (_STLP_CALL max
) () _STLP_NOTHROW
{ return FLT_MAX
; }
427 static float _STLP_CALL
epsilon() _STLP_NOTHROW
{ return FLT_EPSILON
; }
428 static float _STLP_CALL
round_error() _STLP_NOTHROW
{ return 0.5f
; } // Units: ulps.
429 static float _STLP_CALL
infinity() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_F_inf(); }
430 static float _STLP_CALL
quiet_NaN() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_F_qNaN(); }
431 static float _STLP_CALL
signaling_NaN() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_F_sNaN(); }
434 #undef _STLP_FLT_DENORM_MIN
435 #undef _STLP_FLT_DNORM_STYLE
438 class numeric_limits
<double>
439 : public _STLP_PRIV _Floating_limits
<double,
440 DBL_MANT_DIG
, // Binary digits of precision
441 DBL_DIG
, // Decimal digits of precision
442 DBL_MIN_EXP
, // Minimum exponent
443 DBL_MAX_EXP
, // Maximum exponent
444 DBL_MIN_10_EXP
, // Minimum base 10 exponent
445 DBL_MAX_10_EXP
, // Maximum base 10 exponent
447 _STLP_DBL_DENORM_STYLE
,
450 static double (_STLP_CALL min
)() _STLP_NOTHROW
{ return DBL_MIN
; }
451 static double _STLP_CALL
denorm_min() _STLP_NOTHROW
452 #if defined (_STLP_DBL_DENORM_MIN)
453 { return _STLP_DBL_DENORM_MIN
; }
455 { return _STLP_DBL_DENORM_STYLE
? _STLP_PRIV _LimG
<bool>::get_D_denormMin() : DBL_MIN
; }
457 static double (_STLP_CALL max
)() _STLP_NOTHROW
{ return DBL_MAX
; }
458 static double _STLP_CALL
epsilon() _STLP_NOTHROW
{ return DBL_EPSILON
; }
459 static double _STLP_CALL
round_error() _STLP_NOTHROW
{ return 0.5; } // Units: ulps.
460 static double _STLP_CALL
infinity() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_D_inf(); }
461 static double _STLP_CALL
quiet_NaN() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_D_qNaN(); }
462 static double _STLP_CALL
signaling_NaN() _STLP_NOTHROW
{ return _STLP_PRIV _LimG
<bool>::get_D_sNaN(); }
465 #if !defined (_STLP_NO_LONG_DOUBLE)
468 class numeric_limits
<long double>
469 : public _STLP_PRIV _Floating_limits
<long double,
470 LDBL_MANT_DIG
, // Binary digits of precision
471 LDBL_DIG
, // Decimal digits of precision
472 LDBL_MIN_EXP
, // Minimum exponent
473 LDBL_MAX_EXP
, // Maximum exponent
474 LDBL_MIN_10_EXP
,// Minimum base 10 exponent
475 LDBL_MAX_10_EXP
,// Maximum base 10 exponent
476 false, // do not conform to iec559
477 _STLP_LDBL_DENORM_STYLE
,
480 static long double (_STLP_CALL min
) () _STLP_NOTHROW
{ return LDBL_MIN
; }
481 static long double _STLP_CALL
denorm_min() _STLP_NOTHROW
482 #if defined (_STLP_LDBL_DENORM_MIN)
483 { return _STLP_LDBL_DENORM_MIN
; }
485 { return _STLP_LDBL_DENORM_STYLE
? _STLP_PRIV _LimG
<bool>::get_LD_denormMin() : LDBL_MIN
; }
487 _STLP_STATIC_CONSTANT(bool, is_iec559
= false);
488 static long double (_STLP_CALL max
) () _STLP_NOTHROW
{ return LDBL_MAX
; }
489 static long double _STLP_CALL
epsilon() _STLP_NOTHROW
{ return LDBL_EPSILON
; }
490 static long double _STLP_CALL
round_error() _STLP_NOTHROW
{ return 0.5l; }
491 static long double _STLP_CALL
infinity() _STLP_NOTHROW
492 //For MSVC, long double is nothing more than an alias for double.
493 #if !defined (_STLP_MSVC)
494 { return _STLP_PRIV _LimG
<bool>::get_LD_inf(); }
496 { return _STLP_PRIV _LimG
<bool>::get_D_inf(); }
498 static long double _STLP_CALL
quiet_NaN() _STLP_NOTHROW
499 #if !defined (_STLP_MSVC)
500 { return _STLP_PRIV _LimG
<bool>::get_LD_qNaN(); }
502 { return _STLP_PRIV _LimG
<bool>::get_D_qNaN(); }
504 static long double _STLP_CALL
signaling_NaN() _STLP_NOTHROW
505 #if !defined (_STLP_MSVC)
506 { return _STLP_PRIV _LimG
<bool>::get_LD_sNaN(); }
508 { return _STLP_PRIV _LimG
<bool>::get_D_sNaN(); }
514 // We write special values (Inf and NaN) as bit patterns and
515 // cast the the appropriate floating-point types.
518 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
519 # include <stl/_limits.c>