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) 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 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSEboost::proto::terminal::impl401 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 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSEboost::proto::nullary_expr::impl468 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 operator ()boost::proto::functional::as_expr657 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 operator ()boost::proto::functional::as_expr667 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 operator ()boost::proto::functional::as_expr676 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 operator ()boost::proto::functional::as_expr684 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 operator ()boost::proto::functional::as_child720 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 operator ()boost::proto::functional::as_child730 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 operator ()boost::proto::functional::child_c761 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 operator ()boost::proto::functional::child_c771 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 operator ()boost::proto::functional::child806 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 operator ()boost::proto::functional::child816 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 operator ()boost::proto::functional::value846 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 operator ()boost::proto::functional::value856 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 operator ()boost::proto::functional::left886 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 operator ()boost::proto::functional::left896 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 operator ()boost::proto::functional::right926 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 operator ()boost::proto::functional::right934 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 as_expr(T & t BOOST_PROTO_DISABLE_IF_IS_CONST (T)BOOST_PROTO_DISABLE_IF_IS_FUNCTION (T))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 as_expr(T const & t)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 as_expr(T & t BOOST_PROTO_DISABLE_IF_IS_CONST (T)BOOST_PROTO_DISABLE_IF_IS_FUNCTION (T))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 as_expr(T const & t)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 as_child(T & t BOOST_PROTO_DISABLE_IF_IS_CONST (T)BOOST_PROTO_DISABLE_IF_IS_FUNCTION (T))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 as_child(T const & t)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 as_child(T & t BOOST_PROTO_DISABLE_IF_IS_CONST (T)BOOST_PROTO_DISABLE_IF_IS_FUNCTION (T))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 as_child(T const & t)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 child(Expr & e BOOST_PROTO_DISABLE_IF_IS_CONST (Expr))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 child(Expr const & e)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 child(Expr2 & expr2 BOOST_PROTO_DISABLE_IF_IS_CONST (Expr2))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 child(Expr2 const & expr2)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 child_c(Expr & e BOOST_PROTO_DISABLE_IF_IS_CONST (Expr))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 child_c(Expr const & e)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 value(Expr & e BOOST_PROTO_DISABLE_IF_IS_CONST (Expr))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 value(Expr const & e)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 left(Expr & e BOOST_PROTO_DISABLE_IF_IS_CONST (Expr))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 left(Expr const & e)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 right(Expr & e BOOST_PROTO_DISABLE_IF_IS_CONST (Expr))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 right(Expr const & e)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) 1255 # pragma warning(pop) 1256 #endif 1257 1258 #endif 1259