]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/xpressive/include/boost/xpressive/detail/core/matcher/predicate_matcher.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / xpressive / include / boost / xpressive / detail / core / matcher / predicate_matcher.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // predicate_matcher.hpp
3 //
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007
9 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007
10
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER)
13 # pragma once
14 #endif
15
16 #include <boost/mpl/not.hpp>
17 #include <boost/mpl/placeholders.hpp>
18 #include <boost/xpressive/detail/detail_fwd.hpp>
19 #include <boost/xpressive/detail/core/quant_style.hpp>
20 #include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
21 #include <boost/xpressive/detail/core/state.hpp>
22 #include <boost/proto/core.hpp>
23
24 namespace boost { namespace xpressive { namespace detail
25 {
26 ///////////////////////////////////////////////////////////////////////////////
27 // predicate_context
28 //
29 template<typename BidiIter>
30 struct predicate_context
31 {
32 explicit predicate_context(int sub, sub_match_impl<BidiIter> const *sub_matches, action_args_type *action_args)
33 : sub_(sub)
34 , sub_matches_(sub_matches)
35 , action_args_(action_args)
36 {}
37
38 action_args_type const &args() const
39 {
40 return *this->action_args_;
41 }
42
43 // eval_terminal
44 template<typename Expr, typename Arg>
45 struct eval_terminal
46 : proto::default_eval<Expr, predicate_context const>
47 {};
48
49 template<typename Expr, typename Arg>
50 struct eval_terminal<Expr, reference_wrapper<Arg> >
51 {
52 typedef Arg &result_type;
53 result_type operator()(Expr &expr, predicate_context const &) const
54 {
55 return proto::value(expr).get();
56 }
57 };
58
59 template<typename Expr>
60 struct eval_terminal<Expr, any_matcher>
61 {
62 typedef sub_match<BidiIter> const &result_type;
63 result_type operator()(Expr &, predicate_context const &ctx) const
64 {
65 return ctx.sub_matches_[ctx.sub_];
66 }
67 };
68
69 template<typename Expr>
70 struct eval_terminal<Expr, mark_placeholder>
71 {
72 typedef sub_match<BidiIter> const &result_type;
73 result_type operator()(Expr &expr, predicate_context const &ctx) const
74 {
75 return ctx.sub_matches_[proto::value(expr).mark_number_];
76 }
77 };
78
79 template<typename Expr, typename Type, typename Int>
80 struct eval_terminal<Expr, action_arg<Type, Int> >
81 {
82 typedef typename action_arg<Type, Int>::reference result_type;
83 result_type operator()(Expr &expr, predicate_context const &ctx) const
84 {
85 action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
86 if(where_ == ctx.args().end())
87 {
88 BOOST_THROW_EXCEPTION(
89 regex_error(
90 regex_constants::error_badarg
91 , "An argument to an action was unspecified"
92 )
93 );
94 }
95 return proto::value(expr).cast(where_->second);
96 }
97 };
98
99 // eval
100 template<typename Expr, typename Tag = typename Expr::proto_tag>
101 struct eval
102 : proto::default_eval<Expr, predicate_context const>
103 {};
104
105 template<typename Expr>
106 struct eval<Expr, proto::tag::terminal>
107 : eval_terminal<Expr, typename proto::result_of::value<Expr>::type>
108 {};
109
110 #if BOOST_VERSION >= 103500
111 template<typename Expr>
112 struct eval<Expr, proto::tag::mem_ptr>
113 : mem_ptr_eval<Expr, predicate_context const>
114 {};
115 #endif
116
117 int sub_;
118 sub_match_impl<BidiIter> const *sub_matches_;
119 action_args_type *action_args_;
120 };
121
122 ///////////////////////////////////////////////////////////////////////////////
123 // AssertionFunctor
124 //
125 struct AssertionFunctor
126 : proto::function<
127 proto::terminal<check_tag>
128 , proto::terminal<proto::_>
129 >
130 {};
131
132 ///////////////////////////////////////////////////////////////////////////////
133 // predicate_matcher
134 //
135 template<typename Predicate>
136 struct predicate_matcher
137 : quant_style_assertion
138 {
139 int sub_;
140 Predicate predicate_;
141
142 predicate_matcher(Predicate const &pred, int sub)
143 : sub_(sub)
144 , predicate_(pred)
145 {
146 }
147
148 template<typename BidiIter, typename Next>
149 bool match(match_state<BidiIter> &state, Next const &next) const
150 {
151 // Predicate is check(assertion), where assertion can be
152 // a lambda or a function object.
153 return this->match_(state, next, proto::matches<Predicate, AssertionFunctor>());
154 }
155
156 private:
157 template<typename BidiIter, typename Next>
158 bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const
159 {
160 sub_match<BidiIter> const &sub = state.sub_match(this->sub_);
161 return proto::value(proto::child_c<1>(this->predicate_))(sub) && next.match(state);
162 }
163
164 template<typename BidiIter, typename Next>
165 bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
166 {
167 predicate_context<BidiIter> ctx(this->sub_, state.sub_matches_, state.action_args_);
168 return proto::eval(proto::child_c<1>(this->predicate_), ctx) && next.match(state);
169 }
170 };
171
172 }}}
173
174 #endif // BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_PREDICATE_MATCHER_HPP_EAN_03_22_2007