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