#ifndef BOOST_PP_IS_ITERATING /////////////////////////////////////////////////////////////////////////////// /// \file traits.hpp /// Contains definitions for child\<\>, child_c\<\>, left\<\>, /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(), /// value(), left() and right(). // // Copyright 2008 Eric Niebler. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005 #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 ) #pragma warning(push) #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored #endif namespace boost { namespace proto { namespace detail { template struct if_vararg {}; template struct if_vararg : T {}; template struct is_callable2_ : mpl::false_ {}; template struct is_callable2_ : mpl::true_ {}; template::value)> struct is_callable_ : is_callable2_ {}; } /// \brief Boolean metafunction which detects whether a type is /// a callable function object type or not. /// /// is_callable\<\> is used by the when\<\> transform /// to determine whether a function type R(A1,A2,...AN) is a /// callable transform or an object transform. (The former are evaluated /// using call\<\> and the later with make\<\>.) If /// is_callable\::::value is \c true, the function type is /// a callable transform; otherwise, it is an object transform. /// /// Unless specialized for a type \c T, is_callable\::::value /// is computed as follows: /// /// \li If \c T is a template type X\, where all \c Yx /// are types for \c x in [0,N], is_callable\::::value /// is is_same\::::value. /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef /// for \c void, is_callable\::::value is \c true. (Note: this is /// the case for any type that derives from \c proto::callable.) /// \li Otherwise, is_callable\::::value is \c false. template struct is_callable : proto::detail::is_callable_ {}; /// INTERNAL ONLY /// template<> struct is_callable : mpl::true_ {}; /// INTERNAL ONLY /// template<> struct is_callable : mpl::false_ {}; #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) // work around GCC bug template struct is_callable > : mpl::false_ {}; #endif /// \brief A Boolean metafunction that indicates whether a type requires /// aggregate initialization. /// /// is_aggregate\<\> is used by the make\<\> transform /// to determine how to construct an object of some type \c T, given some /// initialization arguments a0,a1,...aN. /// If is_aggregate\::::value is \c true, then an object of /// type T will be initialized as T t = {a0,a1,...aN};. Otherwise, /// it will be initialized as T t(a0,a1,...aN). template struct is_aggregate : is_pod {}; /// \brief Specialization of is_aggregate\<\> that indicates /// that objects of expr\<\> type require aggregate initialization. template struct is_aggregate, void> : mpl::true_ {}; /// INTERNAL ONLY template struct is_aggregate : mpl::true_ {}; /// TODO document me! template struct is_transform : mpl::false_ {}; template struct is_transform : mpl::true_ {}; namespace result_of { /// \brief A Boolean metafunction that indicates whether a given /// type \c T is a Proto expression type. /// /// If \c T has a nested type \c proto_is_expr_ that is a typedef /// for \c void, is_expr\::::value is \c true. (Note, this /// is the case for proto::expr\<\>, any type that is derived /// from proto::extends\<\> or that uses the /// BOOST_PROTO_BASIC_EXTENDS() macro.) Otherwise, /// is_expr\::::value is \c false. template struct is_expr : mpl::false_ {}; /// \brief A Boolean metafunction that indicates whether a given /// type \c T is a Proto expression type. /// /// If \c T has a nested type \c proto_is_expr_ that is a typedef /// for \c void, is_expr\::::value is \c true. (Note, this /// is the case for proto::expr\<\>, any type that is derived /// from proto::extends\<\> or that uses the /// BOOST_PROTO_BASIC_EXTENDS() macro.) Otherwise, /// is_expr\::::value is \c false. template struct is_expr : mpl::true_ {}; template struct is_expr : is_expr {}; /// \brief A metafunction that returns the tag type of a /// Proto expression. template struct tag_of { typedef typename Expr::proto_tag type; }; template struct tag_of { typedef typename Expr::proto_tag type; }; /// \brief A metafunction that returns the arity of a /// Proto expression. template struct arity_of : Expr::proto_arity {}; template struct arity_of : Expr::proto_arity {}; /// \brief A metafunction that computes the return type of the \c as_expr() /// function. /// /// The as_expr\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by value if /// possible. Types which are already Proto types are left alone. /// /// This specialization is selected when the type is not yet a Proto type. /// The resulting terminal type is calculated as follows: /// /// If \c T is a function type, let \c A be T &. /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers. /// Then, the result type as_expr\::::type is /// boost::result_of\ \>)\>::::type. template< typename T , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain) , typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void) #ifdef BOOST_PROTO_BROKEN_PTS , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) #endif > struct as_expr { typedef typename mpl::eval_if_c< is_function::value , add_reference , remove_cv >::type arg0_; typedef proto::expr > expr_; typedef typename Domain::template result::type type; typedef type const reference; /// INTERNAL ONLY /// template static reference call(T2 &t) { return Domain()(expr_::make(t)); } }; /// \brief A metafunction that computes the return type of the \c as_expr() /// function. /// /// The as_expr\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by value if /// possible. Types which are already Proto types are left alone. /// /// This specialization is selected when the type is already a Proto type. /// The result type as_expr\::::type is \c T stripped /// of cv-qualifiers. template struct as_expr< T , Domain , typename T::proto_is_expr_ #ifdef BOOST_PROTO_BROKEN_PTS , typename disable_if >::type #endif > { typedef typename T::proto_derived_expr expr_; // removes the const typedef typename Domain::template result::type type; typedef type const reference; /// INTERNAL ONLY /// template static reference call(T2 &t) { return Domain()(t); } }; template struct as_expr< T , typename T::proto_domain , typename T::proto_is_expr_ #ifdef BOOST_PROTO_BROKEN_PTS , void #endif > { typedef typename T::proto_derived_expr type; // removes the const typedef T &reference; /// INTERNAL ONLY /// template static T2 &call(T2 &t) { return t; } }; /// \brief A metafunction that computes the return type of the \c as_child() /// function. /// /// The as_child\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by reference. /// Types which are already Proto types are returned by reference. /// /// This specialization is selected when the type is not yet a Proto type. /// The result type as_child\::::type is /// boost::result_of\ \>)\>::::type. template< typename T , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain) , typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void) #ifdef BOOST_PROTO_BROKEN_PTS , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) #endif > struct as_child { typedef proto::expr > expr_; typedef typename Domain::template result::type type; /// INTERNAL ONLY /// template static type call(T2 &t) { return Domain()(expr_::make(t)); } }; /// \brief A metafunction that computes the return type of the \c as_child() /// function. /// /// The as_child\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by reference. /// Types which are already Proto types are returned by reference. /// /// This specialization is selected when the type is already a Proto type. /// The result type as_child\::::type is /// T &. template struct as_child< T , Domain , typename T::proto_is_expr_ #ifdef BOOST_PROTO_BROKEN_PTS , typename disable_if >::type #endif > { // BUGBUG should be able to hold this guy by reference, no? #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \ BOOST_WORKAROUND(BOOST_INTEL, BOOST_TESTED_AT(1010)) // These compilers don't strip top-level cv qualifiers // on arguments in function types typedef typename Domain::template result::type type; #else typedef typename Domain::template result::type type; #endif /// INTERNAL ONLY /// template static type call(T2 &t) { return Domain()(t); } }; /// \brief A metafunction that computes the return type of the \c as_child() /// function. /// /// The as_child\<\> metafunction turns types into Proto types, if /// they are not already, by making them Proto terminals held by reference. /// Types which are already Proto types are returned by reference. /// /// This specialization is selected when the type is already a Proto type. /// The result type as_child\::::type is /// T &. template struct as_child< T , typename T::proto_domain , typename T::proto_is_expr_ #ifdef BOOST_PROTO_BROKEN_PTS , void #endif > { typedef T &type; /// INTERNAL ONLY /// template static T2 &call(T2 &t) { return t; } }; /// \brief A metafunction that returns the type of the Nth child /// of a Proto expression, where N is an MPL Integral Constant. /// /// result_of::child\ is equivalent to /// result_of::child_c\. template) > struct child : child_c {}; /// \brief A metafunction that returns the type of the value /// of a terminal Proto expression. /// template struct value { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::proto_child0 value_type; /// The "value" type of the child, suitable for storage by value, /// computed as follows: /// \li T const(&)[N] becomes T[N] /// \li T[N] becomes T[N] /// \li T(&)[N] becomes T[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T /// \li T & becomes T /// \li T becomes T typedef typename detail::term_traits::value_type type; }; template struct value { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::proto_child0 value_type; /// The "reference" type of the child, suitable for storage by /// reference, computed as follows: /// \li T const(&)[N] becomes T const(&)[N] /// \li T[N] becomes T(&)[N] /// \li T(&)[N] becomes T(&)[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T & typedef typename detail::term_traits::reference type; }; template struct value { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::proto_child0 value_type; /// The "const reference" type of the child, suitable for storage by /// const reference, computed as follows: /// \li T const(&)[N] becomes T const(&)[N] /// \li T[N] becomes T const(&)[N] /// \li T(&)[N] becomes T(&)[N] /// \li R(&)(A0,...) becomes R(&)(A0,...) /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T const & typedef typename detail::term_traits::const_reference type; }; // TODO left<> and right<> force the instantiation of Expr. // Couldn't we partially specialize them on proto::expr< T, A > // and return A::child0 / A::child1? /// \brief A metafunction that returns the type of the left child /// of a binary Proto expression. /// /// result_of::left\ is equivalent to /// result_of::child_c\. template struct left : child_c {}; /// \brief A metafunction that returns the type of the right child /// of a binary Proto expression. /// /// result_of::right\ is equivalent to /// result_of::child_c\. template struct right : child_c {}; } // namespace result_of namespace op { /// \brief A metafunction for generating terminal expression types, /// a grammar element for matching terminal expressions, and a /// PrimitiveTransform that returns the current expression unchanged. template struct terminal : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : transform_impl { typedef Expr result_type; /// \param e The current expression /// \pre matches\ \>::::value is \c true. /// \return \c e /// \throw nothrow #ifdef BOOST_HAS_DECLTYPE result_type #else typename impl::expr_param #endif operator ()( typename impl::expr_param e , typename impl::state_param , typename impl::data_param ) const { return e; } }; /// INTERNAL ONLY typedef proto::tag::terminal proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating ternary conditional expression types, /// a grammar element for matching ternary conditional expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct if_else_ : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::if_else_ proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; /// INTERNAL ONLY typedef V proto_child2; }; /// \brief A metafunction for generating nullary expression types with a /// specified tag type, /// a grammar element for matching nullary expressions, and a /// PrimitiveTransform that returns the current expression unchanged. /// /// Use nullary_expr\<_, _\> as a grammar element to match any /// nullary expression. template struct nullary_expr : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : transform_impl { typedef Expr result_type; /// \param e The current expression /// \pre matches\ \>::::value is \c true. /// \return \c e /// \throw nothrow #ifdef BOOST_HAS_DECLTYPE result_type #else typename impl::expr_param #endif operator ()( typename impl::expr_param e , typename impl::state_param , typename impl::data_param ) const { return e; } }; /// INTERNAL ONLY typedef Tag proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating unary expression types with a /// specified tag type, /// a grammar element for matching unary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use unary_expr\<_, _\> as a grammar element to match any /// unary expression. template struct unary_expr : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef Tag proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating binary expression types with a /// specified tag type, /// a grammar element for matching binary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use binary_expr\<_, _, _\> as a grammar element to match any /// binary expression. template struct binary_expr : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef Tag proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating unary plus expression types, /// a grammar element for matching unary plus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct unary_plus : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::unary_plus proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating unary minus expression types, /// a grammar element for matching unary minus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct negate : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::negate proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating defereference expression types, /// a grammar element for matching dereference expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct dereference : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::dereference proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating complement expression types, /// a grammar element for matching complement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct complement : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::complement proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating address_of expression types, /// a grammar element for matching address_of expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct address_of : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::address_of proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating logical_not expression types, /// a grammar element for matching logical_not expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_not : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::logical_not proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating pre-increment expression types, /// a grammar element for matching pre-increment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct pre_inc : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::pre_inc proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating pre-decrement expression types, /// a grammar element for matching pre-decrement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct pre_dec : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::pre_dec proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating post-increment expression types, /// a grammar element for matching post-increment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct post_inc : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::post_inc proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating post-decrement expression types, /// a grammar element for matching post-decrement expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct post_dec : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::post_dec proto_tag; /// INTERNAL ONLY typedef T proto_child0; }; /// \brief A metafunction for generating left-shift expression types, /// a grammar element for matching left-shift expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_left : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::shift_left proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating right-shift expression types, /// a grammar element for matching right-shift expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_right : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::shift_right proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating multiplies expression types, /// a grammar element for matching multiplies expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct multiplies : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::multiplies proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating divides expression types, /// a grammar element for matching divides expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct divides : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::divides proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating modulus expression types, /// a grammar element for matching modulus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct modulus : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::modulus proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating binary plus expression types, /// a grammar element for matching binary plus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct plus : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::plus proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating binary minus expression types, /// a grammar element for matching binary minus expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct minus : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::minus proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating less expression types, /// a grammar element for matching less expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct less : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::less proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating greater expression types, /// a grammar element for matching greater expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct greater : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::greater proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating less-or-equal expression types, /// a grammar element for matching less-or-equal expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct less_equal : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::less_equal proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating greater-or-equal expression types, /// a grammar element for matching greater-or-equal expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct greater_equal : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::greater_equal proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating equal-to expression types, /// a grammar element for matching equal-to expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct equal_to : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::equal_to proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating not-equal-to expression types, /// a grammar element for matching not-equal-to expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct not_equal_to : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::not_equal_to proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating logical-or expression types, /// a grammar element for matching logical-or expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_or : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::logical_or proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating logical-and expression types, /// a grammar element for matching logical-and expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct logical_and : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::logical_and proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-and expression types, /// a grammar element for matching bitwise-and expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_and : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_and proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-or expression types, /// a grammar element for matching bitwise-or expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_or : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_or proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-xor expression types, /// a grammar element for matching bitwise-xor expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_xor : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_xor proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating comma expression types, /// a grammar element for matching comma expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct comma : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::comma proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; template struct mem_ptr : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::mem_ptr proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating assignment expression types, /// a grammar element for matching assignment expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating left-shift-assign expression types, /// a grammar element for matching left-shift-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_left_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::shift_left_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating right-shift-assign expression types, /// a grammar element for matching right-shift-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct shift_right_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::shift_right_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating multiplies-assign expression types, /// a grammar element for matching multiplies-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct multiplies_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::multiplies_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating divides-assign expression types, /// a grammar element for matching divides-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct divides_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::divides_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating modulus-assign expression types, /// a grammar element for matching modulus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct modulus_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::modulus_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating plus-assign expression types, /// a grammar element for matching plus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct plus_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::plus_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating minus-assign expression types, /// a grammar element for matching minus-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct minus_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::minus_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-and-assign expression types, /// a grammar element for matching bitwise-and-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_and_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_and_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-or-assign expression types, /// a grammar element for matching bitwise-or-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_or_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_or_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating bitwise-xor-assign expression types, /// a grammar element for matching bitwise-xor-assign expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct bitwise_xor_assign : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::bitwise_xor_assign proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating subscript expression types, /// a grammar element for matching subscript expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct subscript : transform, empty_base> { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::subscript proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; /// \brief A metafunction for generating virtual data member expression /// types, a grammar element for matching member expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct member : transform, empty_base> { typedef expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::member proto_tag; /// INTERNAL ONLY typedef T proto_child0; /// INTERNAL ONLY typedef U proto_child1; }; } // namespace op #define BOOST_PROTO_CHILD(Z, N, DATA) \ /** INTERNAL ONLY */ \ typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N); \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, )) #include BOOST_PP_ITERATE() #undef BOOST_PROTO_CHILD #undef BOOST_PROTO_IMPLICIT_ARG namespace functional { /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c as_expr() function. template struct as_expr { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename remove_reference::type unref_type; typedef typename result_of::as_expr::type type; }; /// \brief Wrap an object in a Proto terminal if it isn't a /// Proto expression already. /// \param t The object to wrap. /// \return proto::as_expr\(t) template typename result_of::as_expr::reference operator ()(T &t) const { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference operator ()(T const &t) const { return result_of::as_expr::call(t); } #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) template typename result_of::as_expr::reference operator ()(T (&t)[N_]) const { return result_of::as_expr::call(t); } template typename result_of::as_expr::reference operator ()(T const (&t)[N_]) const { return result_of::as_expr::call(t); } #endif }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c as_child() function. template struct as_child { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename remove_reference::type unref_type; typedef typename result_of::as_child::type type; }; /// \brief Wrap an object in a Proto terminal if it isn't a /// Proto expression already. /// \param t The object to wrap. /// \return proto::as_child\(t) template typename result_of::as_child::type operator ()(T &t) const { return result_of::as_child::call(t); } /// \overload /// template typename result_of::as_child::type operator ()(T const &t) const { return result_of::as_child::call(t); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c child_c() function. template struct child_c { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::child_c::type type; }; /// \brief Return the Nth child of the given expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre N \< Expr::proto_arity::value /// \return proto::child_c\(expr) /// \throw nothrow template typename result_of::child_c::type operator ()(Expr &expr) const { return result_of::child_c::call(expr); } /// \overload /// template typename result_of::child_c::type operator ()(Expr const &expr) const { return result_of::child_c::call(expr); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c child() function. /// /// A callable PolymorphicFunctionObject that is /// equivalent to the \c child() function. \c N is required /// to be an MPL Integral Constant. template) > struct child { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::child::type type; }; /// \brief Return the Nth child of the given expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre N::value \< Expr::proto_arity::value /// \return proto::child\(expr) /// \throw nothrow template typename result_of::child::type operator ()(Expr &expr) const { return result_of::child::call(expr); } /// \overload /// template typename result_of::child::type operator ()(Expr const &expr) const { return result_of::child::call(expr); } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c value() function. struct value { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::value::type type; }; /// \brief Return the value of the given terminal expression. /// \param expr The terminal expression node. /// \pre is_expr\::::value is \c true /// \pre 0 == Expr::proto_arity::value /// \return proto::value(expr) /// \throw nothrow template typename result_of::value::type operator ()(Expr &expr) const { return expr.proto_base().child0; } /// \overload /// template typename result_of::value::type operator ()(Expr const &expr) const { return expr.proto_base().child0; } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c left() function. struct left { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::left::type type; }; /// \brief Return the left child of the given binary expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre 2 == Expr::proto_arity::value /// \return proto::left(expr) /// \throw nothrow template typename result_of::left::type operator ()(Expr &expr) const { return expr.proto_base().child0; } /// \overload /// template typename result_of::left::type operator ()(Expr const &expr) const { return expr.proto_base().child0; } }; /// \brief A callable PolymorphicFunctionObject that is /// equivalent to the \c right() function. struct right { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::right::type type; }; /// \brief Return the right child of the given binary expression. /// \param expr The expression node. /// \pre is_expr\::::value is \c true /// \pre 2 == Expr::proto_arity::value /// \return proto::right(expr) /// \throw nothrow template typename result_of::right::type operator ()(Expr &expr) const { return expr.proto_base().child1; } template typename result_of::right::type operator ()(Expr const &expr) const { return expr.proto_base().child1; } }; } /// \brief A function that wraps non-Proto expression types in Proto /// terminals and leaves Proto expression types alone. /// /// The as_expr() function turns objects into Proto terminals if /// they are not Proto expression types already. Non-Proto types are /// held by value, if possible. Types which are already Proto types are /// left alone and returned by reference. /// /// This function can be called either with an explicitly specified /// \c Domain parameter (i.e., as_expr\(t)), or /// without (i.e., as_expr(t)). If no domain is /// specified, \c default_domain is assumed. /// /// If is_expr\::::value is \c true, then the argument is /// returned unmodified, by reference. Otherwise, the argument is wrapped /// in a Proto terminal expression node according to the following rules. /// If \c T is a function type, let \c A be T &. Otherwise, let /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr() /// returns Domain()(terminal\::::type::make(t)). /// /// \param t The object to wrap. template typename result_of::as_expr::reference as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T const &t) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_expr::call(t); } /// \overload /// template typename result_of::as_expr::reference as_expr(T const &t) { return result_of::as_expr::call(t); } /// \brief A function that wraps non-Proto expression types in Proto /// terminals (by reference) and returns Proto expression types by /// reference /// /// The as_child() function turns objects into Proto terminals if /// they are not Proto expression types already. Non-Proto types are /// held by reference. Types which are already Proto types are simply /// returned as-is. /// /// This function can be called either with an explicitly specified /// \c Domain parameter (i.e., as_child\(t)), or /// without (i.e., as_child(t)). If no domain is /// specified, \c default_domain is assumed. /// /// If is_expr\::::value is \c true, then the argument is /// returned as-is. Otherwise, \c as_child() returns /// Domain()(terminal\::::type::make(t)). /// /// \param t The object to wrap. template typename result_of::as_child::type as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_child::call(t); } /// \overload /// template typename result_of::as_child::type as_child(T const &t) { return result_of::as_child::call(t); } /// \overload /// template typename result_of::as_child::type as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) { return result_of::as_child::call(t); } /// \overload /// template typename result_of::as_child::type as_child(T const &t) { return result_of::as_child::call(t); } /// \brief Return the Nth child of the specified Proto expression. /// /// Return the Nth child of the specified Proto expression. If /// \c N is not specified, as in \c child(expr), then \c N is assumed /// to be mpl::long_\<0\>. The child is returned by /// reference. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre \c N is an MPL Integral Constant. /// \pre N::value \< Expr::proto_arity::value /// \throw nothrow /// \return A reference to the Nth child template typename result_of::child::type child(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return result_of::child::call(expr); } /// \overload /// template typename result_of::child::type child(Expr const &expr) { return result_of::child::call(expr); } /// \overload /// template typename detail::expr_traits::reference child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2)) { return expr2.proto_base().child0; } /// \overload /// template typename detail::expr_traits::const_reference child(Expr2 const &expr2) { return expr2.proto_base().child0; } /// \brief Return the Nth child of the specified Proto expression. /// /// Return the Nth child of the specified Proto expression. The child /// is returned by reference. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre N \< Expr::proto_arity::value /// \throw nothrow /// \return A reference to the Nth child template typename result_of::child_c::type child_c(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return result_of::child_c::call(expr); } /// \overload /// template typename result_of::child_c::type child_c(Expr const &expr) { return result_of::child_c::call(expr); } /// \brief Return the value stored within the specified Proto /// terminal expression. /// /// Return the the value stored within the specified Proto /// terminal expression. The value is returned by /// reference. /// /// \param expr The Proto terminal expression. /// \pre N::value == 0 /// \throw nothrow /// \return A reference to the terminal's value template typename result_of::value::type value(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return expr.proto_base().child0; } /// \overload /// template typename result_of::value::type value(Expr const &expr) { return expr.proto_base().child0; } /// \brief Return the left child of the specified binary Proto /// expression. /// /// Return the left child of the specified binary Proto expression. The /// child is returned by reference. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre 2 == Expr::proto_arity::value /// \throw nothrow /// \return A reference to the left child template typename result_of::left::type left(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return expr.proto_base().child0; } /// \overload /// template typename result_of::left::type left(Expr const &expr) { return expr.proto_base().child0; } /// \brief Return the right child of the specified binary Proto /// expression. /// /// Return the right child of the specified binary Proto expression. The /// child is returned by reference. /// /// \param expr The Proto expression. /// \pre is_expr\::::value is \c true. /// \pre 2 == Expr::proto_arity::value /// \throw nothrow /// \return A reference to the right child template typename result_of::right::type right(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr)) { return expr.proto_base().child1; } /// \overload /// template typename result_of::right::type right(Expr const &expr) { return expr.proto_base().child1; } /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 ) #pragma warning(pop) #endif #endif #else // PP_IS_ITERATING #define N BOOST_PP_ITERATION() #if N > 0 namespace op { /// \brief A metafunction for generating function-call expression types, /// a grammar element for matching function-call expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. template struct function< BOOST_PP_ENUM_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > : transform< function< BOOST_PP_ENUM_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > , empty_base > { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef proto::tag::function proto_tag; BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A) BOOST_PP_REPEAT_FROM_TO( N , BOOST_PROTO_MAX_ARITY , BOOST_PROTO_CHILD , detail::if_vararg BOOST_PP_INTERCEPT ) }; /// \brief A metafunction for generating n-ary expression types with a /// specified tag type, /// a grammar element for matching n-ary expressions, and a /// PrimitiveTransform that dispatches to the pass_through\<\> /// transform. /// /// Use nary_expr\<_, vararg\<_\> \> as a grammar element to match any /// n-ary expression; that is, any non-terminal. template struct nary_expr< Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > : transform< nary_expr< Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, A) BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void > , empty_base > { typedef proto::expr > type; typedef type proto_base_expr; template struct impl : pass_through::template impl {}; /// INTERNAL ONLY typedef Tag proto_tag; BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A) BOOST_PP_REPEAT_FROM_TO( N , BOOST_PROTO_MAX_ARITY , BOOST_PROTO_CHILD , detail::if_vararg BOOST_PP_INTERCEPT ) }; } // namespace op namespace detail { template< template class T , BOOST_PP_ENUM_PARAMS(N, typename A) > struct is_callable_ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)> : is_same {}; } #endif namespace result_of { /// \brief A metafunction that returns the type of the Nth child /// of a Proto expression. /// /// A metafunction that returns the type of the Nth child /// of a Proto expression. \c N must be less than /// \c Expr::proto_arity::value. template struct child_c { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; /// The "value" type of the child, suitable for return by value, /// computed as follows: /// \li T const & becomes T /// \li T & becomes T /// \li T becomes T typedef typename detail::expr_traits::value_type type; }; template struct child_c { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; /// The "reference" type of the child, suitable for return by /// reference, computed as follows: /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T & typedef typename detail::expr_traits::reference type; /// INTERNAL ONLY /// static type call(Expr &expr) { return expr.proto_base().BOOST_PP_CAT(child, N); } }; template struct child_c { /// The raw type of the Nth child as it is stored within /// \c Expr. This may be a value or a reference typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; /// The "const reference" type of the child, suitable for return by /// const reference, computed as follows: /// \li T const & becomes T const & /// \li T & becomes T & /// \li T becomes T const & typedef typename detail::expr_traits::const_reference type; /// INTERNAL ONLY /// static type call(Expr const &expr) { return expr.proto_base().BOOST_PP_CAT(child, N); } }; } #undef N #endif