#ifndef BOOST_PP_IS_ITERATING /////////////////////////////////////////////////////////////////////////////// /// \file make_expr.hpp /// Definition of the \c make_expr() and \c unpack_expr() utilities for /// building Proto expression nodes from child nodes or from a Fusion /// sequence of child nodes, respectively. // // 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_MAKE_EXPR_HPP_EAN_04_01_2005 #define BOOST_PROTO_MAKE_EXPR_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 #include #if BOOST_VERSION >= 103500 # include # include # include # include #else # include # include # include # include #endif #include #include #include #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored #endif namespace boost { /// INTERNAL ONLY /// namespace fusion { /// INTERNAL ONLY /// template class unfused_generic; } } namespace boost { namespace proto { /// INTERNAL ONLY /// #define BOOST_PROTO_AS_CHILD_TYPE(Z, N, DATA) \ typename boost::proto::detail::protoify_< \ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ >::type \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_AS_CHILD(Z, N, DATA) \ boost::proto::detail::protoify_< \ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ >::call(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE(Z, N, DATA) \ typedef typename fusion::BOOST_PROTO_FUSION_RESULT_OF::next< \ BOOST_PP_CAT(fusion_iterator, N)>::type \ BOOST_PP_CAT(fusion_iterator, BOOST_PP_INC(N)); \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_ITERATORS_TYPE(N) \ typedef \ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::begin::type \ fusion_iterator0; \ BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE, fusion_iterator) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA) \ typename add_const< \ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_of< \ BOOST_PP_CAT(fusion_iterator, N) \ >::type \ >::type \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_NEXT_ITERATOR(Z, N, DATA) \ BOOST_PP_CAT(fusion_iterator, BOOST_PP_INC(N)) BOOST_PP_CAT(it, BOOST_PP_INC(N)) = \ fusion::next(BOOST_PP_CAT(it, N)); \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_ITERATORS(N) \ fusion_iterator0 it0 = fusion::begin(sequence); \ BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_PROTO_FUSION_NEXT_ITERATOR, fusion_iterator) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_AT(Z, N, DATA) \ *BOOST_PP_CAT(it, N) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE(Z, N, DATA) \ typename detail::protoify_< \ BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA) \ , Domain \ >::type \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_FUSION_AS_CHILD_AT(Z, N, DATA) \ detail::protoify_< \ BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA) \ , Domain \ >::call(BOOST_PROTO_FUSION_AT(Z, N, DATA)) \ /**/ namespace detail { template struct protoify_ { typedef typename boost::unwrap_reference::type unref_type; typedef typename mpl::eval_if_c< boost::is_reference_wrapper::value , proto::result_of::as_child , proto::result_of::as_expr >::type type; static type call(T &t) { return typename mpl::if_c< is_reference_wrapper::value , functional::as_child , functional::as_expr >::type()(static_cast(t)); } }; template struct protoify_ { typedef typename proto::result_of::as_child::type type; static type call(T &t) { return functional::as_child()(t); } }; template< int Index BOOST_PP_ENUM_TRAILING_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY , typename D , = void BOOST_PP_INTERCEPT ) > struct select_nth { BOOST_MPL_ASSERT_MSG((false), PROTO_DOMAIN_MISMATCH, (select_nth)); typedef default_domain type; }; template struct deduce_domain0 { typedef default_domain type; }; template struct sized { char buffer[I]; }; template struct nondeduced_domain { typedef nondeduced_domain type; nondeduced_domain(T); nondeduced_domain(default_domain); }; template<> struct nondeduced_domain { typedef nondeduced_domain type; nondeduced_domain(default_domain); }; template struct unpack_expr_ {}; template struct unpack_expr_ { typedef typename add_const< typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_of< typename fusion::BOOST_PROTO_FUSION_RESULT_OF::begin::type >::type >::type terminal_type; typedef typename proto::detail::protoify_< terminal_type , Domain >::type type; static type const call(Sequence const &sequence) { return proto::detail::protoify_::call(fusion::BOOST_PROTO_FUSION_AT_C(0, sequence)); } }; template struct unpack_expr_ : unpack_expr_ {}; template< typename Tag , typename Domain BOOST_PP_ENUM_TRAILING_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY , typename A , = void BOOST_PP_INTERCEPT ) , typename _ = void > struct make_expr_ {}; template struct make_expr_ { typedef typename proto::detail::protoify_::type result_type; result_type operator()(typename add_reference::type a) const { return proto::detail::protoify_::call(a); } }; template struct make_expr_ : make_expr_ {}; template Expr implicit_expr_wrap(Base const &e, mpl::false_, Expr *) { return Expr(e); } template Expr implicit_expr_wrap(Base const &e, mpl::true_, Expr *) { Expr that = {e}; return that; } template struct implicit_expr_1 { A0 &a0; template operator proto::expr() const { proto::expr that = {this->a0}; return that; } template operator Expr() const { typename Expr::proto_base_expr that = *this; return detail::implicit_expr_wrap(that, is_aggregate(), static_cast(0)); } }; template struct implicit_expr_1 { A0 &a0; #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(1010)) typedef typename remove_cv::type uncv_a0_type; operator uncv_a0_type &() const { return const_cast(this->a0); } #else operator A0 &() const { return this->a0; } #endif template operator proto::expr() const { proto::expr that = {this->a0}; return that; } template operator Expr() const { typename Expr::proto_base_expr that = *this; return detail::implicit_expr_wrap(that, is_aggregate(), static_cast(0)); } }; #define BOOST_PP_ITERATION_PARAMS_1 \ (4, (1, BOOST_PROTO_MAX_ARITY, , 1)) \ /**/ #include BOOST_PP_ITERATE() } namespace result_of { /// \brief Metafunction that computes the return type of the /// \c make_expr() function, with a domain deduced from the /// domains of the children. /// /// Use the result_of::make_expr\<\> metafunction to /// compute the return type of the \c make_expr() function. /// /// In this specialization, the domain is deduced from the /// domains of the child types. (If /// is_domain\::::value is \c true, then another /// specialization is selected.) template< typename Tag , typename A0 , BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY , typename A , BOOST_PROTO_WHEN_BUILDING_DOCS(= void) BOOST_PP_INTERCEPT ) , typename Void1 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) > struct make_expr { /// Same as result_of::make_expr\::::type /// where \c D is the deduced domain, which is calculated as follows: /// /// For each \c x in [0,N) (proceeding in order beginning with /// x=0), if domain_of\::::type is not /// \c default_domain, then \c D is domain_of\::::type. /// Otherwise, \c D is \c default_domain. typedef typename detail::make_expr_< Tag , deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) >::result_type type; }; /// \brief Metafunction that computes the return type of the /// \c make_expr() function, within the specified domain. /// /// Use the result_of::make_expr\<\> metafunction to compute /// the return type of the \c make_expr() function. template< typename Tag , typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A) > struct make_expr< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) , typename Domain::proto_is_domain_ > { /// If \c Tag is tag::terminal, then \c type is a /// typedef for boost::result_of\ \>)\>::::type. /// /// Otherwise, \c type is a typedef for boost::result_of\::::type, ... as_child\::::type\>) /// \>::::type, where \c N is the number of non-void template /// arguments, and as_child\::::type is evaluated as /// follows: /// /// \li If is_expr\::::value is \c true, then the /// child type is \c A. /// \li If \c A is B & or cv boost::reference_wrapper\, /// and is_expr\::::value is \c true, then the /// child type is B &. /// \li If is_expr\::::value is \c false, then the /// child type is boost::result_of\ \> /// )\>::::type. /// \li If \c A is B & or cv boost::reference_wrapper\, /// and is_expr\::::value is \c false, then the /// child type is boost::result_of\ \> /// )\>::::type. typedef typename detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) >::result_type type; }; /// \brief Metafunction that computes the return type of the /// \c unpack_expr() function, with a domain deduced from the /// domains of the children. /// /// Use the result_of::unpack_expr\<\> metafunction to /// compute the return type of the \c unpack_expr() function. /// /// \c Sequence is a Fusion Forward Sequence. /// /// In this specialization, the domain is deduced from the /// domains of the child types. (If /// is_domain\::::value is \c true, then another /// specialization is selected.) template< typename Tag , typename Sequence , typename Void1 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void) > struct unpack_expr { /// Let \c S be the type of a Fusion Random Access Sequence /// equivalent to \c Sequence. Then \c type is the /// same as result_of::make_expr\::::type, ... /// fusion::result_of::value_at_c\::::type\>::::type, /// where \c N is the size of \c S. typedef typename detail::unpack_expr_< Tag , deduce_domain , Sequence , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::type type; }; /// \brief Metafunction that computes the return type of the /// \c unpack_expr() function, within the specified domain. /// /// Use the result_of::make_expr\<\> metafunction to compute /// the return type of the \c make_expr() function. template struct unpack_expr { /// Let \c S be the type of a Fusion Random Access Sequence /// equivalent to \c Sequence. Then \c type is the /// same as result_of::make_expr\::::type, ... /// fusion::result_of::value_at_c\::::type\>::::type, /// where \c N is the size of \c S. typedef typename detail::unpack_expr_< Tag , Domain , Sequence , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::type type; }; } namespace functional { /// \brief A callable function object equivalent to the /// \c proto::make_expr() function. /// /// In all cases, functional::make_expr\()(a0, ... aN) /// is equivalent to proto::make_expr\(a0, ... aN). /// /// functional::make_expr\()(a0, ... aN) /// is equivalent to proto::make_expr\(a0, ... aN). template struct make_expr { BOOST_PROTO_CALLABLE() BOOST_PROTO_POLY_FUNCTION() template struct result; template struct result { typedef typename result_of::make_expr< Tag , Domain , A0 >::type type; }; /// Construct an expression node with tag type \c Tag /// and in the domain \c Domain. /// /// \return proto::make_expr\(a0,...aN) template typename result_of::make_expr< Tag , Domain , A0 const >::type operator ()(A0 const &a0) const { return proto::detail::make_expr_< Tag , Domain , A0 const >()(a0); } // Additional overloads generated by the preprocessor ... #define BOOST_PP_ITERATION_PARAMS_1 \ (4, (2, BOOST_PROTO_MAX_ARITY, , 2)) \ /**/ #include BOOST_PP_ITERATE() /// INTERNAL ONLY /// template< BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY , typename A , = void BOOST_PP_INTERCEPT ) > struct impl : detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) > {}; }; /// \brief A callable function object equivalent to the /// \c proto::unpack_expr() function. /// /// In all cases, functional::unpack_expr\()(seq) /// is equivalent to proto::unpack_expr\(seq). /// /// functional::unpack_expr\()(seq) /// is equivalent to proto::unpack_expr\(seq). template struct unpack_expr { BOOST_PROTO_CALLABLE() template struct result {}; template struct result { typedef typename result_of::unpack_expr< Tag , Domain , typename remove_reference::type >::type type; }; /// Construct an expression node with tag type \c Tag /// and in the domain \c Domain. /// /// \param sequence A Fusion Forward Sequence /// \return proto::unpack_expr\(sequence) template typename result_of::unpack_expr::type operator ()(Sequence const &sequence) const { return proto::detail::unpack_expr_< Tag , Domain , Sequence const , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::call(sequence); } }; /// INTERNAL ONLY /// template struct unfused_expr_fun { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename result_of::unpack_expr< Tag , Domain , typename remove_reference::type >::type type; }; template typename proto::result_of::unpack_expr::type operator ()(Sequence const &sequence) const { return proto::detail::unpack_expr_< Tag , Domain , Sequence const , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::call(sequence); } }; /// INTERNAL ONLY /// template struct unfused_expr : fusion::unfused_generic > { BOOST_PROTO_CALLABLE() }; } // namespace functional /// \brief Construct an expression of the requested tag type /// with a domain and with the specified arguments as children. /// /// This function template may be invoked either with or without /// specifying a \c Domain argument. If no domain is specified, /// the domain is deduced by examining in order the domains of /// the given arguments and taking the first that is not /// \c default_domain, if any such domain exists, or /// \c default_domain otherwise. /// /// Let \c wrap_(x) be defined such that: /// \li If \c x is a boost::reference_wrapper\<\>, /// \c wrap_(x) is equivalent to as_child\(x.get()). /// \li Otherwise, \c wrap_(x) is equivalent to /// as_expr\(x). /// /// Let make_\(b0,...bN) be defined as /// expr\ \>::::make(c0,...cN) /// where \c Bx is the type of \c bx. /// /// \return Domain()(make_\(wrap_(a0),...wrap_(aN))). template typename lazy_disable_if< is_domain , result_of::make_expr< Tag , A0 const > >::type const make_expr(A0 const &a0) { return proto::detail::make_expr_< Tag , deduce_domain , A0 const >()(a0); } /// \overload /// template typename result_of::make_expr< Tag , Domain , C0 const >::type const make_expr(C0 const &c0) { return proto::detail::make_expr_< Tag , Domain , C0 const >()(c0); } // Additional overloads generated by the preprocessor... #define BOOST_PP_ITERATION_PARAMS_1 \ (4, (2, BOOST_PROTO_MAX_ARITY, , 3)) \ /**/ #include BOOST_PP_ITERATE() /// \brief Construct an expression of the requested tag type /// with a domain and with childres from the specified Fusion /// Forward Sequence. /// /// This function template may be invoked either with or without /// specifying a \c Domain argument. If no domain is specified, /// the domain is deduced by examining in order the domains of the /// elements of \c sequence and taking the first that is not /// \c default_domain, if any such domain exists, or /// \c default_domain otherwise. /// /// Let \c s be a Fusion Random Access Sequence equivalent to \c sequence. /// Let wrap_\(s), where \c s has type \c S, be defined /// such that: /// \li If fusion::result_of::value_at_c\::::type is a reference, /// wrap_\(s) is equivalent to /// as_child\(fusion::at_c\(s)). /// \li Otherwise, wrap_\(s) is equivalent to /// as_expr\(fusion::at_c\(s)). /// /// Let make_\(b0,...bN) be defined as /// expr\ \>::::make(b0,...bN) /// where \c Bx is the type of \c bx. /// /// \param sequence a Fusion Forward Sequence. /// \return Domain()(make_\(wrap_\<0\>(s),...wrap_\(s))), /// where N is the size of \c Sequence. template typename lazy_disable_if< is_domain , result_of::unpack_expr >::type const unpack_expr(Sequence const &sequence) { return proto::detail::unpack_expr_< Tag , deduce_domain , Sequence const , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::call(sequence); } /// \overload /// template typename result_of::unpack_expr::type const unpack_expr(Sequence2 const &sequence2) { return proto::detail::unpack_expr_< Tag , Domain , Sequence2 const , fusion::BOOST_PROTO_FUSION_RESULT_OF::size::type::value >::call(sequence2); } /// \brief Return a proxy object that holds its arguments by reference /// and is implicitly convertible to an expression. template detail::implicit_expr_1 const implicit_expr(A0 &a0) { detail::implicit_expr_1 that = {a0}; return that; } // Additional overloads generated by the preprocessor... #define BOOST_PP_ITERATION_PARAMS_1 \ (4, (2, BOOST_PROTO_MAX_ARITY, , 4)) \ /**/ #include BOOST_PP_ITERATE() /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #ifdef _MSC_VER # pragma warning(pop) #endif #undef BOOST_PROTO_FUSION_AT #undef BOOST_PROTO_FUSION_AT_TYPE #undef BOOST_PROTO_FUSION_AS_CHILD_AT #undef BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE #undef BOOST_PROTO_FUSION_NEXT_ITERATOR #undef BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE #undef BOOST_PROTO_FUSION_ITERATORS #undef BOOST_PROTO_FUSION_ITERATORS_TYPE #endif // BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005 #elif BOOST_PP_ITERATION_FLAGS() == 1 #define N BOOST_PP_ITERATION() #define M BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N) #if N > 1 template struct BOOST_PP_CAT(implicit_expr_, N) { #define M0(Z, N, DATA) BOOST_PP_CAT(A, N) &BOOST_PP_CAT(a, N); BOOST_PP_REPEAT(N, M0, ~) #undef M0 template operator proto::expr() const { #define M0(Z, N, DATA) \ implicit_expr_1 BOOST_PP_CAT(b, N) \ = {this->BOOST_PP_CAT(a, N)}; \ typename Args::BOOST_PP_CAT(child, N) BOOST_PP_CAT(c, N) = BOOST_PP_CAT(b, N); \ /**/ BOOST_PP_REPEAT(N, M0, ~) #undef M0 proto::expr that = {BOOST_PP_ENUM_PARAMS(N, c)}; return that; } template operator Expr() const { typename Expr::proto_base_expr that = *this; return detail::implicit_expr_wrap(that, is_aggregate(), static_cast(0)); } }; #endif template struct select_nth { typedef BOOST_PP_CAT(T, BOOST_PP_DEC(N)) type; }; // Use function overloading as an efficient mechanism for // calculating the domain shared by a bunch of proto expressions // (or non-expressions, assumed to be in the default_domain). // The domain of a set of domains S is deduced as follows: // - If S contains only default_domain, the deduced domain is // default_domain. // - If S contains only X and default_domain, the deduced domain // is X. // - If S contains different domains X and Y, neither of which is // default_domain, it is an error. template struct BOOST_PP_CAT(deduce_domain, N) { #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) // The function overloading trick doesn't work on MSVC-7.1, so // do it the hard (expensive) way. typedef typename mpl::eval_if_c< is_same::type, default_domain>::value , BOOST_PP_CAT(deduce_domain, BOOST_PP_DEC(N)) , domain_of >::type type; #else #define M0(N, F) char (&F)[BOOST_PP_INC(N)] static M0(BOOST_PROTO_MAX_ARITY, deducer( BOOST_PP_ENUM_PARAMS(N, dont_care BOOST_PP_INTERCEPT))); #define M1(Z, X, DATA) \ typedef typename domain_of::type BOOST_PP_CAT(D, X); \ static BOOST_PP_CAT(D, X) &BOOST_PP_CAT(d, X); \ template \ static M0(X, deducer( \ BOOST_PP_ENUM_PARAMS_Z(Z, X, default_domain BOOST_PP_INTERCEPT) \ BOOST_PP_COMMA_IF(X) T \ BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ Z \ , BOOST_PP_DEC(BOOST_PP_SUB(N, X)) \ , typename nondeduced_domain::type BOOST_PP_INTERCEPT \ ) \ )); BOOST_PP_REPEAT(N, M1, ~) #undef M0 #undef M1 BOOST_STATIC_CONSTANT(int, value = sizeof(deducer(BOOST_PP_ENUM_PARAMS(N, d))) - 1); typedef typename select_nth::type type; #endif }; template struct make_expr_ { typedef proto::expr< Tag , BOOST_PP_CAT(list, N) , N > expr_type; typedef typename Domain::template result::type result_type; result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type a)) const { expr_type that = { BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD, (A, a, Domain)) }; return Domain()(that); } }; template struct make_expr_ : make_expr_< Tag , typename BOOST_PP_CAT(deduce_domain, N)::type BOOST_PP_ENUM_TRAILING_PARAMS(N, A) > {}; template struct unpack_expr_ { BOOST_PROTO_FUSION_ITERATORS_TYPE(N) typedef proto::expr< Tag , BOOST_PP_CAT(list, N)< BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE, ~) > , N > expr_type; typedef typename Domain::template result::type type; static type const call(Sequence const &sequence) { BOOST_PROTO_FUSION_ITERATORS(N) expr_type that = { BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AS_CHILD_AT, ~) }; return Domain()(that); } }; template struct unpack_expr_ { BOOST_PROTO_FUSION_ITERATORS_TYPE(N) typedef unpack_expr_< Tag , typename BOOST_PP_CAT(deduce_domain, N)< BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AT_TYPE, ~) >::type , Sequence , N > other; typedef typename other::type type; static type const call(Sequence const &sequence) { return other::call(sequence); } }; #undef N #undef M #elif BOOST_PP_ITERATION_FLAGS() == 2 #define N BOOST_PP_ITERATION() template struct result { typedef typename result_of::make_expr< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A) >::type type; }; /// \overload /// template typename result_of::make_expr< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) >::type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a)) const { return proto::detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) >()(BOOST_PP_ENUM_PARAMS(N, a)); } #undef N #elif BOOST_PP_ITERATION_FLAGS() == 3 #define N BOOST_PP_ITERATION() /// \overload /// template typename lazy_disable_if< is_domain , result_of::make_expr< Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) > >::type const make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a)) { return proto::detail::make_expr_< Tag , deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) >()(BOOST_PP_ENUM_PARAMS(N, a)); } /// \overload /// template typename result_of::make_expr< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const C) >::type const make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const C, &c)) { return proto::detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const C) >()(BOOST_PP_ENUM_PARAMS(N, c)); } #undef N #elif BOOST_PP_ITERATION_FLAGS() == 4 #define N BOOST_PP_ITERATION() /// \overload /// template detail::BOOST_PP_CAT(implicit_expr_, N) const implicit_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a)) { detail::BOOST_PP_CAT(implicit_expr_, N) that = {BOOST_PP_ENUM_PARAMS(N, a)}; return that; } #undef N #endif // BOOST_PP_IS_ITERATING