Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_SPIRIT_QI_AUXILIARY_ATTR_CAST_HPP
0007 #define BOOST_SPIRIT_QI_AUXILIARY_ATTR_CAST_HPP
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/qi/meta_compiler.hpp>
0014 #include <boost/spirit/home/qi/parser.hpp>
0015 #include <boost/spirit/home/qi/domain.hpp>
0016 #include <boost/spirit/home/support/unused.hpp>
0017 #include <boost/spirit/home/support/info.hpp>
0018 #include <boost/spirit/home/support/common_terminals.hpp>
0019 #include <boost/spirit/home/qi/detail/attributes.hpp>
0020 #include <boost/spirit/home/support/auxiliary/attr_cast.hpp>
0021 
0022 namespace boost { namespace spirit
0023 {
0024     ///////////////////////////////////////////////////////////////////////////
0025     // Enablers
0026     ///////////////////////////////////////////////////////////////////////////
0027 
0028     // enables attr_cast<>() pseudo parser
0029     template <typename Expr, typename Exposed, typename Transformed>
0030     struct use_terminal<qi::domain
0031           , tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
0032       : mpl::true_ {};
0033 }}
0034 
0035 namespace boost { namespace spirit { namespace qi
0036 {
0037     using spirit::attr_cast;
0038 
0039     ///////////////////////////////////////////////////////////////////////////
0040     // attr_cast_parser consumes the attribute of subject generator without
0041     // generating anything
0042     ///////////////////////////////////////////////////////////////////////////
0043     template <typename Exposed, typename Transformed, typename Subject>
0044     struct attr_cast_parser 
0045       : unary_parser<attr_cast_parser<Exposed, Transformed, Subject> >
0046     {
0047         typedef typename result_of::compile<qi::domain, Subject>::type
0048             subject_type;
0049 
0050         typedef typename mpl::eval_if<
0051             traits::not_is_unused<Transformed>
0052           , mpl::identity<Transformed>
0053           , traits::attribute_of<subject_type> >::type
0054         transformed_attribute_type;
0055 
0056         attr_cast_parser(Subject const& subject_)
0057           : subject(subject_)
0058         {
0059             // If you got an error_invalid_expression error message here,
0060             // then the expression (Subject) is not a valid spirit qi
0061             // expression.
0062             BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Subject);
0063         }
0064 
0065         // If Exposed is given, we use the given type, otherwise all we can do
0066         // is to guess, so we expose our inner type as an attribute and
0067         // deal with the passed attribute inside the parse function.
0068         template <typename Context, typename Iterator>
0069         struct attribute
0070           : mpl::if_<traits::not_is_unused<Exposed>, Exposed
0071               , transformed_attribute_type>
0072         {};
0073 
0074         template <typename Iterator, typename Context, typename Skipper
0075           , typename Attribute>
0076         bool parse(Iterator& first, Iterator const& last
0077           , Context& context, Skipper const& skipper
0078           , Attribute& attr_param) const
0079         {
0080             // Find the real exposed attribute. If exposed is given, we use it
0081             // otherwise we assume the exposed attribute type to be the actual
0082             // attribute type as passed by the user.
0083             typedef typename mpl::if_<
0084                 traits::not_is_unused<Exposed>, Exposed, Attribute>::type
0085             exposed_attribute_type;
0086 
0087             // do down-stream transformation, provides attribute for embedded
0088             // parser
0089             typedef traits::transform_attribute<
0090                 exposed_attribute_type, transformed_attribute_type, domain>
0091             transform;
0092 
0093             typename transform::type attr_ = transform::pre(attr_param);
0094 
0095             if (!compile<qi::domain>(subject).
0096                     parse(first, last, context, skipper, attr_))
0097             {
0098                 transform::fail(attr_param);
0099                 return false;
0100             }
0101 
0102             // do up-stream transformation, this mainly integrates the results
0103             // back into the original attribute value, if appropriate
0104             transform::post(attr_param, attr_);
0105             return true;
0106         }
0107 
0108         template <typename Context>
0109         info what(Context& context) const
0110         {
0111             return info("attr_cast"
0112               , compile<qi::domain>(subject).what(context));
0113         }
0114 
0115         Subject subject;
0116     };
0117 
0118     ///////////////////////////////////////////////////////////////////////////
0119     // Parser generator: make_xxx function (objects)
0120     ///////////////////////////////////////////////////////////////////////////
0121     template <typename Expr, typename Exposed, typename Transformed
0122       , typename Modifiers>
0123     struct make_primitive<
0124         tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
0125     {
0126         typedef attr_cast_parser<Exposed, Transformed, Expr> result_type;
0127 
0128         template <typename Terminal>
0129         result_type operator()(Terminal const& term, unused_type) const
0130         {
0131             typedef tag::stateful_tag<
0132                 Expr, tag::attr_cast, Exposed, Transformed> tag_type;
0133             using spirit::detail::get_stateful_data;
0134             return result_type(get_stateful_data<tag_type>::call(term));
0135         }
0136     };
0137 
0138 
0139 }}}
0140 
0141 #endif