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