test_nonfinite_trap.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright (c) 2006 Johan Rade
  2. // Copyright (c) 2011 Paul A. Bristow To incorporate into Boost.Math
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // test_nonfinite_trap.cpp
  7. #ifdef _MSC_VER
  8. # pragma warning(disable : 4702)
  9. #endif
  10. #define BOOST_TEST_MAIN
  11. #include <boost/test/unit_test.hpp>
  12. #include "almost_equal.ipp" // Similar to BOOST_CLOSE_FRACTION.
  13. #include "s_.ipp" // To create test strings like std::basic_string<CharType> s = S_("0 -0");
  14. #include <boost/math/special_functions/nonfinite_num_facets.hpp>
  15. #include <locale>
  16. #include <sstream>
  17. namespace {
  18. // Using an anonymous namespace resolves ambiguities on platforms
  19. // with fpclassify etc functions at global scope.
  20. using namespace boost::math;
  21. using boost::math::signbit;
  22. using boost::math::changesign;
  23. using boost::math::isnan;
  24. //------------------------------------------------------------------------------
  25. void trap_test_finite();
  26. void trap_test_inf();
  27. void trap_test_nan();
  28. BOOST_AUTO_TEST_CASE(trap_test)
  29. {
  30. trap_test_finite();
  31. trap_test_inf();
  32. trap_test_nan();
  33. }
  34. //------------------------------------------------------------------------------
  35. template<class CharType, class ValType> void trap_test_finite_impl();
  36. void trap_test_finite()
  37. {
  38. trap_test_finite_impl<char, float>();
  39. trap_test_finite_impl<char, double>();
  40. trap_test_finite_impl<char, long double>();
  41. trap_test_finite_impl<wchar_t, float>();
  42. trap_test_finite_impl<wchar_t, double>();
  43. trap_test_finite_impl<wchar_t, long double>();
  44. }
  45. template<class CharType, class ValType> void trap_test_finite_impl()
  46. {
  47. std::locale old_locale;
  48. std::locale tmp_locale(old_locale,
  49. new nonfinite_num_put<CharType>(trap_infinity | trap_nan));
  50. std::locale new_locale(tmp_locale,
  51. new nonfinite_num_get<CharType>(trap_infinity | trap_nan));
  52. std::basic_stringstream<CharType> ss;
  53. ss.imbue(new_locale);
  54. ValType a1 = (ValType)1.2;
  55. ValType a2 = (ValType)-3.5;
  56. ValType a3 = (std::numeric_limits<ValType>::max)();
  57. ValType a4 = -(std::numeric_limits<ValType>::max)();
  58. ss << a1 << ' ' << a2 << ' ' << a3 << ' ' << a4;
  59. ValType b1, b2, b3, b4;
  60. ss >> b1 >> b2 >> b3 >> b4;
  61. BOOST_CHECK(almost_equal(b1, a1));
  62. BOOST_CHECK(almost_equal(b2, a2));
  63. BOOST_CHECK(almost_equal(b3, a3));
  64. BOOST_CHECK(almost_equal(b4, a4));
  65. BOOST_CHECK(b3 != std::numeric_limits<ValType>::infinity());
  66. BOOST_CHECK(b4 != -std::numeric_limits<ValType>::infinity());
  67. BOOST_CHECK(ss.rdstate() == std::ios_base::eofbit);
  68. ss.clear();
  69. ss.str(S_(""));
  70. ss << "++5";
  71. ValType b5;
  72. ss >> b5;
  73. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit);
  74. }
  75. //------------------------------------------------------------------------------
  76. template<class CharType, class ValType> void trap_test_inf_impl();
  77. template<class CharType, class ValType> void trap_test_put_inf_impl();
  78. template<class CharType, class ValType> void trap_test_get_inf_impl();
  79. void trap_test_inf()
  80. {
  81. trap_test_inf_impl<char, float>();
  82. trap_test_inf_impl<char, double>();
  83. trap_test_inf_impl<char, long double>();
  84. trap_test_inf_impl<wchar_t, float>();
  85. trap_test_inf_impl<wchar_t, double>();
  86. trap_test_inf_impl<wchar_t, long double>();
  87. }
  88. template<class CharType, class ValType> void trap_test_inf_impl()
  89. {
  90. trap_test_put_inf_impl<CharType, ValType>();
  91. trap_test_get_inf_impl<CharType, ValType>();
  92. }
  93. template<class CharType, class ValType> void trap_test_put_inf_impl()
  94. {
  95. std::locale old_locale;
  96. std::locale new_locale(old_locale,
  97. new nonfinite_num_put<CharType>(trap_infinity));
  98. std::basic_stringstream<CharType> ss;
  99. ss.imbue(new_locale);
  100. ValType a1 = std::numeric_limits<ValType>::infinity();
  101. ss << a1;
  102. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit
  103. || ss.rdstate() == std::ios_base::badbit);
  104. ss.clear();
  105. ValType a2 = -std::numeric_limits<ValType>::infinity();
  106. ss << a2;
  107. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit
  108. || ss.rdstate() == std::ios_base::badbit);
  109. }
  110. template<class CharType, class ValType> void trap_test_get_inf_impl()
  111. {
  112. std::locale old_locale;
  113. std::locale tmp_locale(old_locale, new nonfinite_num_put<CharType>);
  114. std::locale new_locale(tmp_locale,
  115. new nonfinite_num_get<CharType>(trap_infinity));
  116. std::basic_stringstream<CharType> ss;
  117. ss.imbue(new_locale);
  118. ValType a1 = std::numeric_limits<ValType>::infinity();
  119. ss << a1;
  120. ValType b1;
  121. ss >> b1;
  122. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit);
  123. ss.clear();
  124. ss.str(S_(""));
  125. ValType a2 = -std::numeric_limits<ValType>::infinity();
  126. ss << a2;
  127. ValType b2;
  128. ss >> b2;
  129. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit);
  130. }
  131. //------------------------------------------------------------------------------
  132. template<class CharType, class ValType> void trap_test_nan_impl();
  133. template<class CharType, class ValType> void trap_test_put_nan_impl();
  134. template<class CharType, class ValType> void trap_test_get_nan_impl();
  135. void trap_test_nan()
  136. {
  137. trap_test_nan_impl<char, float>();
  138. trap_test_nan_impl<char, double>();
  139. trap_test_nan_impl<char, long double>();
  140. trap_test_nan_impl<wchar_t, float>();
  141. trap_test_nan_impl<wchar_t, double>();
  142. trap_test_nan_impl<wchar_t, long double>();
  143. }
  144. template<class CharType, class ValType> void trap_test_nan_impl()
  145. {
  146. trap_test_put_nan_impl<CharType, ValType>();
  147. trap_test_get_nan_impl<CharType, ValType>();
  148. }
  149. template<class CharType, class ValType> void trap_test_put_nan_impl()
  150. {
  151. std::locale old_locale;
  152. std::locale new_locale(old_locale,
  153. new nonfinite_num_put<CharType>(trap_nan));
  154. std::basic_stringstream<CharType> ss;
  155. ss.imbue(new_locale);
  156. ValType a1 = std::numeric_limits<ValType>::quiet_NaN();
  157. ss << a1;
  158. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit
  159. || ss.rdstate() == std::ios_base::badbit);
  160. ss.clear();
  161. ValType a2 = std::numeric_limits<ValType>::signaling_NaN();
  162. ss << a2;
  163. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit
  164. || ss.rdstate() == std::ios_base::badbit);
  165. }
  166. template<class CharType, class ValType> void trap_test_get_nan_impl()
  167. {
  168. std::locale old_locale;
  169. std::locale tmp_locale(old_locale, new nonfinite_num_put<CharType>);
  170. std::locale new_locale(tmp_locale,
  171. new nonfinite_num_get<CharType>(trap_nan));
  172. std::basic_stringstream<CharType> ss;
  173. ss.imbue(new_locale);
  174. ValType a1 = std::numeric_limits<ValType>::quiet_NaN();
  175. ss << a1;
  176. ValType b1;
  177. ss >> b1;
  178. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit);
  179. ss.clear();
  180. ss.str(S_(""));
  181. ValType a2 = std::numeric_limits<ValType>::signaling_NaN();
  182. ss << a2;
  183. ValType b2;
  184. ss >> b2;
  185. BOOST_CHECK(ss.rdstate() == std::ios_base::failbit);
  186. }
  187. //------------------------------------------------------------------------------
  188. } // anonymous namespace