]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // boost integer.hpp test program ------------------------------------------// |
2 | ||
3 | // Copyright Beman Dawes 1999. | |
4 | // Copyright Daryle Walker 2001. | |
5 | // Copyright John Maddock 2009. | |
6 | // Distributed under the Boost | |
7 | // Software License, Version 1.0. (See accompanying file | |
8 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | ||
10 | ||
11 | // See http://www.boost.org/libs/integer for documentation. | |
12 | ||
13 | // Revision History | |
14 | // 04 Oct 01 Added tests for new templates; rewrote code (Daryle Walker) | |
15 | // 10 Mar 01 Boost Test Library now used for tests (Beman Dawes) | |
16 | // 31 Aug 99 Initial version | |
17 | ||
18 | #include <boost/detail/lightweight_test.hpp> // for main, BOOST_TEST | |
19 | #include <boost/integer.hpp> // for boost::int_t, boost::uint_t | |
20 | #include <boost/type_traits/is_same.hpp> | |
21 | #include <boost/mpl/bool.hpp> // for mpl::true_ and false_ | |
22 | ||
23 | #include <climits> // for ULONG_MAX, LONG_MAX, LONG_MIN | |
24 | #include <iostream> // for std::cout (std::endl indirectly) | |
25 | #include <typeinfo> // for std::type_info | |
26 | ||
27 | #ifdef BOOST_MSVC | |
28 | #pragma warning(disable:4127) // conditional expression is constant | |
29 | #endif | |
20effc67 | 30 | #if defined( BOOST_BORLANDC ) |
7c673cae FG |
31 | # pragma option -w-8008 -w-8066 // condition is always true |
32 | #endif | |
33 | ||
34 | // | |
35 | // Keep track of error count, so we can print out detailed | |
36 | // info only if we need it: | |
37 | // | |
38 | int last_error_count = 0; | |
39 | // | |
40 | // Helpers to print out the name of a type, | |
41 | // we use these as typeid(X).name() doesn't always | |
42 | // return a human readable string: | |
43 | // | |
44 | template <class T> const char* get_name_of_type(T){ return typeid(T).name(); } | |
45 | const char* get_name_of_type(signed char){ return "signed char"; } | |
46 | const char* get_name_of_type(unsigned char){ return "unsigned char"; } | |
47 | const char* get_name_of_type(short){ return "short"; } | |
48 | const char* get_name_of_type(unsigned short){ return "unsigned short"; } | |
49 | const char* get_name_of_type(int){ return "int"; } | |
50 | const char* get_name_of_type(unsigned int){ return "unsigned int"; } | |
51 | const char* get_name_of_type(long){ return "long"; } | |
52 | const char* get_name_of_type(unsigned long){ return "unsigned long"; } | |
53 | #ifdef BOOST_HAS_LONG_LONG | |
54 | const char* get_name_of_type(boost::long_long_type){ return "boost::long_long_type"; } | |
55 | const char* get_name_of_type(boost::ulong_long_type){ return "boost::ulong_long_type"; } | |
56 | #endif | |
57 | ||
58 | template <int Bits> | |
59 | void do_test_exact(boost::mpl::true_ const&) | |
60 | { | |
61 | // Test the ::exact member: | |
62 | typedef typename boost::int_t<Bits>::exact int_exact; | |
63 | typedef typename boost::uint_t<Bits>::exact uint_exact; | |
64 | typedef typename boost::int_t<Bits>::least least_int; | |
65 | typedef typename boost::uint_t<Bits>::least least_uint; | |
66 | ||
67 | BOOST_TEST((boost::is_same<int_exact, least_int>::value)); | |
68 | BOOST_TEST((boost::is_same<uint_exact, least_uint>::value)); | |
69 | } | |
70 | template <int Bits> | |
71 | void do_test_exact(boost::mpl::false_ const&) | |
72 | { | |
73 | // Nothing to do, type does not have an ::extact member. | |
74 | } | |
75 | ||
76 | template <int Bits> | |
77 | void do_test_bits() | |
78 | { | |
79 | // | |
80 | // Recurse to next smallest number of bits: | |
81 | // | |
82 | do_test_bits<Bits - 1>(); | |
83 | // | |
84 | // Test exact types if we have them: | |
85 | // | |
86 | do_test_exact<Bits>( | |
87 | boost::mpl::bool_< | |
88 | (sizeof(unsigned char) * CHAR_BIT == Bits) | |
89 | || (sizeof(unsigned short) * CHAR_BIT == Bits) | |
90 | || (sizeof(unsigned int) * CHAR_BIT == Bits) | |
91 | || (sizeof(unsigned long) * CHAR_BIT == Bits) | |
92 | #ifdef BOOST_HAS_LONG_LONG | |
93 | || (sizeof(boost::ulong_long_type) * CHAR_BIT == Bits) | |
94 | #endif | |
95 | >()); | |
96 | // | |
97 | // We need to check all aspects of the members of int_t<Bits> and uint_t<Bits>: | |
98 | // | |
99 | typedef typename boost::int_t<Bits>::least least_int; | |
100 | typedef typename boost::int_t<Bits>::least fast_int; | |
101 | typedef typename boost::uint_t<Bits>::least least_uint; | |
102 | typedef typename boost::uint_t<Bits>::fast fast_uint; | |
103 | ||
104 | if(std::numeric_limits<least_int>::is_specialized) | |
105 | { | |
106 | BOOST_TEST(std::numeric_limits<least_int>::digits + 1 >= Bits); | |
107 | } | |
108 | if(std::numeric_limits<least_uint>::is_specialized) | |
109 | { | |
110 | BOOST_TEST(std::numeric_limits<least_uint>::digits >= Bits); | |
111 | } | |
112 | BOOST_TEST(sizeof(least_int) * CHAR_BIT >= Bits); | |
113 | BOOST_TEST(sizeof(least_uint) * CHAR_BIT >= Bits); | |
114 | BOOST_TEST(sizeof(fast_int) >= sizeof(least_int)); | |
115 | BOOST_TEST(sizeof(fast_uint) >= sizeof(least_uint)); | |
116 | // | |
117 | // There should be no type smaller than least_* that also has enough bits: | |
118 | // | |
119 | if(!boost::is_same<signed char, least_int>::value) | |
120 | { | |
121 | BOOST_TEST(std::numeric_limits<signed char>::digits < Bits); | |
122 | if(!boost::is_same<short, least_int>::value) | |
123 | { | |
124 | BOOST_TEST(std::numeric_limits<short>::digits < Bits); | |
125 | if(!boost::is_same<int, least_int>::value) | |
126 | { | |
127 | BOOST_TEST(std::numeric_limits<int>::digits < Bits); | |
128 | if(!boost::is_same<long, least_int>::value) | |
129 | { | |
130 | BOOST_TEST(std::numeric_limits<long>::digits < Bits); | |
131 | } | |
132 | } | |
133 | } | |
134 | } | |
135 | // And again, but unsigned: | |
136 | if(!boost::is_same<unsigned char, least_uint>::value) | |
137 | { | |
138 | BOOST_TEST(std::numeric_limits<unsigned char>::digits < Bits); | |
139 | if(!boost::is_same<unsigned short, least_uint>::value) | |
140 | { | |
141 | BOOST_TEST(std::numeric_limits<unsigned short>::digits < Bits); | |
142 | if(!boost::is_same<unsigned int, least_uint>::value) | |
143 | { | |
144 | BOOST_TEST(std::numeric_limits<unsigned int>::digits < Bits); | |
145 | if(!boost::is_same<unsigned long, least_uint>::value) | |
146 | { | |
147 | BOOST_TEST(std::numeric_limits<unsigned long>::digits < Bits); | |
148 | } | |
149 | } | |
150 | } | |
151 | } | |
152 | ||
153 | if(boost::detail::test_errors() != last_error_count) | |
154 | { | |
155 | last_error_count = boost::detail::test_errors(); | |
156 | std::cout << "Errors occurred while testing with bit count = " << Bits << std::endl; | |
157 | std::cout << "Type int_t<" << Bits << ">::least was " << get_name_of_type(least_int(0)) << std::endl; | |
158 | std::cout << "Type int_t<" << Bits << ">::fast was " << get_name_of_type(fast_int(0)) << std::endl; | |
159 | std::cout << "Type uint_t<" << Bits << ">::least was " << get_name_of_type(least_uint(0)) << std::endl; | |
160 | std::cout << "Type uint_t<" << Bits << ">::fast was " << get_name_of_type(fast_uint(0)) << std::endl; | |
161 | } | |
162 | } | |
163 | template <> | |
164 | void do_test_bits<-1>() | |
165 | { | |
166 | // Nothing to do here!! | |
167 | } | |
168 | ||
169 | template <class Traits, class Expected> | |
170 | void test_min_max_type(Expected val) | |
171 | { | |
172 | typedef typename Traits::least least_type; | |
173 | typedef typename Traits::fast fast_type; | |
174 | BOOST_TEST((boost::is_same<least_type, Expected>::value)); | |
175 | BOOST_TEST(sizeof(fast_type) >= sizeof(least_type)); | |
176 | BOOST_TEST((std::numeric_limits<least_type>::min)() <= val); | |
177 | BOOST_TEST((std::numeric_limits<least_type>::max)() >= val); | |
178 | ||
179 | if(boost::detail::test_errors() != last_error_count) | |
180 | { | |
181 | last_error_count = boost::detail::test_errors(); | |
182 | std::cout << "Traits type is: " << typeid(Traits).name() << std::endl; | |
183 | std::cout << "Least type is: " << get_name_of_type(least_type(0)) << std::endl; | |
184 | std::cout << "Fast type is: " << get_name_of_type(fast_type(0)) << std::endl; | |
185 | std::cout << "Expected type is: " << get_name_of_type(Expected(0)) << std::endl; | |
186 | std::cout << "Required value is: " << val << std::endl; | |
187 | } | |
188 | } | |
189 | ||
190 | // Test program | |
191 | int main(int, char*[]) | |
192 | { | |
193 | // Test int_t and unint_t first: | |
194 | if(std::numeric_limits<boost::intmax_t>::is_specialized) | |
195 | do_test_bits<std::numeric_limits<boost::uintmax_t>::digits>(); | |
196 | else | |
197 | do_test_bits<std::numeric_limits<long>::digits>(); | |
198 | ||
199 | // | |
200 | // Test min and max value types: | |
201 | // | |
202 | test_min_max_type<boost::int_max_value_t<SCHAR_MAX>, signed char>(SCHAR_MAX); | |
203 | test_min_max_type<boost::int_min_value_t<SCHAR_MIN>, signed char>(SCHAR_MIN); | |
204 | test_min_max_type<boost::uint_value_t<UCHAR_MAX>, unsigned char>(UCHAR_MAX); | |
205 | #if(USHRT_MAX != UCHAR_MAX) | |
206 | test_min_max_type<boost::int_max_value_t<SCHAR_MAX+1>, short>(SCHAR_MAX+1); | |
207 | test_min_max_type<boost::int_min_value_t<SCHAR_MIN-1>, short>(SCHAR_MIN-1); | |
208 | test_min_max_type<boost::uint_value_t<UCHAR_MAX+1>, unsigned short>(UCHAR_MAX+1); | |
209 | test_min_max_type<boost::int_max_value_t<SHRT_MAX>, short>(SHRT_MAX); | |
210 | test_min_max_type<boost::int_min_value_t<SHRT_MIN>, short>(SHRT_MIN); | |
211 | test_min_max_type<boost::uint_value_t<USHRT_MAX>, unsigned short>(USHRT_MAX); | |
212 | #endif | |
213 | #if(UINT_MAX != USHRT_MAX) | |
214 | test_min_max_type<boost::int_max_value_t<SHRT_MAX+1>, int>(SHRT_MAX+1); | |
215 | test_min_max_type<boost::int_min_value_t<SHRT_MIN-1>, int>(SHRT_MIN-1); | |
216 | test_min_max_type<boost::uint_value_t<USHRT_MAX+1>, unsigned int>(USHRT_MAX+1); | |
217 | test_min_max_type<boost::int_max_value_t<INT_MAX>, int>(INT_MAX); | |
218 | test_min_max_type<boost::int_min_value_t<INT_MIN>, int>(INT_MIN); | |
219 | test_min_max_type<boost::uint_value_t<UINT_MAX>, unsigned int>(UINT_MAX); | |
220 | #endif | |
221 | #if(ULONG_MAX != UINT_MAX) | |
222 | test_min_max_type<boost::int_max_value_t<INT_MAX+1L>, long>(INT_MAX+1L); | |
223 | test_min_max_type<boost::int_min_value_t<INT_MIN-1L>, long>(INT_MIN-1L); | |
224 | test_min_max_type<boost::uint_value_t<UINT_MAX+1uL>, unsigned long>(UINT_MAX+1uL); | |
225 | test_min_max_type<boost::int_max_value_t<LONG_MAX>, long>(LONG_MAX); | |
226 | test_min_max_type<boost::int_min_value_t<LONG_MIN>, long>(LONG_MIN); | |
227 | test_min_max_type<boost::uint_value_t<ULONG_MAX>, unsigned long>(ULONG_MAX); | |
228 | #endif | |
229 | #ifndef BOOST_NO_INTEGRAL_INT64_T | |
230 | #if defined(BOOST_HAS_LONG_LONG) && (defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) | |
231 | test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); | |
232 | test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); | |
233 | test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); | |
234 | test_min_max_type<boost::int_max_value_t<LLONG_MAX>, boost::long_long_type>(LLONG_MAX); | |
235 | test_min_max_type<boost::int_min_value_t<LLONG_MIN>, boost::long_long_type>(LLONG_MIN); | |
236 | test_min_max_type<boost::uint_value_t<ULLONG_MAX>, boost::ulong_long_type>(ULLONG_MAX); | |
237 | #endif | |
238 | #if defined(BOOST_HAS_LONG_LONG) && (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) | |
239 | test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); | |
240 | test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); | |
241 | test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); | |
242 | test_min_max_type<boost::int_max_value_t<LONG_LONG_MAX>, boost::long_long_type>(LONG_LONG_MAX); | |
243 | test_min_max_type<boost::int_min_value_t<LONG_LONG_MIN>, boost::long_long_type>(LONG_LONG_MIN); | |
244 | test_min_max_type<boost::uint_value_t<ULONG_LONG_MAX>, boost::ulong_long_type>(ULONG_LONG_MAX); | |
245 | #endif | |
246 | #if defined(BOOST_HAS_LONG_LONG) && (defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) | |
247 | test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); | |
248 | test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); | |
249 | test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); | |
250 | test_min_max_type<boost::int_max_value_t<LONGLONG_MAX>, boost::long_long_type>(LONGLONG_MAX); | |
251 | test_min_max_type<boost::int_min_value_t<LONGLONG_MIN>, boost::long_long_type>(LONGLONG_MAX); | |
252 | test_min_max_type<boost::uint_value_t<ULONGLONG_MAX>, boost::ulong_long_type>(ULONGLONG_MAX); | |
253 | #endif | |
254 | #if defined(BOOST_HAS_LONG_LONG) && (defined(_ULLONG_MAX) && defined(_LLONG_MIN) && (_ULLONG_MAX != ULONG_MAX)) | |
255 | test_min_max_type<boost::int_max_value_t<LONG_MAX+1LL>, boost::long_long_type>(LONG_MAX+1LL); | |
256 | test_min_max_type<boost::int_min_value_t<LONG_MIN-1LL>, boost::long_long_type>(LONG_MIN-1LL); | |
257 | test_min_max_type<boost::uint_value_t<ULONG_MAX+1uLL>, boost::ulong_long_type>(ULONG_MAX+1uLL); | |
258 | test_min_max_type<boost::int_max_value_t<_LLONG_MAX>, boost::long_long_type>(_LLONG_MAX); | |
259 | test_min_max_type<boost::int_min_value_t<_LLONG_MIN>, boost::long_long_type>(_LLONG_MIN); | |
260 | test_min_max_type<boost::uint_value_t<_ULLONG_MAX>, boost::ulong_long_type>(_ULLONG_MAX); | |
261 | #endif // BOOST_HAS_LONG_LONG | |
262 | #endif // BOOST_NO_INTEGRAL_INT64_T | |
263 | return boost::report_errors(); | |
264 | } |