Improve vacpp support.
[boost.git] / boost / boost / spirit / core / primitives / numerics.hpp
blob58e552aabaa2f67213e76d75b92c75ebb71f9aff
1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2001-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #ifndef BOOST_SPIRIT_NUMERICS_HPP
11 #define BOOST_SPIRIT_NUMERICS_HPP
13 #include <boost/config.hpp>
14 #include <boost/spirit/core/parser.hpp>
15 #include <boost/spirit/core/composite/directives.hpp>
17 #include <boost/spirit/core/primitives/numerics_fwd.hpp>
18 #include <boost/spirit/core/primitives/impl/numerics.ipp>
20 namespace boost { namespace spirit
22 ///////////////////////////////////////////////////////////////////////////
24 // uint_parser class
26 ///////////////////////////////////////////////////////////////////////////
27 template <
28 typename T,
29 int Radix,
30 unsigned MinDigits,
31 int MaxDigits
33 struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
35 typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
37 template <typename ScannerT>
38 struct result
40 typedef typename match_result<ScannerT, T>::type type;
43 template <typename ScannerT>
44 typename parser_result<self_t, ScannerT>::type
45 parse(ScannerT const& scan) const
47 typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
48 typedef typename parser_result<impl_t, ScannerT>::type result_t;
49 return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
53 ///////////////////////////////////////////////////////////////////////////
55 // int_parser class
57 ///////////////////////////////////////////////////////////////////////////
58 template <
59 typename T,
60 int Radix,
61 unsigned MinDigits,
62 int MaxDigits
64 struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
66 typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
68 template <typename ScannerT>
69 struct result
71 typedef typename match_result<ScannerT, T>::type type;
74 template <typename ScannerT>
75 typename parser_result<self_t, ScannerT>::type
76 parse(ScannerT const& scan) const
78 typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
79 typedef typename parser_result<impl_t, ScannerT>::type result_t;
80 return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
84 ///////////////////////////////////////////////////////////////////////////
86 // uint_parser/int_parser instantiations
88 ///////////////////////////////////////////////////////////////////////////
89 int_parser<int> const
90 int_p = int_parser<int>();
92 uint_parser<unsigned> const
93 uint_p = uint_parser<unsigned>();
95 uint_parser<unsigned, 2> const
96 bin_p = uint_parser<unsigned, 2>();
98 uint_parser<unsigned, 8> const
99 oct_p = uint_parser<unsigned, 8>();
101 uint_parser<unsigned, 16> const
102 hex_p = uint_parser<unsigned, 16>();
104 ///////////////////////////////////////////////////////////////////////////
106 // sign_parser class
108 ///////////////////////////////////////////////////////////////////////////
109 namespace impl
111 // Utility to extract the prefix sign ('-' | '+')
112 template <typename ScannerT>
113 bool extract_sign(ScannerT const& scan, std::size_t& count);
116 struct sign_parser : public parser<sign_parser>
118 typedef sign_parser self_t;
120 template <typename ScannerT>
121 struct result
123 typedef typename match_result<ScannerT, bool>::type type;
126 sign_parser() {}
128 template <typename ScannerT>
129 typename parser_result<self_t, ScannerT>::type
130 parse(ScannerT const& scan) const
132 if (!scan.at_end())
134 std::size_t length;
135 typename ScannerT::iterator_t save(scan.first);
136 bool neg = impl::extract_sign(scan, length);
137 if (length)
138 return scan.create_match(1, neg, save, scan.first);
140 return scan.no_match();
144 sign_parser const sign_p = sign_parser();
146 ///////////////////////////////////////////////////////////////////////////
148 // default real number policies
150 ///////////////////////////////////////////////////////////////////////////
151 template <typename T>
152 struct ureal_parser_policies
154 // trailing dot policy suggested suggested by Gustavo Guerra
155 BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
156 BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
157 BOOST_STATIC_CONSTANT(bool, expect_dot = false);
159 typedef uint_parser<T, 10, 1, -1> uint_parser_t;
160 typedef int_parser<T, 10, 1, -1> int_parser_t;
162 template <typename ScannerT>
163 static typename match_result<ScannerT, nil_t>::type
164 parse_sign(ScannerT& scan)
166 return scan.no_match();
169 template <typename ScannerT>
170 static typename parser_result<uint_parser_t, ScannerT>::type
171 parse_n(ScannerT& scan)
173 return uint_parser_t().parse(scan);
176 template <typename ScannerT>
177 static typename parser_result<chlit<>, ScannerT>::type
178 parse_dot(ScannerT& scan)
180 return ch_p('.').parse(scan);
183 template <typename ScannerT>
184 static typename parser_result<uint_parser_t, ScannerT>::type
185 parse_frac_n(ScannerT& scan)
187 return uint_parser_t().parse(scan);
190 template <typename ScannerT>
191 static typename parser_result<chlit<>, ScannerT>::type
192 parse_exp(ScannerT& scan)
194 return as_lower_d['e'].parse(scan);
197 template <typename ScannerT>
198 static typename parser_result<int_parser_t, ScannerT>::type
199 parse_exp_n(ScannerT& scan)
201 return int_parser_t().parse(scan);
205 template <typename T>
206 struct real_parser_policies : public ureal_parser_policies<T>
208 template <typename ScannerT>
209 static typename parser_result<sign_parser, ScannerT>::type
210 parse_sign(ScannerT& scan)
212 return sign_p.parse(scan);
216 ///////////////////////////////////////////////////////////////////////////
218 // real_parser class
220 ///////////////////////////////////////////////////////////////////////////
221 template <
222 typename T,
223 typename RealPoliciesT
225 struct real_parser
226 : public parser<real_parser<T, RealPoliciesT> >
228 typedef real_parser<T, RealPoliciesT> self_t;
230 template <typename ScannerT>
231 struct result
233 typedef typename match_result<ScannerT, T>::type type;
236 real_parser() {}
238 template <typename ScannerT>
239 typename parser_result<self_t, ScannerT>::type
240 parse(ScannerT const& scan) const
242 typedef typename parser_result<self_t, ScannerT>::type result_t;
243 return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
247 ///////////////////////////////////////////////////////////////////////////
249 // real_parser instantiations
251 ///////////////////////////////////////////////////////////////////////////
252 real_parser<double, ureal_parser_policies<double> > const
253 ureal_p = real_parser<double, ureal_parser_policies<double> >();
255 real_parser<double, real_parser_policies<double> > const
256 real_p = real_parser<double, real_parser_policies<double> >();
258 ///////////////////////////////////////////////////////////////////////////
260 // strict reals (do not allow plain integers (no decimal point))
262 ///////////////////////////////////////////////////////////////////////////
263 template <typename T>
264 struct strict_ureal_parser_policies : public ureal_parser_policies<T>
266 BOOST_STATIC_CONSTANT(bool, expect_dot = true);
269 template <typename T>
270 struct strict_real_parser_policies : public real_parser_policies<T>
272 BOOST_STATIC_CONSTANT(bool, expect_dot = true);
275 real_parser<double, strict_ureal_parser_policies<double> > const
276 strict_ureal_p
277 = real_parser<double, strict_ureal_parser_policies<double> >();
279 real_parser<double, strict_real_parser_policies<double> > const
280 strict_real_p
281 = real_parser<double, strict_real_parser_policies<double> >();
283 }} // namespace boost::spirit
285 #endif