]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | /// \file default.hpp | |
3 | /// Contains definition of the _default transform, which gives operators their | |
4 | /// usual C++ meanings and uses Boost.Typeof to deduce return types. | |
5 | // | |
6 | // Copyright 2008 Eric Niebler. Distributed under the Boost | |
7 | // Software License, Version 1.0. (See accompanying file | |
8 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | ||
10 | #ifndef BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008 | |
11 | #define BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008 | |
12 | ||
13 | #include <boost/preprocessor/iteration/iterate.hpp> | |
14 | #include <boost/preprocessor/repetition/repeat.hpp> | |
15 | #include <boost/preprocessor/arithmetic/add.hpp> | |
16 | #include <boost/preprocessor/arithmetic/sub.hpp> | |
17 | #include <boost/preprocessor/repetition/enum.hpp> | |
18 | #include <boost/preprocessor/repetition/enum_shifted.hpp> | |
19 | #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | |
20 | #include <boost/ref.hpp> | |
21 | #include <boost/get_pointer.hpp> | |
22 | #include <boost/utility/enable_if.hpp> | |
23 | #include <boost/type_traits/is_member_pointer.hpp> | |
24 | #include <boost/type_traits/is_member_object_pointer.hpp> | |
25 | #include <boost/type_traits/is_member_function_pointer.hpp> | |
26 | #include <boost/proto/proto_fwd.hpp> | |
27 | #include <boost/proto/traits.hpp> | |
28 | #include <boost/proto/transform/impl.hpp> | |
29 | #include <boost/proto/transform/arg.hpp> | |
30 | #include <boost/proto/detail/decltype.hpp> | |
31 | ||
32 | namespace boost { namespace proto | |
33 | { | |
34 | namespace detail | |
35 | { | |
36 | template<typename Grammar, typename Tag> | |
37 | struct default_case | |
38 | : not_<_> | |
39 | {}; | |
40 | ||
41 | template<typename Grammar> | |
42 | struct default_case<Grammar, tag::terminal> | |
43 | : when<terminal<_>, _value> | |
44 | {}; | |
45 | ||
46 | template<typename Grammar> | |
47 | struct default_cases | |
48 | { | |
49 | template<typename Tag> | |
50 | struct case_ | |
51 | : default_case<Grammar, Tag> | |
52 | {}; | |
53 | }; | |
54 | ||
55 | #define BOOST_PROTO_UNARY_DEFAULT_EVAL(OP, TAG, MAKE) \ | |
56 | template<typename Grammar> \ | |
57 | struct BOOST_PP_CAT(default_, TAG) \ | |
58 | : transform<BOOST_PP_CAT(default_, TAG)<Grammar> > \ | |
59 | { \ | |
60 | template<typename Expr, typename State, typename Data> \ | |
61 | struct impl \ | |
62 | : transform_impl<Expr, State, Data> \ | |
63 | { \ | |
64 | private: \ | |
65 | typedef typename result_of::child_c<Expr, 0>::type e0; \ | |
66 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \ | |
67 | public: \ | |
68 | BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type) \ | |
69 | result_type operator ()( \ | |
70 | typename impl::expr_param e \ | |
71 | , typename impl::state_param s \ | |
72 | , typename impl::data_param d \ | |
73 | ) const \ | |
74 | { \ | |
75 | typename Grammar::template impl<e0, State, Data> t0; \ | |
76 | return OP t0(proto::child_c<0>(e), s, d); \ | |
77 | } \ | |
78 | }; \ | |
79 | }; \ | |
80 | \ | |
81 | template<typename Grammar> \ | |
82 | struct default_case<Grammar, tag::TAG> \ | |
83 | : when<unary_expr<tag::TAG, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> > \ | |
84 | {}; \ | |
85 | /**/ | |
86 | ||
87 | #define BOOST_PROTO_BINARY_DEFAULT_EVAL(OP, TAG, LMAKE, RMAKE) \ | |
88 | template<typename Grammar> \ | |
89 | struct BOOST_PP_CAT(default_, TAG) \ | |
90 | : transform<BOOST_PP_CAT(default_, TAG)<Grammar> > \ | |
91 | { \ | |
92 | template<typename Expr, typename State, typename Data> \ | |
93 | struct impl \ | |
94 | : transform_impl<Expr, State, Data> \ | |
95 | { \ | |
96 | private: \ | |
97 | typedef typename result_of::child_c<Expr, 0>::type e0; \ | |
98 | typedef typename result_of::child_c<Expr, 1>::type e1; \ | |
99 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \ | |
100 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; \ | |
101 | public: \ | |
102 | BOOST_PROTO_DECLTYPE_( \ | |
103 | proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>() \ | |
104 | , result_type \ | |
105 | ) \ | |
106 | result_type operator ()( \ | |
107 | typename impl::expr_param e \ | |
108 | , typename impl::state_param s \ | |
109 | , typename impl::data_param d \ | |
110 | ) const \ | |
111 | { \ | |
112 | typename Grammar::template impl<e0, State, Data> t0; \ | |
113 | typename Grammar::template impl<e1, State, Data> t1; \ | |
114 | return t0(proto::child_c<0>(e), s, d) \ | |
115 | OP t1(proto::child_c<1>(e), s, d); \ | |
116 | } \ | |
117 | }; \ | |
118 | }; \ | |
119 | \ | |
120 | template<typename Grammar> \ | |
121 | struct default_case<Grammar, tag::TAG> \ | |
122 | : when<binary_expr<tag::TAG, Grammar, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> > \ | |
123 | {}; \ | |
124 | /**/ | |
125 | ||
126 | BOOST_PROTO_UNARY_DEFAULT_EVAL(+, unary_plus, make) | |
127 | BOOST_PROTO_UNARY_DEFAULT_EVAL(-, negate, make) | |
128 | BOOST_PROTO_UNARY_DEFAULT_EVAL(*, dereference, make) | |
129 | BOOST_PROTO_UNARY_DEFAULT_EVAL(~, complement, make) | |
130 | BOOST_PROTO_UNARY_DEFAULT_EVAL(&, address_of, make) | |
131 | BOOST_PROTO_UNARY_DEFAULT_EVAL(!, logical_not, make) | |
132 | BOOST_PROTO_UNARY_DEFAULT_EVAL(++, pre_inc, make_mutable) | |
133 | BOOST_PROTO_UNARY_DEFAULT_EVAL(--, pre_dec, make_mutable) | |
134 | ||
135 | BOOST_PROTO_BINARY_DEFAULT_EVAL(<<, shift_left, make_mutable, make) | |
136 | BOOST_PROTO_BINARY_DEFAULT_EVAL(>>, shift_right, make_mutable, make_mutable) | |
137 | BOOST_PROTO_BINARY_DEFAULT_EVAL(*, multiplies, make, make) | |
138 | BOOST_PROTO_BINARY_DEFAULT_EVAL(/, divides, make, make) | |
139 | BOOST_PROTO_BINARY_DEFAULT_EVAL(%, modulus, make, make) | |
140 | BOOST_PROTO_BINARY_DEFAULT_EVAL(+, plus, make, make) | |
141 | BOOST_PROTO_BINARY_DEFAULT_EVAL(-, minus, make, make) | |
142 | BOOST_PROTO_BINARY_DEFAULT_EVAL(<, less, make, make) | |
143 | BOOST_PROTO_BINARY_DEFAULT_EVAL(>, greater, make, make) | |
144 | BOOST_PROTO_BINARY_DEFAULT_EVAL(<=, less_equal, make, make) | |
145 | BOOST_PROTO_BINARY_DEFAULT_EVAL(>=, greater_equal, make, make) | |
146 | BOOST_PROTO_BINARY_DEFAULT_EVAL(==, equal_to, make, make) | |
147 | BOOST_PROTO_BINARY_DEFAULT_EVAL(!=, not_equal_to, make, make) | |
148 | BOOST_PROTO_BINARY_DEFAULT_EVAL(||, logical_or, make, make) | |
149 | BOOST_PROTO_BINARY_DEFAULT_EVAL(&&, logical_and, make, make) | |
150 | BOOST_PROTO_BINARY_DEFAULT_EVAL(&, bitwise_and, make, make) | |
151 | BOOST_PROTO_BINARY_DEFAULT_EVAL(|, bitwise_or, make, make) | |
152 | BOOST_PROTO_BINARY_DEFAULT_EVAL(^, bitwise_xor, make, make) | |
153 | ||
154 | BOOST_PROTO_BINARY_DEFAULT_EVAL(=, assign, make_mutable, make) | |
155 | BOOST_PROTO_BINARY_DEFAULT_EVAL(<<=, shift_left_assign, make_mutable, make) | |
156 | BOOST_PROTO_BINARY_DEFAULT_EVAL(>>=, shift_right_assign, make_mutable, make) | |
157 | BOOST_PROTO_BINARY_DEFAULT_EVAL(*=, multiplies_assign, make_mutable, make) | |
158 | BOOST_PROTO_BINARY_DEFAULT_EVAL(/=, divides_assign, make_mutable, make) | |
159 | BOOST_PROTO_BINARY_DEFAULT_EVAL(%=, modulus_assign, make_mutable, make) | |
160 | BOOST_PROTO_BINARY_DEFAULT_EVAL(+=, plus_assign, make_mutable, make) | |
161 | BOOST_PROTO_BINARY_DEFAULT_EVAL(-=, minus_assign, make_mutable, make) | |
162 | BOOST_PROTO_BINARY_DEFAULT_EVAL(&=, bitwise_and_assign, make_mutable, make) | |
163 | BOOST_PROTO_BINARY_DEFAULT_EVAL(|=, bitwise_or_assign, make_mutable, make) | |
164 | BOOST_PROTO_BINARY_DEFAULT_EVAL(^=, bitwise_xor_assign, make_mutable, make) | |
165 | ||
166 | #undef BOOST_PROTO_UNARY_DEFAULT_EVAL | |
167 | #undef BOOST_PROTO_BINARY_DEFAULT_EVAL | |
168 | ||
169 | /// INTERNAL ONLY | |
170 | template<typename Grammar, typename Expr, typename State, typename Data> | |
171 | struct is_member_function_invocation | |
172 | : is_member_function_pointer< | |
173 | typename uncvref< | |
174 | typename Grammar::template impl< | |
175 | typename result_of::child_c<Expr, 1>::type | |
176 | , State | |
177 | , Data | |
178 | >::result_type | |
179 | >::type | |
180 | > | |
181 | {}; | |
182 | ||
183 | /// INTERNAL ONLY | |
184 | template<typename Grammar, typename Expr, typename State, typename Data, bool IsMemFunCall> | |
185 | struct default_mem_ptr_impl | |
186 | : transform_impl<Expr, State, Data> | |
187 | { | |
188 | private: | |
189 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
190 | typedef typename result_of::child_c<Expr, 1>::type e1; | |
191 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
192 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; | |
193 | public: | |
194 | typedef typename detail::mem_ptr_fun<r0, r1>::result_type result_type; | |
195 | result_type operator ()( | |
196 | typename default_mem_ptr_impl::expr_param e | |
197 | , typename default_mem_ptr_impl::state_param s | |
198 | , typename default_mem_ptr_impl::data_param d | |
199 | ) const | |
200 | { | |
201 | typename Grammar::template impl<e0, State, Data> t0; | |
202 | typename Grammar::template impl<e1, State, Data> t1; | |
203 | return detail::mem_ptr_fun<r0, r1>()( | |
204 | t0(proto::child_c<0>(e), s, d) | |
205 | , t1(proto::child_c<1>(e), s, d) | |
206 | ); | |
207 | } | |
208 | }; | |
209 | ||
210 | /// INTERNAL ONLY | |
211 | template<typename Grammar, typename Expr, typename State, typename Data> | |
212 | struct default_mem_ptr_impl<Grammar, Expr, State, Data, true> | |
213 | : transform_impl<Expr, State, Data> | |
214 | { | |
215 | private: | |
216 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
217 | typedef typename result_of::child_c<Expr, 1>::type e1; | |
218 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
219 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; | |
220 | public: | |
221 | typedef detail::memfun<r0, r1> result_type; | |
222 | result_type const operator ()( | |
223 | typename default_mem_ptr_impl::expr_param e | |
224 | , typename default_mem_ptr_impl::state_param s | |
225 | , typename default_mem_ptr_impl::data_param d | |
226 | ) const | |
227 | { | |
228 | typename Grammar::template impl<e0, State, Data> t0; | |
229 | typename Grammar::template impl<e1, State, Data> t1; | |
230 | return detail::memfun<r0, r1>( | |
231 | t0(proto::child_c<0>(e), s, d) | |
232 | , t1(proto::child_c<1>(e), s, d) | |
233 | ); | |
234 | } | |
235 | }; | |
236 | ||
237 | template<typename Grammar> | |
238 | struct default_mem_ptr | |
239 | : transform<default_mem_ptr<Grammar> > | |
240 | { | |
241 | template<typename Expr, typename State, typename Data> | |
242 | struct impl | |
243 | : default_mem_ptr_impl< | |
244 | Grammar | |
245 | , Expr | |
246 | , State | |
247 | , Data | |
248 | , is_member_function_invocation<Grammar, Expr, State, Data>::value | |
249 | > | |
250 | {}; | |
251 | }; | |
252 | ||
253 | template<typename Grammar> | |
254 | struct default_case<Grammar, tag::mem_ptr> | |
255 | : when<mem_ptr<Grammar, Grammar>, default_mem_ptr<Grammar> > | |
256 | {}; | |
257 | ||
258 | template<typename Grammar> | |
259 | struct default_post_inc | |
260 | : transform<default_post_inc<Grammar> > | |
261 | { | |
262 | template<typename Expr, typename State, typename Data> | |
263 | struct impl | |
264 | : transform_impl<Expr, State, Data> | |
265 | { | |
266 | private: | |
267 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
268 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
269 | public: | |
270 | BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type) | |
271 | result_type operator ()( | |
272 | typename impl::expr_param e | |
273 | , typename impl::state_param s | |
274 | , typename impl::data_param d | |
275 | ) const | |
276 | { | |
277 | typename Grammar::template impl<e0, State, Data> t0; | |
278 | return t0(proto::child_c<0>(e), s, d) ++; | |
279 | } | |
280 | }; | |
281 | }; | |
282 | ||
283 | template<typename Grammar> | |
284 | struct default_case<Grammar, tag::post_inc> | |
285 | : when<post_inc<Grammar>, default_post_inc<Grammar> > | |
286 | {}; | |
287 | ||
288 | template<typename Grammar> | |
289 | struct default_post_dec | |
290 | : transform<default_post_dec<Grammar> > | |
291 | { | |
292 | template<typename Expr, typename State, typename Data> | |
293 | struct impl | |
294 | : transform_impl<Expr, State, Data> | |
295 | { | |
296 | private: | |
297 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
298 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
299 | public: | |
300 | BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type) | |
301 | result_type operator ()( | |
302 | typename impl::expr_param e | |
303 | , typename impl::state_param s | |
304 | , typename impl::data_param d | |
305 | ) const | |
306 | { | |
307 | typename Grammar::template impl<e0, State, Data> t0; | |
308 | return t0(proto::child_c<0>(e), s, d) --; | |
309 | } | |
310 | }; | |
311 | }; | |
312 | ||
313 | template<typename Grammar> | |
314 | struct default_case<Grammar, tag::post_dec> | |
315 | : when<post_dec<Grammar>, default_post_dec<Grammar> > | |
316 | {}; | |
317 | ||
318 | template<typename Grammar> | |
319 | struct default_subscript | |
320 | : transform<default_subscript<Grammar> > | |
321 | { | |
322 | template<typename Expr, typename State, typename Data> | |
323 | struct impl | |
324 | : transform_impl<Expr, State, Data> | |
325 | { | |
326 | private: | |
327 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
328 | typedef typename result_of::child_c<Expr, 1>::type e1; | |
329 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
330 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; | |
331 | public: | |
332 | BOOST_PROTO_DECLTYPE_( | |
333 | proto::detail::make_subscriptable<r0>() [ proto::detail::make<r1>() ] | |
334 | , result_type | |
335 | ) | |
336 | result_type operator ()( | |
337 | typename impl::expr_param e | |
338 | , typename impl::state_param s | |
339 | , typename impl::data_param d | |
340 | ) const | |
341 | { | |
342 | typename Grammar::template impl<e0, State, Data> t0; | |
343 | typename Grammar::template impl<e1, State, Data> t1; | |
344 | return t0(proto::child_c<0>(e), s, d) [ | |
345 | t1(proto::child_c<1>(e), s, d) ]; | |
346 | } | |
347 | }; | |
348 | }; | |
349 | ||
350 | template<typename Grammar> | |
351 | struct default_case<Grammar, tag::subscript> | |
352 | : when<subscript<Grammar, Grammar>, default_subscript<Grammar> > | |
353 | {}; | |
354 | ||
355 | template<typename Grammar> | |
356 | struct default_if_else_ | |
357 | { | |
358 | template<typename Expr, typename State, typename Data> | |
359 | struct impl | |
360 | : transform_impl<Expr, State, Data> | |
361 | { | |
362 | private: | |
363 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
364 | typedef typename result_of::child_c<Expr, 1>::type e1; | |
365 | typedef typename result_of::child_c<Expr, 2>::type e2; | |
366 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
367 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; | |
368 | typedef typename Grammar::template impl<e2, State, Data>::result_type r2; | |
369 | public: | |
370 | BOOST_PROTO_DECLTYPE_( | |
371 | proto::detail::make<r0>() | |
372 | ? proto::detail::make<r1>() | |
373 | : proto::detail::make<r2>() | |
374 | , result_type | |
375 | ) | |
376 | result_type operator ()( | |
377 | typename impl::expr_param e | |
378 | , typename impl::state_param s | |
379 | , typename impl::data_param d | |
380 | ) const | |
381 | { | |
382 | typename Grammar::template impl<e0, State, Data> t0; | |
383 | typename Grammar::template impl<e1, State, Data> t1; | |
384 | typename Grammar::template impl<e2, State, Data> t2; | |
385 | return t0(proto::child_c<0>(e), s, d) | |
386 | ? t1(proto::child_c<1>(e), s, d) | |
387 | : t2(proto::child_c<2>(e), s, d); | |
388 | } | |
389 | }; | |
390 | }; | |
391 | ||
392 | template<typename Grammar> | |
393 | struct default_case<Grammar, tag::if_else_> | |
394 | : when<if_else_<Grammar, Grammar, Grammar>, default_if_else_<Grammar> > | |
395 | {}; | |
396 | ||
397 | template<typename Grammar> | |
398 | struct default_comma | |
399 | : transform<default_comma<Grammar> > | |
400 | { | |
401 | template<typename Expr, typename State, typename Data> | |
402 | struct impl | |
403 | : transform_impl<Expr, State, Data> | |
404 | { | |
405 | private: | |
406 | typedef typename result_of::child_c<Expr, 0>::type e0; | |
407 | typedef typename result_of::child_c<Expr, 1>::type e1; | |
408 | typedef typename Grammar::template impl<e0, State, Data>::result_type r0; | |
409 | typedef typename Grammar::template impl<e1, State, Data>::result_type r1; | |
410 | public: | |
411 | typedef typename proto::detail::comma_result<r0, r1>::type result_type; | |
412 | result_type operator ()( | |
413 | typename impl::expr_param e | |
414 | , typename impl::state_param s | |
415 | , typename impl::data_param d | |
416 | ) const | |
417 | { | |
418 | typename Grammar::template impl<e0, State, Data> t0; | |
419 | typename Grammar::template impl<e1, State, Data> t1; | |
420 | return t0(proto::child_c<0>(e), s, d) | |
421 | , t1(proto::child_c<1>(e), s, d); | |
422 | } | |
423 | }; | |
424 | }; | |
425 | ||
426 | template<typename Grammar> | |
427 | struct default_case<Grammar, tag::comma> | |
428 | : when<comma<Grammar, Grammar>, default_comma<Grammar> > | |
429 | {}; | |
430 | ||
431 | template<typename Grammar, typename Expr, typename State, typename Data, long Arity> | |
432 | struct default_function_impl; | |
433 | ||
434 | template<typename Grammar> | |
435 | struct default_function | |
436 | : transform<default_function<Grammar> > | |
437 | { | |
438 | template<typename Expr, typename State, typename Data> | |
439 | struct impl | |
440 | : default_function_impl< | |
441 | Grammar | |
442 | , Expr | |
443 | , State | |
444 | , Data | |
445 | , transform_impl<Expr, State, Data>::expr::proto_arity_c | |
446 | > | |
447 | {}; | |
448 | }; | |
449 | ||
450 | template<typename Grammar> | |
451 | struct default_case<Grammar, tag::function> | |
452 | : when<function<Grammar, vararg<Grammar> >, default_function<Grammar> > | |
453 | {}; | |
454 | ||
455 | #define BOOST_PROTO_DEFAULT_EVAL_TYPE(Z, N, DATA) \ | |
456 | typedef \ | |
457 | typename result_of::child_c<DATA, N>::type \ | |
458 | BOOST_PP_CAT(e, N); \ | |
459 | \ | |
460 | typedef \ | |
461 | typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>::result_type \ | |
462 | BOOST_PP_CAT(r, N); \ | |
463 | /**/ | |
464 | ||
465 | #define BOOST_PROTO_DEFAULT_EVAL(Z, N, DATA) \ | |
466 | typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>()( \ | |
467 | proto::child_c<N>(DATA), s, d \ | |
468 | ) \ | |
469 | /**/ | |
470 | ||
471 | template<typename Grammar, typename Expr, typename State, typename Data> | |
472 | struct default_function_impl<Grammar, Expr, State, Data, 1> | |
473 | : transform_impl<Expr, State, Data> | |
474 | { | |
475 | BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr) | |
476 | ||
477 | typedef | |
478 | typename proto::detail::result_of_fixup<r0>::type | |
479 | function_type; | |
480 | ||
481 | typedef | |
482 | typename BOOST_PROTO_RESULT_OF<function_type()>::type | |
483 | result_type; | |
484 | ||
485 | result_type operator ()( | |
486 | typename default_function_impl::expr_param e | |
487 | , typename default_function_impl::state_param s | |
488 | , typename default_function_impl::data_param d | |
489 | ) const | |
490 | { | |
491 | return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(); | |
492 | } | |
493 | }; | |
494 | ||
495 | template<typename Grammar, typename Expr, typename State, typename Data> | |
496 | struct default_function_impl<Grammar, Expr, State, Data, 2> | |
497 | : transform_impl<Expr, State, Data> | |
498 | { | |
499 | BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr) | |
500 | BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 1, Expr) | |
501 | ||
502 | typedef | |
503 | typename proto::detail::result_of_fixup<r0>::type | |
504 | function_type; | |
505 | ||
506 | typedef | |
507 | typename detail::result_of_<function_type(r1)>::type | |
508 | result_type; | |
509 | ||
510 | result_type operator ()( | |
511 | typename default_function_impl::expr_param e | |
512 | , typename default_function_impl::state_param s | |
513 | , typename default_function_impl::data_param d | |
514 | ) const | |
515 | { | |
516 | return this->invoke( | |
517 | e | |
518 | , s | |
519 | , d | |
520 | , is_member_function_pointer<function_type>() | |
521 | , is_member_object_pointer<function_type>() | |
522 | ); | |
523 | } | |
524 | ||
525 | private: | |
526 | result_type invoke( | |
527 | typename default_function_impl::expr_param e | |
528 | , typename default_function_impl::state_param s | |
529 | , typename default_function_impl::data_param d | |
530 | , mpl::false_ | |
531 | , mpl::false_ | |
532 | ) const | |
533 | { | |
534 | return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(BOOST_PROTO_DEFAULT_EVAL(~, 1, e)); | |
535 | } | |
536 | ||
537 | result_type invoke( | |
538 | typename default_function_impl::expr_param e | |
539 | , typename default_function_impl::state_param s | |
540 | , typename default_function_impl::data_param d | |
541 | , mpl::true_ | |
542 | , mpl::false_ | |
543 | ) const | |
544 | { | |
545 | BOOST_PROTO_USE_GET_POINTER(); | |
546 | typedef typename detail::class_member_traits<function_type>::class_type class_type; | |
547 | return ( | |
548 | BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, e))) ->* | |
549 | BOOST_PROTO_DEFAULT_EVAL(~, 0, e) | |
550 | )(); | |
551 | } | |
552 | ||
553 | result_type invoke( | |
554 | typename default_function_impl::expr_param e | |
555 | , typename default_function_impl::state_param s | |
556 | , typename default_function_impl::data_param d | |
557 | , mpl::false_ | |
558 | , mpl::true_ | |
559 | ) const | |
560 | { | |
561 | BOOST_PROTO_USE_GET_POINTER(); | |
562 | typedef typename detail::class_member_traits<function_type>::class_type class_type; | |
563 | return ( | |
564 | BOOST_PROTO_GET_POINTER(class_type, (BOOST_PROTO_DEFAULT_EVAL(~, 1, e))) ->* | |
565 | BOOST_PROTO_DEFAULT_EVAL(~, 0, e) | |
566 | ); | |
567 | } | |
568 | }; | |
569 | ||
570 | #include <boost/proto/transform/detail/default_function_impl.hpp> | |
571 | ||
572 | #undef BOOST_PROTO_DEFAULT_EVAL_TYPE | |
573 | #undef BOOST_PROTO_DEFAULT_EVAL | |
574 | } | |
575 | ||
576 | template<typename Grammar /*= detail::_default*/> | |
577 | struct _default | |
578 | : switch_<detail::default_cases<Grammar> > | |
579 | {}; | |
580 | ||
581 | template<typename Grammar> | |
582 | struct is_callable<_default<Grammar> > | |
583 | : mpl::true_ | |
584 | {}; | |
585 | ||
586 | namespace detail | |
587 | { | |
588 | // Loopy indirection that allows proto::_default<> to be | |
589 | // used without specifying a Grammar argument. | |
590 | struct _default | |
591 | : proto::_default<> | |
592 | {}; | |
593 | } | |
594 | ||
595 | }} | |
596 | ||
597 | #endif | |
598 |