Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c)      2011 Bryce Lelbach
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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         // This one is the class that the user can instantiate directly in
0042         // order to create a customized int parser
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     // Enablers
0052     ///////////////////////////////////////////////////////////////////////////
0053     //[primitive_parsers_enable_short
0054     template <> // enables short_
0055     struct use_terminal<qi::domain, tag::short_> : mpl::true_ {};
0056     //]
0057 
0058     template <typename A0> // enables lit(n)
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> // enables short_(n)
0065     struct use_terminal<qi::domain
0066         , terminal_ex<tag::short_, fusion::vector1<A0> > >
0067       : is_arithmetic<A0> {};
0068 
0069     template <> // enables *lazy* short_(n)
0070     struct use_lazy_terminal<qi::domain, tag::short_, 1> : mpl::true_ {};
0071 
0072     ///////////////////////////////////////////////////////////////////////////
0073     //[primitive_parsers_enable_int
0074     template <> // enables int_
0075     struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
0076     //]
0077 
0078     template <typename A0> // enables lit(n)
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> // enables int_(n)
0085     struct use_terminal<qi::domain
0086         , terminal_ex<tag::int_, fusion::vector1<A0> > >
0087       : is_arithmetic<A0> {};
0088 
0089     template <> // enables *lazy* int_(n)
0090     struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
0091 
0092     ///////////////////////////////////////////////////////////////////////////
0093     //[primitive_parsers_enable_long
0094     template <> // enables long_
0095     struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
0096     //]
0097 
0098     template <typename A0> // enables lit(n)
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> // enables long_(n)
0105     struct use_terminal<qi::domain
0106         , terminal_ex<tag::long_, fusion::vector1<A0> > >
0107       : is_arithmetic<A0> {};
0108 
0109     template <> // enables *lazy* long_(n)
0110     struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
0111 
0112     ///////////////////////////////////////////////////////////////////////////
0113 #ifdef BOOST_HAS_LONG_LONG
0114     //[primitive_parsers_enable_long_long
0115     template <> // enables long_long
0116     struct use_terminal<qi::domain, tag::long_long> : mpl::true_ {};
0117     //]
0118 
0119     template <typename A0> // enables lit(n)
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> // enables long_long(n)
0126     struct use_terminal<qi::domain
0127         , terminal_ex<tag::long_long, fusion::vector1<A0> > >
0128       : is_arithmetic<A0> {};
0129 
0130     template <> // enables *lazy* long_long(n)
0131     struct use_lazy_terminal<qi::domain, tag::long_long, 1> : mpl::true_ {};
0132 #endif
0133 
0134     ///////////////////////////////////////////////////////////////////////////
0135     // enables any custom int_parser
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     // enables any custom int_parser(n)
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     // enables *lazy* custom int_parser(n)
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;    // lit(1) is equivalent to 1
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     // This is the actual int parser
0180     ///////////////////////////////////////////////////////////////////////////
0181     //[primitive_parsers_int_parser
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         // check template parameter 'Radix' for validity
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& /*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& /*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         // check template parameter 'Radix' for validity
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& /*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& /*context*/) const
0263         {
0264             return info("integer");
0265         }
0266 
0267         T n_;
0268     };
0269 
0270     ///////////////////////////////////////////////////////////////////////////
0271     // Parser generators: make_xxx function (objects)
0272     ///////////////////////////////////////////////////////////////////////////
0273     //[primitive_parsers_make_int
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     //[primitive_parsers_short_primitive
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     //[primitive_parsers_int_primitive
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     //[primitive_parsers_long_primitive
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     //[primitive_parsers_long_long_primitive
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