Chris@16
|
1 // Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
2 //
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #if !defined(BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM)
|
Chris@16
|
7 #define BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM
|
Chris@16
|
8
|
Chris@16
|
9 #if defined(_MSC_VER)
|
Chris@16
|
10 #pragma once
|
Chris@16
|
11 #endif
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/limits.hpp>
|
Chris@16
|
14 #include <boost/config.hpp>
|
Chris@16
|
15 #include <boost/mpl/bool.hpp>
|
Chris@16
|
16 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/spirit/home/support/common_terminals.hpp>
|
Chris@16
|
19 #include <boost/spirit/home/support/string_traits.hpp>
|
Chris@16
|
20 #include <boost/spirit/home/support/numeric_traits.hpp>
|
Chris@16
|
21 #include <boost/spirit/home/support/info.hpp>
|
Chris@16
|
22 #include <boost/spirit/home/support/char_class.hpp>
|
Chris@16
|
23 #include <boost/spirit/home/support/container.hpp>
|
Chris@16
|
24 #include <boost/spirit/home/support/detail/get_encoding.hpp>
|
Chris@16
|
25 #include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
Chris@16
|
26 #include <boost/spirit/home/karma/meta_compiler.hpp>
|
Chris@16
|
27 #include <boost/spirit/home/karma/delimit_out.hpp>
|
Chris@16
|
28 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
|
Chris@16
|
29 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
|
Chris@16
|
30 #include <boost/spirit/home/karma/detail/extract_from.hpp>
|
Chris@16
|
31 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
|
Chris@16
|
32 #include <boost/spirit/home/karma/domain.hpp>
|
Chris@16
|
33 #include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
|
Chris@16
|
34 #include <boost/fusion/include/at.hpp>
|
Chris@16
|
35 #include <boost/fusion/include/value_at.hpp>
|
Chris@16
|
36 #include <boost/fusion/include/vector.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost { namespace spirit
|
Chris@16
|
39 {
|
Chris@16
|
40 namespace tag
|
Chris@16
|
41 {
|
Chris@16
|
42 template <typename T, unsigned Radix>
|
Chris@16
|
43 struct uint_generator
|
Chris@16
|
44 {
|
Chris@16
|
45 BOOST_SPIRIT_IS_TAG()
|
Chris@16
|
46 };
|
Chris@16
|
47 }
|
Chris@16
|
48
|
Chris@16
|
49 namespace karma
|
Chris@16
|
50 {
|
Chris@16
|
51 ///////////////////////////////////////////////////////////////////////
|
Chris@16
|
52 // This one is the class that the user can instantiate directly in
|
Chris@16
|
53 // order to create a customized int generator
|
Chris@16
|
54 template <typename T = unsigned int, unsigned Radix = 10>
|
Chris@16
|
55 struct uint_generator
|
Chris@16
|
56 : spirit::terminal<tag::uint_generator<T, Radix> >
|
Chris@16
|
57 {};
|
Chris@16
|
58 }
|
Chris@16
|
59
|
Chris@16
|
60 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
61 // Enablers
|
Chris@16
|
62 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
63 template <>
|
Chris@16
|
64 struct use_terminal<karma::domain, tag::ushort_> // enables ushort_
|
Chris@16
|
65 : mpl::true_ {};
|
Chris@16
|
66
|
Chris@16
|
67 template <>
|
Chris@16
|
68 struct use_terminal<karma::domain, tag::uint_> // enables uint_
|
Chris@16
|
69 : mpl::true_ {};
|
Chris@16
|
70
|
Chris@16
|
71 template <>
|
Chris@16
|
72 struct use_terminal<karma::domain, tag::ulong_> // enables ulong_
|
Chris@16
|
73 : mpl::true_ {};
|
Chris@16
|
74
|
Chris@16
|
75 template <>
|
Chris@16
|
76 struct use_terminal<karma::domain, tag::bin> // enables bin
|
Chris@16
|
77 : mpl::true_ {};
|
Chris@16
|
78
|
Chris@16
|
79 template <>
|
Chris@16
|
80 struct use_terminal<karma::domain, tag::oct> // enables oct
|
Chris@16
|
81 : mpl::true_ {};
|
Chris@16
|
82
|
Chris@16
|
83 template <>
|
Chris@16
|
84 struct use_terminal<karma::domain, tag::hex> // enables hex
|
Chris@16
|
85 : mpl::true_ {};
|
Chris@16
|
86
|
Chris@16
|
87 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
88 template <>
|
Chris@16
|
89 struct use_terminal<karma::domain, tag::ulong_long> // enables ulong_long
|
Chris@16
|
90 : mpl::true_ {};
|
Chris@16
|
91 #endif
|
Chris@16
|
92
|
Chris@16
|
93 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
94 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
Chris@16
|
95 template <> // enables lit(unsigned short(0))
|
Chris@16
|
96 struct use_terminal<karma::domain, unsigned short>
|
Chris@16
|
97 : mpl::true_ {};
|
Chris@16
|
98 #endif
|
Chris@16
|
99
|
Chris@16
|
100 template <> // enables lit(0U)
|
Chris@16
|
101 struct use_terminal<karma::domain, unsigned int>
|
Chris@16
|
102 : mpl::true_ {};
|
Chris@16
|
103
|
Chris@16
|
104 template <> // enables lit(0UL)
|
Chris@16
|
105 struct use_terminal<karma::domain, unsigned long>
|
Chris@16
|
106 : mpl::true_ {};
|
Chris@16
|
107
|
Chris@16
|
108 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
109 template <> // enables lit(0ULL)
|
Chris@16
|
110 struct use_terminal<karma::domain, boost::ulong_long_type>
|
Chris@16
|
111 : mpl::true_ {};
|
Chris@16
|
112 #endif
|
Chris@16
|
113
|
Chris@16
|
114 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
115 template <typename A0>
|
Chris@16
|
116 struct use_terminal<karma::domain // enables ushort_(...)
|
Chris@16
|
117 , terminal_ex<tag::ushort_, fusion::vector1<A0> >
|
Chris@16
|
118 > : mpl::true_ {};
|
Chris@16
|
119
|
Chris@16
|
120 template <typename A0>
|
Chris@16
|
121 struct use_terminal<karma::domain // enables uint_(...)
|
Chris@16
|
122 , terminal_ex<tag::uint_, fusion::vector1<A0> >
|
Chris@16
|
123 > : mpl::true_ {};
|
Chris@16
|
124
|
Chris@16
|
125 template <typename A0>
|
Chris@16
|
126 struct use_terminal<karma::domain // enables ulong_(...)
|
Chris@16
|
127 , terminal_ex<tag::ulong_, fusion::vector1<A0> >
|
Chris@16
|
128 > : mpl::true_ {};
|
Chris@16
|
129
|
Chris@16
|
130 template <typename A0>
|
Chris@16
|
131 struct use_terminal<karma::domain // enables bin(...)
|
Chris@16
|
132 , terminal_ex<tag::bin, fusion::vector1<A0> >
|
Chris@16
|
133 > : mpl::true_ {};
|
Chris@16
|
134
|
Chris@16
|
135 template <typename A0>
|
Chris@16
|
136 struct use_terminal<karma::domain // enables oct(...)
|
Chris@16
|
137 , terminal_ex<tag::oct, fusion::vector1<A0> >
|
Chris@16
|
138 > : mpl::true_ {};
|
Chris@16
|
139
|
Chris@16
|
140 template <typename A0>
|
Chris@16
|
141 struct use_terminal<karma::domain // enables hex(...)
|
Chris@16
|
142 , terminal_ex<tag::hex, fusion::vector1<A0> >
|
Chris@16
|
143 > : mpl::true_ {};
|
Chris@16
|
144
|
Chris@16
|
145 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
146 template <typename A0>
|
Chris@16
|
147 struct use_terminal<karma::domain // enables ulong_long(...)
|
Chris@16
|
148 , terminal_ex<tag::ulong_long, fusion::vector1<A0> >
|
Chris@16
|
149 > : mpl::true_ {};
|
Chris@16
|
150 #endif
|
Chris@16
|
151
|
Chris@16
|
152 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
153 template <> // enables *lazy* ushort_(...)
|
Chris@16
|
154 struct use_lazy_terminal<karma::domain, tag::ushort_, 1>
|
Chris@16
|
155 : mpl::true_ {};
|
Chris@16
|
156
|
Chris@16
|
157 template <> // enables *lazy* uint_(...)
|
Chris@16
|
158 struct use_lazy_terminal<karma::domain, tag::uint_, 1>
|
Chris@16
|
159 : mpl::true_ {};
|
Chris@16
|
160
|
Chris@16
|
161 template <> // enables *lazy* ulong_(...)
|
Chris@16
|
162 struct use_lazy_terminal<karma::domain, tag::ulong_, 1>
|
Chris@16
|
163 : mpl::true_ {};
|
Chris@16
|
164
|
Chris@16
|
165 template <> // enables *lazy* bin(...)
|
Chris@16
|
166 struct use_lazy_terminal<karma::domain, tag::bin, 1>
|
Chris@16
|
167 : mpl::true_ {};
|
Chris@16
|
168
|
Chris@16
|
169 template <> // enables *lazy* oct(...)
|
Chris@16
|
170 struct use_lazy_terminal<karma::domain, tag::oct, 1>
|
Chris@16
|
171 : mpl::true_ {};
|
Chris@16
|
172
|
Chris@16
|
173 template <> // enables *lazy* hex(...)
|
Chris@16
|
174 struct use_lazy_terminal<karma::domain, tag::hex, 1>
|
Chris@16
|
175 : mpl::true_ {};
|
Chris@16
|
176
|
Chris@16
|
177 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
178 template <> // enables *lazy* ulong_long(...)
|
Chris@16
|
179 struct use_lazy_terminal<karma::domain, tag::ulong_long, 1>
|
Chris@16
|
180 : mpl::true_ {};
|
Chris@16
|
181 #endif
|
Chris@16
|
182
|
Chris@16
|
183 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
184 // enables any custom uint_generator
|
Chris@16
|
185 template <typename T, unsigned Radix>
|
Chris@16
|
186 struct use_terminal<karma::domain, tag::uint_generator<T, Radix> >
|
Chris@16
|
187 : mpl::true_ {};
|
Chris@16
|
188
|
Chris@16
|
189 // enables any custom uint_generator(...)
|
Chris@16
|
190 template <typename T, unsigned Radix, typename A0>
|
Chris@16
|
191 struct use_terminal<karma::domain
|
Chris@16
|
192 , terminal_ex<tag::uint_generator<T, Radix>, fusion::vector1<A0> >
|
Chris@16
|
193 > : mpl::true_ {};
|
Chris@16
|
194
|
Chris@16
|
195 // enables *lazy* custom uint_generator
|
Chris@16
|
196 template <typename T, unsigned Radix>
|
Chris@16
|
197 struct use_lazy_terminal<
|
Chris@16
|
198 karma::domain
|
Chris@16
|
199 , tag::uint_generator<T, Radix>
|
Chris@16
|
200 , 1 // arity
|
Chris@16
|
201 > : mpl::true_ {};
|
Chris@16
|
202
|
Chris@16
|
203 // enables lit(uint)
|
Chris@16
|
204 template <typename A0>
|
Chris@16
|
205 struct use_terminal<karma::domain
|
Chris@16
|
206 , terminal_ex<tag::lit, fusion::vector1<A0> >
|
Chris@16
|
207 , typename enable_if<traits::is_uint<A0> >::type>
|
Chris@16
|
208 : mpl::true_ {};
|
Chris@16
|
209 }}
|
Chris@16
|
210
|
Chris@16
|
211 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
212 namespace boost { namespace spirit { namespace karma
|
Chris@16
|
213 {
|
Chris@16
|
214 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
215 using spirit::ushort_;
|
Chris@16
|
216 using spirit::uint_;
|
Chris@16
|
217 using spirit::ulong_;
|
Chris@16
|
218 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
219 using spirit::ulong_long;
|
Chris@16
|
220 #endif
|
Chris@16
|
221 using spirit::bin;
|
Chris@16
|
222 using spirit::oct;
|
Chris@16
|
223 using spirit::hex;
|
Chris@16
|
224
|
Chris@16
|
225 using spirit::lit; // lit(1U) is equivalent to 1U
|
Chris@16
|
226 #endif
|
Chris@16
|
227
|
Chris@16
|
228 using spirit::ushort_type;
|
Chris@16
|
229 using spirit::uint_type;
|
Chris@16
|
230 using spirit::ulong_type;
|
Chris@16
|
231 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
232 using spirit::ulong_long_type;
|
Chris@16
|
233 #endif
|
Chris@16
|
234 using spirit::bin_type;
|
Chris@16
|
235 using spirit::oct_type;
|
Chris@16
|
236 using spirit::hex_type;
|
Chris@16
|
237
|
Chris@16
|
238 using spirit::lit_type;
|
Chris@16
|
239
|
Chris@16
|
240 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
241 // This specialization is used for unsigned int generators not having a
|
Chris@16
|
242 // direct initializer: uint_, ulong_ etc. These generators must be used in
|
Chris@16
|
243 // conjunction with an Attribute.
|
Chris@16
|
244 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
245 template <typename T, typename CharEncoding, typename Tag, unsigned Radix>
|
Chris@16
|
246 struct any_uint_generator
|
Chris@16
|
247 : primitive_generator<any_uint_generator<T, CharEncoding, Tag, Radix> >
|
Chris@16
|
248 {
|
Chris@16
|
249 template <typename Context, typename Unused>
|
Chris@16
|
250 struct attribute
|
Chris@16
|
251 {
|
Chris@16
|
252 typedef T type;
|
Chris@16
|
253 };
|
Chris@16
|
254
|
Chris@16
|
255 // check template Attribute 'Radix' for validity
|
Chris@16
|
256 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
257 Radix >= 2 && Radix <= 36, not_supported_radix, ());
|
Chris@16
|
258
|
Chris@16
|
259 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
260 // the following is a workaround for STLPort, where the simpler
|
Chris@16
|
261 // `!std::numeric_limits<T>::is_signed` wouldn't compile
|
Chris@16
|
262 mpl::not_<mpl::bool_<std::numeric_limits<T>::is_signed> >::value,
|
Chris@16
|
263 signed_unsigned_mismatch, ());
|
Chris@16
|
264
|
Chris@16
|
265 // int has a Attribute attached
|
Chris@16
|
266 template <typename OutputIterator, typename Context, typename Delimiter
|
Chris@16
|
267 , typename Attribute>
|
Chris@16
|
268 static bool
|
Chris@16
|
269 generate(OutputIterator& sink, Context& context, Delimiter const& d
|
Chris@16
|
270 , Attribute const& attr)
|
Chris@16
|
271 {
|
Chris@16
|
272 if (!traits::has_optional_value(attr))
|
Chris@16
|
273 return false; // fail if it's an uninitialized optional
|
Chris@16
|
274
|
Chris@16
|
275 return uint_inserter<Radix, CharEncoding, Tag>::
|
Chris@16
|
276 call(sink, traits::extract_from<T>(attr, context)) &&
|
Chris@16
|
277 delimit_out(sink, d); // always do post-delimiting
|
Chris@16
|
278 }
|
Chris@16
|
279
|
Chris@16
|
280 // this int has no Attribute attached, it needs to have been
|
Chris@16
|
281 // initialized from a direct literal
|
Chris@16
|
282 template <typename OutputIterator, typename Context, typename Delimiter>
|
Chris@16
|
283 static bool
|
Chris@16
|
284 generate(OutputIterator&, Context&, Delimiter const&, unused_type)
|
Chris@16
|
285 {
|
Chris@16
|
286 // It is not possible (doesn't make sense) to use numeric generators
|
Chris@16
|
287 // without providing any attribute, as the generator doesn't 'know'
|
Chris@16
|
288 // what to output. The following assertion fires if this situation
|
Chris@16
|
289 // is detected in your code.
|
Chris@16
|
290 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, uint_not_usable_without_attribute, ());
|
Chris@16
|
291 return false;
|
Chris@16
|
292 }
|
Chris@16
|
293
|
Chris@16
|
294 template <typename Context>
|
Chris@16
|
295 static info what(Context const& /*context*/)
|
Chris@16
|
296 {
|
Chris@16
|
297 return info("unsigned-integer");
|
Chris@16
|
298 }
|
Chris@16
|
299 };
|
Chris@16
|
300
|
Chris@16
|
301 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
302 // This specialization is used for unsigned int generators having a direct
|
Chris@16
|
303 // initializer: uint_(10), ulong_(20) etc.
|
Chris@16
|
304 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
305 template <
|
Chris@16
|
306 typename T, typename CharEncoding, typename Tag, unsigned Radix
|
Chris@16
|
307 , bool no_attribute>
|
Chris@16
|
308 struct literal_uint_generator
|
Chris@16
|
309 : primitive_generator<literal_uint_generator<T, CharEncoding, Tag, Radix
|
Chris@16
|
310 , no_attribute> >
|
Chris@16
|
311 {
|
Chris@16
|
312 template <typename Context, typename Unused = unused_type>
|
Chris@16
|
313 struct attribute
|
Chris@16
|
314 : mpl::if_c<no_attribute, unused_type, T>
|
Chris@16
|
315 {};
|
Chris@16
|
316
|
Chris@16
|
317 literal_uint_generator(typename add_const<T>::type n)
|
Chris@16
|
318 : n_(n) {}
|
Chris@16
|
319
|
Chris@16
|
320 // check template Attribute 'Radix' for validity
|
Chris@16
|
321 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
322 Radix >= 2 && Radix <= 36, not_supported_radix, ());
|
Chris@16
|
323
|
Chris@16
|
324 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
325 // the following is a workaround for STLPort, where the simpler
|
Chris@16
|
326 // `!std::numeric_limits<T>::is_signed wouldn't` compile
|
Chris@16
|
327 mpl::not_<mpl::bool_<std::numeric_limits<T>::is_signed> >::value,
|
Chris@16
|
328 signed_unsigned_mismatch, ());
|
Chris@16
|
329
|
Chris@16
|
330 // A uint(1U) which additionally has an associated attribute emits
|
Chris@16
|
331 // its immediate literal only if it matches the attribute, otherwise
|
Chris@16
|
332 // it fails.
|
Chris@16
|
333 template <typename OutputIterator, typename Context, typename Delimiter
|
Chris@16
|
334 , typename Attribute>
|
Chris@16
|
335 bool generate(OutputIterator& sink, Context& context
|
Chris@16
|
336 , Delimiter const& d, Attribute const& attr) const
|
Chris@16
|
337 {
|
Chris@16
|
338 typedef typename attribute<Context>::type attribute_type;
|
Chris@16
|
339 if (!traits::has_optional_value(attr) ||
|
Chris@16
|
340 n_ != traits::extract_from<attribute_type>(attr, context))
|
Chris@16
|
341 {
|
Chris@16
|
342 return false;
|
Chris@16
|
343 }
|
Chris@16
|
344 return uint_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
|
Chris@16
|
345 delimit_out(sink, d); // always do post-delimiting
|
Chris@16
|
346 }
|
Chris@16
|
347
|
Chris@16
|
348 // A uint(1U) without any associated attribute just emits its
|
Chris@16
|
349 // immediate literal
|
Chris@16
|
350 template <typename OutputIterator, typename Context, typename Delimiter>
|
Chris@16
|
351 bool generate(OutputIterator& sink, Context&, Delimiter const& d
|
Chris@16
|
352 , unused_type) const
|
Chris@16
|
353 {
|
Chris@16
|
354 return uint_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
|
Chris@16
|
355 delimit_out(sink, d); // always do post-delimiting
|
Chris@16
|
356 }
|
Chris@16
|
357
|
Chris@16
|
358 template <typename Context>
|
Chris@16
|
359 static info what(Context const& /*context*/)
|
Chris@16
|
360 {
|
Chris@16
|
361 return info("unsigned-integer");
|
Chris@16
|
362 }
|
Chris@16
|
363
|
Chris@16
|
364 T n_;
|
Chris@16
|
365 };
|
Chris@16
|
366
|
Chris@16
|
367 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
368 // Generator generators: make_xxx function (objects)
|
Chris@16
|
369 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
370 namespace detail
|
Chris@16
|
371 {
|
Chris@16
|
372 template <typename T, typename Modifiers, unsigned Radix = 10>
|
Chris@16
|
373 struct make_uint
|
Chris@16
|
374 {
|
Chris@16
|
375 static bool const lower =
|
Chris@16
|
376 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
|
Chris@16
|
377 static bool const upper =
|
Chris@16
|
378 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
|
Chris@16
|
379
|
Chris@16
|
380 typedef any_uint_generator<
|
Chris@16
|
381 T
|
Chris@16
|
382 , typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
383 Modifiers, unused_type, lower || upper>::type
|
Chris@16
|
384 , typename detail::get_casetag<Modifiers, lower || upper>::type
|
Chris@16
|
385 , Radix
|
Chris@16
|
386 > result_type;
|
Chris@16
|
387
|
Chris@16
|
388 result_type operator()(unused_type, unused_type) const
|
Chris@16
|
389 {
|
Chris@16
|
390 return result_type();
|
Chris@16
|
391 }
|
Chris@16
|
392 };
|
Chris@16
|
393 }
|
Chris@16
|
394
|
Chris@16
|
395 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
396 template <typename Modifiers>
|
Chris@16
|
397 struct make_primitive<tag::ushort_, Modifiers>
|
Chris@16
|
398 : detail::make_uint<unsigned short, Modifiers> {};
|
Chris@16
|
399
|
Chris@16
|
400 template <typename Modifiers>
|
Chris@16
|
401 struct make_primitive<tag::uint_, Modifiers>
|
Chris@16
|
402 : detail::make_uint<unsigned int, Modifiers> {};
|
Chris@16
|
403
|
Chris@16
|
404 template <typename Modifiers>
|
Chris@16
|
405 struct make_primitive<tag::ulong_, Modifiers>
|
Chris@16
|
406 : detail::make_uint<unsigned long, Modifiers> {};
|
Chris@16
|
407
|
Chris@16
|
408 template <typename Modifiers>
|
Chris@16
|
409 struct make_primitive<tag::bin, Modifiers>
|
Chris@16
|
410 : detail::make_uint<unsigned, Modifiers, 2> {};
|
Chris@16
|
411
|
Chris@16
|
412 template <typename Modifiers>
|
Chris@16
|
413 struct make_primitive<tag::oct, Modifiers>
|
Chris@16
|
414 : detail::make_uint<unsigned, Modifiers, 8> {};
|
Chris@16
|
415
|
Chris@16
|
416 template <typename Modifiers>
|
Chris@16
|
417 struct make_primitive<tag::hex, Modifiers>
|
Chris@16
|
418 : detail::make_uint<unsigned, Modifiers, 16> {};
|
Chris@16
|
419
|
Chris@16
|
420 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
421 template <typename Modifiers>
|
Chris@16
|
422 struct make_primitive<tag::ulong_long, Modifiers>
|
Chris@16
|
423 : detail::make_uint<boost::ulong_long_type, Modifiers> {};
|
Chris@16
|
424 #endif
|
Chris@16
|
425
|
Chris@16
|
426 template <typename T, unsigned Radix, typename Modifiers>
|
Chris@16
|
427 struct make_primitive<tag::uint_generator<T, Radix>, Modifiers>
|
Chris@16
|
428 : detail::make_uint<typename remove_const<T>::type, Modifiers, Radix> {};
|
Chris@16
|
429
|
Chris@16
|
430 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
431 namespace detail
|
Chris@16
|
432 {
|
Chris@16
|
433 template <typename T, typename Modifiers, unsigned Radix = 10>
|
Chris@16
|
434 struct make_uint_direct
|
Chris@16
|
435 {
|
Chris@16
|
436 static bool const lower =
|
Chris@16
|
437 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
|
Chris@16
|
438 static bool const upper =
|
Chris@16
|
439 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
|
Chris@16
|
440
|
Chris@16
|
441 typedef literal_uint_generator<
|
Chris@16
|
442 T
|
Chris@16
|
443 , typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
444 Modifiers, unused_type, lower || upper>::type
|
Chris@16
|
445 , typename detail::get_casetag<Modifiers, lower || upper>::type
|
Chris@16
|
446 , Radix, false
|
Chris@16
|
447 > result_type;
|
Chris@16
|
448
|
Chris@16
|
449 template <typename Terminal>
|
Chris@16
|
450 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
451 {
|
Chris@16
|
452 return result_type(fusion::at_c<0>(term.args));
|
Chris@16
|
453 }
|
Chris@16
|
454 };
|
Chris@16
|
455 }
|
Chris@16
|
456
|
Chris@16
|
457 template <typename Modifiers, typename A0>
|
Chris@16
|
458 struct make_primitive<
|
Chris@16
|
459 terminal_ex<tag::ushort_, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
460 : detail::make_uint_direct<unsigned short, Modifiers> {};
|
Chris@16
|
461
|
Chris@16
|
462 template <typename Modifiers, typename A0>
|
Chris@16
|
463 struct make_primitive<
|
Chris@16
|
464 terminal_ex<tag::uint_, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
465 : detail::make_uint_direct<unsigned int, Modifiers> {};
|
Chris@16
|
466
|
Chris@16
|
467 template <typename Modifiers, typename A0>
|
Chris@16
|
468 struct make_primitive<
|
Chris@16
|
469 terminal_ex<tag::ulong_, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
470 : detail::make_uint_direct<unsigned long, Modifiers> {};
|
Chris@16
|
471
|
Chris@16
|
472 template <typename Modifiers, typename A0>
|
Chris@16
|
473 struct make_primitive<
|
Chris@16
|
474 terminal_ex<tag::bin, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
475 : detail::make_uint_direct<unsigned, Modifiers, 2> {};
|
Chris@16
|
476
|
Chris@16
|
477 template <typename Modifiers, typename A0>
|
Chris@16
|
478 struct make_primitive<
|
Chris@16
|
479 terminal_ex<tag::oct, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
480 : detail::make_uint_direct<unsigned, Modifiers, 8> {};
|
Chris@16
|
481
|
Chris@16
|
482 template <typename Modifiers, typename A0>
|
Chris@16
|
483 struct make_primitive<
|
Chris@16
|
484 terminal_ex<tag::hex, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
485 : detail::make_uint_direct<unsigned, Modifiers, 16> {};
|
Chris@16
|
486
|
Chris@16
|
487 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
488 template <typename Modifiers, typename A0>
|
Chris@16
|
489 struct make_primitive<
|
Chris@16
|
490 terminal_ex<tag::ulong_long, fusion::vector1<A0> >, Modifiers>
|
Chris@16
|
491 : detail::make_uint_direct<boost::ulong_long_type, Modifiers> {};
|
Chris@16
|
492 #endif
|
Chris@16
|
493
|
Chris@16
|
494 template <typename T, unsigned Radix, typename A0, typename Modifiers>
|
Chris@16
|
495 struct make_primitive<
|
Chris@16
|
496 terminal_ex<tag::uint_generator<T, Radix>, fusion::vector1<A0> >
|
Chris@16
|
497 , Modifiers>
|
Chris@16
|
498 : detail::make_uint_direct<typename remove_const<T>::type, Modifiers, Radix>
|
Chris@16
|
499 {};
|
Chris@16
|
500
|
Chris@16
|
501 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
502 namespace detail
|
Chris@16
|
503 {
|
Chris@16
|
504 template <typename T, typename Modifiers>
|
Chris@16
|
505 struct basic_uint_literal
|
Chris@16
|
506 {
|
Chris@16
|
507 static bool const lower =
|
Chris@16
|
508 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
|
Chris@16
|
509 static bool const upper =
|
Chris@16
|
510 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
|
Chris@16
|
511
|
Chris@16
|
512 typedef literal_uint_generator<
|
Chris@16
|
513 T
|
Chris@16
|
514 , typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
515 Modifiers, unused_type, lower || upper>::type
|
Chris@16
|
516 , typename detail::get_casetag<Modifiers, lower || upper>::type
|
Chris@16
|
517 , 10, true
|
Chris@16
|
518 > result_type;
|
Chris@16
|
519
|
Chris@16
|
520 template <typename T_>
|
Chris@16
|
521 result_type operator()(T_ i, unused_type) const
|
Chris@16
|
522 {
|
Chris@16
|
523 return result_type(i);
|
Chris@16
|
524 }
|
Chris@16
|
525 };
|
Chris@16
|
526 }
|
Chris@16
|
527
|
Chris@16
|
528 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
Chris@16
|
529 template <typename Modifiers>
|
Chris@16
|
530 struct make_primitive<unsigned short, Modifiers>
|
Chris@16
|
531 : detail::basic_uint_literal<unsigned short, Modifiers> {};
|
Chris@16
|
532 #endif
|
Chris@16
|
533
|
Chris@16
|
534 template <typename Modifiers>
|
Chris@16
|
535 struct make_primitive<unsigned int, Modifiers>
|
Chris@16
|
536 : detail::basic_uint_literal<unsigned int, Modifiers> {};
|
Chris@16
|
537
|
Chris@16
|
538 template <typename Modifiers>
|
Chris@16
|
539 struct make_primitive<unsigned long, Modifiers>
|
Chris@16
|
540 : detail::basic_uint_literal<unsigned long, Modifiers> {};
|
Chris@16
|
541
|
Chris@16
|
542 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
543 template <typename Modifiers>
|
Chris@16
|
544 struct make_primitive<boost::ulong_long_type, Modifiers>
|
Chris@16
|
545 : detail::basic_uint_literal<boost::ulong_long_type, Modifiers> {};
|
Chris@16
|
546 #endif
|
Chris@16
|
547
|
Chris@16
|
548 // lit(uint)
|
Chris@16
|
549 template <typename Modifiers, typename A0>
|
Chris@16
|
550 struct make_primitive<
|
Chris@16
|
551 terminal_ex<tag::lit, fusion::vector1<A0> >
|
Chris@16
|
552 , Modifiers
|
Chris@16
|
553 , typename enable_if<traits::is_uint<A0> >::type>
|
Chris@16
|
554 {
|
Chris@16
|
555 static bool const lower =
|
Chris@16
|
556 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
|
Chris@16
|
557 static bool const upper =
|
Chris@16
|
558 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
|
Chris@16
|
559
|
Chris@16
|
560 typedef literal_uint_generator<
|
Chris@16
|
561 typename remove_const<A0>::type
|
Chris@16
|
562 , typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
563 Modifiers, unused_type, lower || upper>::type
|
Chris@16
|
564 , typename detail::get_casetag<Modifiers, lower || upper>::type
|
Chris@16
|
565 , 10, true
|
Chris@16
|
566 > result_type;
|
Chris@16
|
567
|
Chris@16
|
568 template <typename Terminal>
|
Chris@16
|
569 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
570 {
|
Chris@16
|
571 return result_type(fusion::at_c<0>(term.args));
|
Chris@16
|
572 }
|
Chris@16
|
573 };
|
Chris@16
|
574 }}}
|
Chris@16
|
575
|
Chris@16
|
576 #endif
|