]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/qi/numeric/uint.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / qi / numeric / uint.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2011 Bryce Lelbach
4 Copyright (c) 2011 Jan Frederick Eick
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(SPIRIT_UINT_APR_17_2006_0901AM)
10 #define SPIRIT_UINT_APR_17_2006_0901AM
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/spirit/home/qi/skip_over.hpp>
17 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
18 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
19 #include <boost/spirit/home/qi/meta_compiler.hpp>
20 #include <boost/spirit/home/qi/parser.hpp>
21 #include <boost/spirit/home/support/common_terminals.hpp>
22 #include <boost/spirit/home/support/info.hpp>
23 #include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
24 #include <boost/mpl/assert.hpp>
25 #include <boost/type_traits/is_same.hpp>
26
27 namespace boost { namespace spirit
28 {
29 namespace tag
30 {
31 template <typename T, unsigned Radix, unsigned MinDigits
32 , int MaxDigits>
33 struct uint_parser
34 {
35 BOOST_SPIRIT_IS_TAG()
36 };
37 }
38
39 namespace qi
40 {
41 ///////////////////////////////////////////////////////////////////////
42 // This one is the class that the user can instantiate directly in
43 // order to create a customized int parser
44 template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
45 , int MaxDigits = -1>
46 struct uint_parser
47 : spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
48 {};
49 }
50
51 ///////////////////////////////////////////////////////////////////////////
52 // Enablers
53 ///////////////////////////////////////////////////////////////////////////
54 template <> // enables ushort_
55 struct use_terminal<qi::domain, tag::ushort_> : mpl::true_ {};
56
57 template <typename A0> // enables lit(n)
58 struct use_terminal<qi::domain
59 , terminal_ex<tag::lit, fusion::vector1<A0> >
60 , typename enable_if<is_same<A0, unsigned short> >::type>
61 : mpl::true_ {};
62
63 template <typename A0> // enables ushort_(n)
64 struct use_terminal<qi::domain
65 , terminal_ex<tag::ushort_, fusion::vector1<A0> > >
66 : is_arithmetic<A0> {};
67
68 template <> // enables *lazy* ushort_(n)
69 struct use_lazy_terminal<qi::domain, tag::ushort_, 1> : mpl::true_ {};
70
71 ///////////////////////////////////////////////////////////////////////////
72 template <> // enables uint_
73 struct use_terminal<qi::domain, tag::uint_> : mpl::true_ {};
74
75 template <typename A0> // enables lit(n)
76 struct use_terminal<qi::domain
77 , terminal_ex<tag::lit, fusion::vector1<A0> >
78 , typename enable_if<is_same<A0, unsigned> >::type>
79 : mpl::true_ {};
80
81 template <typename A0> // enables uint_(n)
82 struct use_terminal<qi::domain
83 , terminal_ex<tag::uint_, fusion::vector1<A0> > >
84 : is_arithmetic<A0> {};
85
86 template <> // enables *lazy* uint_(n)
87 struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
88
89 ///////////////////////////////////////////////////////////////////////////
90 template <> // enables ulong_
91 struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
92
93 template <typename A0> // enables lit(n)
94 struct use_terminal<qi::domain
95 , terminal_ex<tag::lit, fusion::vector1<A0> >
96 , typename enable_if<is_same<A0, unsigned long> >::type>
97 : mpl::true_ {};
98
99 template <typename A0> // enables ulong_(n)
100 struct use_terminal<qi::domain
101 , terminal_ex<tag::ulong_, fusion::vector1<A0> > >
102 : is_arithmetic<A0> {};
103
104 template <> // enables *lazy* ulong_(n)
105 struct use_lazy_terminal<qi::domain, tag::ulong_, 1> : mpl::true_ {};
106
107 ///////////////////////////////////////////////////////////////////////////
108 #ifdef BOOST_HAS_LONG_LONG
109 template <> // enables ulong_long
110 struct use_terminal<qi::domain, tag::ulong_long> : mpl::true_ {};
111
112 template <typename A0> // enables lit(n)
113 struct use_terminal<qi::domain
114 , terminal_ex<tag::lit, fusion::vector1<A0> >
115 , typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
116 : mpl::true_ {};
117
118 template <typename A0> // enables ulong_long(n)
119 struct use_terminal<qi::domain
120 , terminal_ex<tag::ulong_long, fusion::vector1<A0> > >
121 : is_arithmetic<A0> {};
122
123 template <> // enables *lazy* ulong_long(n)
124 struct use_lazy_terminal<qi::domain, tag::ulong_long, 1> : mpl::true_ {};
125 #endif
126
127 ///////////////////////////////////////////////////////////////////////////
128 template <> // enables bin
129 struct use_terminal<qi::domain, tag::bin> : mpl::true_ {};
130
131 template <typename A0> // enables bin(n)
132 struct use_terminal<qi::domain
133 , terminal_ex<tag::bin, fusion::vector1<A0> > >
134 : is_arithmetic<A0> {};
135
136 template <> // enables *lazy* bin(n)
137 struct use_lazy_terminal<qi::domain, tag::bin, 1> : mpl::true_ {};
138
139 ///////////////////////////////////////////////////////////////////////////
140 template <> // enables oct
141 struct use_terminal<qi::domain, tag::oct> : mpl::true_ {};
142
143 template <typename A0> // enables oct(n)
144 struct use_terminal<qi::domain
145 , terminal_ex<tag::oct, fusion::vector1<A0> > >
146 : is_arithmetic<A0> {};
147
148 template <> // enables *lazy* oct(n)
149 struct use_lazy_terminal<qi::domain, tag::oct, 1> : mpl::true_ {};
150
151 ///////////////////////////////////////////////////////////////////////////
152 template <> // enables hex
153 struct use_terminal<qi::domain, tag::hex> : mpl::true_ {};
154
155 template <typename A0> // enables hex(n)
156 struct use_terminal<qi::domain
157 , terminal_ex<tag::hex, fusion::vector1<A0> > >
158 : is_arithmetic<A0> {};
159
160 template <> // enables *lazy* hex(n)
161 struct use_lazy_terminal<qi::domain, tag::hex, 1> : mpl::true_ {};
162
163 ///////////////////////////////////////////////////////////////////////////
164 // enables any custom uint_parser
165 template <typename T, unsigned Radix, unsigned MinDigits
166 , int MaxDigits>
167 struct use_terminal<qi::domain
168 , tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
169 : mpl::true_ {};
170
171 // enables any custom uint_parser(n)
172 template <typename T, unsigned Radix, unsigned MinDigits
173 , int MaxDigits, typename A0>
174 struct use_terminal<qi::domain
175 , terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
176 , fusion::vector1<A0> >
177 > : mpl::true_ {};
178
179 // enables *lazy* custom uint_parser(n)
180 template <typename T, unsigned Radix, unsigned MinDigits
181 , int MaxDigits>
182 struct use_lazy_terminal<qi::domain
183 , tag::uint_parser<T, Radix, MinDigits, MaxDigits>, 1
184 > : mpl::true_ {};
185 }}
186
187 namespace boost { namespace spirit { namespace qi
188 {
189 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
190 using spirit::bin;
191 using spirit::oct;
192 using spirit::hex;
193
194 using spirit::ushort_;
195 using spirit::uint_;
196 using spirit::ulong_;
197 #ifdef BOOST_HAS_LONG_LONG
198 using spirit::ulong_long;
199 #endif
200 using spirit::lit; // lit(1) is equivalent to 1
201 #endif
202
203 using spirit::bin_type;
204 using spirit::oct_type;
205 using spirit::hex_type;
206
207 using spirit::ushort_type;
208 using spirit::uint_type;
209 using spirit::ulong_type;
210 #ifdef BOOST_HAS_LONG_LONG
211 using spirit::ulong_long_type;
212 #endif
213 using spirit::lit_type;
214
215 ///////////////////////////////////////////////////////////////////////////
216 // This is the actual uint parser
217 ///////////////////////////////////////////////////////////////////////////
218 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
219 , int MaxDigits = -1>
220 struct any_uint_parser
221 : primitive_parser<any_uint_parser<T, Radix, MinDigits, MaxDigits> >
222 {
223 // check template parameter 'Radix' for validity
224 BOOST_SPIRIT_ASSERT_MSG(
225 Radix >= 2 && Radix <= 36,
226 not_supported_radix, ());
227
228 template <typename Context, typename Iterator>
229 struct attribute
230 {
231 typedef T type;
232 };
233
234 template <typename Iterator, typename Context
235 , typename Skipper, typename Attribute>
236 bool parse(Iterator& first, Iterator const& last
237 , Context& /*context*/, Skipper const& skipper
238 , Attribute& attr_) const
239 {
240 typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
241 qi::skip_over(first, last, skipper);
242 return extract::call(first, last, attr_);
243 }
244
245 template <typename Context>
246 info what(Context& /*context*/) const
247 {
248 return info("unsigned-integer");
249 }
250 };
251 //]
252
253 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
254 , int MaxDigits = -1, bool no_attribute = true>
255 struct literal_uint_parser
256 : primitive_parser<literal_uint_parser<T, Radix, MinDigits, MaxDigits
257 , no_attribute> >
258 {
259 // check template parameter 'Radix' for validity
260 BOOST_SPIRIT_ASSERT_MSG(
261 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
262 not_supported_radix, ());
263
264 template <typename Value>
265 literal_uint_parser(Value const& n) : n_(n) {}
266
267 template <typename Context, typename Iterator>
268 struct attribute
269 : mpl::if_c<no_attribute, unused_type, T>
270 {};
271
272 template <typename Iterator, typename Context
273 , typename Skipper, typename Attribute>
274 bool parse(Iterator& first, Iterator const& last
275 , Context& /*context*/, Skipper const& skipper
276 , Attribute& attr_param) const
277 {
278 typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
279 qi::skip_over(first, last, skipper);
280
281 Iterator save = first;
282 T attr_;
283
284 if (extract::call(first, last, attr_) && (attr_ == n_))
285 {
286 traits::assign_to(attr_, attr_param);
287 return true;
288 }
289
290 first = save;
291 return false;
292 }
293
294 template <typename Context>
295 info what(Context& /*context*/) const
296 {
297 return info("unsigned-integer");
298 }
299
300 T n_;
301 };
302
303 ///////////////////////////////////////////////////////////////////////////
304 // Parser generators: make_xxx function (objects)
305 ///////////////////////////////////////////////////////////////////////////
306 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
307 , int MaxDigits = -1>
308 struct make_uint
309 {
310 typedef any_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
311 result_type operator()(unused_type, unused_type) const
312 {
313 return result_type();
314 }
315 };
316
317 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
318 , int MaxDigits = -1>
319 struct make_direct_uint
320 {
321 typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits, false>
322 result_type;
323 template <typename Terminal>
324 result_type operator()(Terminal const& term, unused_type) const
325 {
326 return result_type(fusion::at_c<0>(term.args));
327 }
328 };
329
330 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
331 , int MaxDigits = -1>
332 struct make_literal_uint
333 {
334 typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
335 template <typename Terminal>
336 result_type operator()(Terminal const& term, unused_type) const
337 {
338 return result_type(fusion::at_c<0>(term.args));
339 }
340 };
341
342 ///////////////////////////////////////////////////////////////////////////
343 template <typename Modifiers, typename A0>
344 struct make_primitive<
345 terminal_ex<tag::lit, fusion::vector1<A0> >
346 , Modifiers, typename enable_if<is_same<A0, unsigned short> >::type>
347 : make_literal_uint<unsigned short> {};
348
349 template <typename Modifiers, typename A0>
350 struct make_primitive<
351 terminal_ex<tag::lit, fusion::vector1<A0> >
352 , Modifiers, typename enable_if<is_same<A0, unsigned> >::type>
353 : make_literal_uint<unsigned> {};
354
355 template <typename Modifiers, typename A0>
356 struct make_primitive<
357 terminal_ex<tag::lit, fusion::vector1<A0> >
358 , Modifiers, typename enable_if<is_same<A0, unsigned long> >::type>
359 : make_literal_uint<unsigned long> {};
360
361 #ifdef BOOST_HAS_LONG_LONG
362 template <typename Modifiers, typename A0>
363 struct make_primitive<
364 terminal_ex<tag::lit, fusion::vector1<A0> >
365 , Modifiers, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
366 : make_literal_uint<boost::ulong_long_type> {};
367 #endif
368
369 ///////////////////////////////////////////////////////////////////////////
370 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
371 , typename Modifiers>
372 struct make_primitive<
373 tag::uint_parser<T, Radix, MinDigits, MaxDigits>
374 , Modifiers>
375 : make_uint<T, Radix, MinDigits, MaxDigits> {};
376
377 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
378 , typename A0, typename Modifiers>
379 struct make_primitive<
380 terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
381 , fusion::vector1<A0> >, Modifiers>
382 : make_direct_uint<T, Radix, MinDigits, MaxDigits> {};
383
384 ///////////////////////////////////////////////////////////////////////////
385 template <typename Modifiers>
386 struct make_primitive<tag::bin, Modifiers>
387 : make_uint<unsigned, 2> {};
388
389 template <typename Modifiers, typename A0>
390 struct make_primitive<
391 terminal_ex<tag::bin
392 , fusion::vector1<A0> > , Modifiers>
393 : make_direct_uint<unsigned, 2> {};
394
395 ///////////////////////////////////////////////////////////////////////////
396 template <typename Modifiers>
397 struct make_primitive<tag::oct, Modifiers>
398 : make_uint<unsigned, 8> {};
399
400 template <typename Modifiers, typename A0>
401 struct make_primitive<
402 terminal_ex<tag::oct
403 , fusion::vector1<A0> > , Modifiers>
404 : make_direct_uint<unsigned, 8> {};
405
406 ///////////////////////////////////////////////////////////////////////////
407 template <typename Modifiers>
408 struct make_primitive<tag::hex, Modifiers>
409 : make_uint<unsigned, 16> {};
410
411 template <typename Modifiers, typename A0>
412 struct make_primitive<
413 terminal_ex<tag::hex
414 , fusion::vector1<A0> > , Modifiers>
415 : make_direct_uint<unsigned, 16> {};
416
417 ///////////////////////////////////////////////////////////////////////////
418 template <typename Modifiers>
419 struct make_primitive<tag::ushort_, Modifiers>
420 : make_uint<unsigned short> {};
421
422 template <typename Modifiers, typename A0>
423 struct make_primitive<
424 terminal_ex<tag::ushort_
425 , fusion::vector1<A0> > , Modifiers>
426 : make_direct_uint<unsigned short> {};
427
428 ///////////////////////////////////////////////////////////////////////////
429 template <typename Modifiers>
430 struct make_primitive<tag::uint_, Modifiers>
431 : make_uint<unsigned> {};
432
433 template <typename Modifiers, typename A0>
434 struct make_primitive<
435 terminal_ex<tag::uint_
436 , fusion::vector1<A0> > , Modifiers>
437 : make_direct_uint<unsigned> {};
438
439 ///////////////////////////////////////////////////////////////////////////
440 template <typename Modifiers>
441 struct make_primitive<tag::ulong_, Modifiers>
442 : make_uint<unsigned long> {};
443
444 template <typename Modifiers, typename A0>
445 struct make_primitive<
446 terminal_ex<tag::ulong_
447 , fusion::vector1<A0> > , Modifiers>
448 : make_direct_uint<unsigned long> {};
449
450 ///////////////////////////////////////////////////////////////////////////
451 #ifdef BOOST_HAS_LONG_LONG
452 template <typename Modifiers>
453 struct make_primitive<tag::ulong_long, Modifiers>
454 : make_uint<boost::ulong_long_type> {};
455
456 template <typename Modifiers, typename A0>
457 struct make_primitive<
458 terminal_ex<tag::ulong_long
459 , fusion::vector1<A0> > , Modifiers>
460 : make_direct_uint<boost::ulong_long_type> {};
461 #endif
462 }}}
463
464 #endif