]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2010 Joel de Guzman | |
3 | Copyright (c) 2001-2010 Hartmut Kaiser | |
4 | ||
5 | Use, modification and distribution is subject to the Boost Software | |
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | http://www.boost.org/LICENSE_1_0.txt) | |
8 | =============================================================================*/ | |
9 | #if !defined(BOOST_SPIRIT_TEST_X3_REAL_HPP) | |
10 | #define BOOST_SPIRIT_TEST_X3_REAL_HPP | |
11 | ||
12 | #include <climits> | |
7c673cae FG |
13 | #include <boost/spirit/home/x3/char.hpp> |
14 | #include <boost/spirit/home/x3/numeric.hpp> | |
15 | #include <boost/spirit/home/x3/operator.hpp> | |
7c673cae FG |
16 | |
17 | #include "test.hpp" | |
18 | ||
1e59de90 TL |
19 | #include <boost/type_traits/type_identity.hpp> |
20 | ||
7c673cae FG |
21 | /////////////////////////////////////////////////////////////////////////////// |
22 | // These policies can be used to parse thousand separated | |
23 | // numbers with at most 2 decimal digits after the decimal | |
24 | // point. e.g. 123,456,789.01 | |
25 | /////////////////////////////////////////////////////////////////////////////// | |
26 | template <typename T> | |
27 | struct ts_real_policies : boost::spirit::x3::ureal_policies<T> | |
28 | { | |
29 | // 2 decimal places Max | |
30 | template <typename Iterator, typename Attribute> | |
31 | static bool | |
32 | parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr) | |
33 | { | |
34 | namespace x3 = boost::spirit::x3; | |
35 | return boost::spirit::x3::extract_uint<T, 10, 1, 2, true>::call(first, last, attr); | |
36 | } | |
37 | ||
38 | // No exponent | |
39 | template <typename Iterator> | |
40 | static bool | |
41 | parse_exp(Iterator&, Iterator const&) | |
42 | { | |
43 | return false; | |
44 | } | |
45 | ||
46 | // No exponent | |
47 | template <typename Iterator, typename Attribute> | |
48 | static bool | |
49 | parse_exp_n(Iterator&, Iterator const&, Attribute&) | |
50 | { | |
51 | return false; | |
52 | } | |
53 | ||
54 | // Thousands separated numbers | |
92f5a8d4 | 55 | template <typename Iterator, typename Accumulator> |
7c673cae | 56 | static bool |
92f5a8d4 | 57 | parse_n(Iterator& first, Iterator const& last, Accumulator& result) |
7c673cae FG |
58 | { |
59 | using boost::spirit::x3::uint_parser; | |
60 | namespace x3 = boost::spirit::x3; | |
61 | ||
62 | uint_parser<unsigned, 10, 1, 3> uint3; | |
63 | uint_parser<unsigned, 10, 3, 3> uint3_3; | |
64 | ||
7c673cae FG |
65 | if (parse(first, last, uint3, result)) |
66 | { | |
92f5a8d4 TL |
67 | Accumulator n; |
68 | Iterator iter = first; | |
7c673cae | 69 | |
92f5a8d4 | 70 | while (x3::parse(iter, last, ',') && x3::parse(iter, last, uint3_3, n)) |
7c673cae FG |
71 | { |
72 | result = result * 1000 + n; | |
92f5a8d4 | 73 | first = iter; |
7c673cae FG |
74 | } |
75 | ||
92f5a8d4 | 76 | return true; |
7c673cae FG |
77 | } |
78 | return false; | |
79 | } | |
80 | }; | |
81 | ||
82 | template <typename T> | |
83 | struct no_trailing_dot_policy : boost::spirit::x3::real_policies<T> | |
84 | { | |
85 | static bool const allow_trailing_dot = false; | |
86 | }; | |
87 | ||
88 | template <typename T> | |
89 | struct no_leading_dot_policy : boost::spirit::x3::real_policies<T> | |
90 | { | |
91 | static bool const allow_leading_dot = false; | |
92 | }; | |
93 | ||
1e59de90 TL |
94 | template <typename T> |
95 | bool compare(T n, boost::type_identity_t<T> expected) | |
7c673cae | 96 | { |
1e59de90 TL |
97 | using std::abs; |
98 | using std::log10; | |
20effc67 | 99 | using std::pow; |
1e59de90 | 100 | T const eps = pow(T(10), -std::numeric_limits<T>::digits10 + log10(abs(expected))); |
7c673cae FG |
101 | T delta = n - expected; |
102 | return (delta >= -eps) && (delta <= eps); | |
103 | } | |
104 | ||
105 | /////////////////////////////////////////////////////////////////////////////// | |
106 | // A custom real type | |
107 | struct custom_real | |
108 | { | |
109 | double n; | |
110 | custom_real() : n(0) {} | |
111 | custom_real(double n_) : n(n_) {} | |
112 | friend bool operator==(custom_real a, custom_real b) | |
113 | { return a.n == b.n; } | |
7c673cae FG |
114 | friend custom_real operator*(custom_real a, custom_real b) |
115 | { return custom_real(a.n * b.n); } | |
116 | friend custom_real operator+(custom_real a, custom_real b) | |
117 | { return custom_real(a.n + b.n); } | |
118 | friend custom_real operator-(custom_real a, custom_real b) | |
119 | { return custom_real(a.n - b.n); } | |
120 | }; | |
121 | ||
122 | #endif |