File indexing completed on 2025-01-18 09:53:48
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007
0009 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/mpl/not.hpp>
0017 #include <boost/mpl/placeholders.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/core/quant_style.hpp>
0020 #include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
0021 #include <boost/xpressive/detail/core/state.hpp>
0022 #include <boost/proto/core.hpp>
0023
0024 namespace boost { namespace xpressive { namespace detail
0025 {
0026
0027
0028
0029 template<typename BidiIter>
0030 struct predicate_context
0031 {
0032 explicit predicate_context(int sub, sub_match_impl<BidiIter> const *sub_matches, action_args_type *action_args)
0033 : sub_(sub)
0034 , sub_matches_(sub_matches)
0035 , action_args_(action_args)
0036 {}
0037
0038 action_args_type const &args() const
0039 {
0040 return *this->action_args_;
0041 }
0042
0043
0044 template<typename Expr, typename Arg>
0045 struct eval_terminal
0046 : proto::default_eval<Expr, predicate_context const>
0047 {};
0048
0049 template<typename Expr, typename Arg>
0050 struct eval_terminal<Expr, reference_wrapper<Arg> >
0051 {
0052 typedef Arg &result_type;
0053 result_type operator()(Expr &expr, predicate_context const &) const
0054 {
0055 return proto::value(expr).get();
0056 }
0057 };
0058
0059 template<typename Expr>
0060 struct eval_terminal<Expr, any_matcher>
0061 {
0062 typedef sub_match<BidiIter> const &result_type;
0063 result_type operator()(Expr &, predicate_context const &ctx) const
0064 {
0065 return ctx.sub_matches_[ctx.sub_];
0066 }
0067 };
0068
0069 template<typename Expr>
0070 struct eval_terminal<Expr, mark_placeholder>
0071 {
0072 typedef sub_match<BidiIter> const &result_type;
0073 result_type operator()(Expr &expr, predicate_context const &ctx) const
0074 {
0075 return ctx.sub_matches_[proto::value(expr).mark_number_];
0076 }
0077 };
0078
0079 template<typename Expr, typename Type, typename Int>
0080 struct eval_terminal<Expr, action_arg<Type, Int> >
0081 {
0082 typedef typename action_arg<Type, Int>::reference result_type;
0083 result_type operator()(Expr &expr, predicate_context const &ctx) const
0084 {
0085 action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
0086 if(where_ == ctx.args().end())
0087 {
0088 BOOST_THROW_EXCEPTION(
0089 regex_error(
0090 regex_constants::error_badarg
0091 , "An argument to an action was unspecified"
0092 )
0093 );
0094 }
0095 return proto::value(expr).cast(where_->second);
0096 }
0097 };
0098
0099
0100 template<typename Expr, typename Tag = typename Expr::proto_tag>
0101 struct eval
0102 : proto::default_eval<Expr, predicate_context const>
0103 {};
0104
0105 template<typename Expr>
0106 struct eval<Expr, proto::tag::terminal>
0107 : eval_terminal<Expr, typename proto::result_of::value<Expr>::type>
0108 {};
0109
0110 #if BOOST_VERSION >= 103500
0111 template<typename Expr>
0112 struct eval<Expr, proto::tag::mem_ptr>
0113 : mem_ptr_eval<Expr, predicate_context const>
0114 {};
0115 #endif
0116
0117 int sub_;
0118 sub_match_impl<BidiIter> const *sub_matches_;
0119 action_args_type *action_args_;
0120 };
0121
0122
0123
0124
0125 struct AssertionFunctor
0126 : proto::function<
0127 proto::terminal<check_tag>
0128 , proto::terminal<proto::_>
0129 >
0130 {};
0131
0132
0133
0134
0135 template<typename Predicate>
0136 struct predicate_matcher
0137 : quant_style_assertion
0138 {
0139 int sub_;
0140 Predicate predicate_;
0141
0142 predicate_matcher(Predicate const &pred, int sub)
0143 : sub_(sub)
0144 , predicate_(pred)
0145 {
0146 }
0147
0148 template<typename BidiIter, typename Next>
0149 bool match(match_state<BidiIter> &state, Next const &next) const
0150 {
0151
0152
0153 return this->match_(state, next, proto::matches<Predicate, AssertionFunctor>());
0154 }
0155
0156 private:
0157 template<typename BidiIter, typename Next>
0158 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const
0159 {
0160 sub_match<BidiIter> const &sub = state.sub_match(this->sub_);
0161 return proto::value(proto::child_c<1>(this->predicate_))(sub) && next.match(state);
0162 }
0163
0164 template<typename BidiIter, typename Next>
0165 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
0166 {
0167 predicate_context<BidiIter> ctx(this->sub_, state.sub_matches_, state.action_args_);
0168 return proto::eval(proto::child_c<1>(this->predicate_), ctx) && next.match(state);
0169 }
0170 };
0171
0172 }}}
0173
0174 #endif