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