]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/xpressive/include/boost/xpressive/detail/core/matcher/action_matcher.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / xpressive / include / boost / xpressive / detail / core / matcher / action_matcher.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // action_matcher.hpp
3 //
4 // Copyright 2008 Eric Niebler.
5 // Copyright 2008 David Jenkins.
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
12 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
13
14 // MS compatible compilers support #pragma once
15 #if defined(_MSC_VER)
16 # pragma once
17 #endif
18
19 #include <boost/config.hpp>
20 #include <boost/version.hpp>
21 #include <boost/ref.hpp>
22 #include <boost/assert.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/throw_exception.hpp>
25 #include <boost/utility/result_of.hpp>
26 #include <boost/type_traits/is_const.hpp>
27 #include <boost/type_traits/remove_reference.hpp>
28 #include <boost/xpressive/detail/detail_fwd.hpp>
29 #include <boost/xpressive/detail/core/quant_style.hpp>
30 #include <boost/xpressive/detail/core/action.hpp>
31 #include <boost/xpressive/detail/core/state.hpp>
32 #include <boost/proto/core.hpp>
33 #include <boost/proto/context.hpp>
34 #include <boost/xpressive/match_results.hpp> // for type_info_less
35 #include <boost/xpressive/detail/static/transforms/as_action.hpp> // for 'read_attr'
36 #if BOOST_VERSION >= 103500
37 # include <boost/proto/fusion.hpp>
38 # include <boost/fusion/include/transform_view.hpp>
39 # include <boost/fusion/include/invoke.hpp>
40 # include <boost/fusion/include/push_front.hpp>
41 # include <boost/fusion/include/pop_front.hpp>
42 #endif
43
44 #if BOOST_MSVC
45 #pragma warning(push)
46 #pragma warning(disable : 4510) // default constructor could not be generated
47 #pragma warning(disable : 4512) // assignment operator could not be generated
48 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
49 #endif
50
51 namespace boost { namespace xpressive { namespace detail
52 {
53
54 #if BOOST_VERSION >= 103500
55 struct DataMember
56 : proto::mem_ptr<proto::_, proto::terminal<proto::_> >
57 {};
58
59 template<typename Expr, long N>
60 struct child_
61 : remove_reference<
62 typename proto::result_of::child_c<Expr &, N>::type
63 >
64 {};
65
66 ///////////////////////////////////////////////////////////////////////////////
67 // mem_ptr_eval
68 // Rewrites expressions of the form x->*foo(a) into foo(x, a) and then
69 // evaluates them.
70 template<typename Expr, typename Context, bool IsDataMember = proto::matches<Expr, DataMember>::value>
71 struct mem_ptr_eval
72 {
73 typedef typename child_<Expr, 0>::type left_type;
74 typedef typename child_<Expr, 1>::type right_type;
75
76 typedef
77 typename proto::result_of::value<
78 typename proto::result_of::child_c<right_type, 0>::type
79 >::type
80 function_type;
81
82 typedef
83 fusion::transform_view<
84 typename fusion::result_of::push_front<
85 typename fusion::result_of::pop_front<right_type>::type const
86 , reference_wrapper<left_type>
87 >::type const
88 , proto::eval_fun<Context>
89 >
90 evaluated_args;
91
92 typedef
93 typename fusion::result_of::invoke<function_type, evaluated_args>::type
94 result_type;
95
96 result_type operator()(Expr &expr, Context &ctx) const
97 {
98 return fusion::invoke<function_type>(
99 proto::value(proto::child_c<0>(proto::right(expr)))
100 , evaluated_args(
101 fusion::push_front(fusion::pop_front(proto::right(expr)), boost::ref(proto::left(expr)))
102 , proto::eval_fun<Context>(ctx)
103 )
104 );
105 }
106 };
107
108 ///////////////////////////////////////////////////////////////////////////////
109 // mem_ptr_eval
110 // Rewrites expressions of the form x->*foo into foo(x) and then
111 // evaluates them.
112 template<typename Expr, typename Context>
113 struct mem_ptr_eval<Expr, Context, true>
114 {
115 typedef typename child_<Expr, 0>::type left_type;
116 typedef typename child_<Expr, 1>::type right_type;
117
118 typedef
119 typename proto::result_of::value<right_type>::type
120 function_type;
121
122 typedef typename boost::result_of<
123 function_type(typename proto::result_of::eval<left_type, Context>::type)
124 >::type result_type;
125
126 result_type operator()(Expr &expr, Context &ctx) const
127 {
128 return proto::value(proto::right(expr))(
129 proto::eval(proto::left(expr), ctx)
130 );
131 }
132 };
133 #endif
134
135 struct attr_with_default_tag
136 {};
137
138 template<typename T>
139 struct opt;
140
141 ///////////////////////////////////////////////////////////////////////////////
142 // action_context
143 //
144 struct action_context
145 {
146 explicit action_context(action_args_type *action_args)
147 : action_args_(action_args)
148 {}
149
150 action_args_type const &args() const
151 {
152 return *this->action_args_;
153 }
154
155 // eval_terminal
156 template<typename Expr, typename Arg>
157 struct eval_terminal
158 : proto::default_eval<Expr, action_context const>
159 {};
160
161 template<typename Expr, typename Arg>
162 struct eval_terminal<Expr, reference_wrapper<Arg> >
163 {
164 typedef Arg &result_type;
165 result_type operator()(Expr &expr, action_context const &) const
166 {
167 return proto::value(expr).get();
168 }
169 };
170
171 template<typename Expr, typename Arg>
172 struct eval_terminal<Expr, opt<Arg> >
173 {
174 typedef Arg const &result_type;
175 result_type operator()(Expr &expr, action_context const &) const
176 {
177 return proto::value(expr);
178 }
179 };
180
181 template<typename Expr, typename Type, typename Int>
182 struct eval_terminal<Expr, action_arg<Type, Int> >
183 {
184 typedef typename action_arg<Type, Int>::reference result_type;
185 result_type operator()(Expr &expr, action_context const &ctx) const
186 {
187 action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
188 if(where_ == ctx.args().end())
189 {
190 BOOST_THROW_EXCEPTION(
191 regex_error(
192 regex_constants::error_badarg
193 , "An argument to an action was unspecified"
194 )
195 );
196 }
197 return proto::value(expr).cast(where_->second);
198 }
199 };
200
201 // eval
202 template<typename Expr, typename Tag = typename Expr::proto_tag>
203 struct eval
204 : proto::default_eval<Expr, action_context const>
205 {};
206
207 template<typename Expr>
208 struct eval<Expr, proto::tag::terminal>
209 : eval_terminal<Expr, typename proto::result_of::value<Expr>::type>
210 {};
211
212 // Evaluate attributes like a1|42
213 template<typename Expr>
214 struct eval<Expr, attr_with_default_tag>
215 {
216 typedef
217 typename proto::result_of::value<
218 typename proto::result_of::left<
219 typename proto::result_of::child<
220 Expr
221 >::type
222 >::type
223 >::type
224 temp_type;
225
226 typedef typename temp_type::type result_type;
227
228 result_type operator ()(Expr const &expr, action_context const &ctx) const
229 {
230 return proto::value(proto::left(proto::child(expr))).t_
231 ? *proto::value(proto::left(proto::child(expr))).t_
232 : proto::eval(proto::right(proto::child(expr)), ctx);
233 }
234 };
235
236 #if BOOST_VERSION >= 103500
237 template<typename Expr>
238 struct eval<Expr, proto::tag::mem_ptr>
239 : mem_ptr_eval<Expr, action_context const>
240 {};
241 #endif
242
243 private:
244 action_args_type *action_args_;
245 };
246
247 ///////////////////////////////////////////////////////////////////////////////
248 // action
249 //
250 template<typename Actor>
251 struct action
252 : actionable
253 {
254 action(Actor const &actor)
255 : actionable()
256 , actor_(actor)
257 {
258 }
259
260 virtual void execute(action_args_type *action_args) const
261 {
262 action_context const ctx(action_args);
263 proto::eval(this->actor_, ctx);
264 }
265
266 private:
267 Actor actor_;
268 };
269
270 ///////////////////////////////////////////////////////////////////////////////
271 // subreg_transform
272 //
273 struct subreg_transform : proto::transform<subreg_transform>
274 {
275 template<typename Expr, typename State, typename Data>
276 struct impl : proto::transform_impl<Expr, State, Data>
277 {
278 typedef typename impl::state state_type;
279
280 typedef
281 typename proto::terminal<sub_match<typename state_type::iterator> >::type
282 result_type;
283
284 result_type operator ()(
285 typename impl::expr_param
286 , typename impl::state_param state
287 , typename impl::data_param data
288 ) const
289 {
290 return result_type::make(state.sub_matches_[ data ]);
291 }
292 };
293 };
294
295 ///////////////////////////////////////////////////////////////////////////////
296 // mark_transform
297 //
298 struct mark_transform : proto::transform<mark_transform>
299 {
300 template<typename Expr, typename State, typename Data>
301 struct impl : proto::transform_impl<Expr, State, Data>
302 {
303 typedef typename impl::state state_type;
304 typedef
305 typename proto::terminal<sub_match<typename state_type::iterator> >::type
306 result_type;
307
308 result_type operator ()(
309 typename impl::expr_param expr
310 , typename impl::state_param state
311 , typename impl::data_param
312 ) const
313 {
314 return result_type::make(state.sub_matches_[ proto::value(expr).mark_number_ ]);
315 }
316 };
317 };
318
319 ///////////////////////////////////////////////////////////////////////////////
320 // opt
321 //
322 template<typename T>
323 struct opt
324 {
325 typedef T type;
326 typedef T const &reference;
327
328 opt(T const *t)
329 : t_(t)
330 {}
331
332 operator reference() const
333 {
334 BOOST_XPR_ENSURE_(0 != this->t_, regex_constants::error_badattr, "Use of uninitialized regex attribute");
335 return *this->t_;
336 }
337
338 T const *t_;
339 };
340
341 ///////////////////////////////////////////////////////////////////////////////
342 // attr_transform
343 //
344 struct attr_transform : proto::transform<attr_transform>
345 {
346 template<typename Expr, typename State, typename Data>
347 struct impl : proto::transform_impl<Expr, State, Data>
348 {
349 typedef typename impl::expr expr_type;
350
351 typedef
352 typename expr_type::proto_child0::matcher_type::value_type::second_type
353 attr_type;
354
355 typedef
356 typename proto::terminal<opt<attr_type> >::type
357 result_type;
358
359 result_type operator ()(
360 typename impl::expr_param
361 , typename impl::state_param state
362 , typename impl::data_param
363 ) const
364 {
365 int slot = typename expr_type::proto_child0::nbr_type();
366 attr_type const *attr = static_cast<attr_type const *>(state.attr_context_.attr_slots_[slot-1]);
367 return result_type::make(opt<attr_type>(attr));
368 }
369 };
370 };
371
372 ///////////////////////////////////////////////////////////////////////////////
373 // attr_with_default_transform
374 //
375 template<typename Grammar, typename Callable = proto::callable>
376 struct attr_with_default_transform : proto::transform<attr_with_default_transform<Grammar, Callable> >
377 {
378 template<typename Expr, typename State, typename Data>
379 struct impl : proto::transform_impl<Expr, State, Data>
380 {
381 typedef
382 typename proto::unary_expr<
383 attr_with_default_tag
384 , typename Grammar::template impl<Expr, State, Data>::result_type
385 >::type
386 result_type;
387
388 result_type operator ()(
389 typename impl::expr_param expr
390 , typename impl::state_param state
391 , typename impl::data_param data
392 ) const
393 {
394 result_type that = {
395 typename Grammar::template impl<Expr, State, Data>()(expr, state, data)
396 };
397 return that;
398 }
399 };
400 };
401
402 ///////////////////////////////////////////////////////////////////////////////
403 // by_ref_transform
404 //
405 struct by_ref_transform : proto::transform<by_ref_transform>
406 {
407 template<typename Expr, typename State, typename Data>
408 struct impl : proto::transform_impl<Expr, State, Data>
409 {
410 typedef
411 typename proto::result_of::value<typename impl::expr_param>::type
412 reference;
413
414 typedef
415 typename proto::terminal<reference>::type
416 result_type;
417
418 result_type operator ()(
419 typename impl::expr_param expr
420 , typename impl::state_param
421 , typename impl::data_param
422 ) const
423 {
424 return result_type::make(proto::value(expr));
425 }
426 };
427 };
428
429 ///////////////////////////////////////////////////////////////////////////////
430 // BindActionArgs
431 //
432 struct BindActionArgs
433 : proto::or_<
434 proto::when<proto::terminal<any_matcher>, subreg_transform>
435 , proto::when<proto::terminal<mark_placeholder>, mark_transform>
436 , proto::when<proto::terminal<read_attr<proto::_, proto::_> >, attr_transform>
437 , proto::when<proto::terminal<proto::_>, by_ref_transform>
438 , proto::when<
439 proto::bitwise_or<proto::terminal<read_attr<proto::_, proto::_> >, BindActionArgs>
440 , attr_with_default_transform<proto::bitwise_or<attr_transform, BindActionArgs> >
441 >
442 , proto::otherwise<proto::nary_expr<proto::_, proto::vararg<BindActionArgs> > >
443 >
444 {};
445
446 ///////////////////////////////////////////////////////////////////////////////
447 // action_matcher
448 //
449 template<typename Actor>
450 struct action_matcher
451 : quant_style<quant_none, 0, false>
452 {
453 int sub_;
454 Actor actor_;
455
456 action_matcher(Actor const &actor, int sub)
457 : sub_(sub)
458 , actor_(actor)
459 {
460 }
461
462 template<typename BidiIter, typename Next>
463 bool match(match_state<BidiIter> &state, Next const &next) const
464 {
465 // Bind the arguments
466 typedef
467 typename boost::result_of<BindActionArgs(
468 Actor const &
469 , match_state<BidiIter> &
470 , int const &
471 )>::type
472 action_type;
473
474 action<action_type> actor(BindActionArgs()(this->actor_, state, this->sub_));
475
476 // Put the action in the action list
477 actionable const **action_list_tail = state.action_list_tail_;
478 *state.action_list_tail_ = &actor;
479 state.action_list_tail_ = &actor.next;
480
481 // Match the rest of the pattern
482 if(next.match(state))
483 {
484 return true;
485 }
486
487 BOOST_ASSERT(0 == actor.next);
488 // remove action from list
489 *action_list_tail = 0;
490 state.action_list_tail_ = action_list_tail;
491 return false;
492 }
493 };
494
495 }}}
496
497 #if BOOST_MSVC
498 #pragma warning(pop)
499 #endif
500
501 #endif