]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/support/make_component.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / spirit / home / support / make_component.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 http://spirit.sourceforge.net/
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7=============================================================================*/
8#ifndef BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
9#define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
10
11#if defined(_MSC_VER)
12#pragma once
13#endif
14
7c673cae
FG
15#include <boost/spirit/home/support/detail/make_cons.hpp>
16#include <boost/spirit/home/support/modify.hpp>
f67539c2
TL
17#include <boost/phoenix/core/actor.hpp>
18#include <boost/phoenix/core/is_actor.hpp>
19#include <boost/proto/tags.hpp>
20#include <boost/proto/traits.hpp>
21#include <boost/proto/transform.hpp>
7c673cae
FG
22
23namespace boost { namespace spirit
24{
25 // There is no real "component" class. Each domain is responsible
26 // for creating its own components. You need to specialize this for
27 // each component in your domain. Use this as a guide.
28
29 template <typename Domain, typename Tag, typename Enable = void>
30 struct make_component
31 {
32 template <typename Sig>
33 struct result;
34
35 template <typename This, typename Elements, typename Modifiers>
36 struct result<This(Elements, Modifiers)>;
37
38 template <typename Elements, typename Modifiers>
39 typename result<make_component(Elements, Modifiers)>::type
40 operator()(Elements const& elements, Modifiers const& modifiers) const;
41 };
42
43 namespace tag
44 {
45 // Normally, we use proto tags as-is to distinguish operators.
46 // The special case is proto::tag::subscript. Spirit uses this
47 // as either sementic actions or directives. To distinguish between
48 // the two, we use these special tags below.
49
50 struct directive;
51 struct action;
52 }
53
54 template <typename Domain, typename T, typename Enable = void>
55 struct flatten_tree;
56}}
57
58namespace boost { namespace spirit { namespace detail
59{
60 template <typename Expr, typename State, typename Data, typename Domain>
61 struct make_terminal_impl
62 : proto::transform_impl<Expr, State, Data>
63 {
64 typedef typename
65 proto::result_of::value<Expr>::type
66 value;
67
68 typedef typename result_of::make_cons<value>::type elements;
69
70 typedef
71 make_component<Domain, proto::tag::terminal>
72 make_component_;
73
74 typedef typename
75 make_component_::template
76 result<make_component_(elements, Data)>::type
77 result_type;
78
79 result_type operator()(
80 typename make_terminal_impl::expr_param expr
81 , typename make_terminal_impl::state_param /*state*/
82 , typename make_terminal_impl::data_param data
83 ) const
84 {
85 return typename make_terminal_impl::make_component_()(
86 detail::make_cons(proto::value(expr))
87 , data
88 );
89 }
90 };
91
92 template <typename Expr, typename State, typename Data, typename Domain>
93 struct make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
94 : proto::transform_impl<phoenix::actor<Expr>, State, Data>
95 {
96 typedef phoenix::actor<Expr> value;
97 typedef typename result_of::make_cons<value>::type elements;
98 typedef make_component<Domain, proto::tag::terminal> make_component_;
99
100 typedef typename
101 make_component_::template
102 result<make_component_(elements, Data)>::type
103 result_type;
104
105 result_type operator()(
106 typename make_terminal_impl::expr_param expr
107 , typename make_terminal_impl::state_param /*state*/
108 , typename make_terminal_impl::data_param data
109 ) const
110 {
111 return typename make_terminal_impl::make_component_()(
112 detail::make_cons(expr)
113 , data
114 );
115 }
116 };
117
118 template <typename Expr, typename State, typename Data, typename Domain>
119 struct make_terminal_impl<phoenix::actor<Expr> &, State, Data, Domain>
120 : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
121 {};
122
123 template <typename Expr, typename State, typename Data, typename Domain>
124 struct make_terminal_impl<phoenix::actor<Expr> const &, State, Data, Domain>
125 : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
126 {};
127
128 template <typename Domain>
129 struct make_terminal : proto::transform<make_terminal<Domain> >
130 {
131 template<typename Expr, typename State, typename Data>
132 struct impl : make_terminal_impl<Expr, State, Data, Domain> {};
133 };
134
135 template <typename Domain, typename Tag, typename Grammar>
136 struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
137 {
138 template<typename Expr, typename State, typename Data>
139 struct impl : proto::transform_impl<Expr, State, Data>
140 {
141 typedef typename
142 proto::result_of::child_c<Expr, 0>::type
143 child;
144
145 typedef typename Grammar::
146 template result<Grammar(child, State, Data)>::type
147 child_component;
148
149 typedef typename
150 result_of::make_cons<child_component>::type
151 elements;
152
153 typedef make_component<Domain, Tag> make_component_;
154
155 typedef typename
156 make_component_::template
157 result<make_component_(elements, Data)>::type
158 result_type;
159
160 result_type operator()(
161 typename impl::expr_param expr
162 , typename impl::state_param state
163 , typename impl::data_param data
164 ) const
165 {
166 return typename impl::make_component_()(
167 detail::make_cons(
168 Grammar()(proto::child(expr), state, data))
169 , data
170 );
171 }
172 };
173 };
174
175 // un-flattened version
176 template <typename Domain, typename Tag, typename Grammar,
177 bool flatten = flatten_tree<Domain, Tag>::value>
178 struct make_binary
179 {
180 template<typename Expr, typename State, typename Data>
181 struct impl : proto::transform_impl<Expr, State, Data>
182 {
183 typedef typename Grammar::
184 template result<Grammar(
185 typename proto::result_of::child_c<Expr, 0>::type
186 , State, Data)>::type
187 lhs_component;
188
189 typedef typename Grammar::
190 template result<Grammar(
191 typename proto::result_of::child_c<Expr, 1>::type
192 , State, Data)>::type
193 rhs_component;
194
195 typedef typename
196 result_of::make_cons<
197 lhs_component
198 , typename result_of::make_cons<rhs_component>::type
199 >::type
200 elements_type;
201
202 typedef make_component<Domain, Tag> make_component_;
203
204 typedef typename
205 make_component_::template
206 result<make_component_(elements_type, Data)>::type
207 result_type;
208
209 result_type operator()(
210 typename impl::expr_param expr
211 , typename impl::state_param state
212 , typename impl::data_param data
213 ) const
214 {
215 elements_type elements =
216 detail::make_cons(
217 Grammar()(
218 proto::child_c<0>(expr), state, data) // LHS
219 , detail::make_cons(
220 Grammar()(
221 proto::child_c<1>(expr), state, data) // RHS
222 )
223 );
224
225 return make_component_()(elements, data);
226 }
227 };
228 };
229
230 template <typename Grammar>
231 struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
232 {
233 template<typename Expr, typename State, typename Data>
234 struct impl : proto::transform_impl<Expr, State, Data>
235 {
236 typedef typename Grammar::
237 template result<Grammar(Expr, State, Data)>::type
238 lhs;
239
240 typedef typename result_of::make_cons<lhs, State>::type result_type;
241
242 result_type operator()(
243 typename impl::expr_param expr
244 , typename impl::state_param state
245 , typename impl::data_param data
246 ) const
247 {
248 return detail::make_cons(Grammar()(expr, state, data), state);
249 }
250 };
251 };
252
253 // Flattened version
254 template <typename Domain, typename Tag, typename Grammar>
255 struct make_binary<Domain, Tag, Grammar, true>
256 : proto::transform<make_binary<Domain, Tag, Grammar> >
257 {
258 template<typename Expr, typename State, typename Data>
259 struct impl : proto::transform_impl<Expr, State, Data>
260 {
261 typedef typename
262 proto::reverse_fold_tree<
263 proto::_
264 , proto::make<fusion::nil_>
265 , make_binary_helper<Grammar>
266 >::template impl<Expr, State, Data>
267 reverse_fold_tree;
268
269 typedef typename reverse_fold_tree::result_type elements;
270 typedef make_component<Domain, Tag> make_component_;
271
272 typedef typename
273 make_component_::template
274 result<make_component_(elements, Data)>::type
275 result_type;
276
277 result_type operator()(
278 typename impl::expr_param expr
279 , typename impl::state_param state
280 , typename impl::data_param data
281 ) const
282 {
283 return make_component_()(
284 reverse_fold_tree()(expr, state, data), data);
285 }
286 };
287 };
288
289 template <typename Domain, typename Grammar>
290 struct make_directive : proto::transform<make_directive<Domain, Grammar> >
291 {
292 template<typename Expr, typename State, typename Data>
293 struct impl : proto::transform_impl<Expr, State, Data>
294 {
295 typedef typename
296 proto::result_of::child_c<Expr, 0>::type
297 lhs;
298
299 typedef typename
300 proto::result_of::value<lhs>::type
301 tag_type;
302
303 typedef typename modify<Domain>::
304 template result<modify<Domain>(tag_type, Data)>::type
305 modifier_type;
306
307 typedef typename Grammar::
308 template result<Grammar(
309 typename proto::result_of::child_c<Expr, 1>::type
310 , State
311 , modifier_type
312 )>::type
313 rhs_component;
314
315 typedef typename
316 result_of::make_cons<
317 tag_type
318 , typename result_of::make_cons<rhs_component>::type
319 >::type
320 elements_type;
321
322 typedef make_component<Domain, tag::directive> make_component_;
323
324 typedef typename
325 make_component_::template
326 result<make_component_(elements_type, Data)>::type
327 result_type;
328
329 result_type operator()(
330 typename impl::expr_param expr
331 , typename impl::state_param state
332 , typename impl::data_param data
333 ) const
334 {
335 tag_type tag = proto::value(proto::child_c<0>(expr));
336 typename remove_reference<modifier_type>::type
337 modifier = modify<Domain>()(tag, data);
338
339 elements_type elements =
340 detail::make_cons(
341 tag // LHS
342 , detail::make_cons(
343 Grammar()(
344 proto::child_c<1>(expr) // RHS
345 , state, modifier)
346 )
347 );
348
349 return make_component_()(elements, data);
350 }
351 };
352 };
353
354 template <typename Domain, typename Grammar>
355 struct make_action : proto::transform<make_action<Domain, Grammar> >
356 {
357 template<typename Expr, typename State, typename Data>
358 struct impl : proto::transform_impl<Expr, State, Data>
359 {
360 typedef typename Grammar::
361 template result<Grammar(
362 typename proto::result_of::child_c<Expr, 0>::type
363 , State
364 , Data
365 )>::type
366 lhs_component;
367
368 typedef
369 typename mpl::eval_if_c<
370 phoenix::is_actor<
371 typename proto::result_of::child_c<Expr, 1>::type
372 >::type::value
373 , proto::result_of::child_c<Expr, 1>
374 , proto::result_of::value<
375 typename proto::result_of::child_c<Expr, 1>::type
376 >
377 >::type
378 rhs_component;
379
380 typedef typename
381 result_of::make_cons<
382 lhs_component
383 , typename result_of::make_cons<rhs_component>::type
384 >::type
385 elements_type;
386
387 typedef make_component<Domain, tag::action> make_component_;
388
389 typedef typename
390 make_component_::template
391 result<make_component_(elements_type, Data)>::type
392 result_type;
393
394 result_type operator()(
395 typename impl::expr_param expr
396 , typename impl::state_param state
397 , typename impl::data_param data
398 ) const
399 {
400 return
401 (*this)(
402 expr
403 , state
404 , data
405 , typename phoenix::is_actor<
406 typename proto::result_of::child_c<Expr, 1>::type
407 >::type()
408 );
409 }
410
411 result_type operator()(
412 typename impl::expr_param expr
413 , typename impl::state_param state
414 , typename impl::data_param data
415 , mpl::false_
416 ) const
417 {
418 elements_type elements =
419 detail::make_cons(
420 Grammar()(
421 proto::child_c<0>(expr), state, data) // LHS
422 , detail::make_cons(
423 proto::value(proto::child_c<1>(expr))) // RHS
424 );
425
426 return make_component_()(elements, data);
427 }
428
429 result_type operator()(
430 typename impl::expr_param expr
431 , typename impl::state_param state
432 , typename impl::data_param data
433 , mpl::true_
434 ) const
435 {
436 elements_type elements =
437 detail::make_cons(
438 Grammar()(
439 proto::child_c<0>(expr), state, data) // LHS
440 , detail::make_cons(
441 proto::child_c<1>(expr)) // RHS
442 );
443
444 return make_component_()(elements, data);
445 }
446 };
447 };
448}}}
449
450#endif