Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:46

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2011 Bryce Lelbach
0004     Copyright (c) 2011 Jan Frederick Eick
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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         // This one is the class that the user can instantiate directly in
0043         // order to create a customized int parser
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     // Enablers
0053     ///////////////////////////////////////////////////////////////////////////
0054     template <> // enables ushort_
0055     struct use_terminal<qi::domain, tag::ushort_> : mpl::true_ {};
0056 
0057     template <typename A0> // enables lit(n)
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> // enables ushort_(n)
0064     struct use_terminal<qi::domain
0065         , terminal_ex<tag::ushort_, fusion::vector1<A0> > >
0066       : is_arithmetic<A0> {};
0067 
0068     template <> // enables *lazy* ushort_(n)
0069     struct use_lazy_terminal<qi::domain, tag::ushort_, 1> : mpl::true_ {};
0070 
0071     ///////////////////////////////////////////////////////////////////////////
0072     template <> // enables uint_
0073     struct use_terminal<qi::domain, tag::uint_> : mpl::true_ {};
0074 
0075     template <typename A0> // enables lit(n)
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> // enables uint_(n)
0082     struct use_terminal<qi::domain
0083         , terminal_ex<tag::uint_, fusion::vector1<A0> > >
0084       : is_arithmetic<A0> {};
0085 
0086     template <> // enables *lazy* uint_(n)
0087     struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
0088 
0089     ///////////////////////////////////////////////////////////////////////////
0090     template <> // enables ulong_
0091     struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
0092 
0093     template <typename A0> // enables lit(n)
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> // enables ulong_(n)
0100     struct use_terminal<qi::domain
0101         , terminal_ex<tag::ulong_, fusion::vector1<A0> > >
0102       : is_arithmetic<A0> {};
0103 
0104     template <> // enables *lazy* ulong_(n)
0105     struct use_lazy_terminal<qi::domain, tag::ulong_, 1> : mpl::true_ {};
0106 
0107     ///////////////////////////////////////////////////////////////////////////
0108 #ifdef BOOST_HAS_LONG_LONG
0109     template <> // enables ulong_long
0110     struct use_terminal<qi::domain, tag::ulong_long> : mpl::true_ {};
0111 
0112     template <typename A0> // enables lit(n)
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> // enables ulong_long(n)
0119     struct use_terminal<qi::domain
0120         , terminal_ex<tag::ulong_long, fusion::vector1<A0> > >
0121       : is_arithmetic<A0> {};
0122 
0123     template <> // enables *lazy* ulong_long(n)
0124     struct use_lazy_terminal<qi::domain, tag::ulong_long, 1> : mpl::true_ {};
0125 #endif
0126 
0127     ///////////////////////////////////////////////////////////////////////////
0128     template <> // enables bin
0129     struct use_terminal<qi::domain, tag::bin> : mpl::true_ {};
0130 
0131     template <typename A0> // enables bin(n)
0132     struct use_terminal<qi::domain
0133         , terminal_ex<tag::bin, fusion::vector1<A0> > >
0134       : is_arithmetic<A0> {};
0135 
0136     template <> // enables *lazy* bin(n)
0137     struct use_lazy_terminal<qi::domain, tag::bin, 1> : mpl::true_ {};
0138 
0139     ///////////////////////////////////////////////////////////////////////////
0140     template <> // enables oct
0141     struct use_terminal<qi::domain, tag::oct> : mpl::true_ {};
0142 
0143     template <typename A0> // enables oct(n)
0144     struct use_terminal<qi::domain
0145         , terminal_ex<tag::oct, fusion::vector1<A0> > >
0146       : is_arithmetic<A0> {};
0147 
0148     template <> // enables *lazy* oct(n)
0149     struct use_lazy_terminal<qi::domain, tag::oct, 1> : mpl::true_ {};
0150 
0151     ///////////////////////////////////////////////////////////////////////////
0152     template <> // enables hex
0153     struct use_terminal<qi::domain, tag::hex> : mpl::true_ {};
0154 
0155     template <typename A0> // enables hex(n)
0156     struct use_terminal<qi::domain
0157         , terminal_ex<tag::hex, fusion::vector1<A0> > >
0158       : is_arithmetic<A0> {};
0159 
0160     template <> // enables *lazy* hex(n)
0161     struct use_lazy_terminal<qi::domain, tag::hex, 1> : mpl::true_ {};
0162 
0163     ///////////////////////////////////////////////////////////////////////////
0164     // enables any custom uint_parser
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     // enables any custom uint_parser(n)
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     // enables *lazy* custom uint_parser(n)
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; // lit(1) is equivalent to 1
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     // This is the actual uint parser
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         // check template parameter 'Radix' for validity
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& /*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& /*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         // check template parameter 'Radix' for validity
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& /*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& /*context*/) const
0296         {
0297             return info("unsigned-integer");
0298         }
0299 
0300         T n_;
0301     };
0302 
0303     ///////////////////////////////////////////////////////////////////////////
0304     // Parser generators: make_xxx function (objects)
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