Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
18.numeric.special.int.cpp
Go to the documentation of this file.
1
30#include <limits> // for numeric_limits
31#include <climits> // for {CHAR,SHRT,INT,LONG}_{MIN,MAX}, etc.
32#include <cstdio> // for sprintf()
33
34#include <rw_driver.h>
35
36
37template <class T>
38struct Limits
39{
40 enum { is_specialized = false };
41
42 static T (min) () { return 0; }
43 static T (max) () { return 0; }
44
45 enum { digits };
46 enum { digits10 };
47 enum { is_signed };
48 enum { is_integer };
49 enum { is_exact };
50 enum { radix };
51 enum { is_bounded = false };
52
53 static bool is_modulo () { return false; }
54
55 static int compute_digits10 () {
56 return 0;
57 }
58};
59
60
61// edg (DEC cxx and others) gives an error in strict ANSI mode
62// for things like INT_MAX + 1; this works around that error...
63template <class T>
64inline bool is_modulo (T _max)
65{
66 // avoid MSVC warning C4800: 'int' :
67 // forcing value to bool 'true' or 'false' (performance warning)
68 T max_plus_one = _max;
69
70 return ++max_plus_one < _max;
71}
72
74inline bool is_modulo (bool)
75{
76 return false;
77}
78
79
81struct Limits<int>
82{
83 enum { is_specialized = true };
84 static int (min) () { return INT_MIN; }
85 static int (max) () { return INT_MAX; }
86
87 enum { digits = CHAR_BIT * sizeof (int) - 1 };
88 enum { digits10 = (digits * 301) / 1000 };
89 enum { is_signed = true };
90 enum { is_integer = true };
91 enum { is_exact = true };
92 enum { radix = 2 };
93 enum { is_bounded = true };
94
95 static bool is_modulo () { return ::is_modulo ((max)()); }
96
97 static int compute_digits10 () {
98 char buf [80];
99 return std::sprintf (buf, "%d", INT_MAX) - 1;
100 }
101};
102
103
104#ifndef _RWSTD_NO_BOOL
107{
108 enum { is_specialized = true };
109 static bool (min) () { return false; }
110 static bool (max) () { return true; }
111
112 enum { digits = 1 };
113 enum { digits10 = (digits * 301) / 1000 };
114 enum { is_signed = false };
115 enum { is_integer = true };
116 enum { is_exact = true };
117 enum { radix = 2 };
118 enum { is_bounded = true };
119
120 static bool is_modulo () { return ::is_modulo ((max)()); }
121
122 static int compute_digits10 () {
123 return 0;
124 }
125};
126
127#endif //_RWSTD_NO_BOOL
128
129
131struct Limits<char>
132{
133 enum { is_specialized = true };
134 static char (min) () { return CHAR_MIN; }
135 static char (max) () { return CHAR_MAX; }
136
137 enum { is_signed = CHAR_MAX == SCHAR_MAX ? true : false };
138 enum {
139 digits = is_signed ? CHAR_BIT * sizeof (char) -1
140 : CHAR_BIT * sizeof (char)
141 };
142 enum { digits10 = (digits * 301) / 1000 };
143 enum { is_integer = true };
144 enum { is_exact = true };
145 enum { radix = 2 };
146 enum { is_bounded = true };
147
148 static bool is_modulo () { return ::is_modulo ((max)()); }
149
150 static int compute_digits10 () {
151 char buf [80];
152 return std::sprintf (buf, "%d", (unsigned char)CHAR_MAX) - 1;
153 }
154};
155
156
158struct Limits<signed char>
159{
160
161 enum { is_specialized = true };
162 static signed char (min) () { return SCHAR_MIN; }
163 static signed char (max) () { return SCHAR_MAX; }
164
165 enum { digits = CHAR_BIT * sizeof (signed char) - 1 };
166 enum { digits10 = (digits * 301) / 1000 };
167 enum { is_signed = true };
168 enum { is_integer = true };
169 enum { is_exact = true };
170 enum { radix = 2 };
171 enum { is_bounded = true };
172
173 static bool is_modulo () { return ::is_modulo ((max)()); }
174
175 static int compute_digits10 () {
176 char buf [80];
177 return std::sprintf (buf, "%d", (unsigned char)SCHAR_MAX) - 1;
178 }
179};
180
181
183struct Limits<unsigned char>
184{
185 enum { is_specialized = true };
186 static unsigned char (min) () { return 0; }
187 static unsigned char (max) () { return UCHAR_MAX; }
188
189 enum { digits = CHAR_BIT * sizeof (unsigned char) };
190 enum { digits10 = (digits * 301) / 1000 };
191
192 enum { is_signed = false };
193 enum { is_integer = true };
194 enum { is_exact = true };
195 enum { radix = 2 };
196 enum { is_bounded = true };
197
198 static bool is_modulo () { return ::is_modulo ((max)()); }
199
200 static int compute_digits10 () {
201 char buf [80];
202 return std::sprintf (buf, "%d", (unsigned char)UCHAR_MAX) - 1;
203 }
204};
205
206#ifndef _RWSTD_NO_NATIVE_WCHAR_T
207
210{
211 enum { is_specialized = true };
212
213 static wchar_t (min) () {
214 return wchar_t (-1) > wchar_t (0) ? 0
215 : sizeof (wchar_t) == sizeof (short) ? wchar_t (SHRT_MIN)
216 : sizeof (wchar_t) == sizeof (int) ? wchar_t (INT_MIN)
217 : sizeof (wchar_t) == sizeof (long) ? wchar_t (LONG_MIN)
218 : wchar_t (SCHAR_MIN);
219 }
220
221 static wchar_t (max) () {
222 return wchar_t (-1) > wchar_t (0) ?
223 ( sizeof (wchar_t) == sizeof (short) ? wchar_t (USHRT_MAX)
224 : sizeof (wchar_t) == sizeof (int) ? wchar_t (UINT_MAX)
225 : sizeof (wchar_t) == sizeof (long) ? wchar_t (ULONG_MAX)
226 : wchar_t (SCHAR_MAX))
227 : ( sizeof (wchar_t) == sizeof (short) ? wchar_t (SHRT_MAX)
228 : sizeof (wchar_t) == sizeof (int) ? wchar_t (INT_MAX)
229 : sizeof (wchar_t) == sizeof (long) ? wchar_t (LONG_MAX)
230 : wchar_t (UCHAR_MAX));
231 }
232
233 enum { is_signed = wchar_t (0) > wchar_t (~0) };
234
235 enum {
236 digits = is_signed ? CHAR_BIT * sizeof (wchar_t) - 1
237 : CHAR_BIT*sizeof(wchar_t)
238 };
239 enum { digits10 = (digits * 301) / 1000 };
240 enum { is_integer = true };
241 enum { is_exact = true };
242 enum { radix = 2 };
243 enum { is_bounded = true };
244
245 static bool is_modulo () { return ::is_modulo ((max)()); }
246
247 static int compute_digits10 () {
248 char buf [80];
249 return std::sprintf (buf, "%u", wchar_t (~0)) - 1;
250 }
251};
252
253#endif //_RWSTD_NO_NATIVE_WCHAR_T
254
255
257struct Limits<short>
258{
259 enum { is_specialized = true };
260 static short (min) () { return SHRT_MIN; }
261 static short (max) () { return SHRT_MAX; }
262
263 enum { digits = CHAR_BIT * sizeof (short) - 1 };
264 enum { digits10 = (digits * 301) / 1000 };
265 enum { is_signed = true };
266 enum { is_integer = true };
267 enum { is_exact = true };
268 enum { radix = 2 };
269 enum { is_bounded = true };
270
271 static bool is_modulo () { return ::is_modulo ((max)()); }
272
273 static int compute_digits10 () {
274 char buf [80];
275 return std::sprintf (buf, "%d", (int)SHRT_MAX) - 1;
276 }
277};
278
279
280
282struct Limits<long>
283{
284 enum { is_specialized = true };
285 static long (min) () { return LONG_MIN; }
286 static long (max) () { return LONG_MAX; }
287
288 enum { digits = CHAR_BIT * sizeof(long)-1 };
289 enum { digits10 = (digits * 301) / 1000 };
290 enum { is_signed = true };
291 enum { is_integer = true };
292 enum { is_exact = true };
293 enum { radix = 2 };
294 enum { is_bounded = true };
295
296 static bool is_modulo () { return ::is_modulo ((max)()); }
297
298 static int compute_digits10 () {
299 char buf [80];
300 return std::sprintf (buf, "%ld", LONG_MAX) - 1;
301 }
302};
303
304
306struct Limits <unsigned short>
307{
308 enum { is_specialized = true };
309 static unsigned short (min) () { return 0; }
310 static unsigned short (max) () { return USHRT_MAX; }
311
312 enum { digits = CHAR_BIT * sizeof(unsigned short) };
313 enum { digits10 = (digits * 301) / 1000 };
314 enum { is_signed = false };
315 enum { is_integer = true };
316 enum { is_exact = true };
317 enum { radix = 2 };
318 enum { is_bounded = true };
319
320 static bool is_modulo () { return ::is_modulo ((max)()); }
321
322 static int compute_digits10 () {
323 char buf [80];
324 return std::sprintf (buf, "%u", unsigned (USHRT_MAX)) - 1;
325 }
326};
327
328
330struct Limits<unsigned int>
331{
332 enum { is_specialized = true };
333 static unsigned int (min) () { return 0; }
334 static unsigned int (max) () { return UINT_MAX; }
335
336 enum { digits = CHAR_BIT * sizeof(unsigned int) };
337 enum { digits10 = (digits * 301) / 1000 };
338 enum { is_signed = false };
339 enum { is_integer = true };
340 enum { is_exact = true };
341 enum { radix = 2 };
342 enum { is_bounded = true };
343
344 static bool is_modulo () { return ::is_modulo ((max)()); }
345
346 static int compute_digits10 () {
347 char buf [80];
348 return std::sprintf (buf, "%u", UINT_MAX) - 1;
349 }
350};
351
352
354struct Limits<unsigned long>
355{
356 enum { is_specialized = true };
357
358 static unsigned long (min) () { return 0; }
359 static unsigned long (max) () { return ULONG_MAX; }
360
361 enum { digits = CHAR_BIT * sizeof(unsigned long) };
362 enum { digits10 = (digits * 301) / 1000 };
363 enum { is_signed = false };
364 enum { is_integer = true };
365 enum { is_exact = true };
366 enum { radix = 2 };
367 enum { is_bounded = true };
368
369 static bool is_modulo () { return ::is_modulo ((max)()); }
370
371 static int compute_digits10 () {
372 char buf [80];
373 return std::sprintf (buf, "%lu", ULONG_MAX) - 1;
374 }
375};
376
377
378#ifdef _RWSTD_LONG_LONG
379
382{
383 typedef _RWSTD_LONG_LONG LLong;
384
385 enum { is_specialized = true };
386
387 static LLong (min) () {
388 typedef unsigned _RWSTD_LONG_LONG ULLong;
389 ULLong zero = 0; // prevent an EDG eccp warning #68-D
390 return ~zero / ULLong (2) + ULLong (1);
391 }
392
393 static LLong (max) () {
394 typedef unsigned _RWSTD_LONG_LONG ULLong;
395 return ~ULLong (0) / ULLong (2);
396 }
397
398 enum { digits = CHAR_BIT * sizeof (LLong) - 1 };
399 enum { digits10 = (digits * 301) / 1000 };
400 enum { is_signed = true };
401 enum { is_integer = true };
402 enum { is_exact = true };
403 enum { radix = 2 };
404 enum { is_bounded = true };
405
406 static bool is_modulo () { return ::is_modulo ((max)()); }
407
408 static int compute_digits10 () {
409 char buf [80];
410 const char fmt[] = "%" _RWSTD_LLONG_PRINTF_PREFIX "u";
411 return std::sprintf (buf, fmt, (max) ()) - 1;
412 }
413};
414
415
417struct Limits<unsigned _RWSTD_LONG_LONG>
418{
419 typedef unsigned _RWSTD_LONG_LONG ULLong;
420
421 enum { is_specialized = true };
422
423 static ULLong (min) () { return 0; }
424 static ULLong (max) () { return ~ULLong (0); }
425
426 enum { digits = CHAR_BIT * sizeof (ULLong) };
427 enum { digits10 = (digits * 301) / 1000 };
428 enum { is_signed = false };
429 enum { is_integer = true };
430 enum { is_exact = true };
431 enum { radix = 2 };
432 enum { is_bounded = true };
433
434 static bool is_modulo () { return ::is_modulo ((max)()); }
435
436 static int compute_digits10 () {
437 char buf [80];
438 const char fmt[] = "%" _RWSTD_LLONG_PRINTF_PREFIX "i";
439
440 // work around libc bugs (e.g., glibc on Linux)
441 const int n = std::sprintf (buf, fmt, (max) ());
442
444 return digits10;
445
446 return n - 1;
447 }
448};
449
450#endif // _RWSTD_LONG_LONG
451
452
453template <class T>
454void run_test (T*, const char *tname, const char *fmt)
455{
456 typedef std::numeric_limits<T> limT;
457 typedef Limits<T> Traits;
458
459 RW_ASSERT (0 != tname);
460 RW_ASSERT (0 != fmt);
461
462#if !defined (__EDG__) || __EDG_VERSION__ > 245
463
464# define ASSERT(expr, fmt) \
465 /* verify that `expr' is a constant integral expression */ \
466 { enum { is_const_integral_expression = limT::expr }; } \
467 rw_assert (limT::expr == int (Traits::expr), 0, __LINE__, \
468 "std::numeric_limits<%s>::" #expr \
469 " == %{@}, got %{@}", \
470 tname, fmt, Traits::expr, fmt, limT::expr)
471
472#else // if EDG eccp < 3.0
473 // working around an EDG eccp 2.4x ICE
474# define ASSERT(expr) \
475 /* verify that `expr' is a constant integral expression */ \
476 switch (limT::expr) { case limT::expr: break; }; \
477 rw_assert (limT::expr == int (Traits::expr), 0, __LINE__, \
478 "std::numeric_limits<%s>::" #expr \
479 "== %{@}, got %{@}", \
480 tname, fmt, Traits::expr, fmt, limT::expr)
481#endif // EDG eccp < 3.0
482
483#define ASSERT_0(expr, fmt) \
484 rw_assert (!limT::expr, 0, __LINE__, \
485 "std::numeric_limits<%s>::" #expr " == 0, got %{@}", \
486 tname, fmt, limT::expr)
487
488 ASSERT (is_specialized, "%#b");
489
490 // [numeric.special], p1
491 rw_assert ((limT::min)() == (Traits::min)(), 0, __LINE__,
492 "std::numeric_limits<%s>::min() == %{@}, got %{@}",
493 tname, fmt, (Traits::min)(), fmt, (limT::min)());
494
495 // [numeric.special], p4
496 rw_assert ((limT::max)() == (Traits::max)(), 0, __LINE__,
497 "std::numeric_limits<%s>::max() == %{@}, got %{@}",
498 tname, fmt, (Traits::max)(), fmt, (limT::max)());
499
500 // [numeric.special], p6
501 ASSERT (digits, "%d");
502
503 // [numeric.special], p9
504 ASSERT (digits10, "%d");
505
506 rw_assert (limT::digits10 == Traits::compute_digits10 (), 0, __LINE__,
507 "std::numeric_limits<%s>::digits10 == %d (computed), got %d",
508 tname, Traits::compute_digits10 (), limT::digits10);
509
510 // [numeric.special], p11
511 ASSERT (is_signed, "%b");
512
513 // [numeric.special], p13
514 ASSERT (is_integer, "%b");
515
516 // [numeric.special], p15
517 ASSERT (is_exact, "%b");
518
519 // [numeric.special], p17
520 ASSERT (radix, "%i");
521
522 // [numeric.special], p20
523 ASSERT_0 (epsilon (), fmt);
524
525 // [numeric.special], p22
526 ASSERT_0 (round_error (), fmt);
527
528 // [numeric.special], p23
529 ASSERT_0 (min_exponent, "%i");
530
531 // [numeric.special], p25
532 ASSERT_0 (min_exponent10, "%i");
533
534 // [numeric.special], p27
535 ASSERT_0 (max_exponent, "%i");
536
537 // [numeric.special], p29
538 ASSERT_0 (max_exponent10, "%i");
539
540 // [numeric.special], p31
541 ASSERT_0 (has_infinity, "%b");
542
543 // [numeric.special], p34
544 ASSERT_0 (has_quiet_NaN, "%b");
545
546 // [numeric.special], p37
547 ASSERT_0 (has_signaling_NaN, "%b");
548
549 // [numeric.special], p40
550 ASSERT_0 (has_denorm, "%b");
551
552 // [numeric.special], p42
553 ASSERT_0 (has_denorm_loss, "%b");
554
555 // [numeric.special], p43
556 ASSERT_0 (infinity (), fmt);
557
558 // [numeric.special], p45
559 ASSERT_0 (quiet_NaN (), fmt);
560
561 // [numeric.special], p47
562 ASSERT_0 (signaling_NaN (), fmt);
563
564 // [numeric.special], p49
565 ASSERT_0 (denorm_min (), fmt);
566
567 // [numeric.special], p52
568 ASSERT_0 (is_iec559, "%b");
569
570 // [numeric.special], p54
571 ASSERT (is_bounded, "%b");
572
573 // [numeric.special], p56
574 rw_assert (limT::is_modulo == Traits::is_modulo (), 0, __LINE__,
575 "std::numeric_limits<%s>::is_modulo == %#b",
576 tname, Traits::is_modulo ());
577
578 // [numeric.special], p59
579 // numeric_limits::traps exercised separately in 18.limits.traps.cpp
580 // to prevent runtime errors (SIGFPE) from hiding potential assertion
581 // failures in the rest of the test
582 // ASSERT_0 (traps, "%b");
583
584 // [numeric.special], p61
585 ASSERT_0 (tinyness_before, "%b");
586
587 // [numeric.special], p63
588 rw_assert (limT::round_style == int (std::round_toward_zero), 0, __LINE__,
589 "std::numeric_limits<%s>::round_style == %d",
590 tname, std::round_toward_zero);
591}
592
593
594static int
595run_test (int, char**)
596{
597#define TEST(T, fmt) run_test ((T*)0, #T, fmt)
598
599
600#ifndef _RWSTD_NO_BOOL
601
602 TEST (bool, "%#b");
603
604#endif //_RWSTD_NO_BOOL
605
606
607 TEST (char, "%{#c}");
608 TEST (signed char, "%{#c}");
609 TEST (unsigned char, "%{#c}");
610
611 TEST (short, "%hi");
612 TEST (unsigned short, "%hu");
613
614 TEST (int, "%i");
615 TEST (unsigned int, "%u");
616
617 TEST (long, "%li");
618 TEST (unsigned long, "%lu");
619
620#ifdef _RWSTD_LONG_LONG
621
622 run_test ((_RWSTD_LONG_LONG*)0, "long long", "%lli");
623 run_test ((unsigned _RWSTD_LONG_LONG*)0, "unsigned long long", "%llu");
624
625#endif // _RWSTD_LONG_LONG
626
627#ifndef _RWSTD_NO_NATIVE_WCHAR_T
628
629 TEST (wchar_t, "%{#lc}");
630
631#endif //_RWSTD_NO_NATIVE_WCHAR_T
632
633 TEST (void*, "%#p");
634
635 return 0;
636}
637
638
639
641int main (int argc, char *argv[])
642{
643 return rw_test (argc, argv, __FILE__,
644 "numeric.special",
645 "integer specializations",
646 run_test,
647 "",
648 (void*)0);
649}
#define T
Definition 17.names.cpp:163
#define Traits
Definition 17.names.cpp:556
#define buf
Definition 17.names.cpp:452
#define n
Definition 17.names.cpp:130
bool is_modulo(T _max)
#define ASSERT_0(expr, fmt)
#define TEST(T, fmt)
#define ASSERT(expr, fmt)
void run_test(T *, const char *tname, const char *fmt)
@ ULLong
#define main
#define _RWSTD_SPECIALIZED_CLASS
#define LLong
volatile int zero
Definition LIMITS.cpp:60
#define _RWSTD_LONG_LONG
unsigned short wchar_t
#define _RWSTD_SPECIALIZED_FUNCTION
Definition _defs.h:556
#define SHRT_MAX
Definition limits.h:64
#define INT_MIN
Definition limits.h:80
#define CHAR_BIT
Definition limits.h:40
#define UCHAR_MAX
Definition limits.h:60
#define ULONG_MAX
Definition limits.h:96
#define LONG_MAX
Definition limits.h:88
#define CHAR_MIN
Definition limits.h:48
#define USHRT_MAX
Definition limits.h:72
#define CHAR_MAX
Definition limits.h:44
#define SCHAR_MAX
Definition limits.h:52
#define INT_MAX
Definition limits.h:76
#define SCHAR_MIN
Definition limits.h:56
#define UINT_MAX
Definition limits.h:84
#define SHRT_MIN
Definition limits.h:68
#define LONG_MIN
Definition limits.h:92
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
#define RW_ASSERT(expr)
#define true
Definition stdbool.h:25
#define bool
Definition stdbool.h:24
static int compute_digits10()
static T() max()
static T() min()
static bool is_modulo()
static int compute_digits10()