integer_test.cpp 12 KB

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