2 * Copyright (c) 1998,1999
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 #ifndef _STLP_LIMITS_C
20 #define _STLP_LIMITS_C
22 #ifndef _STLP_INTERNAL_LIMITS
23 # include <stl/_limits.h>
26 //==========================================================
27 // numeric_limits static members
28 //==========================================================
32 _STLP_MOVE_TO_PRIV_NAMESPACE
34 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
36 # define __declare_numeric_base_member(__type, __mem) \
37 template <class __number> \
38 const __type _Numeric_limits_base<__number>:: __mem
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
);
63 # undef __declare_numeric_base_member
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
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
80 # if defined (__GNUC__) && (__GNUC__ != 2 || __GNUC_MINOR__ > 96) && (__GNUC__ != 3 || __GNUC_MINOR__ == 0) && (__GNUC__ <= 3)
81 _STLP_MOVE_TO_STD_NAMESPACE
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
94 __declare_numeric_limits_member(_STLP_LONG_LONG
);
95 __declare_numeric_limits_member(unsigned _STLP_LONG_LONG
);
97 # undef __declare_numeric_limits_member
99 _STLP_MOVE_TO_PRIV_NAMESPACE
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, \
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>::\
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
139 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
141 # if defined (__GNUC__) || defined (__BORLANDC__)
142 # define _STLP_ADDITIONAL_OPEN_BRACKET {
143 # define _STLP_ADDITIONAL_CLOSE_BRACKET }
145 # define _STLP_ADDITIONAL_OPEN_BRACKET
146 # define _STLP_ADDITIONAL_CLOSE_BRACKET
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
154 template<class _Number
, unsigned short _Word
>
155 struct float_helper
{
157 unsigned short _Words
[8];
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
};
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
;
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();
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();
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
{
189 unsigned short _Words
[8];
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;
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
;
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();
212 /* Former values kept in case moving to boost code has introduce a regression on
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}
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 }
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 }
272 unsigned short rep
[2];
276 unsigned short rep
[4];
280 # ifndef _STLP_NO_LONG_DOUBLE
282 unsigned short rep
[8];
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();
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();
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();
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();
309 template <int __use_double_limits
>
310 class _NumericLimitsAccess
;
313 class _NumericLimitsAccess
<1> {
315 static double get_inf() {
316 typedef float_helper
<double, 0x7ff0u
> _FloatHelper
;
317 return _FloatHelper::get_from_last_word();
319 static double get_qNaN() {
320 typedef float_helper
<double, 0x7ff1u
> _FloatHelper
;
321 return _FloatHelper::get_from_last_word();
323 static double get_sNaN() {
324 typedef float_helper
<double, 0x7ff9u
> _FloatHelper
;
325 return _FloatHelper::get_from_last_word();
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();
344 # if !defined (_STLP_NO_LONG_DOUBLE)
346 class _NumericLimitsAccess
<0> {
348 static long double get_inf() {
349 # if defined (_STLP_BIG_ENDIAN)
350 typedef float_helper
<long double, 0x7ff0u
> _FloatHelper
;
352 typedef float_helper2
<long double, 0x8000u
, 0x7fffu
> _FloatHelper
;
354 return _FloatHelper::get_from_last_word();
356 static long double get_qNaN() {
357 # if defined (_STLP_BIG_ENDIAN)
358 typedef float_helper
<long double, 0x7ff1u
> _FloatHelper
;
360 typedef float_helper2
<long double, 0xc000u
, 0x7fffu
> _FloatHelper
;
362 return _FloatHelper::get_from_last_word();
364 static long double get_sNaN() {
365 # if defined (_STLP_BIG_ENDIAN)
366 typedef float_helper
<long double, 0x7ff9u
> _FloatHelper
;
368 typedef float_helper2
<long double, 0x9000u
, 0x7fffu
> _FloatHelper
;
370 return _FloatHelper::get_from_last_word();
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();
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();
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();
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();
396 #endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */
398 #undef _STLP_LIMITS_MIN_TYPE
399 #undef _STLP_LIMITS_MAX_TYPE
401 _STLP_MOVE_TO_STD_NAMESPACE
405 #endif /* _STLP_LIMITS_C_INCLUDED */