Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
4
|
Chris@16
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 ==============================================================================*/
|
Chris@16
|
8 #if !defined(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM)
|
Chris@16
|
9 #define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
|
Chris@16
|
10
|
Chris@16
|
11 #if defined(_MSC_VER)
|
Chris@16
|
12 #pragma once
|
Chris@16
|
13 #endif
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
Chris@16
|
16 #include <boost/spirit/home/qi/detail/string_parse.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost { namespace spirit { namespace qi
|
Chris@16
|
19 {
|
Chris@16
|
20 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
21 // Default (unsigned) real number policies
|
Chris@16
|
22 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
23 template <typename T>
|
Chris@16
|
24 struct ureal_policies
|
Chris@16
|
25 {
|
Chris@16
|
26 // trailing dot policy suggested by Gustavo Guerra
|
Chris@16
|
27 static bool const allow_leading_dot = true;
|
Chris@16
|
28 static bool const allow_trailing_dot = true;
|
Chris@16
|
29 static bool const expect_dot = false;
|
Chris@16
|
30
|
Chris@16
|
31 template <typename Iterator>
|
Chris@16
|
32 static bool
|
Chris@16
|
33 parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
|
Chris@16
|
34 {
|
Chris@16
|
35 return false;
|
Chris@16
|
36 }
|
Chris@16
|
37
|
Chris@16
|
38 template <typename Iterator, typename Attribute>
|
Chris@16
|
39 static bool
|
Chris@16
|
40 parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
41 {
|
Chris@16
|
42 return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 template <typename Iterator>
|
Chris@16
|
46 static bool
|
Chris@16
|
47 parse_dot(Iterator& first, Iterator const& last)
|
Chris@16
|
48 {
|
Chris@16
|
49 if (first == last || *first != '.')
|
Chris@16
|
50 return false;
|
Chris@16
|
51 ++first;
|
Chris@16
|
52 return true;
|
Chris@16
|
53 }
|
Chris@16
|
54
|
Chris@16
|
55 template <typename Iterator, typename Attribute>
|
Chris@16
|
56 static bool
|
Chris@16
|
57 parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
58 {
|
Chris@16
|
59 return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
|
Chris@16
|
60 }
|
Chris@16
|
61
|
Chris@16
|
62 template <typename Iterator>
|
Chris@16
|
63 static bool
|
Chris@16
|
64 parse_exp(Iterator& first, Iterator const& last)
|
Chris@16
|
65 {
|
Chris@16
|
66 if (first == last || (*first != 'e' && *first != 'E'))
|
Chris@16
|
67 return false;
|
Chris@16
|
68 ++first;
|
Chris@16
|
69 return true;
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 template <typename Iterator>
|
Chris@16
|
73 static bool
|
Chris@16
|
74 parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
|
Chris@16
|
75 {
|
Chris@16
|
76 return extract_int<int, 10, 1, -1>::call(first, last, attr_);
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 ///////////////////////////////////////////////////////////////////////
|
Chris@16
|
80 // The parse_nan() and parse_inf() functions get called whenever:
|
Chris@16
|
81 //
|
Chris@16
|
82 // - a number to parse does not start with a digit (after having
|
Chris@16
|
83 // successfully parsed an optional sign)
|
Chris@16
|
84 //
|
Chris@16
|
85 // or
|
Chris@16
|
86 //
|
Chris@16
|
87 // - after a floating point number of the value 1 (having no
|
Chris@16
|
88 // exponential part and a fractional part value of 0) has been
|
Chris@16
|
89 // parsed.
|
Chris@16
|
90 //
|
Chris@16
|
91 // The first call allows to recognize representations of NaN or Inf
|
Chris@16
|
92 // starting with a non-digit character (such as NaN, Inf, QNaN etc.).
|
Chris@16
|
93 //
|
Chris@16
|
94 // The second call allows to recognize representation formats starting
|
Chris@16
|
95 // with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
|
Chris@16
|
96 //
|
Chris@16
|
97 // The functions should return true if a Nan or Inf has been found. In
|
Chris@16
|
98 // this case the attr should be set to the matched value (NaN or
|
Chris@16
|
99 // Inf). The optional sign will be automatically applied afterwards.
|
Chris@16
|
100 //
|
Chris@16
|
101 // The default implementation below recognizes representations of NaN
|
Chris@16
|
102 // and Inf as mandated by the C99 Standard and as proposed for
|
Chris@16
|
103 // inclusion into the C++0x Standard: nan, nan(...), inf and infinity
|
Chris@16
|
104 // (the matching is performed case-insensitively).
|
Chris@16
|
105 ///////////////////////////////////////////////////////////////////////
|
Chris@16
|
106 template <typename Iterator, typename Attribute>
|
Chris@16
|
107 static bool
|
Chris@16
|
108 parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
109 {
|
Chris@16
|
110 if (first == last)
|
Chris@16
|
111 return false; // end of input reached
|
Chris@16
|
112
|
Chris@16
|
113 if (*first != 'n' && *first != 'N')
|
Chris@16
|
114 return false; // not "nan"
|
Chris@16
|
115
|
Chris@16
|
116 // nan[(...)] ?
|
Chris@16
|
117 if (detail::string_parse("nan", "NAN", first, last, unused))
|
Chris@16
|
118 {
|
Chris@101
|
119 if (first != last && *first == '(')
|
Chris@16
|
120 {
|
Chris@16
|
121 // skip trailing (...) part
|
Chris@16
|
122 Iterator i = first;
|
Chris@16
|
123
|
Chris@16
|
124 while (++i != last && *i != ')')
|
Chris@16
|
125 ;
|
Chris@16
|
126 if (i == last)
|
Chris@16
|
127 return false; // no trailing ')' found, give up
|
Chris@16
|
128
|
Chris@16
|
129 first = ++i;
|
Chris@16
|
130 }
|
Chris@16
|
131 attr_ = std::numeric_limits<T>::quiet_NaN();
|
Chris@16
|
132 return true;
|
Chris@16
|
133 }
|
Chris@16
|
134 return false;
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 template <typename Iterator, typename Attribute>
|
Chris@16
|
138 static bool
|
Chris@16
|
139 parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
140 {
|
Chris@16
|
141 if (first == last)
|
Chris@16
|
142 return false; // end of input reached
|
Chris@16
|
143
|
Chris@16
|
144 if (*first != 'i' && *first != 'I')
|
Chris@16
|
145 return false; // not "inf"
|
Chris@16
|
146
|
Chris@16
|
147 // inf or infinity ?
|
Chris@16
|
148 if (detail::string_parse("inf", "INF", first, last, unused))
|
Chris@16
|
149 {
|
Chris@16
|
150 // skip allowed 'inity' part of infinity
|
Chris@16
|
151 detail::string_parse("inity", "INITY", first, last, unused);
|
Chris@16
|
152 attr_ = std::numeric_limits<T>::infinity();
|
Chris@16
|
153 return true;
|
Chris@16
|
154 }
|
Chris@16
|
155 return false;
|
Chris@16
|
156 }
|
Chris@16
|
157 };
|
Chris@16
|
158
|
Chris@16
|
159 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
160 // Default (signed) real number policies
|
Chris@16
|
161 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
162 template <typename T>
|
Chris@16
|
163 struct real_policies : ureal_policies<T>
|
Chris@16
|
164 {
|
Chris@16
|
165 template <typename Iterator>
|
Chris@16
|
166 static bool
|
Chris@16
|
167 parse_sign(Iterator& first, Iterator const& last)
|
Chris@16
|
168 {
|
Chris@16
|
169 return extract_sign(first, last);
|
Chris@16
|
170 }
|
Chris@16
|
171 };
|
Chris@16
|
172
|
Chris@16
|
173 template <typename T>
|
Chris@16
|
174 struct strict_ureal_policies : ureal_policies<T>
|
Chris@16
|
175 {
|
Chris@16
|
176 static bool const expect_dot = true;
|
Chris@16
|
177 };
|
Chris@16
|
178
|
Chris@16
|
179 template <typename T>
|
Chris@16
|
180 struct strict_real_policies : real_policies<T>
|
Chris@16
|
181 {
|
Chris@16
|
182 static bool const expect_dot = true;
|
Chris@16
|
183 };
|
Chris@16
|
184 }}}
|
Chris@16
|
185
|
Chris@16
|
186 #endif
|