]>
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 | |
57 | template <typename Iterator, typename Attribute> | |
58 | static bool | |
59 | parse_n(Iterator& first, Iterator const& last, Attribute& attr) | |
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 | ||
67 | T result = 0; | |
68 | if (parse(first, last, uint3, result)) | |
69 | { | |
70 | bool hit = false; | |
71 | T n; | |
72 | Iterator save = first; | |
73 | ||
74 | while (x3::parse(first, last, ',') && x3::parse(first, last, uint3_3, n)) | |
75 | { | |
76 | result = result * 1000 + n; | |
77 | save = first; | |
78 | hit = true; | |
79 | } | |
80 | ||
81 | first = save; | |
82 | if (hit) | |
83 | attr = result; | |
84 | return hit; | |
85 | } | |
86 | return false; | |
87 | } | |
88 | }; | |
89 | ||
90 | template <typename T> | |
91 | struct no_trailing_dot_policy : boost::spirit::x3::real_policies<T> | |
92 | { | |
93 | static bool const allow_trailing_dot = false; | |
94 | }; | |
95 | ||
96 | template <typename T> | |
97 | struct no_leading_dot_policy : boost::spirit::x3::real_policies<T> | |
98 | { | |
99 | static bool const allow_leading_dot = false; | |
100 | }; | |
101 | ||
102 | template <typename T> | |
103 | bool | |
104 | compare(T n, double expected) | |
105 | { | |
106 | T const eps = std::pow(10.0, -std::numeric_limits<T>::digits10); | |
107 | T delta = n - expected; | |
108 | return (delta >= -eps) && (delta <= eps); | |
109 | } | |
110 | ||
111 | /////////////////////////////////////////////////////////////////////////////// | |
112 | // A custom real type | |
113 | struct custom_real | |
114 | { | |
115 | double n; | |
116 | custom_real() : n(0) {} | |
117 | custom_real(double n_) : n(n_) {} | |
118 | friend bool operator==(custom_real a, custom_real b) | |
119 | { return a.n == b.n; } | |
120 | friend bool operator==(custom_real a, double b) | |
121 | { return a.n == b; } | |
122 | friend custom_real operator*(custom_real a, custom_real b) | |
123 | { return custom_real(a.n * b.n); } | |
124 | friend custom_real operator+(custom_real a, custom_real b) | |
125 | { return custom_real(a.n + b.n); } | |
126 | friend custom_real operator-(custom_real a, custom_real b) | |
127 | { return custom_real(a.n - b.n); } | |
128 | }; | |
129 | ||
130 | #endif |