|
1 // |
|
2 // boost limits_test.cpp test your <limits> file for important |
|
3 // Copyright Jens Maurer 2000 |
|
4 // Permission to use, copy, modify, sell, and distribute this software |
|
5 // is hereby granted without fee provided that the above copyright notice |
|
6 // appears in all copies and that both that copyright notice and this |
|
7 // permission notice appear in supporting documentation, |
|
8 // Jens Maurer makes no representations about the suitability of this |
|
9 // software for any purpose. It is provided "as is" without express or |
|
10 // implied warranty. |
|
11 // |
|
12 // |
|
13 |
|
14 #include <limits> |
|
15 |
|
16 #include "cppunit/cppunit_proxy.h" |
|
17 |
|
18 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) |
|
19 using namespace std; |
|
20 #endif |
|
21 |
|
22 // |
|
23 // TestCase class |
|
24 // |
|
25 class LimitTest : public CPPUNIT_NS::TestCase |
|
26 { |
|
27 CPPUNIT_TEST_SUITE(LimitTest); |
|
28 CPPUNIT_TEST(test); |
|
29 # if defined (__BORLANDC__) |
|
30 CPPUNIT_IGNORE; |
|
31 # endif |
|
32 CPPUNIT_TEST(qnan_test); |
|
33 CPPUNIT_TEST(limits_cov); |
|
34 CPPUNIT_TEST_SUITE_END(); |
|
35 |
|
36 protected: |
|
37 void test(); |
|
38 void qnan_test(); |
|
39 void limits_cov(); |
|
40 }; |
|
41 |
|
42 CPPUNIT_TEST_SUITE_REGISTRATION(LimitTest); |
|
43 |
|
44 # define CHECK_COND(X) if (!(X)) return false; |
|
45 |
|
46 bool valid_sign_info(bool, bool) |
|
47 { return true; } |
|
48 |
|
49 template <class _Tp> |
|
50 bool valid_sign_info(bool limit_is_signed, const _Tp &) { |
|
51 return limit_is_signed && _Tp(-1) < 0 || |
|
52 !limit_is_signed && _Tp(-1) > 0; |
|
53 } |
|
54 |
|
55 template <class _Tp> |
|
56 bool test_integral_limits(const _Tp &, bool unknown_sign = true, bool is_signed = true) { |
|
57 typedef numeric_limits<_Tp> lim; |
|
58 |
|
59 CHECK_COND(lim::is_specialized); |
|
60 CHECK_COND(lim::is_integer); |
|
61 /*CHECK_COND(lim::is_modulo);*/ |
|
62 CHECK_COND(lim::min() < lim::max()); |
|
63 CHECK_COND((unknown_sign && ((lim::is_signed && (lim::min() != 0)) || (!lim::is_signed && (lim::min() == 0)))) || |
|
64 (!unknown_sign && ((lim::is_signed && is_signed) || (!lim::is_signed && !is_signed)))); |
|
65 |
|
66 if (unknown_sign) { |
|
67 CHECK_COND(valid_sign_info(lim::is_signed, _Tp())); |
|
68 } |
|
69 return true; |
|
70 } |
|
71 |
|
72 template <class _Tp> |
|
73 bool test_signed_integral_limits(const _Tp &__val) { |
|
74 return test_integral_limits(__val, false, true); |
|
75 } |
|
76 template <class _Tp> |
|
77 bool test_unsigned_integral_limits(const _Tp &__val) { |
|
78 return test_integral_limits(__val, false, false); |
|
79 } |
|
80 |
|
81 template <class _Tp> |
|
82 bool test_float_limits(const _Tp &) { |
|
83 typedef numeric_limits<_Tp> lim; |
|
84 CHECK_COND(lim::is_specialized); |
|
85 CHECK_COND(!lim::is_modulo); |
|
86 CHECK_COND(!lim::is_integer); |
|
87 CHECK_COND(lim::is_signed); |
|
88 |
|
89 CHECK_COND(lim::max() > 1000); |
|
90 CHECK_COND(lim::min() > 0); |
|
91 CHECK_COND(lim::min() < 0.001); |
|
92 CHECK_COND(lim::epsilon() > 0); |
|
93 |
|
94 if (lim::is_iec559) { |
|
95 CHECK_COND(lim::has_infinity); |
|
96 CHECK_COND(lim::has_quiet_NaN); |
|
97 CHECK_COND(lim::has_signaling_NaN); |
|
98 CHECK_COND(lim::signaling_NaN); |
|
99 } |
|
100 |
|
101 if (lim::has_infinity) { |
|
102 const _Tp infinity = lim::infinity(); |
|
103 /* Make sure those values are not 0 or similar nonsense. |
|
104 * Infinity must compare as if larger than the maximum representable value. |
|
105 */ |
|
106 CHECK_COND(infinity > lim::max()); |
|
107 CHECK_COND(-infinity < -lim::max()); |
|
108 } |
|
109 return true; |
|
110 } |
|
111 |
|
112 template <class _Tp> |
|
113 bool test_qnan(const _Tp &) { |
|
114 typedef numeric_limits<_Tp> lim; |
|
115 if (lim::has_quiet_NaN) { |
|
116 const _Tp qnan = lim::quiet_NaN(); |
|
117 |
|
118 /* NaNs shall always compare "false" when compared for equality |
|
119 * If one of these fail, your compiler may be optimizing incorrectly, |
|
120 * or the STLport is incorrectly configured. |
|
121 */ |
|
122 CHECK_COND(! (qnan == 42)); |
|
123 CHECK_COND(! (qnan == qnan)); |
|
124 CHECK_COND(qnan != 42); |
|
125 CHECK_COND(qnan != qnan); |
|
126 |
|
127 /* The following tests may cause arithmetic traps. |
|
128 * CHECK_COND(! (qnan < 42)); |
|
129 * CHECK_COND(! (qnan > 42)); |
|
130 * CHECK_COND(! (qnan <= 42)); |
|
131 * CHECK_COND(! (qnan >= 42)); |
|
132 */ |
|
133 } |
|
134 return true; |
|
135 } |
|
136 void LimitTest::test() { |
|
137 CPPUNIT_ASSERT(test_integral_limits(bool())); |
|
138 /* |
|
139 It is implementation-defined whether a char object can hold |
|
140 negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned |
|
141 char are three distinct types. |
|
142 */ |
|
143 //CPPUNIT_ASSERT(test_integral_limits(char())); |
|
144 typedef signed char signed_char; |
|
145 CPPUNIT_ASSERT(test_signed_integral_limits(signed_char())); |
|
146 typedef unsigned char unsigned_char; |
|
147 CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_char())); |
|
148 # if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT) |
|
149 CPPUNIT_ASSERT(test_integral_limits(wchar_t())); |
|
150 # endif |
|
151 CPPUNIT_ASSERT(test_signed_integral_limits(short())); |
|
152 typedef unsigned short unsigned_short; |
|
153 CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_short())); |
|
154 CPPUNIT_ASSERT(test_signed_integral_limits(int())); |
|
155 typedef unsigned int unsigned_int; |
|
156 CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_int())); |
|
157 CPPUNIT_ASSERT(test_signed_integral_limits(long())); |
|
158 typedef unsigned long unsigned_long; |
|
159 CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_long())); |
|
160 # if defined (_STLP_LONG_LONG) |
|
161 typedef _STLP_LONG_LONG long_long; |
|
162 CPPUNIT_ASSERT(test_signed_integral_limits(long_long())); |
|
163 typedef unsigned _STLP_LONG_LONG unsigned_long_long; |
|
164 CPPUNIT_ASSERT(test_unsigned_integral_limits(unsigned_long_long())); |
|
165 #endif |
|
166 |
|
167 CPPUNIT_ASSERT(test_float_limits(float())); |
|
168 CPPUNIT_ASSERT(test_float_limits(double())); |
|
169 # if !defined ( _STLP_NO_LONG_DOUBLE ) |
|
170 typedef long double long_double; |
|
171 CPPUNIT_ASSERT(test_float_limits(long_double())); |
|
172 # endif |
|
173 } |
|
174 |
|
175 void LimitTest::qnan_test() { |
|
176 CPPUNIT_ASSERT(test_qnan(float())); |
|
177 CPPUNIT_ASSERT(test_qnan(double())); |
|
178 # if !defined ( _STLP_NO_LONG_DOUBLE ) |
|
179 typedef long double long_double; |
|
180 CPPUNIT_ASSERT(test_qnan(long_double())); |
|
181 # endif |
|
182 } |
|
183 void LimitTest::limits_cov() |
|
184 { |
|
185 if(numeric_limits<float>::has_denorm == false) |
|
186 { |
|
187 CPPUNIT_ASSERT(numeric_limits<float>::denorm_min( )); // denorm_min for float |
|
188 CPPUNIT_ASSERT(numeric_limits<double>::denorm_min( )); // denorm_min for double |
|
189 CPPUNIT_ASSERT(numeric_limits<long double>::denorm_min( )); // denorm_min for long double |
|
190 } |
|
191 numeric_limits<float>::round_error( ); // round_error for float |
|
192 numeric_limits<double>::round_error( ); // round_error for double |
|
193 numeric_limits<long double>::round_error( ); // round_error for long double |
|
194 if(numeric_limits<long double>::is_iec559) |
|
195 { |
|
196 CPPUNIT_ASSERT(numeric_limits<long double>::infinity( )); // infinity for long double |
|
197 CPPUNIT_ASSERT(numeric_limits<long double>::quiet_NaN( ));// quiet_NaN for long double |
|
198 } |
|
199 } |