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