source: NonGTP/Boost/boost/spirit/core/primitives/numerics.hpp @ 857

Revision 857, 9.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 1998-2003 Joel de Guzman
3    Copyright (c) 2001-2003 Hartmut Kaiser
4    http://spirit.sourceforge.net/
5
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
12
13#include <boost/config.hpp>
14#include <boost/spirit/core/parser.hpp>
15#include <boost/spirit/core/composite/directives.hpp>
16#include <boost/spirit/core/primitives/impl/numerics.ipp>
17
18namespace boost { namespace spirit
19{
20    ///////////////////////////////////////////////////////////////////////////
21    //
22    //  uint_parser class
23    //
24    ///////////////////////////////////////////////////////////////////////////
25    template <
26        typename T = unsigned,
27        int Radix = 10,
28        unsigned MinDigits = 1,
29        int MaxDigits = -1
30    >
31    struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
32    {
33        typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
34   
35        template <typename ScannerT>
36        struct result
37        {
38            typedef typename match_result<ScannerT, T>::type type;
39        };
40       
41        template <typename ScannerT>
42        typename parser_result<self_t, ScannerT>::type
43        parse(ScannerT const& scan) const
44        {
45            typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
46            typedef typename parser_result<impl_t, ScannerT>::type result_t;
47            return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
48        }
49    };
50   
51    ///////////////////////////////////////////////////////////////////////////
52    //
53    //  int_parser class
54    //
55    ///////////////////////////////////////////////////////////////////////////
56    template <
57        typename T = unsigned,
58        int Radix = 10,
59        unsigned MinDigits = 1,
60        int MaxDigits = -1
61    >
62    struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
63    {
64        typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
65   
66        template <typename ScannerT>
67        struct result
68        {
69            typedef typename match_result<ScannerT, T>::type type;
70        };
71       
72        template <typename ScannerT>
73        typename parser_result<self_t, ScannerT>::type
74        parse(ScannerT const& scan) const
75        {
76            typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
77            typedef typename parser_result<impl_t, ScannerT>::type result_t;
78            return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
79        }
80    };
81   
82    ///////////////////////////////////////////////////////////////////////////
83    //
84    //  uint_parser/int_parser instantiations
85    //
86    ///////////////////////////////////////////////////////////////////////////
87    int_parser<int> const
88        int_p   = int_parser<int>();
89   
90    uint_parser<unsigned> const
91        uint_p  = uint_parser<unsigned>();
92   
93    uint_parser<unsigned, 2> const
94        bin_p   = uint_parser<unsigned, 2>();
95   
96    uint_parser<unsigned, 8> const
97        oct_p   = uint_parser<unsigned, 8>();
98   
99    uint_parser<unsigned, 16> const
100        hex_p   = uint_parser<unsigned, 16>();
101   
102    ///////////////////////////////////////////////////////////////////////////
103    //
104    //  sign_parser class
105    //
106    ///////////////////////////////////////////////////////////////////////////
107    namespace impl
108    {
109        //  Utility to extract the prefix sign ('-' | '+')
110        template <typename ScannerT>
111        bool extract_sign(ScannerT const& scan, std::size_t& count);
112    }
113   
114    struct sign_parser : public parser<sign_parser>
115    {
116        typedef sign_parser self_t;
117
118        template <typename ScannerT>
119        struct result
120        {
121            typedef typename match_result<ScannerT, bool>::type type;
122        };
123
124        sign_parser() {}
125   
126        template <typename ScannerT>
127        typename parser_result<self_t, ScannerT>::type
128        parse(ScannerT const& scan) const
129        {
130            if (!scan.at_end())
131            {
132                std::size_t length;
133                typename ScannerT::iterator_t save(scan.first);
134                bool neg = impl::extract_sign(scan, length);
135                if (length)
136                    return scan.create_match(1, neg, save, scan.first);
137            }
138            return scan.no_match();
139        }
140    };
141   
142    sign_parser const sign_p = sign_parser();
143   
144    ///////////////////////////////////////////////////////////////////////////
145    //
146    //  default real number policies
147    //
148    ///////////////////////////////////////////////////////////////////////////
149    template <typename T>
150    struct ureal_parser_policies
151    {
152        // trailing dot policy suggested suggested by Gustavo Guerra
153        BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
154        BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
155        BOOST_STATIC_CONSTANT(bool, expect_dot = false);
156   
157        typedef uint_parser<T, 10, 1, -1>   uint_parser_t;
158        typedef int_parser<T, 10, 1, -1>    int_parser_t;
159   
160        template <typename ScannerT>
161        static typename match_result<ScannerT, nil_t>::type
162        parse_sign(ScannerT& scan)
163        {
164            return scan.no_match();
165        }
166   
167        template <typename ScannerT>
168        static typename parser_result<uint_parser_t, ScannerT>::type
169        parse_n(ScannerT& scan)
170        {
171            return uint_parser_t().parse(scan);
172        }
173   
174        template <typename ScannerT>
175        static typename parser_result<chlit<>, ScannerT>::type
176        parse_dot(ScannerT& scan)
177        {
178            return ch_p('.').parse(scan);
179        }
180   
181        template <typename ScannerT>
182        static typename parser_result<uint_parser_t, ScannerT>::type
183        parse_frac_n(ScannerT& scan)
184        {
185            return uint_parser_t().parse(scan);
186        }
187   
188        template <typename ScannerT>
189        static typename parser_result<chlit<>, ScannerT>::type
190        parse_exp(ScannerT& scan)
191        {
192            return as_lower_d['e'].parse(scan);
193        }
194   
195        template <typename ScannerT>
196        static typename parser_result<int_parser_t, ScannerT>::type
197        parse_exp_n(ScannerT& scan)
198        {
199            return int_parser_t().parse(scan);
200        }
201    };
202   
203    template <typename T>
204    struct real_parser_policies : public ureal_parser_policies<T>
205    {
206        template <typename ScannerT>
207        static typename parser_result<sign_parser, ScannerT>::type
208        parse_sign(ScannerT& scan)
209        {
210            return sign_p.parse(scan);
211        }
212    };
213   
214    ///////////////////////////////////////////////////////////////////////////
215    //
216    //  real_parser class
217    //
218    ///////////////////////////////////////////////////////////////////////////
219    template <
220        typename T = double,
221        typename RealPoliciesT = ureal_parser_policies<T>
222    >
223    struct real_parser
224    :   public parser<real_parser<T, RealPoliciesT> >
225    {
226        typedef real_parser<T, RealPoliciesT> self_t;
227   
228        template <typename ScannerT>
229        struct result
230        {
231            typedef typename match_result<ScannerT, T>::type type;
232        };
233   
234        real_parser() {}
235   
236        template <typename ScannerT>
237        typename parser_result<self_t, ScannerT>::type
238        parse(ScannerT const& scan) const
239        {
240            typedef typename parser_result<self_t, ScannerT>::type result_t;
241            return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
242        }
243    };
244   
245    ///////////////////////////////////////////////////////////////////////////
246    //
247    //  real_parser instantiations
248    //
249    ///////////////////////////////////////////////////////////////////////////
250    real_parser<double, ureal_parser_policies<double> > const
251        ureal_p     = real_parser<double, ureal_parser_policies<double> >();
252   
253    real_parser<double, real_parser_policies<double> > const
254        real_p      = real_parser<double, real_parser_policies<double> >();
255   
256    ///////////////////////////////////////////////////////////////////////////
257    //
258    //  strict reals (do not allow plain integers (no decimal point))
259    //
260    ///////////////////////////////////////////////////////////////////////////
261    template <typename T>
262    struct strict_ureal_parser_policies : public ureal_parser_policies<T>
263    {
264        BOOST_STATIC_CONSTANT(bool, expect_dot = true);
265    };
266   
267    template <typename T>
268    struct strict_real_parser_policies : public real_parser_policies<T>
269    {
270        BOOST_STATIC_CONSTANT(bool, expect_dot = true);
271    };
272   
273    real_parser<double, strict_ureal_parser_policies<double> > const
274        strict_ureal_p
275            = real_parser<double, strict_ureal_parser_policies<double> >();
276   
277    real_parser<double, strict_real_parser_policies<double> > const
278        strict_real_p
279            = real_parser<double, strict_real_parser_policies<double> >();
280   
281}} // namespace boost::spirit
282
283#endif
Note: See TracBrowser for help on using the repository browser.