Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:35

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003     Copyright (c) 2013 Agustin Berge
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_X3_PARSER_OCTOBER_16_2008_0254PM)
0009 #define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
0010 
0011 #include <boost/mpl/bool.hpp>
0012 #include <boost/type_traits/is_base_of.hpp>
0013 #include <boost/type_traits/remove_cv.hpp>
0014 #include <boost/type_traits/remove_reference.hpp>
0015 #include <boost/utility/declval.hpp>
0016 #include <boost/utility/enable_if.hpp>
0017 #include <boost/spirit/home/x3/support/unused.hpp>
0018 #include <boost/spirit/home/x3/support/context.hpp>
0019 #include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
0020 #include <boost/core/ignore_unused.hpp>
0021 #include <boost/assert.hpp>
0022 #include <string>
0023 
0024 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
0025 #include <typeinfo>
0026 #endif
0027 
0028 namespace boost { namespace spirit { namespace x3
0029 {
0030     template <typename Subject, typename Action>
0031     struct action;
0032 
0033     template <typename Subject, typename Handler>
0034     struct guard;
0035 
0036     struct parser_base {};
0037     struct parser_id;
0038 
0039     template <typename Derived>
0040     struct parser : parser_base
0041     {
0042         typedef Derived derived_type;
0043         static bool const handles_container = false;
0044         static bool const is_pass_through_unary = false;
0045         static bool const has_action = false;
0046 
0047         constexpr Derived const& derived() const
0048         {
0049             return *static_cast<Derived const*>(this);
0050         }
0051 
0052         template <typename Action>
0053         constexpr action<Derived, Action> operator[](Action f) const
0054         {
0055             return { this->derived(), f };
0056         }
0057 
0058         template <typename Handler>
0059         constexpr guard<Derived, Handler> on_error(Handler f) const
0060         {
0061             return { this->derived(), f };
0062         }
0063     };
0064 
0065     struct unary_category;
0066     struct binary_category;
0067 
0068     template <typename Subject, typename Derived>
0069     struct unary_parser : parser<Derived>
0070     {
0071         typedef unary_category category;
0072         typedef Subject subject_type;
0073         static bool const has_action = Subject::has_action;
0074 
0075         constexpr unary_parser(Subject const& subject)
0076             : subject(subject) {}
0077 
0078         unary_parser const& get_unary() const { return *this; }
0079 
0080         Subject subject;
0081     };
0082 
0083     template <typename Left, typename Right, typename Derived>
0084     struct binary_parser : parser<Derived>
0085     {
0086         typedef binary_category category;
0087         typedef Left left_type;
0088         typedef Right right_type;
0089         static bool const has_action =
0090             left_type::has_action || right_type::has_action;
0091 
0092         constexpr binary_parser(Left const& left, Right const& right)
0093             : left(left), right(right) {}
0094 
0095         binary_parser const& get_binary() const { return *this; }
0096 
0097         Left left;
0098         Right right;
0099     };
0100 
0101     ///////////////////////////////////////////////////////////////////////////
0102     // as_parser: convert a type, T, into a parser.
0103     ///////////////////////////////////////////////////////////////////////////
0104     namespace extension
0105     {
0106         namespace detail
0107         {
0108             namespace as_parser_guard
0109             {
0110                 void as_spirit_parser(...);
0111 
0112                 template<typename T, typename R =
0113                     decltype(as_spirit_parser(boost::declval<T const&>()))>
0114                 struct deduce_as_parser
0115                 {
0116                     typedef R type;
0117                     typedef typename
0118                         boost::remove_cv<
0119                             typename boost::remove_reference<R>::type
0120                         >::type
0121                     value_type;
0122 
0123                     static type call(T const& v)
0124                     {
0125                         return as_spirit_parser(v);
0126                     }
0127                 };
0128                 template<typename T>
0129                 struct deduce_as_parser<T, void>
0130                 {};
0131             }
0132             using as_parser_guard::deduce_as_parser;
0133         }
0134 
0135         template <typename T, typename Enable = void>
0136         struct as_parser : detail::deduce_as_parser<T> {};
0137 
0138         template <>
0139         struct as_parser<unused_type>
0140         {
0141             typedef unused_type type;
0142             typedef unused_type value_type;
0143             static constexpr type call(unused_type)
0144             {
0145                 return unused;
0146             }
0147         };
0148 
0149         template <typename Derived>
0150         struct as_parser<Derived
0151             , typename enable_if<is_base_of<parser_base, Derived>>::type>
0152         {
0153             typedef Derived const& type;
0154             typedef Derived value_type;
0155             static constexpr type call(Derived const& p)
0156             {
0157                 return p;
0158             }
0159         };
0160 
0161         template <typename Derived>
0162         struct as_parser<parser<Derived>>
0163         {
0164             typedef Derived const& type;
0165             typedef Derived value_type;
0166             static constexpr type call(parser<Derived> const& p)
0167             {
0168                 return p.derived();
0169             }
0170         };
0171     }
0172 
0173     template <typename T>
0174     constexpr typename extension::as_parser<T>::type
0175     as_parser(T const& x)
0176     {
0177         return extension::as_parser<T>::call(x);
0178     }
0179 
0180     template <typename Derived>
0181     constexpr Derived const&
0182     as_parser(parser<Derived> const& p)
0183     {
0184         return p.derived();
0185     }
0186 
0187     ///////////////////////////////////////////////////////////////////////////
0188     // The main what function
0189     //
0190     // Note: unlike Spirit2, spirit parsers are no longer required to have a
0191     // "what" member function. In X3, we specialize the get_info struct
0192     // below where needed. If a specialization is not provided, the default
0193     // below will be used. The default "what" result will be the typeid
0194     // name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
0195     // "undefined"
0196     ///////////////////////////////////////////////////////////////////////////
0197     template <typename Parser, typename Enable = void>
0198     struct get_info
0199     {
0200         typedef std::string result_type;
0201         std::string operator()(Parser const&) const
0202         {
0203 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
0204             return typeid(Parser).name();
0205 #else
0206             return "undefined";
0207 #endif
0208         }
0209     };
0210 
0211     template <typename Parser>
0212     std::string what(Parser const& p)
0213     {
0214         return get_info<Parser>()(p);
0215     }
0216 }}}
0217 
0218 namespace boost { namespace spirit { namespace x3 { namespace traits
0219 {
0220     template <typename Subject, typename Derived, typename Context>
0221     struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
0222         : has_attribute<Subject, Context> {};
0223 
0224     template <typename Left, typename Right, typename Derived, typename Context>
0225     struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
0226         : mpl::bool_<has_attribute<Left, Context>::value ||
0227                 has_attribute<Right, Context>::value> {};
0228 }}}}
0229 
0230 #endif