]>
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> | |
13 | #include <boost/math/concepts/real_concept.hpp> | |
14 | #include <boost/detail/lightweight_test.hpp> | |
15 | #include <boost/spirit/home/x3/char.hpp> | |
16 | #include <boost/spirit/home/x3/numeric.hpp> | |
17 | #include <boost/spirit/home/x3/operator.hpp> | |
18 | #include <boost/math/special_functions/fpclassify.hpp> | |
19 | #include <boost/math/special_functions/sign.hpp> | |
20 | ||
21 | #include "test.hpp" | |
22 | ||
23 | /////////////////////////////////////////////////////////////////////////////// | |
24 | // These policies can be used to parse thousand separated | |
25 | // numbers with at most 2 decimal digits after the decimal | |
26 | // point. e.g. 123,456,789.01 | |
27 | /////////////////////////////////////////////////////////////////////////////// | |
28 | template <typename T> | |
29 | struct ts_real_policies : boost::spirit::x3::ureal_policies<T> | |
30 | { | |
31 | // 2 decimal places Max | |
32 | template <typename Iterator, typename Attribute> | |
33 | static bool | |
34 | parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr) | |
35 | { | |
36 | namespace x3 = boost::spirit::x3; | |
37 | return boost::spirit::x3::extract_uint<T, 10, 1, 2, true>::call(first, last, attr); | |
38 | } | |
39 | ||
40 | // No exponent | |
41 | template <typename Iterator> | |
42 | static bool | |
43 | parse_exp(Iterator&, Iterator const&) | |
44 | { | |
45 | return false; | |
46 | } | |
47 | ||
48 | // No exponent | |
49 | template <typename Iterator, typename Attribute> | |
50 | static bool | |
51 | parse_exp_n(Iterator&, Iterator const&, Attribute&) | |
52 | { | |
53 | return false; | |
54 | } | |
55 | ||
56 | // Thousands separated numbers | |
92f5a8d4 | 57 | template <typename Iterator, typename Accumulator> |
7c673cae | 58 | static bool |
92f5a8d4 | 59 | parse_n(Iterator& first, Iterator const& last, Accumulator& result) |
7c673cae FG |
60 | { |
61 | using boost::spirit::x3::uint_parser; | |
62 | namespace x3 = boost::spirit::x3; | |
63 | ||
64 | uint_parser<unsigned, 10, 1, 3> uint3; | |
65 | uint_parser<unsigned, 10, 3, 3> uint3_3; | |
66 | ||
7c673cae FG |
67 | if (parse(first, last, uint3, result)) |
68 | { | |
92f5a8d4 TL |
69 | Accumulator n; |
70 | Iterator iter = first; | |
7c673cae | 71 | |
92f5a8d4 | 72 | while (x3::parse(iter, last, ',') && x3::parse(iter, last, uint3_3, n)) |
7c673cae FG |
73 | { |
74 | result = result * 1000 + n; | |
92f5a8d4 | 75 | first = iter; |
7c673cae FG |
76 | } |
77 | ||
92f5a8d4 | 78 | return true; |
7c673cae FG |
79 | } |
80 | return false; | |
81 | } | |
82 | }; | |
83 | ||
84 | template <typename T> | |
85 | struct no_trailing_dot_policy : boost::spirit::x3::real_policies<T> | |
86 | { | |
87 | static bool const allow_trailing_dot = false; | |
88 | }; | |
89 | ||
90 | template <typename T> | |
91 | struct no_leading_dot_policy : boost::spirit::x3::real_policies<T> | |
92 | { | |
93 | static bool const allow_leading_dot = false; | |
94 | }; | |
95 | ||
92f5a8d4 | 96 | template <typename T, typename T2> |
7c673cae | 97 | bool |
92f5a8d4 | 98 | compare(T n, T2 expected) |
7c673cae FG |
99 | { |
100 | T const eps = std::pow(10.0, -std::numeric_limits<T>::digits10); | |
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 |