• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2020 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 
7 #include <boost/spirit/include/version.hpp>
8 #include <boost/spirit/include/karma_phoenix_attributes.hpp>
9 #include <boost/spirit/include/phoenix_core.hpp>
10 #include <boost/spirit/include/phoenix_operator.hpp>
11 #include "real.hpp"
12 
13 ///////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_SPIRIT_NO_MATH_REAL_CONCEPT
15 // does not provide proper std::numeric_limits, we need to roll our own
16 namespace boost { namespace spirit { namespace traits
17 {
18     template <>
19     struct is_nan<boost::math::concepts::real_concept>
20     {
callboost::spirit::traits::is_nan21         static bool call(boost::math::concepts::real_concept n)
22         {
23             return test_nan(n.value());
24         }
25     };
26 
27     template <>
28     struct is_infinite<boost::math::concepts::real_concept>
29     {
callboost::spirit::traits::is_infinite30         static bool call(boost::math::concepts::real_concept n)
31         {
32             return test_infinite(n.value());
33         }
34     };
35 }}}
36 #endif
37 
38 ///////////////////////////////////////////////////////////////////////////////
main()39 int main()
40 {
41     using namespace boost::spirit;
42 
43     {
44         using namespace boost::spirit::ascii;
45 
46         ///////////////////////////////////////////////////////////////////////
47         typedef karma::real_generator<double, fixed_policy<double> > fixed_type;
48         fixed_type const fixed = fixed_type();
49 
50         BOOST_TEST(test("0.0", fixed, 0.0));
51         BOOST_TEST(test("1.0", fixed, 1.0));
52 
53         BOOST_TEST(test("0.0", fixed, 0.000012345));
54         BOOST_TEST(test("0.0", fixed, 0.00012345));
55         BOOST_TEST(test("0.001", fixed, 0.0012345));
56         BOOST_TEST(test("0.012", fixed, 0.012345));
57         BOOST_TEST(test("0.123", fixed, 0.12345));
58         BOOST_TEST(test("1.234", fixed, 1.2345));
59         BOOST_TEST(test("12.345", fixed, 12.345));
60         BOOST_TEST(test("123.45", fixed, 123.45));
61         BOOST_TEST(test("1234.5", fixed, 1234.5));
62         BOOST_TEST(test("12342.0", fixed, 12342.));
63         BOOST_TEST(test("123420.0", fixed, 123420.));
64         BOOST_TEST(test("123420000000000000000.0", fixed, 1.23420e20));
65 
66         BOOST_TEST(test("0.0", fixed, -0.000012345));
67         BOOST_TEST(test("0.0", fixed, -0.00012345));
68         BOOST_TEST(test("-0.001", fixed, -0.0012345));
69         BOOST_TEST(test("-0.012", fixed, -0.012345));
70         BOOST_TEST(test("-0.123", fixed, -0.12345));
71         BOOST_TEST(test("-1.234", fixed, -1.2345));
72         BOOST_TEST(test("-12.346", fixed, -12.346));
73         BOOST_TEST(test("-123.46", fixed, -123.46));
74         BOOST_TEST(test("-1234.5", fixed, -1234.5));
75         BOOST_TEST(test("-12342.0", fixed, -12342.));
76         BOOST_TEST(test("-123420.0", fixed, -123420.));
77         BOOST_TEST(test("-123420000000000000000.0", fixed, -1.23420e20));
78     }
79 
80 #ifndef BOOST_SPIRIT_NO_MATH_REAL_CONCEPT
81     {
82         using boost::math::concepts::real_concept;
83         typedef karma::real_generator<real_concept> custom_type;
84         custom_type const custom = custom_type();
85 
86         BOOST_TEST(test("0.0", custom, real_concept(0.0)));
87         BOOST_TEST(test("1.0", custom, real_concept(1.0)));
88         BOOST_TEST(test("1.0", custom, real_concept(1.0001)));
89         BOOST_TEST(test("1.001", custom, real_concept(1.001)));
90         BOOST_TEST(test("1.01", custom, real_concept(1.010)));
91         BOOST_TEST(test("1.1", custom, real_concept(1.100)));
92 
93         BOOST_TEST(test("1.234e-04", custom, real_concept(0.00012345)));
94         BOOST_TEST(test("0.001", custom, real_concept(0.0012345)));
95         BOOST_TEST(test("0.012", custom, real_concept(0.012345)));
96         BOOST_TEST(test("0.123", custom, real_concept(0.12345)));
97         BOOST_TEST(test("1.234", custom, real_concept(1.2345)));
98         BOOST_TEST(test("12.346", custom, real_concept(12.346)));
99         BOOST_TEST(test("123.46", custom, real_concept(123.46)));
100         BOOST_TEST(test("1234.5", custom, real_concept(1234.5)));
101         BOOST_TEST(test("12342.0", custom, real_concept(12342.)));
102         BOOST_TEST(test("1.234e05", custom, real_concept(123420.)));
103 
104         BOOST_TEST(test("-1.0", custom, real_concept(-1.0)));
105         BOOST_TEST(test("-1.234", custom, real_concept(-1.2345)));
106         BOOST_TEST(test("-1.235", custom, real_concept(-1.2346)));
107         BOOST_TEST(test("-1234.2", custom, real_concept(-1234.2)));
108 
109         BOOST_TEST(test("1.0", custom(real_concept(1.0))));
110         BOOST_TEST(test("1.0", custom(real_concept(1.0001))));
111         BOOST_TEST(test("1.001", custom(real_concept(1.001))));
112         BOOST_TEST(test("1.01", custom(real_concept(1.010))));
113         BOOST_TEST(test("1.1", custom(real_concept(1.100))));
114 
115         BOOST_TEST(test("1.234e-04", custom(real_concept(0.00012345))));
116         BOOST_TEST(test("0.001", custom(real_concept(0.0012345))));
117         BOOST_TEST(test("0.012", custom(real_concept(0.012345))));
118         BOOST_TEST(test("0.123", custom(real_concept(0.12345))));
119         BOOST_TEST(test("1.234", custom(real_concept(1.2345))));
120         BOOST_TEST(test("12.346", custom(real_concept(12.346))));
121         BOOST_TEST(test("123.46", custom(real_concept(123.46))));
122         BOOST_TEST(test("1234.5", custom(real_concept(1234.5))));
123         BOOST_TEST(test("12342.0", custom(real_concept(12342.))));
124         BOOST_TEST(test("1.234e05", custom(real_concept(123420.))));
125     }
126 #endif
127 
128 // this appears to be broken on Apple Tiger x86 with gcc4.0.1
129 #if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ != 40001) || \
130     !defined(__APPLE__)
131     {
132         ///////////////////////////////////////////////////////////////////////
133         typedef karma::real_generator<double, bordercase_policy<double> >
134             bordercase_type;
135         bordercase_type const bordercase = bordercase_type();
136 
137 //         BOOST_TEST(test("-5.7222349715140557e307",
138 //             bordercase(-5.7222349715140557e307)));
139 
140         BOOST_TEST(test("1.7976931348623158e308",
141             bordercase(1.7976931348623158e308)));       // DBL_MAX
142         BOOST_TEST(test("-1.7976931348623158e308",
143             bordercase(-1.7976931348623158e308)));      // -DBL_MAX
144         BOOST_TEST(test("2.2250738585072014e-308",
145             bordercase(2.2250738585072014e-308)));      // DBL_MIN
146         BOOST_TEST(test("-2.2250738585072014e-308",
147             bordercase(-2.2250738585072014e-308)));     // -DBL_MIN
148     }
149 #endif
150 
151     {
152         boost::optional<double> v;
153         BOOST_TEST(!test("", double_, v));
154         BOOST_TEST(!test("", double_(1.0), v));
155 
156         v = 1.0;
157         BOOST_TEST(test("1.0", double_, v));
158         BOOST_TEST(test("1.0", double_(1.0), v));
159     }
160 
161 // we support Phoenix attributes only starting with V2.2
162 #if SPIRIT_VERSION >= 0x2020
163     {   // Phoenix expression tests (requires to include
164         // karma_phoenix_attributes.hpp)
165         namespace phoenix = boost::phoenix;
166 
167         BOOST_TEST(test("1.0", double_, phoenix::val(1.0)));
168 
169         double d = 1.2;
170         BOOST_TEST(test("1.2", double_, phoenix::ref(d)));
171         BOOST_TEST(test("2.2", double_, ++phoenix::ref(d)));
172     }
173 #endif
174 
175     // test for denormalized numbers
176     {
177         BOOST_TEST(test("4.941e-324", double_, std::numeric_limits<double>::denorm_min()));
178     }
179 
180     // test for #628: spirit::karma::generate generates 10.0e-04, but expecting 1.0e-03
181     {
182         BOOST_TEST(test("1.0", double_, 0.99999999999999829));
183         BOOST_TEST(test("0.1", double_, 0.099999999999999829));
184         BOOST_TEST(test("0.01", double_, 0.0099999999999999829));
185         BOOST_TEST(test("1.0e-03", double_, 0.00099999999999999829));
186         BOOST_TEST(test("1.0e-04", double_, 0.00009999999999999982));
187         BOOST_TEST(test("1.0e-05", double_, 0.00000999999999999998));
188     }
189 
190     return boost::report_errors();
191 }
192 
193