Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:48

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // predicate_matcher.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // MS compatible compilers support #pragma once
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     // predicate_context
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         // eval_terminal
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         // eval
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     // AssertionFunctor
0124     //
0125     struct AssertionFunctor
0126       : proto::function<
0127             proto::terminal<check_tag>
0128           , proto::terminal<proto::_>
0129         >
0130     {};
0131 
0132     ///////////////////////////////////////////////////////////////////////////////
0133     // predicate_matcher
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             // Predicate is check(assertion), where assertion can be
0152             // a lambda or a function object.
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 // BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007