File indexing completed on 2025-01-19 09:47:43
0001
0002
0003
0004
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
0026
0027
0028
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
0041
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
0060
0061
0062 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Subject);
0063 }
0064
0065
0066
0067
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
0081
0082
0083 typedef typename mpl::if_<
0084 traits::not_is_unused<Exposed>, Exposed, Attribute>::type
0085 exposed_attribute_type;
0086
0087
0088
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
0103
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
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