#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 children nodes or from a Fusion /// sequence of children 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #if BOOST_VERSION >= 103500 # include # include # include #else # include # include # include #endif #include namespace boost { /// INTERNAL ONLY /// namespace fusion { /// INTERNAL ONLY /// template class unfused_generic; } } namespace boost { namespace proto { /// INTERNAL ONLY /// #define BOOST_PROTO_AS_ARG_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_ARG(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_AT_TYPE(Z, N, DATA) \ typename add_const< \ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c< \ BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ , N \ >::type \ >::type \ /**/ /// INTERNAL ONLY /// # define BOOST_PROTO_AT(Z, N, DATA) \ fusion::BOOST_PROTO_FUSION_AT_C(N, BOOST_PP_TUPLE_ELEM(3, 1, DATA)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_AS_ARG_AT_TYPE(Z, N, DATA) \ typename boost::proto::detail::protoify_< \ BOOST_PROTO_AT_TYPE(Z, N, DATA) \ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ >::type \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_AS_ARG_AT(Z, N, DATA) \ boost::proto::detail::protoify_< \ BOOST_PROTO_AT_TYPE(Z, N, DATA) \ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ >::call(BOOST_PROTO_AT(Z, N, DATA)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM) \ (ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM) \ BOOST_PP_LIST_FOR_EACH_I_R( \ R \ , BOOST_PROTO_VARARG_TEMPLATE_AUX_ \ , I \ , BOOST_PP_TUPLE_TO_LIST( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \ , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \ ) \ ) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM) \ BOOST_PP_IF( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \ , BOOST_PROTO_VARARG_TEMPLATE_YES_ \ , BOOST_PROTO_VARARG_TEMPLATE_NO_ \ )(R, DATA, I, ELEM) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM) \ (BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM) \ < \ BOOST_PP_SEQ_ENUM( \ BOOST_PP_LIST_FOR_EACH_I_R( \ R \ , BOOST_PROTO_VARARG_TYPE_AUX_ \ , I \ , BOOST_PP_TUPLE_TO_LIST( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \ , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \ ) \ ) \ ) \ > \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM) \ BOOST_PP_COMMA_IF(I) \ BOOST_PP_SEQ_HEAD(ELEM) \ BOOST_PP_IF( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \ , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \ , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \ )(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM) \ BOOST_PP_EXPR_IF( \ BOOST_PP_GREATER(I, 1) \ , (( \ BOOST_PP_SEQ_HEAD(ELEM) \ BOOST_PP_IF( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \ , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \ , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \ )(R, DATA, I, ELEM)() \ )) \ ) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_AS_ARG_(Z, N, DATA) \ (BOOST_PP_CAT(DATA, N)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM) \ BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA) \ (BOOST_PP_CAT(DATA, N)) \ /**/ /// INTERNAL ONLY /// #define BOOST_PROTO_VARARG_FUN_(Z, N, DATA) \ template< \ BOOST_PP_SEQ_ENUM( \ BOOST_PP_SEQ_FOR_EACH_I( \ BOOST_PROTO_VARARG_TEMPLATE_, ~ \ , BOOST_PP_SEQ_PUSH_FRONT( \ BOOST_PROTO_SEQ_PUSH_FRONT( \ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \ ) \ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \ ) \ ) \ BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A) \ ) \ > \ typename boost::proto::result_of::make_expr< \ BOOST_PP_SEQ_FOR_EACH_I( \ BOOST_PROTO_VARARG_TYPE_, ~ \ , BOOST_PP_SEQ_PUSH_FRONT( \ BOOST_PROTO_SEQ_PUSH_FRONT( \ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \ ) \ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \ ) \ ) \ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \ >::type const \ BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) \ { \ return boost::proto::detail::make_expr_< \ BOOST_PP_SEQ_FOR_EACH_I( \ BOOST_PROTO_VARARG_TYPE_, ~ \ , BOOST_PP_SEQ_PUSH_FRONT( \ BOOST_PROTO_SEQ_PUSH_FRONT( \ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \ ) \ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \ ) \ ) \ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \ >::call( \ BOOST_PP_SEQ_ENUM( \ BOOST_PP_SEQ_FOR_EACH_I( \ BOOST_PROTO_VARARG_AS_EXPR_, ~ \ , BOOST_PP_SEQ_PUSH_FRONT( \ BOOST_PROTO_SEQ_PUSH_FRONT( \ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \ ) \ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \ ) \ ) \ BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_ARG_, a) \ ) \ ); \ } \ /**/ /// \code /// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE( /// 1 /// , construct /// , boost::proto::default_domain /// , (boost::proto::tag::function) /// , ((op::construct)(typename)(int)) /// ) /// \endcode #define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS) \ BOOST_PP_REPEAT_FROM_TO( \ ARGCOUNT \ , BOOST_PP_INC(ARGCOUNT) \ , BOOST_PROTO_VARARG_FUN_ \ , (NAME, TAG, BOUNDARGS, DOMAIN) \ )\ /**/ /// \code /// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( /// construct /// , boost::proto::default_domain /// , (boost::proto::tag::function) /// , ((op::construct)(typename)(int)) /// ) /// \endcode #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS) \ BOOST_PP_REPEAT( \ BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS)) \ , BOOST_PROTO_VARARG_FUN_ \ , (NAME, TAG, BOUNDARGS, DOMAIN) \ ) \ /**/ namespace detail { template struct protoify_ { typedef typename boost::unwrap_reference::type unref_type; typedef typename mpl::eval_if< boost::is_reference_wrapper , proto::result_of::as_arg , proto::result_of::as_expr >::type type; static type call(T &t) { return typename mpl::if_< is_reference_wrapper , functional::as_arg , functional::as_expr >::type()(static_cast(t)); } }; template struct protoify_ { typedef typename boost::unwrap_reference::type unref_type; typedef typename proto::result_of::as_arg::type type; static type call(T &t) { return functional::as_arg()(static_cast(t)); } }; template< typename Domain BOOST_PP_ENUM_TRAILING_BINARY_PARAMS( BOOST_PROTO_MAX_ARITY , typename A , = default_domain BOOST_PP_INTERCEPT ) > struct deduce_domain_ { typedef Domain type; }; template struct deduce_domain_< default_domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) > : deduce_domain_< typename domain_of::type , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PROTO_MAX_ARITY, A) > {}; template<> struct deduce_domain_ { typedef default_domain type; }; template struct unpack_expr_ {}; template struct unpack_expr_ { typedef typename add_const< typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c< Sequence , 0 >::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 type; static type const call(typename add_reference::type a) { return proto::detail::protoify_::call(a); } }; template struct make_expr_ : make_expr_ {}; #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 children 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_FOR_DOXYGEN_ONLY(= void) BOOST_PP_INTERCEPT ) , typename Void1 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) , typename Void2 BOOST_PROTO_FOR_DOXYGEN_ONLY(= 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) >::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 Domain::apply\ \> \>::::type. /// /// Otherwise, \c type is a typedef for Domain::apply\::::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 ref_\. /// \li If is_expr\::::value is \c false, then the /// child type is Domain::apply\ \> /// \>::::type. /// \li If \c A is B & or cv boost::reference_wrapper\, /// and is_expr\::::value is \c false, then the /// child type is Domain::apply\ \> /// \>::::type. typedef typename detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A) >::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 Random Access Sequence. /// /// In this specialization, the domain is deduced from the /// domains of the children types. (If /// is_domain\::::value is \c true, then another /// specialization is selected.) template< typename Tag , typename Sequence , typename Void1 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) , typename Void2 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) > struct unpack_expr { /// Same as result_of::make_expr\::::type, ... /// fusion::value_at\::::type\>::::type, /// where \c N is the size of \c Sequence. 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 { /// Same as result_of::make_expr\::::type, ... /// fusion::value_at\::::type\>::::type, /// where \c N is the size of \c Sequence. 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() 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 const operator ()(A0 const &a0) const { return proto::detail::make_expr_< Tag , Domain , A0 const >::call(a0); } // Additional overloads generated by the preprocessor ... #define BOOST_PP_ITERATION_PARAMS_1 \ (4, (2, BOOST_PROTO_MAX_ARITY, , 2)) \ /**/ #include BOOST_PP_ITERATE() }; /// \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 Random Access Sequence /// \return proto::unpack_expr\(sequence) template typename result_of::unpack_expr::type const 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 const 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() }; } /// \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_arg\(x.get()). /// \li Otherwise, \c wrap_(x) is equivalent to /// as_expr\(x). /// /// Let make_\(b0,...bN) be defined as /// expr\ \>::::make(b0,...bN) /// where \c Bx is the type of \c bx. /// /// \return Domain::make(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 >::call(a0); } /// \overload /// template typename result_of::make_expr< Tag , Domain , B0 const >::type const make_expr(B0 const &b0) { return proto::detail::make_expr_< Tag , Domain , B0 const >::call(b0); } // 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 /// Random Access 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 wrap_\(s), where \c s has type \c S, be defined /// such that: /// \li If fusion::value_at\::::type is a reference, /// wrap_\(s) is equivalent to /// as_arg\(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 Random Access Sequence. /// \return Domain::make(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); } /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; /// INTERNAL ONLY /// template struct is_callable > : mpl::true_ {}; }} #undef BOOST_PROTO_AT #undef BOOST_PROTO_AT_TYPE #undef BOOST_PROTO_AS_ARG_AT #undef BOOST_PROTO_AS_ARG_AT_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) template struct make_expr_ { typedef proto::expr< Tag , BOOST_PP_CAT(args, N) > expr_type; typedef typename Domain::template apply::type type; static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type a)) { expr_type that = { BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG, (A, a, Domain)) }; return Domain::make(that); } }; template struct make_expr_ : make_expr_< Tag , typename detail::deduce_domain_< typename domain_of< A0 >::type BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) BOOST_PP_ENUM_SHIFTED_PARAMS(N, A) >::type BOOST_PP_ENUM_TRAILING_PARAMS(N, A) > {}; template struct unpack_expr_ { typedef proto::expr< Tag , BOOST_PP_CAT(args, N)< BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT_TYPE, (Sequence const, ~, Domain)) > > expr_type; typedef typename Domain::template apply::type type; static type const call(Sequence const &sequence) { expr_type that = { BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT, (Sequence const, sequence, Domain)) }; return Domain::make(that); } }; template struct unpack_expr_ : unpack_expr_< Tag , typename detail::deduce_domain_< typename domain_of< BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~, ~)) >::type BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~, ~)) >::type , Sequence , N > {}; #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 const 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) >::call(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) >::call(BOOST_PP_ENUM_PARAMS(N, a)); } /// \overload /// template typename result_of::make_expr< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const B) >::type const make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const B, &b)) { return proto::detail::make_expr_< Tag , Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const B) >::call(BOOST_PP_ENUM_PARAMS(N, b)); } #undef N #endif // BOOST_PP_IS_ITERATING