File indexing completed on 2025-01-19 09:47:46
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_SPIRIT_QI_NUMERIC_UINT_HPP
0010 #define BOOST_SPIRIT_QI_NUMERIC_UINT_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/spirit/home/qi/skip_over.hpp>
0017 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
0018 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
0019 #include <boost/spirit/home/qi/meta_compiler.hpp>
0020 #include <boost/spirit/home/qi/parser.hpp>
0021 #include <boost/spirit/home/support/common_terminals.hpp>
0022 #include <boost/spirit/home/support/info.hpp>
0023 #include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
0024 #include <boost/mpl/assert.hpp>
0025 #include <boost/type_traits/is_same.hpp>
0026
0027 namespace boost { namespace spirit
0028 {
0029 namespace tag
0030 {
0031 template <typename T, unsigned Radix, unsigned MinDigits
0032 , int MaxDigits>
0033 struct uint_parser
0034 {
0035 BOOST_SPIRIT_IS_TAG()
0036 };
0037 }
0038
0039 namespace qi
0040 {
0041
0042
0043
0044 template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
0045 , int MaxDigits = -1>
0046 struct uint_parser
0047 : spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
0048 {};
0049 }
0050
0051
0052
0053
0054 template <>
0055 struct use_terminal<qi::domain, tag::ushort_> : mpl::true_ {};
0056
0057 template <typename A0>
0058 struct use_terminal<qi::domain
0059 , terminal_ex<tag::lit, fusion::vector1<A0> >
0060 , typename enable_if<is_same<A0, unsigned short> >::type>
0061 : mpl::true_ {};
0062
0063 template <typename A0>
0064 struct use_terminal<qi::domain
0065 , terminal_ex<tag::ushort_, fusion::vector1<A0> > >
0066 : is_arithmetic<A0> {};
0067
0068 template <>
0069 struct use_lazy_terminal<qi::domain, tag::ushort_, 1> : mpl::true_ {};
0070
0071
0072 template <>
0073 struct use_terminal<qi::domain, tag::uint_> : mpl::true_ {};
0074
0075 template <typename A0>
0076 struct use_terminal<qi::domain
0077 , terminal_ex<tag::lit, fusion::vector1<A0> >
0078 , typename enable_if<is_same<A0, unsigned> >::type>
0079 : mpl::true_ {};
0080
0081 template <typename A0>
0082 struct use_terminal<qi::domain
0083 , terminal_ex<tag::uint_, fusion::vector1<A0> > >
0084 : is_arithmetic<A0> {};
0085
0086 template <>
0087 struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
0088
0089
0090 template <>
0091 struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
0092
0093 template <typename A0>
0094 struct use_terminal<qi::domain
0095 , terminal_ex<tag::lit, fusion::vector1<A0> >
0096 , typename enable_if<is_same<A0, unsigned long> >::type>
0097 : mpl::true_ {};
0098
0099 template <typename A0>
0100 struct use_terminal<qi::domain
0101 , terminal_ex<tag::ulong_, fusion::vector1<A0> > >
0102 : is_arithmetic<A0> {};
0103
0104 template <>
0105 struct use_lazy_terminal<qi::domain, tag::ulong_, 1> : mpl::true_ {};
0106
0107
0108 #ifdef BOOST_HAS_LONG_LONG
0109 template <>
0110 struct use_terminal<qi::domain, tag::ulong_long> : mpl::true_ {};
0111
0112 template <typename A0>
0113 struct use_terminal<qi::domain
0114 , terminal_ex<tag::lit, fusion::vector1<A0> >
0115 , typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
0116 : mpl::true_ {};
0117
0118 template <typename A0>
0119 struct use_terminal<qi::domain
0120 , terminal_ex<tag::ulong_long, fusion::vector1<A0> > >
0121 : is_arithmetic<A0> {};
0122
0123 template <>
0124 struct use_lazy_terminal<qi::domain, tag::ulong_long, 1> : mpl::true_ {};
0125 #endif
0126
0127
0128 template <>
0129 struct use_terminal<qi::domain, tag::bin> : mpl::true_ {};
0130
0131 template <typename A0>
0132 struct use_terminal<qi::domain
0133 , terminal_ex<tag::bin, fusion::vector1<A0> > >
0134 : is_arithmetic<A0> {};
0135
0136 template <>
0137 struct use_lazy_terminal<qi::domain, tag::bin, 1> : mpl::true_ {};
0138
0139
0140 template <>
0141 struct use_terminal<qi::domain, tag::oct> : mpl::true_ {};
0142
0143 template <typename A0>
0144 struct use_terminal<qi::domain
0145 , terminal_ex<tag::oct, fusion::vector1<A0> > >
0146 : is_arithmetic<A0> {};
0147
0148 template <>
0149 struct use_lazy_terminal<qi::domain, tag::oct, 1> : mpl::true_ {};
0150
0151
0152 template <>
0153 struct use_terminal<qi::domain, tag::hex> : mpl::true_ {};
0154
0155 template <typename A0>
0156 struct use_terminal<qi::domain
0157 , terminal_ex<tag::hex, fusion::vector1<A0> > >
0158 : is_arithmetic<A0> {};
0159
0160 template <>
0161 struct use_lazy_terminal<qi::domain, tag::hex, 1> : mpl::true_ {};
0162
0163
0164
0165 template <typename T, unsigned Radix, unsigned MinDigits
0166 , int MaxDigits>
0167 struct use_terminal<qi::domain
0168 , tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
0169 : mpl::true_ {};
0170
0171
0172 template <typename T, unsigned Radix, unsigned MinDigits
0173 , int MaxDigits, typename A0>
0174 struct use_terminal<qi::domain
0175 , terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
0176 , fusion::vector1<A0> >
0177 > : mpl::true_ {};
0178
0179
0180 template <typename T, unsigned Radix, unsigned MinDigits
0181 , int MaxDigits>
0182 struct use_lazy_terminal<qi::domain
0183 , tag::uint_parser<T, Radix, MinDigits, MaxDigits>, 1
0184 > : mpl::true_ {};
0185 }}
0186
0187 namespace boost { namespace spirit { namespace qi
0188 {
0189 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0190 using spirit::bin;
0191 using spirit::oct;
0192 using spirit::hex;
0193
0194 using spirit::ushort_;
0195 using spirit::uint_;
0196 using spirit::ulong_;
0197 #ifdef BOOST_HAS_LONG_LONG
0198 using spirit::ulong_long;
0199 #endif
0200 using spirit::lit;
0201 #endif
0202
0203 using spirit::bin_type;
0204 using spirit::oct_type;
0205 using spirit::hex_type;
0206
0207 using spirit::ushort_type;
0208 using spirit::uint_type;
0209 using spirit::ulong_type;
0210 #ifdef BOOST_HAS_LONG_LONG
0211 using spirit::ulong_long_type;
0212 #endif
0213 using spirit::lit_type;
0214
0215
0216
0217
0218 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
0219 , int MaxDigits = -1>
0220 struct any_uint_parser
0221 : primitive_parser<any_uint_parser<T, Radix, MinDigits, MaxDigits> >
0222 {
0223
0224 BOOST_SPIRIT_ASSERT_MSG(
0225 Radix >= 2 && Radix <= 36,
0226 not_supported_radix, ());
0227
0228 template <typename Context, typename Iterator>
0229 struct attribute
0230 {
0231 typedef T type;
0232 };
0233
0234 template <typename Iterator, typename Context
0235 , typename Skipper, typename Attribute>
0236 bool parse(Iterator& first, Iterator const& last
0237 , Context& , Skipper const& skipper
0238 , Attribute& attr_) const
0239 {
0240 typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
0241 qi::skip_over(first, last, skipper);
0242 return extract::call(first, last, attr_);
0243 }
0244
0245 template <typename Context>
0246 info what(Context& ) const
0247 {
0248 return info("unsigned-integer");
0249 }
0250 };
0251
0252
0253 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
0254 , int MaxDigits = -1, bool no_attribute = true>
0255 struct literal_uint_parser
0256 : primitive_parser<literal_uint_parser<T, Radix, MinDigits, MaxDigits
0257 , no_attribute> >
0258 {
0259
0260 BOOST_SPIRIT_ASSERT_MSG(
0261 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
0262 not_supported_radix, ());
0263
0264 template <typename Value>
0265 literal_uint_parser(Value const& n) : n_(n) {}
0266
0267 template <typename Context, typename Iterator>
0268 struct attribute
0269 : mpl::if_c<no_attribute, unused_type, T>
0270 {};
0271
0272 template <typename Iterator, typename Context
0273 , typename Skipper, typename Attribute>
0274 bool parse(Iterator& first, Iterator const& last
0275 , Context& , Skipper const& skipper
0276 , Attribute& attr_param) const
0277 {
0278 typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
0279 qi::skip_over(first, last, skipper);
0280
0281 Iterator save = first;
0282 T attr_;
0283
0284 if (extract::call(first, last, attr_) && (attr_ == n_))
0285 {
0286 traits::assign_to(attr_, attr_param);
0287 return true;
0288 }
0289
0290 first = save;
0291 return false;
0292 }
0293
0294 template <typename Context>
0295 info what(Context& ) const
0296 {
0297 return info("unsigned-integer");
0298 }
0299
0300 T n_;
0301 };
0302
0303
0304
0305
0306 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
0307 , int MaxDigits = -1>
0308 struct make_uint
0309 {
0310 typedef any_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
0311 result_type operator()(unused_type, unused_type) const
0312 {
0313 return result_type();
0314 }
0315 };
0316
0317 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
0318 , int MaxDigits = -1>
0319 struct make_direct_uint
0320 {
0321 typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits, false>
0322 result_type;
0323 template <typename Terminal>
0324 result_type operator()(Terminal const& term, unused_type) const
0325 {
0326 return result_type(fusion::at_c<0>(term.args));
0327 }
0328 };
0329
0330 template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
0331 , int MaxDigits = -1>
0332 struct make_literal_uint
0333 {
0334 typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
0335 template <typename Terminal>
0336 result_type operator()(Terminal const& term, unused_type) const
0337 {
0338 return result_type(fusion::at_c<0>(term.args));
0339 }
0340 };
0341
0342
0343 template <typename Modifiers, typename A0>
0344 struct make_primitive<
0345 terminal_ex<tag::lit, fusion::vector1<A0> >
0346 , Modifiers, typename enable_if<is_same<A0, unsigned short> >::type>
0347 : make_literal_uint<unsigned short> {};
0348
0349 template <typename Modifiers, typename A0>
0350 struct make_primitive<
0351 terminal_ex<tag::lit, fusion::vector1<A0> >
0352 , Modifiers, typename enable_if<is_same<A0, unsigned> >::type>
0353 : make_literal_uint<unsigned> {};
0354
0355 template <typename Modifiers, typename A0>
0356 struct make_primitive<
0357 terminal_ex<tag::lit, fusion::vector1<A0> >
0358 , Modifiers, typename enable_if<is_same<A0, unsigned long> >::type>
0359 : make_literal_uint<unsigned long> {};
0360
0361 #ifdef BOOST_HAS_LONG_LONG
0362 template <typename Modifiers, typename A0>
0363 struct make_primitive<
0364 terminal_ex<tag::lit, fusion::vector1<A0> >
0365 , Modifiers, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
0366 : make_literal_uint<boost::ulong_long_type> {};
0367 #endif
0368
0369
0370 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
0371 , typename Modifiers>
0372 struct make_primitive<
0373 tag::uint_parser<T, Radix, MinDigits, MaxDigits>
0374 , Modifiers>
0375 : make_uint<T, Radix, MinDigits, MaxDigits> {};
0376
0377 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
0378 , typename A0, typename Modifiers>
0379 struct make_primitive<
0380 terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
0381 , fusion::vector1<A0> >, Modifiers>
0382 : make_direct_uint<T, Radix, MinDigits, MaxDigits> {};
0383
0384
0385 template <typename Modifiers>
0386 struct make_primitive<tag::bin, Modifiers>
0387 : make_uint<unsigned, 2> {};
0388
0389 template <typename Modifiers, typename A0>
0390 struct make_primitive<
0391 terminal_ex<tag::bin
0392 , fusion::vector1<A0> > , Modifiers>
0393 : make_direct_uint<unsigned, 2> {};
0394
0395
0396 template <typename Modifiers>
0397 struct make_primitive<tag::oct, Modifiers>
0398 : make_uint<unsigned, 8> {};
0399
0400 template <typename Modifiers, typename A0>
0401 struct make_primitive<
0402 terminal_ex<tag::oct
0403 , fusion::vector1<A0> > , Modifiers>
0404 : make_direct_uint<unsigned, 8> {};
0405
0406
0407 template <typename Modifiers>
0408 struct make_primitive<tag::hex, Modifiers>
0409 : make_uint<unsigned, 16> {};
0410
0411 template <typename Modifiers, typename A0>
0412 struct make_primitive<
0413 terminal_ex<tag::hex
0414 , fusion::vector1<A0> > , Modifiers>
0415 : make_direct_uint<unsigned, 16> {};
0416
0417
0418 template <typename Modifiers>
0419 struct make_primitive<tag::ushort_, Modifiers>
0420 : make_uint<unsigned short> {};
0421
0422 template <typename Modifiers, typename A0>
0423 struct make_primitive<
0424 terminal_ex<tag::ushort_
0425 , fusion::vector1<A0> > , Modifiers>
0426 : make_direct_uint<unsigned short> {};
0427
0428
0429 template <typename Modifiers>
0430 struct make_primitive<tag::uint_, Modifiers>
0431 : make_uint<unsigned> {};
0432
0433 template <typename Modifiers, typename A0>
0434 struct make_primitive<
0435 terminal_ex<tag::uint_
0436 , fusion::vector1<A0> > , Modifiers>
0437 : make_direct_uint<unsigned> {};
0438
0439
0440 template <typename Modifiers>
0441 struct make_primitive<tag::ulong_, Modifiers>
0442 : make_uint<unsigned long> {};
0443
0444 template <typename Modifiers, typename A0>
0445 struct make_primitive<
0446 terminal_ex<tag::ulong_
0447 , fusion::vector1<A0> > , Modifiers>
0448 : make_direct_uint<unsigned long> {};
0449
0450
0451 #ifdef BOOST_HAS_LONG_LONG
0452 template <typename Modifiers>
0453 struct make_primitive<tag::ulong_long, Modifiers>
0454 : make_uint<boost::ulong_long_type> {};
0455
0456 template <typename Modifiers, typename A0>
0457 struct make_primitive<
0458 terminal_ex<tag::ulong_long
0459 , fusion::vector1<A0> > , Modifiers>
0460 : make_direct_uint<boost::ulong_long_type> {};
0461 #endif
0462 }}}
0463
0464 #endif