File indexing completed on 2025-01-19 09:47:38
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM)
0007 #define BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/limits.hpp>
0014 #include <boost/config.hpp>
0015 #include <boost/mpl/bool.hpp>
0016 #include <boost/utility/enable_if.hpp>
0017
0018 #include <boost/spirit/home/support/common_terminals.hpp>
0019 #include <boost/spirit/home/support/string_traits.hpp>
0020 #include <boost/spirit/home/support/numeric_traits.hpp>
0021 #include <boost/spirit/home/support/info.hpp>
0022 #include <boost/spirit/home/support/char_class.hpp>
0023 #include <boost/spirit/home/support/container.hpp>
0024 #include <boost/spirit/home/support/detail/get_encoding.hpp>
0025 #include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
0026 #include <boost/spirit/home/karma/meta_compiler.hpp>
0027 #include <boost/spirit/home/karma/delimit_out.hpp>
0028 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0029 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0030 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0031 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
0032 #include <boost/spirit/home/karma/domain.hpp>
0033 #include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
0034 #include <boost/fusion/include/at.hpp>
0035 #include <boost/fusion/include/value_at.hpp>
0036 #include <boost/fusion/include/vector.hpp>
0037
0038 namespace boost { namespace spirit
0039 {
0040 namespace tag
0041 {
0042 template <typename T, unsigned Radix>
0043 struct uint_generator
0044 {
0045 BOOST_SPIRIT_IS_TAG()
0046 };
0047 }
0048
0049 namespace karma
0050 {
0051
0052
0053
0054 template <typename T = unsigned int, unsigned Radix = 10>
0055 struct uint_generator
0056 : spirit::terminal<tag::uint_generator<T, Radix> >
0057 {};
0058 }
0059
0060
0061
0062
0063 template <>
0064 struct use_terminal<karma::domain, tag::ushort_>
0065 : mpl::true_ {};
0066
0067 template <>
0068 struct use_terminal<karma::domain, tag::uint_>
0069 : mpl::true_ {};
0070
0071 template <>
0072 struct use_terminal<karma::domain, tag::ulong_>
0073 : mpl::true_ {};
0074
0075 template <>
0076 struct use_terminal<karma::domain, tag::bin>
0077 : mpl::true_ {};
0078
0079 template <>
0080 struct use_terminal<karma::domain, tag::oct>
0081 : mpl::true_ {};
0082
0083 template <>
0084 struct use_terminal<karma::domain, tag::hex>
0085 : mpl::true_ {};
0086
0087 #ifdef BOOST_HAS_LONG_LONG
0088 template <>
0089 struct use_terminal<karma::domain, tag::ulong_long>
0090 : mpl::true_ {};
0091 #endif
0092
0093
0094 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0095 template <>
0096 struct use_terminal<karma::domain, unsigned short>
0097 : mpl::true_ {};
0098 #endif
0099
0100 template <>
0101 struct use_terminal<karma::domain, unsigned int>
0102 : mpl::true_ {};
0103
0104 template <>
0105 struct use_terminal<karma::domain, unsigned long>
0106 : mpl::true_ {};
0107
0108 #ifdef BOOST_HAS_LONG_LONG
0109 template <>
0110 struct use_terminal<karma::domain, boost::ulong_long_type>
0111 : mpl::true_ {};
0112 #endif
0113
0114
0115 template <typename A0>
0116 struct use_terminal<karma::domain
0117 , terminal_ex<tag::ushort_, fusion::vector1<A0> >
0118 > : mpl::true_ {};
0119
0120 template <typename A0>
0121 struct use_terminal<karma::domain
0122 , terminal_ex<tag::uint_, fusion::vector1<A0> >
0123 > : mpl::true_ {};
0124
0125 template <typename A0>
0126 struct use_terminal<karma::domain
0127 , terminal_ex<tag::ulong_, fusion::vector1<A0> >
0128 > : mpl::true_ {};
0129
0130 template <typename A0>
0131 struct use_terminal<karma::domain
0132 , terminal_ex<tag::bin, fusion::vector1<A0> >
0133 > : mpl::true_ {};
0134
0135 template <typename A0>
0136 struct use_terminal<karma::domain
0137 , terminal_ex<tag::oct, fusion::vector1<A0> >
0138 > : mpl::true_ {};
0139
0140 template <typename A0>
0141 struct use_terminal<karma::domain
0142 , terminal_ex<tag::hex, fusion::vector1<A0> >
0143 > : mpl::true_ {};
0144
0145 #ifdef BOOST_HAS_LONG_LONG
0146 template <typename A0>
0147 struct use_terminal<karma::domain
0148 , terminal_ex<tag::ulong_long, fusion::vector1<A0> >
0149 > : mpl::true_ {};
0150 #endif
0151
0152
0153 template <>
0154 struct use_lazy_terminal<karma::domain, tag::ushort_, 1>
0155 : mpl::true_ {};
0156
0157 template <>
0158 struct use_lazy_terminal<karma::domain, tag::uint_, 1>
0159 : mpl::true_ {};
0160
0161 template <>
0162 struct use_lazy_terminal<karma::domain, tag::ulong_, 1>
0163 : mpl::true_ {};
0164
0165 template <>
0166 struct use_lazy_terminal<karma::domain, tag::bin, 1>
0167 : mpl::true_ {};
0168
0169 template <>
0170 struct use_lazy_terminal<karma::domain, tag::oct, 1>
0171 : mpl::true_ {};
0172
0173 template <>
0174 struct use_lazy_terminal<karma::domain, tag::hex, 1>
0175 : mpl::true_ {};
0176
0177 #ifdef BOOST_HAS_LONG_LONG
0178 template <>
0179 struct use_lazy_terminal<karma::domain, tag::ulong_long, 1>
0180 : mpl::true_ {};
0181 #endif
0182
0183
0184
0185 template <typename T, unsigned Radix>
0186 struct use_terminal<karma::domain, tag::uint_generator<T, Radix> >
0187 : mpl::true_ {};
0188
0189
0190 template <typename T, unsigned Radix, typename A0>
0191 struct use_terminal<karma::domain
0192 , terminal_ex<tag::uint_generator<T, Radix>, fusion::vector1<A0> >
0193 > : mpl::true_ {};
0194
0195
0196 template <typename T, unsigned Radix>
0197 struct use_lazy_terminal<
0198 karma::domain
0199 , tag::uint_generator<T, Radix>
0200 , 1
0201 > : mpl::true_ {};
0202
0203
0204 template <typename A0>
0205 struct use_terminal<karma::domain
0206 , terminal_ex<tag::lit, fusion::vector1<A0> >
0207 , typename enable_if<traits::is_uint<A0> >::type>
0208 : mpl::true_ {};
0209 }}
0210
0211
0212 namespace boost { namespace spirit { namespace karma
0213 {
0214 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0215 using spirit::ushort_;
0216 using spirit::uint_;
0217 using spirit::ulong_;
0218 #ifdef BOOST_HAS_LONG_LONG
0219 using spirit::ulong_long;
0220 #endif
0221 using spirit::bin;
0222 using spirit::oct;
0223 using spirit::hex;
0224
0225 using spirit::lit;
0226 #endif
0227
0228 using spirit::ushort_type;
0229 using spirit::uint_type;
0230 using spirit::ulong_type;
0231 #ifdef BOOST_HAS_LONG_LONG
0232 using spirit::ulong_long_type;
0233 #endif
0234 using spirit::bin_type;
0235 using spirit::oct_type;
0236 using spirit::hex_type;
0237
0238 using spirit::lit_type;
0239
0240
0241
0242
0243
0244
0245 template <typename T, typename CharEncoding, typename Tag, unsigned Radix>
0246 struct any_uint_generator
0247 : primitive_generator<any_uint_generator<T, CharEncoding, Tag, Radix> >
0248 {
0249 template <typename Context, typename Unused>
0250 struct attribute
0251 {
0252 typedef T type;
0253 };
0254
0255
0256 BOOST_SPIRIT_ASSERT_MSG(
0257 Radix >= 2 && Radix <= 36, not_supported_radix, ());
0258
0259 BOOST_SPIRIT_ASSERT_MSG(
0260
0261
0262 mpl::not_<mpl::bool_<std::numeric_limits<T>::is_signed> >::value,
0263 signed_unsigned_mismatch, ());
0264
0265
0266 template <typename OutputIterator, typename Context, typename Delimiter
0267 , typename Attribute>
0268 static bool
0269 generate(OutputIterator& sink, Context& context, Delimiter const& d
0270 , Attribute const& attr)
0271 {
0272 if (!traits::has_optional_value(attr))
0273 return false;
0274
0275 return uint_inserter<Radix, CharEncoding, Tag>::
0276 call(sink, traits::extract_from<T>(attr, context)) &&
0277 delimit_out(sink, d);
0278 }
0279
0280
0281
0282 template <typename OutputIterator, typename Context, typename Delimiter>
0283 static bool
0284 generate(OutputIterator&, Context&, Delimiter const&, unused_type)
0285 {
0286
0287
0288
0289
0290 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, uint_not_usable_without_attribute, ());
0291 return false;
0292 }
0293
0294 template <typename Context>
0295 static info what(Context const& )
0296 {
0297 return info("unsigned-integer");
0298 }
0299 };
0300
0301
0302
0303
0304
0305 template <
0306 typename T, typename CharEncoding, typename Tag, unsigned Radix
0307 , bool no_attribute>
0308 struct literal_uint_generator
0309 : primitive_generator<literal_uint_generator<T, CharEncoding, Tag, Radix
0310 , no_attribute> >
0311 {
0312 template <typename Context, typename Unused = unused_type>
0313 struct attribute
0314 : mpl::if_c<no_attribute, unused_type, T>
0315 {};
0316
0317 literal_uint_generator(typename add_const<T>::type n)
0318 : n_(n) {}
0319
0320
0321 BOOST_SPIRIT_ASSERT_MSG(
0322 Radix >= 2 && Radix <= 36, not_supported_radix, ());
0323
0324 BOOST_SPIRIT_ASSERT_MSG(
0325
0326
0327 mpl::not_<mpl::bool_<std::numeric_limits<T>::is_signed> >::value,
0328 signed_unsigned_mismatch, ());
0329
0330
0331
0332
0333 template <typename OutputIterator, typename Context, typename Delimiter
0334 , typename Attribute>
0335 bool generate(OutputIterator& sink, Context& context
0336 , Delimiter const& d, Attribute const& attr) const
0337 {
0338 typedef typename attribute<Context>::type attribute_type;
0339 if (!traits::has_optional_value(attr) ||
0340 n_ != traits::extract_from<attribute_type>(attr, context))
0341 {
0342 return false;
0343 }
0344 return uint_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
0345 delimit_out(sink, d);
0346 }
0347
0348
0349
0350 template <typename OutputIterator, typename Context, typename Delimiter>
0351 bool generate(OutputIterator& sink, Context&, Delimiter const& d
0352 , unused_type) const
0353 {
0354 return uint_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
0355 delimit_out(sink, d);
0356 }
0357
0358 template <typename Context>
0359 static info what(Context const& )
0360 {
0361 return info("unsigned-integer");
0362 }
0363
0364 T n_;
0365 };
0366
0367
0368
0369
0370 namespace detail
0371 {
0372 template <typename T, typename Modifiers, unsigned Radix = 10>
0373 struct make_uint
0374 {
0375 static bool const lower =
0376 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0377 static bool const upper =
0378 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0379
0380 typedef any_uint_generator<
0381 T
0382 , typename spirit::detail::get_encoding_with_case<
0383 Modifiers, unused_type, lower || upper>::type
0384 , typename detail::get_casetag<Modifiers, lower || upper>::type
0385 , Radix
0386 > result_type;
0387
0388 result_type operator()(unused_type, unused_type) const
0389 {
0390 return result_type();
0391 }
0392 };
0393 }
0394
0395
0396 template <typename Modifiers>
0397 struct make_primitive<tag::ushort_, Modifiers>
0398 : detail::make_uint<unsigned short, Modifiers> {};
0399
0400 template <typename Modifiers>
0401 struct make_primitive<tag::uint_, Modifiers>
0402 : detail::make_uint<unsigned int, Modifiers> {};
0403
0404 template <typename Modifiers>
0405 struct make_primitive<tag::ulong_, Modifiers>
0406 : detail::make_uint<unsigned long, Modifiers> {};
0407
0408 template <typename Modifiers>
0409 struct make_primitive<tag::bin, Modifiers>
0410 : detail::make_uint<unsigned, Modifiers, 2> {};
0411
0412 template <typename Modifiers>
0413 struct make_primitive<tag::oct, Modifiers>
0414 : detail::make_uint<unsigned, Modifiers, 8> {};
0415
0416 template <typename Modifiers>
0417 struct make_primitive<tag::hex, Modifiers>
0418 : detail::make_uint<unsigned, Modifiers, 16> {};
0419
0420 #ifdef BOOST_HAS_LONG_LONG
0421 template <typename Modifiers>
0422 struct make_primitive<tag::ulong_long, Modifiers>
0423 : detail::make_uint<boost::ulong_long_type, Modifiers> {};
0424 #endif
0425
0426 template <typename T, unsigned Radix, typename Modifiers>
0427 struct make_primitive<tag::uint_generator<T, Radix>, Modifiers>
0428 : detail::make_uint<typename remove_const<T>::type, Modifiers, Radix> {};
0429
0430
0431 namespace detail
0432 {
0433 template <typename T, typename Modifiers, unsigned Radix = 10>
0434 struct make_uint_direct
0435 {
0436 static bool const lower =
0437 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0438 static bool const upper =
0439 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0440
0441 typedef literal_uint_generator<
0442 T
0443 , typename spirit::detail::get_encoding_with_case<
0444 Modifiers, unused_type, lower || upper>::type
0445 , typename detail::get_casetag<Modifiers, lower || upper>::type
0446 , Radix, false
0447 > result_type;
0448
0449 template <typename Terminal>
0450 result_type operator()(Terminal const& term, unused_type) const
0451 {
0452 return result_type(fusion::at_c<0>(term.args));
0453 }
0454 };
0455 }
0456
0457 template <typename Modifiers, typename A0>
0458 struct make_primitive<
0459 terminal_ex<tag::ushort_, fusion::vector1<A0> >, Modifiers>
0460 : detail::make_uint_direct<unsigned short, Modifiers> {};
0461
0462 template <typename Modifiers, typename A0>
0463 struct make_primitive<
0464 terminal_ex<tag::uint_, fusion::vector1<A0> >, Modifiers>
0465 : detail::make_uint_direct<unsigned int, Modifiers> {};
0466
0467 template <typename Modifiers, typename A0>
0468 struct make_primitive<
0469 terminal_ex<tag::ulong_, fusion::vector1<A0> >, Modifiers>
0470 : detail::make_uint_direct<unsigned long, Modifiers> {};
0471
0472 template <typename Modifiers, typename A0>
0473 struct make_primitive<
0474 terminal_ex<tag::bin, fusion::vector1<A0> >, Modifiers>
0475 : detail::make_uint_direct<unsigned, Modifiers, 2> {};
0476
0477 template <typename Modifiers, typename A0>
0478 struct make_primitive<
0479 terminal_ex<tag::oct, fusion::vector1<A0> >, Modifiers>
0480 : detail::make_uint_direct<unsigned, Modifiers, 8> {};
0481
0482 template <typename Modifiers, typename A0>
0483 struct make_primitive<
0484 terminal_ex<tag::hex, fusion::vector1<A0> >, Modifiers>
0485 : detail::make_uint_direct<unsigned, Modifiers, 16> {};
0486
0487 #ifdef BOOST_HAS_LONG_LONG
0488 template <typename Modifiers, typename A0>
0489 struct make_primitive<
0490 terminal_ex<tag::ulong_long, fusion::vector1<A0> >, Modifiers>
0491 : detail::make_uint_direct<boost::ulong_long_type, Modifiers> {};
0492 #endif
0493
0494 template <typename T, unsigned Radix, typename A0, typename Modifiers>
0495 struct make_primitive<
0496 terminal_ex<tag::uint_generator<T, Radix>, fusion::vector1<A0> >
0497 , Modifiers>
0498 : detail::make_uint_direct<typename remove_const<T>::type, Modifiers, Radix>
0499 {};
0500
0501
0502 namespace detail
0503 {
0504 template <typename T, typename Modifiers>
0505 struct basic_uint_literal
0506 {
0507 static bool const lower =
0508 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0509 static bool const upper =
0510 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0511
0512 typedef literal_uint_generator<
0513 T
0514 , typename spirit::detail::get_encoding_with_case<
0515 Modifiers, unused_type, lower || upper>::type
0516 , typename detail::get_casetag<Modifiers, lower || upper>::type
0517 , 10, true
0518 > result_type;
0519
0520 template <typename T_>
0521 result_type operator()(T_ i, unused_type) const
0522 {
0523 return result_type(i);
0524 }
0525 };
0526 }
0527
0528 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0529 template <typename Modifiers>
0530 struct make_primitive<unsigned short, Modifiers>
0531 : detail::basic_uint_literal<unsigned short, Modifiers> {};
0532 #endif
0533
0534 template <typename Modifiers>
0535 struct make_primitive<unsigned int, Modifiers>
0536 : detail::basic_uint_literal<unsigned int, Modifiers> {};
0537
0538 template <typename Modifiers>
0539 struct make_primitive<unsigned long, Modifiers>
0540 : detail::basic_uint_literal<unsigned long, Modifiers> {};
0541
0542 #ifdef BOOST_HAS_LONG_LONG
0543 template <typename Modifiers>
0544 struct make_primitive<boost::ulong_long_type, Modifiers>
0545 : detail::basic_uint_literal<boost::ulong_long_type, Modifiers> {};
0546 #endif
0547
0548
0549 template <typename Modifiers, typename A0>
0550 struct make_primitive<
0551 terminal_ex<tag::lit, fusion::vector1<A0> >
0552 , Modifiers
0553 , typename enable_if<traits::is_uint<A0> >::type>
0554 {
0555 static bool const lower =
0556 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0557 static bool const upper =
0558 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0559
0560 typedef literal_uint_generator<
0561 typename remove_const<A0>::type
0562 , typename spirit::detail::get_encoding_with_case<
0563 Modifiers, unused_type, lower || upper>::type
0564 , typename detail::get_casetag<Modifiers, lower || upper>::type
0565 , 10, true
0566 > result_type;
0567
0568 template <typename Terminal>
0569 result_type operator()(Terminal const& term, unused_type) const
0570 {
0571 return result_type(fusion::at_c<0>(term.args));
0572 }
0573 };
0574 }}}
0575
0576 #endif