• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
30 #if defined( BOOST_BORLANDC )
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 //
get_name_of_type(T)44 template <class T> const char* get_name_of_type(T){ return typeid(T).name(); }
get_name_of_type(signed char)45 const char* get_name_of_type(signed char){ return "signed char"; }
get_name_of_type(unsigned char)46 const char* get_name_of_type(unsigned char){ return "unsigned char"; }
get_name_of_type(short)47 const char* get_name_of_type(short){ return "short"; }
get_name_of_type(unsigned short)48 const char* get_name_of_type(unsigned short){ return "unsigned short"; }
get_name_of_type(int)49 const char* get_name_of_type(int){ return "int"; }
get_name_of_type(unsigned int)50 const char* get_name_of_type(unsigned int){ return "unsigned int"; }
get_name_of_type(long)51 const char* get_name_of_type(long){ return "long"; }
get_name_of_type(unsigned long)52 const char* get_name_of_type(unsigned long){ return "unsigned long"; }
53 #ifdef BOOST_HAS_LONG_LONG
get_name_of_type(boost::long_long_type)54 const char* get_name_of_type(boost::long_long_type){ return "boost::long_long_type"; }
get_name_of_type(boost::ulong_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>
do_test_exact(boost::mpl::true_ const &)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>
do_test_exact(boost::mpl::false_ const &)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>
do_test_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 <>
do_test_bits()164 void do_test_bits<-1>()
165 {
166    // Nothing to do here!!
167 }
168 
169 template <class Traits, class Expected>
test_min_max_type(Expected val)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
main(int,char * [])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 }
265