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