Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/proto/traits.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 /// \file traits.hpp | |
3 /// Contains definitions for child\<\>, child_c\<\>, left\<\>, | |
4 /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(), | |
5 /// value(), left() and right(). | |
6 // | |
7 // Copyright 2008 Eric Niebler. Distributed under the Boost | |
8 // Software License, Version 1.0. (See accompanying file | |
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 | |
11 #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005 | |
12 #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005 | |
13 | |
14 #include <boost/config.hpp> | |
15 #include <boost/detail/workaround.hpp> | |
16 #include <boost/preprocessor/iteration/iterate.hpp> | |
17 #include <boost/preprocessor/repetition/enum.hpp> | |
18 #include <boost/preprocessor/repetition/enum_params.hpp> | |
19 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
20 #include <boost/preprocessor/repetition/repeat.hpp> | |
21 #include <boost/preprocessor/repetition/repeat_from_to.hpp> | |
22 #include <boost/preprocessor/facilities/intercept.hpp> | |
23 #include <boost/preprocessor/arithmetic/sub.hpp> | |
24 #include <boost/static_assert.hpp> | |
25 #include <boost/mpl/bool.hpp> | |
26 #include <boost/proto/detail/template_arity.hpp> | |
27 #include <boost/type_traits/is_pod.hpp> | |
28 #include <boost/type_traits/is_same.hpp> | |
29 #include <boost/type_traits/add_const.hpp> | |
30 #include <boost/proto/proto_fwd.hpp> | |
31 #include <boost/proto/args.hpp> | |
32 #include <boost/proto/domain.hpp> | |
33 #include <boost/proto/transform/pass_through.hpp> | |
34 | |
35 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
36 # pragma warning(push) | |
37 # if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 ) | |
38 # pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored | |
39 # endif | |
40 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined | |
41 #endif | |
42 | |
43 namespace boost { namespace proto | |
44 { | |
45 namespace detail | |
46 { | |
47 template<typename T, typename Void = void> | |
48 struct if_vararg | |
49 {}; | |
50 | |
51 template<typename T> | |
52 struct if_vararg<T, typename T::proto_is_vararg_> | |
53 : T | |
54 {}; | |
55 | |
56 template<typename T, typename Void = void> | |
57 struct is_callable2_ | |
58 : mpl::false_ | |
59 {}; | |
60 | |
61 template<typename T> | |
62 struct is_callable2_<T, typename T::proto_is_callable_> | |
63 : mpl::true_ | |
64 {}; | |
65 | |
66 template<typename T BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = boost::proto::detail::template_arity<T>::value)> | |
67 struct is_callable_ | |
68 : is_callable2_<T> | |
69 {}; | |
70 | |
71 } | |
72 | |
73 /// \brief Boolean metafunction which detects whether a type is | |
74 /// a callable function object type or not. | |
75 /// | |
76 /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform | |
77 /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a | |
78 /// callable transform or an object transform. (The former are evaluated | |
79 /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If | |
80 /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is | |
81 /// a callable transform; otherwise, it is an object transform. | |
82 /// | |
83 /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt> | |
84 /// is computed as follows: | |
85 /// | |
86 /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx | |
87 /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt> | |
88 /// is <tt>is_same\<YN, proto::callable\>::value</tt>. | |
89 /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef | |
90 /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is | |
91 /// the case for any type that derives from \c proto::callable.) | |
92 /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false. | |
93 template<typename T> | |
94 struct is_callable | |
95 : proto::detail::is_callable_<T> | |
96 {}; | |
97 | |
98 /// INTERNAL ONLY | |
99 /// | |
100 template<> | |
101 struct is_callable<proto::_> | |
102 : mpl::true_ | |
103 {}; | |
104 | |
105 /// INTERNAL ONLY | |
106 /// | |
107 template<> | |
108 struct is_callable<proto::callable> | |
109 : mpl::false_ | |
110 {}; | |
111 | |
112 /// INTERNAL ONLY | |
113 /// | |
114 template<typename PrimitiveTransform, typename X> | |
115 struct is_callable<proto::transform<PrimitiveTransform, X> > | |
116 : mpl::false_ | |
117 {}; | |
118 | |
119 #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0) | |
120 // work around GCC bug | |
121 template<typename Tag, typename Args, long N> | |
122 struct is_callable<proto::expr<Tag, Args, N> > | |
123 : mpl::false_ | |
124 {}; | |
125 | |
126 // work around GCC bug | |
127 template<typename Tag, typename Args, long N> | |
128 struct is_callable<proto::basic_expr<Tag, Args, N> > | |
129 : mpl::false_ | |
130 {}; | |
131 #endif | |
132 | |
133 namespace detail | |
134 { | |
135 template<typename T, typename Void /*= void*/> | |
136 struct is_transform_ | |
137 : mpl::false_ | |
138 {}; | |
139 | |
140 template<typename T> | |
141 struct is_transform_<T, typename T::proto_is_transform_> | |
142 : mpl::true_ | |
143 {}; | |
144 } | |
145 | |
146 /// \brief Boolean metafunction which detects whether a type is | |
147 /// a PrimitiveTransform type or not. | |
148 /// | |
149 /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform | |
150 /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>, | |
151 /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data | |
152 /// parameters (as needed). | |
153 /// | |
154 /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt> | |
155 /// is computed as follows: | |
156 /// | |
157 /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef | |
158 /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is | |
159 /// the case for any type that derives from an instantiation of \c proto::transform.) | |
160 /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false. | |
161 template<typename T> | |
162 struct is_transform | |
163 : proto::detail::is_transform_<T> | |
164 {}; | |
165 | |
166 namespace detail | |
167 { | |
168 template<typename T, typename Void /*= void*/> | |
169 struct is_aggregate_ | |
170 : is_pod<T> | |
171 {}; | |
172 | |
173 template<typename Tag, typename Args, long N> | |
174 struct is_aggregate_<proto::expr<Tag, Args, N>, void> | |
175 : mpl::true_ | |
176 {}; | |
177 | |
178 template<typename Tag, typename Args, long N> | |
179 struct is_aggregate_<proto::basic_expr<Tag, Args, N>, void> | |
180 : mpl::true_ | |
181 {}; | |
182 | |
183 template<typename T> | |
184 struct is_aggregate_<T, typename T::proto_is_aggregate_> | |
185 : mpl::true_ | |
186 {}; | |
187 } | |
188 | |
189 /// \brief A Boolean metafunction that indicates whether a type requires | |
190 /// aggregate initialization. | |
191 /// | |
192 /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform | |
193 /// to determine how to construct an object of some type \c T, given some | |
194 /// initialization arguments <tt>a0,a1,...aN</tt>. | |
195 /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of | |
196 /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise, | |
197 /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>. | |
198 template<typename T> | |
199 struct is_aggregate | |
200 : proto::detail::is_aggregate_<T> | |
201 {}; | |
202 | |
203 /// \brief A Boolean metafunction that indicates whether a given | |
204 /// type \c T is a Proto expression type. | |
205 /// | |
206 /// If \c T has a nested type \c proto_is_expr_ that is a typedef | |
207 /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this | |
208 /// is the case for <tt>proto::expr\<\></tt>, any type that is derived | |
209 /// from <tt>proto::extends\<\></tt> or that uses the | |
210 /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise, | |
211 /// <tt>is_expr\<T\>::value</tt> is \c false. | |
212 template<typename T, typename Void /* = void*/> | |
213 struct is_expr | |
214 : mpl::false_ | |
215 {}; | |
216 | |
217 /// \brief A Boolean metafunction that indicates whether a given | |
218 /// type \c T is a Proto expression type. | |
219 /// | |
220 /// If \c T has a nested type \c proto_is_expr_ that is a typedef | |
221 /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this | |
222 /// is the case for <tt>proto::expr\<\></tt>, any type that is derived | |
223 /// from <tt>proto::extends\<\></tt> or that uses the | |
224 /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise, | |
225 /// <tt>is_expr\<T\>::value</tt> is \c false. | |
226 template<typename T> | |
227 struct is_expr<T, typename T::proto_is_expr_> | |
228 : mpl::true_ | |
229 {}; | |
230 | |
231 template<typename T> | |
232 struct is_expr<T &, void> | |
233 : is_expr<T> | |
234 {}; | |
235 | |
236 /// \brief A metafunction that returns the tag type of a | |
237 /// Proto expression. | |
238 template<typename Expr> | |
239 struct tag_of | |
240 { | |
241 typedef typename Expr::proto_tag type; | |
242 }; | |
243 | |
244 template<typename Expr> | |
245 struct tag_of<Expr &> | |
246 { | |
247 typedef typename Expr::proto_tag type; | |
248 }; | |
249 | |
250 /// \brief A metafunction that returns the arity of a | |
251 /// Proto expression. | |
252 template<typename Expr> | |
253 struct arity_of | |
254 : Expr::proto_arity | |
255 {}; | |
256 | |
257 template<typename Expr> | |
258 struct arity_of<Expr &> | |
259 : Expr::proto_arity | |
260 {}; | |
261 | |
262 namespace result_of | |
263 { | |
264 /// \brief A metafunction that computes the return type of the \c as_expr() | |
265 /// function. | |
266 template<typename T, typename Domain /*= default_domain*/> | |
267 struct as_expr | |
268 { | |
269 typedef typename Domain::template as_expr<T>::result_type type; | |
270 }; | |
271 | |
272 /// \brief A metafunction that computes the return type of the \c as_child() | |
273 /// function. | |
274 template<typename T, typename Domain /*= default_domain*/> | |
275 struct as_child | |
276 { | |
277 typedef typename Domain::template as_child<T>::result_type type; | |
278 }; | |
279 | |
280 /// \brief A metafunction that returns the type of the Nth child | |
281 /// of a Proto expression, where N is an MPL Integral Constant. | |
282 /// | |
283 /// <tt>result_of::child\<Expr, N\></tt> is equivalent to | |
284 /// <tt>result_of::child_c\<Expr, N::value\></tt>. | |
285 template<typename Expr, typename N /* = mpl::long_<0>*/> | |
286 struct child | |
287 : child_c<Expr, N::value> | |
288 {}; | |
289 | |
290 /// \brief A metafunction that returns the type of the value | |
291 /// of a terminal Proto expression. | |
292 /// | |
293 template<typename Expr> | |
294 struct value | |
295 { | |
296 /// Verify that we are actually operating on a terminal | |
297 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c); | |
298 | |
299 /// The raw type of the Nth child as it is stored within | |
300 /// \c Expr. This may be a value or a reference | |
301 typedef typename Expr::proto_child0 value_type; | |
302 | |
303 /// The "value" type of the child, suitable for storage by value, | |
304 /// computed as follows: | |
305 /// \li <tt>T const(&)[N]</tt> becomes <tt>T[N]</tt> | |
306 /// \li <tt>T[N]</tt> becomes <tt>T[N]</tt> | |
307 /// \li <tt>T(&)[N]</tt> becomes <tt>T[N]</tt> | |
308 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt> | |
309 /// \li <tt>T const &</tt> becomes <tt>T</tt> | |
310 /// \li <tt>T &</tt> becomes <tt>T</tt> | |
311 /// \li <tt>T</tt> becomes <tt>T</tt> | |
312 typedef typename detail::term_traits<typename Expr::proto_child0>::value_type type; | |
313 }; | |
314 | |
315 template<typename Expr> | |
316 struct value<Expr &> | |
317 { | |
318 /// Verify that we are actually operating on a terminal | |
319 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c); | |
320 | |
321 /// The raw type of the Nth child as it is stored within | |
322 /// \c Expr. This may be a value or a reference | |
323 typedef typename Expr::proto_child0 value_type; | |
324 | |
325 /// The "reference" type of the child, suitable for storage by | |
326 /// reference, computed as follows: | |
327 /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt> | |
328 /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt> | |
329 /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt> | |
330 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt> | |
331 /// \li <tt>T const &</tt> becomes <tt>T const &</tt> | |
332 /// \li <tt>T &</tt> becomes <tt>T &</tt> | |
333 /// \li <tt>T</tt> becomes <tt>T &</tt> | |
334 typedef typename detail::term_traits<typename Expr::proto_child0>::reference type; | |
335 }; | |
336 | |
337 template<typename Expr> | |
338 struct value<Expr const &> | |
339 { | |
340 /// Verify that we are actually operating on a terminal | |
341 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c); | |
342 | |
343 /// The raw type of the Nth child as it is stored within | |
344 /// \c Expr. This may be a value or a reference | |
345 typedef typename Expr::proto_child0 value_type; | |
346 | |
347 /// The "const reference" type of the child, suitable for storage by | |
348 /// const reference, computed as follows: | |
349 /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt> | |
350 /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt> | |
351 /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt> | |
352 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt> | |
353 /// \li <tt>T const &</tt> becomes <tt>T const &</tt> | |
354 /// \li <tt>T &</tt> becomes <tt>T &</tt> | |
355 /// \li <tt>T</tt> becomes <tt>T const &</tt> | |
356 typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type; | |
357 }; | |
358 | |
359 /// \brief A metafunction that returns the type of the left child | |
360 /// of a binary Proto expression. | |
361 /// | |
362 /// <tt>result_of::left\<Expr\></tt> is equivalent to | |
363 /// <tt>result_of::child_c\<Expr, 0\></tt>. | |
364 template<typename Expr> | |
365 struct left | |
366 : child_c<Expr, 0> | |
367 {}; | |
368 | |
369 /// \brief A metafunction that returns the type of the right child | |
370 /// of a binary Proto expression. | |
371 /// | |
372 /// <tt>result_of::right\<Expr\></tt> is equivalent to | |
373 /// <tt>result_of::child_c\<Expr, 1\></tt>. | |
374 template<typename Expr> | |
375 struct right | |
376 : child_c<Expr, 1> | |
377 {}; | |
378 | |
379 } // namespace result_of | |
380 | |
381 /// \brief A metafunction for generating terminal expression types, | |
382 /// a grammar element for matching terminal expressions, and a | |
383 /// PrimitiveTransform that returns the current expression unchanged. | |
384 template<typename T> | |
385 struct terminal | |
386 : proto::transform<terminal<T>, int> | |
387 { | |
388 typedef proto::expr<proto::tag::terminal, term<T>, 0> type; | |
389 typedef proto::basic_expr<proto::tag::terminal, term<T>, 0> proto_grammar; | |
390 | |
391 template<typename Expr, typename State, typename Data> | |
392 struct impl : transform_impl<Expr, State, Data> | |
393 { | |
394 typedef Expr result_type; | |
395 | |
396 /// \param e The current expression | |
397 /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true. | |
398 /// \return \c e | |
399 /// \throw nothrow | |
400 BOOST_FORCEINLINE | |
401 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param) | |
402 operator ()( | |
403 typename impl::expr_param e | |
404 , typename impl::state_param | |
405 , typename impl::data_param | |
406 ) const | |
407 { | |
408 return e; | |
409 } | |
410 }; | |
411 | |
412 /// INTERNAL ONLY | |
413 typedef proto::tag::terminal proto_tag; | |
414 /// INTERNAL ONLY | |
415 typedef T proto_child0; | |
416 }; | |
417 | |
418 /// \brief A metafunction for generating ternary conditional expression types, | |
419 /// a grammar element for matching ternary conditional expressions, and a | |
420 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt> | |
421 /// transform. | |
422 template<typename T, typename U, typename V> | |
423 struct if_else_ | |
424 : proto::transform<if_else_<T, U, V>, int> | |
425 { | |
426 typedef proto::expr<proto::tag::if_else_, list3<T, U, V>, 3> type; | |
427 typedef proto::basic_expr<proto::tag::if_else_, list3<T, U, V>, 3> proto_grammar; | |
428 | |
429 template<typename Expr, typename State, typename Data> | |
430 struct impl | |
431 : detail::pass_through_impl<if_else_, deduce_domain, Expr, State, Data> | |
432 {}; | |
433 | |
434 /// INTERNAL ONLY | |
435 typedef proto::tag::if_else_ proto_tag; | |
436 /// INTERNAL ONLY | |
437 typedef T proto_child0; | |
438 /// INTERNAL ONLY | |
439 typedef U proto_child1; | |
440 /// INTERNAL ONLY | |
441 typedef V proto_child2; | |
442 }; | |
443 | |
444 /// \brief A metafunction for generating nullary expression types with a | |
445 /// specified tag type, | |
446 /// a grammar element for matching nullary expressions, and a | |
447 /// PrimitiveTransform that returns the current expression unchanged. | |
448 /// | |
449 /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any | |
450 /// nullary expression. | |
451 template<typename Tag, typename T> | |
452 struct nullary_expr | |
453 : proto::transform<nullary_expr<Tag, T>, int> | |
454 { | |
455 typedef proto::expr<Tag, term<T>, 0> type; | |
456 typedef proto::basic_expr<Tag, term<T>, 0> proto_grammar; | |
457 | |
458 template<typename Expr, typename State, typename Data> | |
459 struct impl : transform_impl<Expr, State, Data> | |
460 { | |
461 typedef Expr result_type; | |
462 | |
463 /// \param e The current expression | |
464 /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true. | |
465 /// \return \c e | |
466 /// \throw nothrow | |
467 BOOST_FORCEINLINE | |
468 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param) | |
469 operator ()( | |
470 typename impl::expr_param e | |
471 , typename impl::state_param | |
472 , typename impl::data_param | |
473 ) const | |
474 { | |
475 return e; | |
476 } | |
477 }; | |
478 | |
479 /// INTERNAL ONLY | |
480 typedef Tag proto_tag; | |
481 /// INTERNAL ONLY | |
482 typedef T proto_child0; | |
483 }; | |
484 | |
485 /// \brief A metafunction for generating unary expression types with a | |
486 /// specified tag type, | |
487 /// a grammar element for matching unary expressions, and a | |
488 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt> | |
489 /// transform. | |
490 /// | |
491 /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any | |
492 /// unary expression. | |
493 template<typename Tag, typename T> | |
494 struct unary_expr | |
495 : proto::transform<unary_expr<Tag, T>, int> | |
496 { | |
497 typedef proto::expr<Tag, list1<T>, 1> type; | |
498 typedef proto::basic_expr<Tag, list1<T>, 1> proto_grammar; | |
499 | |
500 template<typename Expr, typename State, typename Data> | |
501 struct impl | |
502 : detail::pass_through_impl<unary_expr, deduce_domain, Expr, State, Data> | |
503 {}; | |
504 | |
505 /// INTERNAL ONLY | |
506 typedef Tag proto_tag; | |
507 /// INTERNAL ONLY | |
508 typedef T proto_child0; | |
509 }; | |
510 | |
511 /// \brief A metafunction for generating binary expression types with a | |
512 /// specified tag type, | |
513 /// a grammar element for matching binary expressions, and a | |
514 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt> | |
515 /// transform. | |
516 /// | |
517 /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any | |
518 /// binary expression. | |
519 template<typename Tag, typename T, typename U> | |
520 struct binary_expr | |
521 : proto::transform<binary_expr<Tag, T, U>, int> | |
522 { | |
523 typedef proto::expr<Tag, list2<T, U>, 2> type; | |
524 typedef proto::basic_expr<Tag, list2<T, U>, 2> proto_grammar; | |
525 | |
526 template<typename Expr, typename State, typename Data> | |
527 struct impl | |
528 : detail::pass_through_impl<binary_expr, deduce_domain, Expr, State, Data> | |
529 {}; | |
530 | |
531 /// INTERNAL ONLY | |
532 typedef Tag proto_tag; | |
533 /// INTERNAL ONLY | |
534 typedef T proto_child0; | |
535 /// INTERNAL ONLY | |
536 typedef U proto_child1; | |
537 }; | |
538 | |
539 #define BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(Op) \ | |
540 template<typename T> \ | |
541 struct Op \ | |
542 : proto::transform<Op<T>, int> \ | |
543 { \ | |
544 typedef proto::expr<proto::tag::Op, list1<T>, 1> type; \ | |
545 typedef proto::basic_expr<proto::tag::Op, list1<T>, 1> proto_grammar; \ | |
546 \ | |
547 template<typename Expr, typename State, typename Data> \ | |
548 struct impl \ | |
549 : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \ | |
550 {}; \ | |
551 \ | |
552 typedef proto::tag::Op proto_tag; \ | |
553 typedef T proto_child0; \ | |
554 }; \ | |
555 /**/ | |
556 | |
557 #define BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(Op) \ | |
558 template<typename T, typename U> \ | |
559 struct Op \ | |
560 : proto::transform<Op<T, U>, int> \ | |
561 { \ | |
562 typedef proto::expr<proto::tag::Op, list2<T, U>, 2> type; \ | |
563 typedef proto::basic_expr<proto::tag::Op, list2<T, U>, 2> proto_grammar; \ | |
564 \ | |
565 template<typename Expr, typename State, typename Data> \ | |
566 struct impl \ | |
567 : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \ | |
568 {}; \ | |
569 \ | |
570 typedef proto::tag::Op proto_tag; \ | |
571 typedef T proto_child0; \ | |
572 typedef U proto_child1; \ | |
573 }; \ | |
574 /**/ | |
575 | |
576 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(unary_plus) | |
577 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(negate) | |
578 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(dereference) | |
579 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(complement) | |
580 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(address_of) | |
581 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(logical_not) | |
582 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_inc) | |
583 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_dec) | |
584 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_inc) | |
585 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_dec) | |
586 | |
587 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left) | |
588 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right) | |
589 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies) | |
590 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides) | |
591 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus) | |
592 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus) | |
593 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus) | |
594 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less) | |
595 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater) | |
596 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less_equal) | |
597 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater_equal) | |
598 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(equal_to) | |
599 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(not_equal_to) | |
600 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_or) | |
601 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_and) | |
602 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or) | |
603 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and) | |
604 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor) | |
605 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(comma) | |
606 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(mem_ptr) | |
607 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(assign) | |
608 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left_assign) | |
609 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right_assign) | |
610 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies_assign) | |
611 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides_assign) | |
612 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus_assign) | |
613 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus_assign) | |
614 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus_assign) | |
615 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign) | |
616 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign) | |
617 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign) | |
618 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(subscript) | |
619 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(member) | |
620 | |
621 #undef BOOST_PROTO_DEFINE_UNARY_METAFUNCTION | |
622 #undef BOOST_PROTO_DEFINE_BINARY_METAFUNCTION | |
623 | |
624 #include <boost/proto/detail/traits.hpp> | |
625 | |
626 namespace functional | |
627 { | |
628 /// \brief A callable PolymorphicFunctionObject that is | |
629 /// equivalent to the \c as_expr() function. | |
630 template<typename Domain /* = default_domain*/> | |
631 struct as_expr | |
632 { | |
633 BOOST_PROTO_CALLABLE() | |
634 | |
635 template<typename Sig> | |
636 struct result; | |
637 | |
638 template<typename This, typename T> | |
639 struct result<This(T)> | |
640 { | |
641 typedef typename Domain::template as_expr<T>::result_type type; | |
642 }; | |
643 | |
644 template<typename This, typename T> | |
645 struct result<This(T &)> | |
646 { | |
647 typedef typename Domain::template as_expr<T>::result_type type; | |
648 }; | |
649 | |
650 /// \brief Wrap an object in a Proto terminal if it isn't a | |
651 /// Proto expression already. | |
652 /// \param t The object to wrap. | |
653 /// \return <tt>proto::as_expr\<Domain\>(t)</tt> | |
654 template<typename T> | |
655 BOOST_FORCEINLINE | |
656 typename add_const<typename result<as_expr(T &)>::type>::type | |
657 operator ()(T &t) const | |
658 { | |
659 return typename Domain::template as_expr<T>()(t); | |
660 } | |
661 | |
662 /// \overload | |
663 /// | |
664 template<typename T> | |
665 BOOST_FORCEINLINE | |
666 typename add_const<typename result<as_expr(T const &)>::type>::type | |
667 operator ()(T const &t) const | |
668 { | |
669 return typename Domain::template as_expr<T const>()(t); | |
670 } | |
671 | |
672 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) | |
673 template<typename T, std::size_t N_> | |
674 BOOST_FORCEINLINE | |
675 typename add_const<typename result<as_expr(T (&)[N_])>::type>::type | |
676 operator ()(T (&t)[N_]) const | |
677 { | |
678 return typename Domain::template as_expr<T[N_]>()(t); | |
679 } | |
680 | |
681 template<typename T, std::size_t N_> | |
682 BOOST_FORCEINLINE | |
683 typename add_const<typename result<as_expr(T const (&)[N_])>::type>::type | |
684 operator ()(T const (&t)[N_]) const | |
685 { | |
686 return typename Domain::template as_expr<T const[N_]>()(t); | |
687 } | |
688 #endif | |
689 }; | |
690 | |
691 /// \brief A callable PolymorphicFunctionObject that is | |
692 /// equivalent to the \c as_child() function. | |
693 template<typename Domain /* = default_domain*/> | |
694 struct as_child | |
695 { | |
696 BOOST_PROTO_CALLABLE() | |
697 | |
698 template<typename Sig> | |
699 struct result; | |
700 | |
701 template<typename This, typename T> | |
702 struct result<This(T)> | |
703 { | |
704 typedef typename Domain::template as_child<T>::result_type type; | |
705 }; | |
706 | |
707 template<typename This, typename T> | |
708 struct result<This(T &)> | |
709 { | |
710 typedef typename Domain::template as_child<T>::result_type type; | |
711 }; | |
712 | |
713 /// \brief Wrap an object in a Proto terminal if it isn't a | |
714 /// Proto expression already. | |
715 /// \param t The object to wrap. | |
716 /// \return <tt>proto::as_child\<Domain\>(t)</tt> | |
717 template<typename T> | |
718 BOOST_FORCEINLINE | |
719 typename add_const<typename result<as_child(T &)>::type>::type | |
720 operator ()(T &t) const | |
721 { | |
722 return typename Domain::template as_child<T>()(t); | |
723 } | |
724 | |
725 /// \overload | |
726 /// | |
727 template<typename T> | |
728 BOOST_FORCEINLINE | |
729 typename add_const<typename result<as_child(T const &)>::type>::type | |
730 operator ()(T const &t) const | |
731 { | |
732 return typename Domain::template as_child<T const>()(t); | |
733 } | |
734 }; | |
735 | |
736 /// \brief A callable PolymorphicFunctionObject that is | |
737 /// equivalent to the \c child_c() function. | |
738 template<long N> | |
739 struct child_c | |
740 { | |
741 BOOST_PROTO_CALLABLE() | |
742 | |
743 template<typename Sig> | |
744 struct result; | |
745 | |
746 template<typename This, typename Expr> | |
747 struct result<This(Expr)> | |
748 { | |
749 typedef typename result_of::child_c<Expr, N>::type type; | |
750 }; | |
751 | |
752 /// \brief Return the Nth child of the given expression. | |
753 /// \param expr The expression node. | |
754 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true | |
755 /// \pre <tt>N \< Expr::proto_arity::value</tt> | |
756 /// \return <tt>proto::child_c\<N\>(expr)</tt> | |
757 /// \throw nothrow | |
758 template<typename Expr> | |
759 BOOST_FORCEINLINE | |
760 typename result_of::child_c<Expr &, N>::type | |
761 operator ()(Expr &e) const | |
762 { | |
763 return result_of::child_c<Expr &, N>::call(e); | |
764 } | |
765 | |
766 /// \overload | |
767 /// | |
768 template<typename Expr> | |
769 BOOST_FORCEINLINE | |
770 typename result_of::child_c<Expr const &, N>::type | |
771 operator ()(Expr const &e) const | |
772 { | |
773 return result_of::child_c<Expr const &, N>::call(e); | |
774 } | |
775 }; | |
776 | |
777 /// \brief A callable PolymorphicFunctionObject that is | |
778 /// equivalent to the \c child() function. | |
779 /// | |
780 /// A callable PolymorphicFunctionObject that is | |
781 /// equivalent to the \c child() function. \c N is required | |
782 /// to be an MPL Integral Constant. | |
783 template<typename N /* = mpl::long_<0>*/> | |
784 struct child | |
785 { | |
786 BOOST_PROTO_CALLABLE() | |
787 | |
788 template<typename Sig> | |
789 struct result; | |
790 | |
791 template<typename This, typename Expr> | |
792 struct result<This(Expr)> | |
793 { | |
794 typedef typename result_of::child<Expr, N>::type type; | |
795 }; | |
796 | |
797 /// \brief Return the Nth child of the given expression. | |
798 /// \param expr The expression node. | |
799 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true | |
800 /// \pre <tt>N::value \< Expr::proto_arity::value</tt> | |
801 /// \return <tt>proto::child\<N\>(expr)</tt> | |
802 /// \throw nothrow | |
803 template<typename Expr> | |
804 BOOST_FORCEINLINE | |
805 typename result_of::child<Expr &, N>::type | |
806 operator ()(Expr &e) const | |
807 { | |
808 return result_of::child<Expr &, N>::call(e); | |
809 } | |
810 | |
811 /// \overload | |
812 /// | |
813 template<typename Expr> | |
814 BOOST_FORCEINLINE | |
815 typename result_of::child<Expr const &, N>::type | |
816 operator ()(Expr const &e) const | |
817 { | |
818 return result_of::child<Expr const &, N>::call(e); | |
819 } | |
820 }; | |
821 | |
822 /// \brief A callable PolymorphicFunctionObject that is | |
823 /// equivalent to the \c value() function. | |
824 struct value | |
825 { | |
826 BOOST_PROTO_CALLABLE() | |
827 | |
828 template<typename Sig> | |
829 struct result; | |
830 | |
831 template<typename This, typename Expr> | |
832 struct result<This(Expr)> | |
833 { | |
834 typedef typename result_of::value<Expr>::type type; | |
835 }; | |
836 | |
837 /// \brief Return the value of the given terminal expression. | |
838 /// \param expr The terminal expression node. | |
839 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true | |
840 /// \pre <tt>0 == Expr::proto_arity::value</tt> | |
841 /// \return <tt>proto::value(expr)</tt> | |
842 /// \throw nothrow | |
843 template<typename Expr> | |
844 BOOST_FORCEINLINE | |
845 typename result_of::value<Expr &>::type | |
846 operator ()(Expr &e) const | |
847 { | |
848 return e.proto_base().child0; | |
849 } | |
850 | |
851 /// \overload | |
852 /// | |
853 template<typename Expr> | |
854 BOOST_FORCEINLINE | |
855 typename result_of::value<Expr const &>::type | |
856 operator ()(Expr const &e) const | |
857 { | |
858 return e.proto_base().child0; | |
859 } | |
860 }; | |
861 | |
862 /// \brief A callable PolymorphicFunctionObject that is | |
863 /// equivalent to the \c left() function. | |
864 struct left | |
865 { | |
866 BOOST_PROTO_CALLABLE() | |
867 | |
868 template<typename Sig> | |
869 struct result; | |
870 | |
871 template<typename This, typename Expr> | |
872 struct result<This(Expr)> | |
873 { | |
874 typedef typename result_of::left<Expr>::type type; | |
875 }; | |
876 | |
877 /// \brief Return the left child of the given binary expression. | |
878 /// \param expr The expression node. | |
879 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true | |
880 /// \pre <tt>2 == Expr::proto_arity::value</tt> | |
881 /// \return <tt>proto::left(expr)</tt> | |
882 /// \throw nothrow | |
883 template<typename Expr> | |
884 BOOST_FORCEINLINE | |
885 typename result_of::left<Expr &>::type | |
886 operator ()(Expr &e) const | |
887 { | |
888 return e.proto_base().child0; | |
889 } | |
890 | |
891 /// \overload | |
892 /// | |
893 template<typename Expr> | |
894 BOOST_FORCEINLINE | |
895 typename result_of::left<Expr const &>::type | |
896 operator ()(Expr const &e) const | |
897 { | |
898 return e.proto_base().child0; | |
899 } | |
900 }; | |
901 | |
902 /// \brief A callable PolymorphicFunctionObject that is | |
903 /// equivalent to the \c right() function. | |
904 struct right | |
905 { | |
906 BOOST_PROTO_CALLABLE() | |
907 | |
908 template<typename Sig> | |
909 struct result; | |
910 | |
911 template<typename This, typename Expr> | |
912 struct result<This(Expr)> | |
913 { | |
914 typedef typename result_of::right<Expr>::type type; | |
915 }; | |
916 | |
917 /// \brief Return the right child of the given binary expression. | |
918 /// \param expr The expression node. | |
919 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true | |
920 /// \pre <tt>2 == Expr::proto_arity::value</tt> | |
921 /// \return <tt>proto::right(expr)</tt> | |
922 /// \throw nothrow | |
923 template<typename Expr> | |
924 BOOST_FORCEINLINE | |
925 typename result_of::right<Expr &>::type | |
926 operator ()(Expr &e) const | |
927 { | |
928 return e.proto_base().child1; | |
929 } | |
930 | |
931 template<typename Expr> | |
932 BOOST_FORCEINLINE | |
933 typename result_of::right<Expr const &>::type | |
934 operator ()(Expr const &e) const | |
935 { | |
936 return e.proto_base().child1; | |
937 } | |
938 }; | |
939 | |
940 } | |
941 | |
942 /// \brief A function that wraps non-Proto expression types in Proto | |
943 /// terminals and leaves Proto expression types alone. | |
944 /// | |
945 /// The <tt>as_expr()</tt> function turns objects into Proto terminals if | |
946 /// they are not Proto expression types already. Non-Proto types are | |
947 /// held by value, if possible. Types which are already Proto types are | |
948 /// left alone and returned by reference. | |
949 /// | |
950 /// This function can be called either with an explicitly specified | |
951 /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or | |
952 /// without (i.e., <tt>as_expr(t)</tt>). If no domain is | |
953 /// specified, \c default_domain is assumed. | |
954 /// | |
955 /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is | |
956 /// returned unmodified, by reference. Otherwise, the argument is wrapped | |
957 /// in a Proto terminal expression node according to the following rules. | |
958 /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let | |
959 /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr() | |
960 /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>. | |
961 /// | |
962 /// \param t The object to wrap. | |
963 template<typename T> | |
964 BOOST_FORCEINLINE | |
965 typename add_const<typename result_of::as_expr<T, default_domain>::type>::type | |
966 as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)) | |
967 { | |
968 return default_domain::as_expr<T>()(t); | |
969 } | |
970 | |
971 /// \overload | |
972 /// | |
973 template<typename T> | |
974 BOOST_FORCEINLINE | |
975 typename add_const<typename result_of::as_expr<T const, default_domain>::type>::type | |
976 as_expr(T const &t) | |
977 { | |
978 return default_domain::as_expr<T const>()(t); | |
979 } | |
980 | |
981 /// \overload | |
982 /// | |
983 template<typename Domain, typename T> | |
984 BOOST_FORCEINLINE | |
985 typename add_const<typename result_of::as_expr<T, Domain>::type>::type | |
986 as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)) | |
987 { | |
988 return typename Domain::template as_expr<T>()(t); | |
989 } | |
990 | |
991 /// \overload | |
992 /// | |
993 template<typename Domain, typename T> | |
994 BOOST_FORCEINLINE | |
995 typename add_const<typename result_of::as_expr<T const, Domain>::type>::type | |
996 as_expr(T const &t) | |
997 { | |
998 return typename Domain::template as_expr<T const>()(t); | |
999 } | |
1000 | |
1001 /// \brief A function that wraps non-Proto expression types in Proto | |
1002 /// terminals (by reference) and returns Proto expression types by | |
1003 /// reference | |
1004 /// | |
1005 /// The <tt>as_child()</tt> function turns objects into Proto terminals if | |
1006 /// they are not Proto expression types already. Non-Proto types are | |
1007 /// held by reference. Types which are already Proto types are simply | |
1008 /// returned as-is. | |
1009 /// | |
1010 /// This function can be called either with an explicitly specified | |
1011 /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or | |
1012 /// without (i.e., <tt>as_child(t)</tt>). If no domain is | |
1013 /// specified, \c default_domain is assumed. | |
1014 /// | |
1015 /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is | |
1016 /// returned as-is. Otherwise, \c as_child() returns | |
1017 /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>. | |
1018 /// | |
1019 /// \param t The object to wrap. | |
1020 template<typename T> | |
1021 BOOST_FORCEINLINE | |
1022 typename add_const<typename result_of::as_child<T, default_domain>::type>::type | |
1023 as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)) | |
1024 { | |
1025 return default_domain::as_child<T>()(t); | |
1026 } | |
1027 | |
1028 /// \overload | |
1029 /// | |
1030 template<typename T> | |
1031 BOOST_FORCEINLINE | |
1032 typename add_const<typename result_of::as_child<T const, default_domain>::type>::type | |
1033 as_child(T const &t) | |
1034 { | |
1035 return default_domain::as_child<T const>()(t); | |
1036 } | |
1037 | |
1038 /// \overload | |
1039 /// | |
1040 template<typename Domain, typename T> | |
1041 BOOST_FORCEINLINE | |
1042 typename add_const<typename result_of::as_child<T, Domain>::type>::type | |
1043 as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)) | |
1044 { | |
1045 return typename Domain::template as_child<T>()(t); | |
1046 } | |
1047 | |
1048 /// \overload | |
1049 /// | |
1050 template<typename Domain, typename T> | |
1051 BOOST_FORCEINLINE | |
1052 typename add_const<typename result_of::as_child<T const, Domain>::type>::type | |
1053 as_child(T const &t) | |
1054 { | |
1055 return typename Domain::template as_child<T const>()(t); | |
1056 } | |
1057 | |
1058 /// \brief Return the Nth child of the specified Proto expression. | |
1059 /// | |
1060 /// Return the Nth child of the specified Proto expression. If | |
1061 /// \c N is not specified, as in \c child(expr), then \c N is assumed | |
1062 /// to be <tt>mpl::long_\<0\></tt>. The child is returned by | |
1063 /// reference. | |
1064 /// | |
1065 /// \param expr The Proto expression. | |
1066 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true. | |
1067 /// \pre \c N is an MPL Integral Constant. | |
1068 /// \pre <tt>N::value \< Expr::proto_arity::value</tt> | |
1069 /// \throw nothrow | |
1070 /// \return A reference to the Nth child | |
1071 template<typename N, typename Expr> | |
1072 BOOST_FORCEINLINE | |
1073 typename result_of::child<Expr &, N>::type | |
1074 child(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) | |
1075 { | |
1076 return result_of::child<Expr &, N>::call(e); | |
1077 } | |
1078 | |
1079 /// \overload | |
1080 /// | |
1081 template<typename N, typename Expr> | |
1082 BOOST_FORCEINLINE | |
1083 typename result_of::child<Expr const &, N>::type | |
1084 child(Expr const &e) | |
1085 { | |
1086 return result_of::child<Expr const &, N>::call(e); | |
1087 } | |
1088 | |
1089 /// \overload | |
1090 /// | |
1091 template<typename Expr2> | |
1092 BOOST_FORCEINLINE | |
1093 typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::reference | |
1094 child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2)) | |
1095 { | |
1096 return expr2.proto_base().child0; | |
1097 } | |
1098 | |
1099 /// \overload | |
1100 /// | |
1101 template<typename Expr2> | |
1102 BOOST_FORCEINLINE | |
1103 typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::const_reference | |
1104 child(Expr2 const &expr2) | |
1105 { | |
1106 return expr2.proto_base().child0; | |
1107 } | |
1108 | |
1109 /// \brief Return the Nth child of the specified Proto expression. | |
1110 /// | |
1111 /// Return the Nth child of the specified Proto expression. The child | |
1112 /// is returned by reference. | |
1113 /// | |
1114 /// \param expr The Proto expression. | |
1115 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true. | |
1116 /// \pre <tt>N \< Expr::proto_arity::value</tt> | |
1117 /// \throw nothrow | |
1118 /// \return A reference to the Nth child | |
1119 template<long N, typename Expr> | |
1120 BOOST_FORCEINLINE | |
1121 typename result_of::child_c<Expr &, N>::type | |
1122 child_c(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) | |
1123 { | |
1124 return result_of::child_c<Expr &, N>::call(e); | |
1125 } | |
1126 | |
1127 /// \overload | |
1128 /// | |
1129 template<long N, typename Expr> | |
1130 BOOST_FORCEINLINE | |
1131 typename result_of::child_c<Expr const &, N>::type | |
1132 child_c(Expr const &e) | |
1133 { | |
1134 return result_of::child_c<Expr const &, N>::call(e); | |
1135 } | |
1136 | |
1137 /// \brief Return the value stored within the specified Proto | |
1138 /// terminal expression. | |
1139 /// | |
1140 /// Return the value stored within the specified Proto | |
1141 /// terminal expression. The value is returned by | |
1142 /// reference. | |
1143 /// | |
1144 /// \param expr The Proto terminal expression. | |
1145 /// \pre <tt>N::value == 0</tt> | |
1146 /// \throw nothrow | |
1147 /// \return A reference to the terminal's value | |
1148 template<typename Expr> | |
1149 BOOST_FORCEINLINE | |
1150 typename result_of::value<Expr &>::type | |
1151 value(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) | |
1152 { | |
1153 return e.proto_base().child0; | |
1154 } | |
1155 | |
1156 /// \overload | |
1157 /// | |
1158 template<typename Expr> | |
1159 BOOST_FORCEINLINE | |
1160 typename result_of::value<Expr const &>::type | |
1161 value(Expr const &e) | |
1162 { | |
1163 return e.proto_base().child0; | |
1164 } | |
1165 | |
1166 /// \brief Return the left child of the specified binary Proto | |
1167 /// expression. | |
1168 /// | |
1169 /// Return the left child of the specified binary Proto expression. The | |
1170 /// child is returned by reference. | |
1171 /// | |
1172 /// \param expr The Proto expression. | |
1173 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true. | |
1174 /// \pre <tt>2 == Expr::proto_arity::value</tt> | |
1175 /// \throw nothrow | |
1176 /// \return A reference to the left child | |
1177 template<typename Expr> | |
1178 BOOST_FORCEINLINE | |
1179 typename result_of::left<Expr &>::type | |
1180 left(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) | |
1181 { | |
1182 return e.proto_base().child0; | |
1183 } | |
1184 | |
1185 /// \overload | |
1186 /// | |
1187 template<typename Expr> | |
1188 BOOST_FORCEINLINE | |
1189 typename result_of::left<Expr const &>::type | |
1190 left(Expr const &e) | |
1191 { | |
1192 return e.proto_base().child0; | |
1193 } | |
1194 | |
1195 /// \brief Return the right child of the specified binary Proto | |
1196 /// expression. | |
1197 /// | |
1198 /// Return the right child of the specified binary Proto expression. The | |
1199 /// child is returned by reference. | |
1200 /// | |
1201 /// \param expr The Proto expression. | |
1202 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true. | |
1203 /// \pre <tt>2 == Expr::proto_arity::value</tt> | |
1204 /// \throw nothrow | |
1205 /// \return A reference to the right child | |
1206 template<typename Expr> | |
1207 BOOST_FORCEINLINE | |
1208 typename result_of::right<Expr &>::type | |
1209 right(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) | |
1210 { | |
1211 return e.proto_base().child1; | |
1212 } | |
1213 | |
1214 /// \overload | |
1215 /// | |
1216 template<typename Expr> | |
1217 BOOST_FORCEINLINE | |
1218 typename result_of::right<Expr const &>::type | |
1219 right(Expr const &e) | |
1220 { | |
1221 return e.proto_base().child1; | |
1222 } | |
1223 | |
1224 /// INTERNAL ONLY | |
1225 /// | |
1226 template<typename Domain> | |
1227 struct is_callable<functional::as_expr<Domain> > | |
1228 : mpl::true_ | |
1229 {}; | |
1230 | |
1231 /// INTERNAL ONLY | |
1232 /// | |
1233 template<typename Domain> | |
1234 struct is_callable<functional::as_child<Domain> > | |
1235 : mpl::true_ | |
1236 {}; | |
1237 | |
1238 /// INTERNAL ONLY | |
1239 /// | |
1240 template<long N> | |
1241 struct is_callable<functional::child_c<N> > | |
1242 : mpl::true_ | |
1243 {}; | |
1244 | |
1245 /// INTERNAL ONLY | |
1246 /// | |
1247 template<typename N> | |
1248 struct is_callable<functional::child<N> > | |
1249 : mpl::true_ | |
1250 {}; | |
1251 | |
1252 }} | |
1253 | |
1254 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
1255 # pragma warning(pop) | |
1256 #endif | |
1257 | |
1258 #endif |