/////////////////////////////////////////////////////////////////////////////// // predicate_matcher.hpp // // Copyright 2008 Eric Niebler. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007 // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #include #include #include namespace boost { namespace xpressive { namespace detail { /////////////////////////////////////////////////////////////////////////////// // predicate_context // template struct predicate_context { explicit predicate_context(int sub, sub_match_impl const *sub_matches, action_args_type *action_args) : sub_(sub) , sub_matches_(sub_matches) , action_args_(action_args) {} action_args_type const &args() const { return *this->action_args_; } // eval_terminal template struct eval_terminal : proto::default_eval {}; template struct eval_terminal > { typedef Arg &result_type; result_type operator()(Expr &expr, predicate_context const &) const { return proto::value(expr).get(); } }; template struct eval_terminal { typedef sub_match const &result_type; result_type operator()(Expr &, predicate_context const &ctx) const { return ctx.sub_matches_[ctx.sub_]; } }; template struct eval_terminal { typedef sub_match const &result_type; result_type operator()(Expr &expr, predicate_context const &ctx) const { return ctx.sub_matches_[proto::value(expr).mark_number_]; } }; template struct eval_terminal > { typedef typename action_arg::reference result_type; result_type operator()(Expr &expr, predicate_context const &ctx) const { action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr))); if(where_ == ctx.args().end()) { BOOST_THROW_EXCEPTION( regex_error( regex_constants::error_badarg , "An argument to an action was unspecified" ) ); } return proto::value(expr).cast(where_->second); } }; // eval template struct eval : proto::default_eval {}; template struct eval : eval_terminal::type> {}; #if BOOST_VERSION >= 103500 template struct eval : mem_ptr_eval {}; #endif int sub_; sub_match_impl const *sub_matches_; action_args_type *action_args_; }; /////////////////////////////////////////////////////////////////////////////// // AssertionFunctor // struct AssertionFunctor : proto::function< proto::terminal , proto::terminal > {}; /////////////////////////////////////////////////////////////////////////////// // predicate_matcher // template struct predicate_matcher : quant_style_assertion { int sub_; Predicate predicate_; predicate_matcher(Predicate const &pred, int sub) : sub_(sub) , predicate_(pred) { } template bool match(match_state &state, Next const &next) const { // Predicate is check(assertion), where assertion can be // a lambda or a function object. return this->match_(state, next, proto::matches()); } private: template bool match_(match_state &state, Next const &next, mpl::true_) const { sub_match const &sub = state.sub_match(this->sub_); return proto::value(proto::child_c<1>(this->predicate_))(sub) && next.match(state); } template bool match_(match_state &state, Next const &next, mpl::false_) const { predicate_context ctx(this->sub_, state.sub_matches_, state.action_args_); return proto::eval(proto::child_c<1>(this->predicate_), ctx) && next.match(state); } }; }}} #endif // BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007