comparison DEPENDENCIES/generic/include/boost/spirit/home/qi/numeric/int.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2011 Bryce Lelbach
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_INT_APR_17_2006_0830AM)
9 #define BOOST_SPIRIT_INT_APR_17_2006_0830AM
10
11 #if defined(_MSC_VER)
12 #pragma once
13 #endif
14
15 #include <boost/spirit/home/qi/skip_over.hpp>
16 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
17 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
18 #include <boost/spirit/home/qi/meta_compiler.hpp>
19 #include <boost/spirit/home/qi/parser.hpp>
20 #include <boost/spirit/home/support/common_terminals.hpp>
21 #include <boost/spirit/home/support/info.hpp>
22 #include <boost/mpl/assert.hpp>
23 #include <boost/type_traits/is_same.hpp>
24
25 namespace boost { namespace spirit
26 {
27 namespace tag
28 {
29 template <typename T, unsigned Radix, unsigned MinDigits
30 , int MaxDigits>
31 struct int_parser {};
32 }
33
34 namespace qi
35 {
36 ///////////////////////////////////////////////////////////////////////
37 // This one is the class that the user can instantiate directly in
38 // order to create a customized int parser
39 template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
40 , int MaxDigits = -1>
41 struct int_parser
42 : spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
43 {};
44 }
45
46 ///////////////////////////////////////////////////////////////////////////
47 // Enablers
48 ///////////////////////////////////////////////////////////////////////////
49 //[primitive_parsers_enable_short
50 template <> // enables short_
51 struct use_terminal<qi::domain, tag::short_> : mpl::true_ {};
52 //]
53
54 template <typename A0> // enables lit(n)
55 struct use_terminal<qi::domain
56 , terminal_ex<tag::lit, fusion::vector1<A0> >
57 , typename enable_if<is_same<A0, signed short> >::type>
58 : mpl::true_ {};
59
60 template <typename A0> // enables short_(n)
61 struct use_terminal<qi::domain
62 , terminal_ex<tag::short_, fusion::vector1<A0> > >
63 : is_arithmetic<A0> {};
64
65 template <> // enables *lazy* short_(n)
66 struct use_lazy_terminal<qi::domain, tag::short_, 1> : mpl::true_ {};
67
68 ///////////////////////////////////////////////////////////////////////////
69 //[primitive_parsers_enable_int
70 template <> // enables int_
71 struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
72 //]
73
74 template <typename A0> // enables lit(n)
75 struct use_terminal<qi::domain
76 , terminal_ex<tag::lit, fusion::vector1<A0> >
77 , typename enable_if<is_same<A0, signed> >::type>
78 : mpl::true_ {};
79
80 template <typename A0> // enables int_(n)
81 struct use_terminal<qi::domain
82 , terminal_ex<tag::int_, fusion::vector1<A0> > >
83 : is_arithmetic<A0> {};
84
85 template <> // enables *lazy* int_(n)
86 struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
87
88 ///////////////////////////////////////////////////////////////////////////
89 //[primitive_parsers_enable_long
90 template <> // enables long_
91 struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
92 //]
93
94 template <typename A0> // enables lit(n)
95 struct use_terminal<qi::domain
96 , terminal_ex<tag::lit, fusion::vector1<A0> >
97 , typename enable_if<is_same<A0, signed long> >::type>
98 : mpl::true_ {};
99
100 template <typename A0> // enables long_(n)
101 struct use_terminal<qi::domain
102 , terminal_ex<tag::long_, fusion::vector1<A0> > >
103 : is_arithmetic<A0> {};
104
105 template <> // enables *lazy* long_(n)
106 struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
107
108 ///////////////////////////////////////////////////////////////////////////
109 #ifdef BOOST_HAS_LONG_LONG
110 //[primitive_parsers_enable_long_long
111 template <> // enables long_long
112 struct use_terminal<qi::domain, tag::long_long> : mpl::true_ {};
113 //]
114
115 template <typename A0> // enables lit(n)
116 struct use_terminal<qi::domain
117 , terminal_ex<tag::lit, fusion::vector1<A0> >
118 , typename enable_if<is_same<A0, boost::long_long_type> >::type>
119 : mpl::true_ {};
120
121 template <typename A0> // enables long_long(n)
122 struct use_terminal<qi::domain
123 , terminal_ex<tag::long_long, fusion::vector1<A0> > >
124 : is_arithmetic<A0> {};
125
126 template <> // enables *lazy* long_long(n)
127 struct use_lazy_terminal<qi::domain, tag::long_long, 1> : mpl::true_ {};
128 #endif
129
130 ///////////////////////////////////////////////////////////////////////////
131 // enables any custom int_parser
132 template <typename T, unsigned Radix, unsigned MinDigits
133 , int MaxDigits>
134 struct use_terminal<qi::domain
135 , tag::int_parser<T, Radix, MinDigits, MaxDigits> >
136 : mpl::true_ {};
137
138 // enables any custom int_parser(n)
139 template <typename T, unsigned Radix, unsigned MinDigits
140 , int MaxDigits, typename A0>
141 struct use_terminal<qi::domain
142 , terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
143 , fusion::vector1<A0> >
144 > : mpl::true_ {};
145
146 // enables *lazy* custom int_parser(n)
147 template <typename T, unsigned Radix, unsigned MinDigits
148 , int MaxDigits>
149 struct use_lazy_terminal<qi::domain
150 , tag::int_parser<T, Radix, MinDigits, MaxDigits>, 1
151 > : mpl::true_ {};
152 }}
153
154 namespace boost { namespace spirit { namespace qi
155 {
156 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
157 using spirit::short_;
158 using spirit::int_;
159 using spirit::long_;
160 #ifdef BOOST_HAS_LONG_LONG
161 using spirit::long_long;
162 #endif
163 using spirit::lit; // lit(1) is equivalent to 1
164 #endif
165 using spirit::short_type;
166 using spirit::int_type;
167 using spirit::long_type;
168 using spirit::lit_type;
169 #ifdef BOOST_HAS_LONG_LONG
170 using spirit::long_long_type;
171 #endif
172 using spirit::lit_type;
173
174 ///////////////////////////////////////////////////////////////////////////
175 // This is the actual int parser
176 ///////////////////////////////////////////////////////////////////////////
177 //[primitive_parsers_int_parser
178 template <
179 typename T
180 , unsigned Radix = 10
181 , unsigned MinDigits = 1
182 , int MaxDigits = -1>
183 struct any_int_parser
184 : primitive_parser<any_int_parser<T, Radix, MinDigits, MaxDigits> >
185 {
186 // check template parameter 'Radix' for validity
187 BOOST_SPIRIT_ASSERT_MSG(
188 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
189 not_supported_radix, ());
190
191 template <typename Context, typename Iterator>
192 struct attribute
193 {
194 typedef T type;
195 };
196
197 template <typename Iterator, typename Context
198 , typename Skipper, typename Attribute>
199 bool parse(Iterator& first, Iterator const& last
200 , Context& /*context*/, Skipper const& skipper
201 , Attribute& attr_) const
202 {
203 typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
204 qi::skip_over(first, last, skipper);
205 return extract::call(first, last, attr_);
206 }
207
208 template <typename Context>
209 info what(Context& /*context*/) const
210 {
211 return info("integer");
212 }
213 };
214 //]
215
216 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
217 , int MaxDigits = -1, bool no_attribute = true>
218 struct literal_int_parser
219 : primitive_parser<literal_int_parser<T, Radix, MinDigits, MaxDigits
220 , no_attribute> >
221 {
222 // check template parameter 'Radix' for validity
223 BOOST_SPIRIT_ASSERT_MSG(
224 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
225 not_supported_radix, ());
226
227 template <typename Value>
228 literal_int_parser(Value const& n) : n_(n) {}
229
230 template <typename Context, typename Iterator>
231 struct attribute
232 : mpl::if_c<no_attribute, unused_type, T>
233 {};
234
235 template <typename Iterator, typename Context
236 , typename Skipper, typename Attribute>
237 bool parse(Iterator& first, Iterator const& last
238 , Context& /*context*/, Skipper const& skipper
239 , Attribute& attr_param) const
240 {
241 typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
242 qi::skip_over(first, last, skipper);
243
244 Iterator save = first;
245 T attr_;
246
247 if (extract::call(first, last, attr_) && (attr_ == n_))
248 {
249 traits::assign_to(attr_, attr_param);
250 return true;
251 }
252
253 first = save;
254 return false;
255 }
256
257 template <typename Context>
258 info what(Context& /*context*/) const
259 {
260 return info("integer");
261 }
262
263 T n_;
264 };
265
266 ///////////////////////////////////////////////////////////////////////////
267 // Parser generators: make_xxx function (objects)
268 ///////////////////////////////////////////////////////////////////////////
269 //[primitive_parsers_make_int
270 template <
271 typename T
272 , unsigned Radix = 10
273 , unsigned MinDigits = 1
274 , int MaxDigits = -1>
275 struct make_int
276 {
277 typedef any_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
278 result_type operator()(unused_type, unused_type) const
279 {
280 return result_type();
281 }
282 };
283 //]
284
285 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
286 , int MaxDigits = -1>
287 struct make_direct_int
288 {
289 typedef literal_int_parser<T, Radix, MinDigits, MaxDigits, false>
290 result_type;
291 template <typename Terminal>
292 result_type operator()(Terminal const& term, unused_type) const
293 {
294 return result_type(fusion::at_c<0>(term.args));
295 }
296 };
297
298 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
299 , int MaxDigits = -1>
300 struct make_literal_int
301 {
302 typedef literal_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
303 template <typename Terminal>
304 result_type operator()(Terminal const& term, unused_type) const
305 {
306 return result_type(fusion::at_c<0>(term.args));
307 }
308 };
309
310 ///////////////////////////////////////////////////////////////////////////
311 template <typename Modifiers, typename A0>
312 struct make_primitive<
313 terminal_ex<tag::lit, fusion::vector1<A0> >
314 , Modifiers, typename enable_if<is_same<A0, signed short> >::type>
315 : make_literal_int<signed short> {};
316
317 template <typename Modifiers, typename A0>
318 struct make_primitive<
319 terminal_ex<tag::lit, fusion::vector1<A0> >
320 , Modifiers, typename enable_if<is_same<A0, signed> >::type>
321 : make_literal_int<signed> {};
322
323 template <typename Modifiers, typename A0>
324 struct make_primitive<
325 terminal_ex<tag::lit, fusion::vector1<A0> >
326 , Modifiers, typename enable_if<is_same<A0, signed long> >::type>
327 : make_literal_int<signed long> {};
328
329 #ifdef BOOST_HAS_LONG_LONG
330 template <typename Modifiers, typename A0>
331 struct make_primitive<
332 terminal_ex<tag::lit, fusion::vector1<A0> >
333 , Modifiers, typename enable_if<is_same<A0, boost::long_long_type> >::type>
334 : make_literal_int<boost::long_long_type> {};
335 #endif
336
337 ///////////////////////////////////////////////////////////////////////////
338 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
339 , typename Modifiers>
340 struct make_primitive<
341 tag::int_parser<T, Radix, MinDigits, MaxDigits>
342 , Modifiers>
343 : make_int<T, Radix, MinDigits, MaxDigits> {};
344
345 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
346 , typename A0, typename Modifiers>
347 struct make_primitive<
348 terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
349 , fusion::vector1<A0> >, Modifiers>
350 : make_direct_int<T, Radix, MinDigits, MaxDigits> {};
351
352 ///////////////////////////////////////////////////////////////////////////
353 //[primitive_parsers_short_primitive
354 template <typename Modifiers>
355 struct make_primitive<tag::short_, Modifiers>
356 : make_int<short> {};
357 //]
358
359 template <typename Modifiers, typename A0>
360 struct make_primitive<
361 terminal_ex<tag::short_
362 , fusion::vector1<A0> > , Modifiers>
363 : make_direct_int<short> {};
364
365 ///////////////////////////////////////////////////////////////////////////
366 //[primitive_parsers_int_primitive
367 template <typename Modifiers>
368 struct make_primitive<tag::int_, Modifiers>
369 : make_int<int> {};
370 //]
371
372 template <typename Modifiers, typename A0>
373 struct make_primitive<
374 terminal_ex<tag::int_
375 , fusion::vector1<A0> > , Modifiers>
376 : make_direct_int<int> {};
377
378 ///////////////////////////////////////////////////////////////////////////
379 //[primitive_parsers_long_primitive
380 template <typename Modifiers>
381 struct make_primitive<tag::long_, Modifiers>
382 : make_int<long> {};
383 //]
384
385 template <typename Modifiers, typename A0>
386 struct make_primitive<
387 terminal_ex<tag::long_
388 , fusion::vector1<A0> > , Modifiers>
389 : make_direct_int<long> {};
390
391 ///////////////////////////////////////////////////////////////////////////
392 #ifdef BOOST_HAS_LONG_LONG
393 //[primitive_parsers_long_long_primitive
394 template <typename Modifiers>
395 struct make_primitive<tag::long_long, Modifiers>
396 : make_int<boost::long_long_type> {};
397 //]
398
399 template <typename Modifiers, typename A0>
400 struct make_primitive<
401 terminal_ex<tag::long_long
402 , fusion::vector1<A0> > , Modifiers>
403 : make_direct_int<boost::long_long_type> {};
404 #endif
405 }}}
406
407 #endif