limits_test.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* boost limits_test.cpp test your <limits> file for important
  2. *
  3. * Copyright Jens Maurer 2000
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * $Id$
  9. */
  10. #include <boost/limits.hpp>
  11. #include <boost/detail/lightweight_main.hpp>
  12. #include <boost/core/lightweight_test.hpp>
  13. #include <iostream>
  14. /*
  15. * General portability note:
  16. * MSVC mis-compiles explicit function template instantiations.
  17. * For example, f<A>() and f<B>() are both compiled to call f<A>().
  18. * BCC is unable to implicitly convert a "const char *" to a std::string
  19. * when using explicit function template instantiations.
  20. *
  21. * Therefore, avoid explicit function template instantiations.
  22. */
  23. #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
  24. template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
  25. namespace fix{
  26. inline int make_char_numeric_for_streaming(char c) { return c; }
  27. inline int make_char_numeric_for_streaming(signed char c) { return c; }
  28. inline int make_char_numeric_for_streaming(unsigned char c) { return c; }
  29. }
  30. using namespace fix;
  31. # if defined(_YVALS) && !defined(_CPPLIB_VER) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  32. // fix for missing operator<< in original Dinkumware lib:
  33. std::ostream& operator<<(std::ostream& os, __int64 i )
  34. {
  35. char buf[80];
  36. sprintf(buf,"%I64d", i );
  37. os << buf;
  38. return os;
  39. }
  40. std::ostream& operator<<(std::ostream& os, unsigned __int64 i )
  41. {
  42. char buf[80];
  43. sprintf(buf,"%I64u", i );
  44. os << buf;
  45. return os;
  46. }
  47. # endif
  48. #else
  49. template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
  50. inline int make_char_numeric_for_streaming(char c) { return c; }
  51. inline int make_char_numeric_for_streaming(signed char c) { return c; }
  52. inline int make_char_numeric_for_streaming(unsigned char c) { return c; }
  53. #endif
  54. #if (defined(_GLIBCPP_VERSION) || defined(_GLIBCXX_VERSION)) \
  55. && defined(BOOST_HAS_LONG_LONG) \
  56. && !defined(_GLIBCPP_USE_LONG_LONG) \
  57. && !defined(_GLIBCXX_USE_LONG_LONG)
  58. //
  59. // Some libstdc++ versions have numeric_limits<long long> but no
  60. // iostream support for long long. TODO, find a better fix!!
  61. //
  62. std::ostream& operator<<(std::ostream& os, long long i )
  63. {
  64. return os << static_cast<long double>(i);
  65. }
  66. std::ostream& operator<<(std::ostream& os, unsigned long long i )
  67. {
  68. return os << static_cast<long double>(i);
  69. }
  70. #endif
  71. template<class T>
  72. void test_integral_limits(const T &, const char * msg)
  73. {
  74. typedef std::numeric_limits<T> lim;
  75. std::cout << "Testing " << msg
  76. << " (size " << sizeof(T) << ")"
  77. << " min: " << make_char_numeric_for_streaming((lim::min)())
  78. << ", max: " << make_char_numeric_for_streaming((lim::max)())
  79. << std::endl;
  80. BOOST_TEST(static_cast<bool>(lim::is_specialized));
  81. BOOST_TEST(static_cast<bool>(lim::is_integer));
  82. // BOOST_TEST(lim::is_modulo);
  83. BOOST_TEST(static_cast<bool>((lim::min)() < (lim::max)()));
  84. }
  85. template <class T>
  86. void print_hex_val(T t, const char* name)
  87. {
  88. const unsigned char* p = (const unsigned char*)&t;
  89. std::cout << "hex value of " << name << " is: ";
  90. for (unsigned int i = 0; i < sizeof(T); ++i) {
  91. if(p[i] <= 0xF)
  92. std::cout << "0";
  93. std::cout << std::hex << (int)p[i];
  94. }
  95. std::cout << std::dec << std::endl;
  96. }
  97. template<class T>
  98. void test_float_limits(const T &, const char * msg)
  99. {
  100. std::cout << "\nTesting " << msg << std::endl;
  101. typedef std::numeric_limits<T> lim;
  102. BOOST_TEST(static_cast<bool>(lim::is_specialized));
  103. BOOST_TEST(static_cast<bool>(!lim::is_modulo));
  104. BOOST_TEST(static_cast<bool>(!lim::is_integer));
  105. BOOST_TEST(static_cast<bool>(lim::is_signed));
  106. const T infinity = lim::infinity();
  107. const T qnan = lim::quiet_NaN();
  108. const T snan = lim::signaling_NaN();
  109. std::cout << "IEEE-compatible: " << lim::is_iec559
  110. << ", traps: " << lim::traps
  111. << ", bounded: " << lim::is_bounded
  112. << ", exact: " << lim::is_exact << '\n'
  113. << "min: " << (lim::min)() << ", max: " << (lim::max)() << '\n'
  114. << "infinity: " << infinity << ", QNaN: " << qnan << '\n';
  115. print_hex_val((lim::max)(), "max");
  116. print_hex_val(infinity, "infinity");
  117. print_hex_val(qnan, "qnan");
  118. print_hex_val(snan, "snan");
  119. BOOST_TEST((lim::max)() > 1000);
  120. BOOST_TEST((lim::min)() > 0);
  121. BOOST_TEST((lim::min)() < 0.001);
  122. BOOST_TEST(lim::epsilon() > 0);
  123. if(lim::is_iec559) {
  124. BOOST_TEST(static_cast<bool>(lim::has_infinity));
  125. BOOST_TEST(static_cast<bool>(lim::has_quiet_NaN));
  126. BOOST_TEST(static_cast<bool>(lim::has_signaling_NaN));
  127. } else {
  128. std::cout << "Does not claim IEEE conformance" << std::endl;
  129. }
  130. if(lim::has_infinity) {
  131. // Make sure those values are not 0 or similar nonsense.
  132. // Infinity must compare as if larger than the maximum representable value.
  133. BOOST_TEST(infinity > (lim::max)());
  134. BOOST_TEST(-infinity < -(lim::max)());
  135. } else {
  136. std::cout << "Does not have infinity" << std::endl;
  137. }
  138. if(lim::has_quiet_NaN) {
  139. // NaNs shall always compare "false" when compared for equality
  140. // If one of these fail, your compiler may be optimizing incorrectly,
  141. // or the standard library is incorrectly configured.
  142. BOOST_TEST(! (qnan == 42));
  143. BOOST_TEST(qnan != 42);
  144. if(lim::is_iec559)
  145. {
  146. BOOST_TEST(! (qnan == qnan));
  147. BOOST_TEST(qnan != qnan);
  148. }
  149. // The following tests may cause arithmetic traps.
  150. // BOOST_TEST(! (qnan < 42));
  151. // BOOST_TEST(! (qnan > 42));
  152. // BOOST_TEST(! (qnan <= 42));
  153. // BOOST_TEST(! (qnan >= 42));
  154. } else {
  155. std::cout << "Does not have QNaN" << std::endl;
  156. }
  157. }
  158. int cpp_main(int, char*[])
  159. {
  160. test_integral_limits(bool(), "bool");
  161. test_integral_limits(char(), "char");
  162. typedef signed char signed_char;
  163. test_integral_limits(signed_char(), "signed char");
  164. typedef unsigned char unsigned_char;
  165. test_integral_limits(unsigned_char(), "unsigned char");
  166. test_integral_limits(wchar_t(), "wchar_t");
  167. test_integral_limits(short(), "short");
  168. typedef unsigned short unsigned_short;
  169. test_integral_limits(unsigned_short(), "unsigned short");
  170. test_integral_limits(int(), "int");
  171. typedef unsigned int unsigned_int;
  172. test_integral_limits(unsigned_int(), "unsigned int");
  173. test_integral_limits(long(), "long");
  174. typedef unsigned long unsigned_long;
  175. test_integral_limits(unsigned_long(), "unsigned long");
  176. #if defined(BOOST_HAS_LONG_LONG)
  177. test_integral_limits(::boost::long_long_type(), "long long");
  178. test_integral_limits(::boost::ulong_long_type(), "unsigned long long");
  179. #endif
  180. #ifdef BOOST_HAS_MS_INT64
  181. typedef __int64 long_long2;
  182. test_integral_limits(long_long2(), "__int64");
  183. typedef unsigned __int64 unsigned_long_long2;
  184. test_integral_limits(unsigned_long_long2(), "unsigned __int64");
  185. #endif
  186. test_float_limits(float(), "float");
  187. test_float_limits(double(), "double");
  188. typedef long double long_double;
  189. test_float_limits(long_double(), "long double");
  190. // Some compilers don't pay attention to std:3.6.1/5 and issue a
  191. // warning here if "return 0;" is omitted.
  192. return boost::report_errors();
  193. }