real3.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. // Copyright (c) 2011 Bryce Lelbach
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/spirit/include/version.hpp>
  7. #include <boost/spirit/include/karma_phoenix_attributes.hpp>
  8. #include <boost/spirit/include/phoenix_core.hpp>
  9. #include <boost/spirit/include/phoenix_operator.hpp>
  10. #include "real.hpp"
  11. ///////////////////////////////////////////////////////////////////////////////
  12. // the customization points below have been added only recently
  13. #if SPIRIT_VERSION >= 0x2050
  14. // does not provide proper std::numeric_limits, we need to roll our own
  15. namespace boost { namespace spirit { namespace traits
  16. {
  17. template <>
  18. struct is_nan<boost::math::concepts::real_concept>
  19. {
  20. static bool call(boost::math::concepts::real_concept n)
  21. {
  22. return test_nan(n.value());
  23. }
  24. };
  25. template <>
  26. struct is_infinite<boost::math::concepts::real_concept>
  27. {
  28. static bool call(boost::math::concepts::real_concept n)
  29. {
  30. return test_infinite(n.value());
  31. }
  32. };
  33. }}}
  34. #endif
  35. ///////////////////////////////////////////////////////////////////////////////
  36. int main()
  37. {
  38. using namespace boost::spirit;
  39. {
  40. using namespace boost::spirit::ascii;
  41. ///////////////////////////////////////////////////////////////////////
  42. typedef karma::real_generator<double, fixed_policy<double> > fixed_type;
  43. fixed_type const fixed = fixed_type();
  44. BOOST_TEST(test("0.0", fixed, 0.0));
  45. BOOST_TEST(test("1.0", fixed, 1.0));
  46. BOOST_TEST(test("0.0", fixed, 0.000012345));
  47. BOOST_TEST(test("0.0", fixed, 0.00012345));
  48. BOOST_TEST(test("0.001", fixed, 0.0012345));
  49. BOOST_TEST(test("0.012", fixed, 0.012345));
  50. BOOST_TEST(test("0.123", fixed, 0.12345));
  51. BOOST_TEST(test("1.234", fixed, 1.2345));
  52. BOOST_TEST(test("12.345", fixed, 12.345));
  53. BOOST_TEST(test("123.45", fixed, 123.45));
  54. BOOST_TEST(test("1234.5", fixed, 1234.5));
  55. BOOST_TEST(test("12342.0", fixed, 12342.));
  56. BOOST_TEST(test("123420.0", fixed, 123420.));
  57. BOOST_TEST(test("123420000000000000000.0", fixed, 1.23420e20));
  58. BOOST_TEST(test("0.0", fixed, -0.000012345));
  59. BOOST_TEST(test("0.0", fixed, -0.00012345));
  60. BOOST_TEST(test("-0.001", fixed, -0.0012345));
  61. BOOST_TEST(test("-0.012", fixed, -0.012345));
  62. BOOST_TEST(test("-0.123", fixed, -0.12345));
  63. BOOST_TEST(test("-1.234", fixed, -1.2345));
  64. BOOST_TEST(test("-12.346", fixed, -12.346));
  65. BOOST_TEST(test("-123.46", fixed, -123.46));
  66. BOOST_TEST(test("-1234.5", fixed, -1234.5));
  67. BOOST_TEST(test("-12342.0", fixed, -12342.));
  68. BOOST_TEST(test("-123420.0", fixed, -123420.));
  69. BOOST_TEST(test("-123420000000000000000.0", fixed, -1.23420e20));
  70. }
  71. // support for using real_concept with a Karma generator has been implemented
  72. // in Boost versions > 1.36 only, additionally real_concept is available only
  73. // if BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS is not defined
  74. #if BOOST_VERSION > 103600 && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
  75. {
  76. using boost::math::concepts::real_concept;
  77. typedef karma::real_generator<real_concept> custom_type;
  78. custom_type const custom = custom_type();
  79. BOOST_TEST(test("0.0", custom, real_concept(0.0)));
  80. BOOST_TEST(test("1.0", custom, real_concept(1.0)));
  81. BOOST_TEST(test("1.0", custom, real_concept(1.0001)));
  82. BOOST_TEST(test("1.001", custom, real_concept(1.001)));
  83. BOOST_TEST(test("1.01", custom, real_concept(1.010)));
  84. BOOST_TEST(test("1.1", custom, real_concept(1.100)));
  85. BOOST_TEST(test("1.234e-04", custom, real_concept(0.00012345)));
  86. BOOST_TEST(test("0.001", custom, real_concept(0.0012345)));
  87. BOOST_TEST(test("0.012", custom, real_concept(0.012345)));
  88. BOOST_TEST(test("0.123", custom, real_concept(0.12345)));
  89. BOOST_TEST(test("1.234", custom, real_concept(1.2345)));
  90. BOOST_TEST(test("12.346", custom, real_concept(12.346)));
  91. BOOST_TEST(test("123.46", custom, real_concept(123.46)));
  92. BOOST_TEST(test("1234.5", custom, real_concept(1234.5)));
  93. BOOST_TEST(test("12342.0", custom, real_concept(12342.)));
  94. BOOST_TEST(test("1.234e05", custom, real_concept(123420.)));
  95. BOOST_TEST(test("-1.0", custom, real_concept(-1.0)));
  96. BOOST_TEST(test("-1.234", custom, real_concept(-1.2345)));
  97. BOOST_TEST(test("-1.235", custom, real_concept(-1.2346)));
  98. BOOST_TEST(test("-1234.2", custom, real_concept(-1234.2)));
  99. BOOST_TEST(test("1.0", custom(real_concept(1.0))));
  100. BOOST_TEST(test("1.0", custom(real_concept(1.0001))));
  101. BOOST_TEST(test("1.001", custom(real_concept(1.001))));
  102. BOOST_TEST(test("1.01", custom(real_concept(1.010))));
  103. BOOST_TEST(test("1.1", custom(real_concept(1.100))));
  104. BOOST_TEST(test("1.234e-04", custom(real_concept(0.00012345))));
  105. BOOST_TEST(test("0.001", custom(real_concept(0.0012345))));
  106. BOOST_TEST(test("0.012", custom(real_concept(0.012345))));
  107. BOOST_TEST(test("0.123", custom(real_concept(0.12345))));
  108. BOOST_TEST(test("1.234", custom(real_concept(1.2345))));
  109. BOOST_TEST(test("12.346", custom(real_concept(12.346))));
  110. BOOST_TEST(test("123.46", custom(real_concept(123.46))));
  111. BOOST_TEST(test("1234.5", custom(real_concept(1234.5))));
  112. BOOST_TEST(test("12342.0", custom(real_concept(12342.))));
  113. BOOST_TEST(test("1.234e05", custom(real_concept(123420.))));
  114. }
  115. #endif
  116. // this appears to be broken on Apple Tiger x86 with gcc4.0.1
  117. #if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ != 40001) || \
  118. !defined(__APPLE__)
  119. {
  120. ///////////////////////////////////////////////////////////////////////
  121. typedef karma::real_generator<double, bordercase_policy<double> >
  122. bordercase_type;
  123. bordercase_type const bordercase = bordercase_type();
  124. // BOOST_TEST(test("-5.7222349715140557e307",
  125. // bordercase(-5.7222349715140557e307)));
  126. BOOST_TEST(test("1.7976931348623158e308",
  127. bordercase(1.7976931348623158e308))); // DBL_MAX
  128. BOOST_TEST(test("-1.7976931348623158e308",
  129. bordercase(-1.7976931348623158e308))); // -DBL_MAX
  130. BOOST_TEST(test("2.2250738585072014e-308",
  131. bordercase(2.2250738585072014e-308))); // DBL_MIN
  132. BOOST_TEST(test("-2.2250738585072014e-308",
  133. bordercase(-2.2250738585072014e-308))); // -DBL_MIN
  134. }
  135. #endif
  136. {
  137. boost::optional<double> v;
  138. BOOST_TEST(!test("", double_, v));
  139. BOOST_TEST(!test("", double_(1.0), v));
  140. v = 1.0;
  141. BOOST_TEST(test("1.0", double_, v));
  142. BOOST_TEST(test("1.0", double_(1.0), v));
  143. }
  144. // we support Phoenix attributes only starting with V2.2
  145. #if SPIRIT_VERSION >= 0x2020
  146. { // Phoenix expression tests (requires to include
  147. // karma_phoenix_attributes.hpp)
  148. namespace phoenix = boost::phoenix;
  149. BOOST_TEST(test("1.0", double_, phoenix::val(1.0)));
  150. double d = 1.2;
  151. BOOST_TEST(test("1.2", double_, phoenix::ref(d)));
  152. BOOST_TEST(test("2.2", double_, ++phoenix::ref(d)));
  153. }
  154. #endif
  155. // test for denormalized numbers
  156. {
  157. BOOST_TEST(test("4.941e-324", double_, std::numeric_limits<double>::denorm_min()));
  158. }
  159. return boost::report_errors();
  160. }