Warning, file /include/boost/spirit/home/qi/action/action.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_SPIRIT_QI_ACTION_ACTION_HPP
0008 #define BOOST_SPIRIT_QI_ACTION_ACTION_HPP
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/spirit/home/qi/meta_compiler.hpp>
0015 #include <boost/spirit/home/qi/parser.hpp>
0016 #include <boost/spirit/home/qi/detail/attributes.hpp>
0017 #include <boost/spirit/home/support/argument.hpp>
0018 #include <boost/spirit/home/support/context.hpp>
0019 #include <boost/spirit/home/support/unused.hpp>
0020 #include <boost/spirit/home/support/info.hpp>
0021 #include <boost/spirit/home/support/action_dispatch.hpp>
0022 #include <boost/spirit/home/support/handles_container.hpp>
0023
0024 #include <boost/mpl/bool.hpp>
0025 #include <boost/mpl/if.hpp>
0026 #include <boost/type_traits/remove_const.hpp>
0027 #include <boost/type_traits/is_same.hpp>
0028
0029 namespace boost { namespace spirit { namespace qi
0030 {
0031 BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
0032
0033 template <typename Subject, typename Action>
0034 struct action : unary_parser<action<Subject, Action> >
0035 {
0036 typedef Subject subject_type;
0037 typedef Action action_type;
0038
0039 template <typename Context, typename Iterator>
0040 struct attribute
0041 : traits::attribute_of<Subject, Context, Iterator>
0042 {};
0043
0044 action(Subject const& subject_, Action f_)
0045 : subject(subject_), f(f_) {}
0046
0047 #ifndef BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
0048 template <typename Iterator, typename Context
0049 , typename Skipper, typename Attribute>
0050 bool parse(Iterator& first, Iterator const& last
0051 , Context& context, Skipper const& skipper
0052 , Attribute& attr_) const
0053 {
0054 typedef typename attribute<Context, Iterator>::type attr_type;
0055
0056
0057 typedef traits::transform_attribute<
0058 Attribute, attr_type, domain> transform;
0059
0060 typename transform::type attr = transform::pre(attr_);
0061
0062 Iterator save = first;
0063 if (subject.parse(first, last, context, skipper, attr))
0064 {
0065
0066
0067 if (traits::action_dispatch<Subject>()(f, attr, context))
0068 {
0069
0070
0071 transform::post(attr_, attr);
0072 return true;
0073 }
0074
0075
0076
0077 first = save;
0078 }
0079 return false;
0080 }
0081 #else
0082 template <typename Iterator, typename Context
0083 , typename Skipper, typename Attribute>
0084 bool parse(Iterator& first, Iterator const& last
0085 , Context& context, Skipper const& skipper
0086 , Attribute& attr) const
0087 {
0088 Iterator save = first;
0089 if (subject.parse(first, last, context, skipper, attr))
0090 {
0091
0092
0093 if (traits::action_dispatch<Subject>()(f, attr, context))
0094 return true;
0095
0096
0097
0098 first = save;
0099 }
0100 return false;
0101 }
0102
0103 template <typename Iterator, typename Context
0104 , typename Skipper>
0105 bool parse(Iterator& first, Iterator const& last
0106 , Context& context, Skipper const& skipper
0107 , unused_type) const
0108 {
0109 typedef typename attribute<Context, Iterator>::type attr_type;
0110
0111
0112 attr_type attr = attr_type();
0113
0114 Iterator save = first;
0115 if (subject.parse(first, last, context, skipper, attr))
0116 {
0117
0118
0119 if (traits::action_dispatch<Subject>()(f, attr, context))
0120 return true;
0121
0122
0123
0124 first = save;
0125 }
0126 return false;
0127 }
0128 #endif
0129
0130 template <typename Context>
0131 info what(Context& context) const
0132 {
0133
0134 return subject.what(context);
0135 }
0136
0137 Subject subject;
0138 Action f;
0139 };
0140 }}}
0141
0142 namespace boost { namespace spirit
0143 {
0144
0145 template <>
0146 struct make_component<qi::domain, tag::action>
0147 {
0148 template <typename Sig>
0149 struct result;
0150
0151 template <typename This, typename Elements, typename Modifiers>
0152 struct result<This(Elements, Modifiers)>
0153 {
0154 typedef typename
0155 remove_const<typename Elements::car_type>::type
0156 subject_type;
0157
0158 typedef typename
0159 remove_const<typename Elements::cdr_type::car_type>::type
0160 action_type;
0161
0162 typedef qi::action<subject_type, action_type> type;
0163 };
0164
0165 template <typename Elements>
0166 typename result<make_component(Elements, unused_type)>::type
0167 operator()(Elements const& elements, unused_type) const
0168 {
0169 typename result<make_component(Elements, unused_type)>::type
0170 result(elements.car, elements.cdr.car);
0171 return result;
0172 }
0173 };
0174 }}
0175
0176 namespace boost { namespace spirit { namespace traits
0177 {
0178
0179 template <typename Subject, typename Action>
0180 struct has_semantic_action<qi::action<Subject, Action> >
0181 : mpl::true_ {};
0182
0183
0184 template <typename Subject, typename Action, typename Attribute
0185 , typename Context, typename Iterator>
0186 struct handles_container<qi::action<Subject, Action>, Attribute
0187 , Context, Iterator>
0188 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0189 }}}
0190
0191 #endif