Scopira  20080306
limits.h
1 
2 /*
3  * Copyright (c) 2002 National Research Council
4  *
5  * All rights reserved.
6  *
7  * This material is confidential and proprietary information of
8  * National Research Council Canada ("Confidential Information").
9  * This Confidential Information may only be used and reproduced
10  * in accordance with the terms of the license agreement.
11  *
12  */
13 
14 #ifndef __INCLUDED_SCOPIRA_TOOL_LIMITS_H__
15 #define __INCLUDED_SCOPIRA_TOOL_LIMITS_H__
16 
17 #if defined(__GNUC__) && (__GNUC__ < 3)
18 
19 //
20 // taken from Boost, because <limits> is missin on gnu c++.
21 //
22 
23 #include <limits.h>
24 #include <float.h>
25 
26 #if defined(__sparc) || defined(__sparc__) || defined(__powerpc__) || defined(__ppc__) || defined(__hppa) || defined(_MIPSEB)
27 #define BOOST_BIG_ENDIAN
28 #elif defined(__i386__)
29 #define BOOST_LITTLE_ENDIAN
30 #else
31 #error The file boost/detail/limits.hpp needs to be set up for your CPU type.
32 #endif
33 
34 namespace std {
35 
36 enum float_round_style {
37  round_indeterminate = -1,
38  round_toward_zero = 0,
39  round_to_nearest = 1,
40  round_toward_infinity = 2,
41  round_toward_neg_infinity = 3
42 };
43 
44 enum float_denorm_style {
45  denorm_indeterminate = -1,
46  denorm_absent = 0,
47  denorm_present = 1
48 };
49 
50 // The C++ standard (section 18.2.1) requires that some of the members of
51 // numeric_limits be static const data members that are given constant-
52 // initializers within the class declaration. On compilers where the
53 // BOOST_NO_INCLASS_MEMBER_INITIALIZATION macro is defined, it is impossible to write
54 // a standard-conforming numeric_limits class.
55 //
56 // There are two possible workarounds: either initialize the data
57 // members outside the class, or change them from data members to
58 // enums. Neither workaround is satisfactory: the former makes it
59 // impossible to use the data members in constant-expressions, and the
60 // latter means they have the wrong type and that it is impossible to
61 // take their addresses. We choose the former workaround.
62 
63 #ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
64 # define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
65  enum { __mem_name = __mem_value }
66 #else /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */
67 # define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
68  static const __mem_type __mem_name = __mem_value
69 #endif /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */
70 
71 // Base class for all specializations of numeric_limits.
72 
73 template <class __number>
74 class _Numeric_limits_base {
75 public:
76  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false);
77 
78  static __number min() throw() { return __number(); }
79  static __number max() throw() { return __number(); }
80 
81  BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0);
82  BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0);
83 
84  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false);
85  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false);
86  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false);
87 
88  BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0);
89 
90  static __number epsilon() throw() { return __number(); }
91  static __number round_error() throw() { return __number(); }
92 
93  BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0);
94  BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0);
95  BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0);
96  BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0);
97 
98  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false);
99  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false);
100  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false);
101  BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
102  has_denorm,
103  denorm_absent);
104  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
105 
106  static __number infinity() throw() { return __number(); }
107  static __number quiet_NaN() throw() { return __number(); }
108  static __number signaling_NaN() throw() { return __number(); }
109  static __number denorm_min() throw() { return __number(); }
110 
111  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false);
112  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false);
113  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false);
114 
115  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false);
116  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
117  BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style,
118  round_style,
119  round_toward_zero);
120 };
121 
122 // Base class for integers.
123 
124 template <class _Int,
125  _Int __imin,
126  _Int __imax,
127  int __idigits = -1>
128 class _Integer_limits : public _Numeric_limits_base<_Int>
129 {
130 public:
131  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
132 
133  static _Int min() throw() { return __imin; }
134  static _Int max() throw() { return __imax; }
135 
136  BOOST_STL_DECLARE_LIMITS_MEMBER(int,
137  digits,
138  (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT)
139  - (__imin == 0 ? 0 : 1)
140  : __idigits);
141  BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000);
142  // log 2 = 0.301029995664...
143 
144  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0);
145  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true);
146  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true);
147  BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
148 
149  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
150  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true);
151 };
152 
153 #if defined(BOOST_BIG_ENDIAN)
154 
155  template<class Number, unsigned int Word>
156  struct float_helper{
157  static Number get_word() throw() {
158  // sizeof(long double) == 16
159  const unsigned int _S_word[4] = { Word, 0, 0, 0 };
160  return *reinterpret_cast<const Number*>(&_S_word);
161  }
162 };
163 
164 #else
165 
166  template<class Number, unsigned int Word>
167  struct float_helper{
168  static Number get_word() throw() {
169  // sizeof(long double) == 12, but only 10 bytes significant
170  const unsigned int _S_word[4] = { 0, 0, 0, Word };
171  return *reinterpret_cast<const Number*>(
172  reinterpret_cast<const char *>(&_S_word)+16-
173  (sizeof(Number) == 12 ? 10 : sizeof(Number)));
174  }
175 };
176 
177 #endif
178 
179 // Base class for floating-point numbers.
180 template <class __number,
181  int __Digits, int __Digits10,
182  int __MinExp, int __MaxExp,
183  int __MinExp10, int __MaxExp10,
184  unsigned int __InfinityWord,
185  unsigned int __QNaNWord, unsigned int __SNaNWord,
186  bool __IsIEC559,
187  float_round_style __RoundStyle>
188 class _Floating_limits : public _Numeric_limits_base<__number>
189 {
190 public:
191  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
192 
193  BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits);
194  BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10);
195 
196  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true);
197 
198  BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
199 
200  BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp);
201  BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp);
202  BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10);
203  BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10);
204 
205  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true);
206  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true);
207  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true);
208  BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
209  has_denorm,
210  denorm_indeterminate);
211  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
212 
213 
214  static __number infinity() throw() {
215  return float_helper<__number, __InfinityWord>::get_word();
216  }
217  static __number quiet_NaN() throw() {
218  return float_helper<__number,__QNaNWord>::get_word();
219  }
220  static __number signaling_NaN() throw() {
221  return float_helper<__number,__SNaNWord>::get_word();
222  }
223 
224  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559);
225  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
226  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false /* was: true */ );
227  BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
228 
229  BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle);
230 };
231 
232 // Class numeric_limits
233 
234 // The unspecialized class.
235 
236 template<class T>
237 class numeric_limits : public _Numeric_limits_base<T> {};
238 
239 // Specializations for all built-in integral types.
240 
241 template<>
242 class numeric_limits<bool>
243  : public _Integer_limits<bool, false, true, 0>
244 {};
245 
246 template<>
247 class numeric_limits<char>
248  : public _Integer_limits<char, CHAR_MIN, CHAR_MAX>
249 {};
250 
251 template<>
252 class numeric_limits<signed char>
253  : public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX>
254 {};
255 
256 template<>
257 class numeric_limits<unsigned char>
258  : public _Integer_limits<unsigned char, 0, UCHAR_MAX>
259 {};
260 
261 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
262 template<>
263 class numeric_limits<wchar_t>
264 #if !defined(WCHAR_MAX) || !defined(WCHAR_MIN)
265 #if defined(_WIN32) || defined(__CYGWIN__)
266  : public _Integer_limits<wchar_t, 0, USHRT_MAX>
267 #elif defined(__hppa)
268 // wchar_t has "unsigned int" as the underlying type
269  : public _Integer_limits<wchar_t, 0, UINT_MAX>
270 #else
271 // assume that wchar_t has "int" as the underlying type
272  : public _Integer_limits<wchar_t, INT_MIN, INT_MAX>
273 #endif
274 #else
275 // we have WCHAR_MIN and WCHAR_MAX defined, so use it
276  : public _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX>
277 #endif
278 {};
279 #endif
280 
281 template<>
282 class numeric_limits<short>
283  : public _Integer_limits<short, SHRT_MIN, SHRT_MAX>
284 {};
285 
286 template<>
287 class numeric_limits<unsigned short>
288  : public _Integer_limits<unsigned short, 0, USHRT_MAX>
289 {};
290 
291 template<>
292 class numeric_limits<int>
293  : public _Integer_limits<int, INT_MIN, INT_MAX>
294 {};
295 
296 template<>
297 class numeric_limits<unsigned int>
298  : public _Integer_limits<unsigned int, 0, UINT_MAX>
299 {};
300 
301 template<>
302 class numeric_limits<long>
303  : public _Integer_limits<long, LONG_MIN, LONG_MAX>
304 {};
305 
306 template<>
307 class numeric_limits<unsigned long>
308  : public _Integer_limits<unsigned long, 0, ULONG_MAX>
309 {};
310 
311 #ifdef __GNUC__
312 
313 // Some compilers have long long, but don't define the
314 // LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This
315 // assumes that long long is 64 bits.
316 #if !defined(LONGLONG_MIN) && !defined(LONGLONG_MAX) \
317  && !defined(ULONGLONG_MAX)
318 
319 #define ULONGLONG_MAX 0xffffffffffffffffLLU
320 #define LONGLONG_MAX 0x7fffffffffffffffLL
321 #define LONGLONG_MIN (-LONGLONG_MAX - 1)
322 
323 #endif
324 
325 template<>
326 class numeric_limits<long long>
327  : public _Integer_limits<long long, LONGLONG_MIN, LONGLONG_MAX>
328 {};
329 
330 template<>
331 class numeric_limits<unsigned long long>
332  : public _Integer_limits<unsigned long long, 0, ULONGLONG_MAX>
333 {};
334 
335 #endif /* __GNUC__ */
336 
337 // Specializations for all built-in floating-point type.
338 
339 template<> class numeric_limits<float>
340  : public _Floating_limits<float,
341  FLT_MANT_DIG, // Binary digits of precision
342  FLT_DIG, // Decimal digits of precision
343  FLT_MIN_EXP, // Minimum exponent
344  FLT_MAX_EXP, // Maximum exponent
345  FLT_MIN_10_EXP, // Minimum base 10 exponent
346  FLT_MAX_10_EXP, // Maximum base 10 exponent
347 #if defined(BOOST_BIG_ENDIAN)
348  0x7f80 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
349  0x7f81 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
350  0x7fc1 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
351 #else
352  0x7f800000u, // Last word of +infinity
353  0x7f810000u, // Last word of quiet NaN
354  0x7fc10000u, // Last word of signaling NaN
355 #endif
356  true, // conforms to iec559
357  round_to_nearest>
358 {
359 public:
360  static float min() throw() { return FLT_MIN; }
361  static float denorm_min() throw() { return FLT_MIN; }
362  static float max() throw() { return FLT_MAX; }
363  static float epsilon() throw() { return FLT_EPSILON; }
364  static float round_error() throw() { return 0.5f; } // Units: ulps.
365 };
366 
367 template<> class numeric_limits<double>
368  : public _Floating_limits<double,
369  DBL_MANT_DIG, // Binary digits of precision
370  DBL_DIG, // Decimal digits of precision
371  DBL_MIN_EXP, // Minimum exponent
372  DBL_MAX_EXP, // Maximum exponent
373  DBL_MIN_10_EXP, // Minimum base 10 exponent
374  DBL_MAX_10_EXP, // Maximum base 10 exponent
375 #if defined(BOOST_BIG_ENDIAN)
376  0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
377  0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
378  0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
379 #else
380  0x7ff00000u, // Last word of +infinity
381  0x7ff10000u, // Last word of quiet NaN
382  0x7ff90000u, // Last word of signaling NaN
383 #endif
384  true, // conforms to iec559
385  round_to_nearest>
386 {
387 public:
388  static double min() throw() { return DBL_MIN; }
389  static double denorm_min() throw() { return DBL_MIN; }
390  static double max() throw() { return DBL_MAX; }
391  static double epsilon() throw() { return DBL_EPSILON; }
392  static double round_error() throw() { return 0.5; } // Units: ulps.
393 };
394 
395 template<> class numeric_limits<long double>
396  : public _Floating_limits<long double,
397  LDBL_MANT_DIG, // Binary digits of precision
398  LDBL_DIG, // Decimal digits of precision
399  LDBL_MIN_EXP, // Minimum exponent
400  LDBL_MAX_EXP, // Maximum exponent
401  LDBL_MIN_10_EXP,// Minimum base 10 exponent
402  LDBL_MAX_10_EXP,// Maximum base 10 exponent
403 #if defined(BOOST_BIG_ENDIAN)
404  0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
405  0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
406  0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
407 #else
408  0x7fff8000u, // Last word of +infinity
409  0x7fffc000u, // Last word of quiet NaN
410  0x7fff9000u, // Last word of signaling NaN
411 #endif
412  false, // Doesn't conform to iec559
413  round_to_nearest>
414 {
415 public:
416  static long double min() throw() { return LDBL_MIN; }
417  static long double denorm_min() throw() { return LDBL_MIN; }
418  static long double max() throw() { return LDBL_MAX; }
419  static long double epsilon() throw() { return LDBL_EPSILON; }
420  static long double round_error() throw() { return 4; } // Units: ulps.
421 };
422 
423 } // namespace std
424 
425 #else
426 #include <limits>
427 #endif //__GNUC__
428 
429 #endif
430 
STL namespace.
size_t min(const V &v, T &out)
Definition: vectormath.h:275
size_t max(const V &v, T &out)
Definition: vectormath.h:297