From fecfd2fffeb0174bca29a45d95fc0fe2a793fadd Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Tue, 25 Nov 2008 16:00:40 +0000 Subject: [PATCH] deprecate old BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE macro, replace with more flexible and useful BOOST_PROTO_REPEAT and BOOST_PROTO_LOCAL_ITERATE [SVN r49930] --- example/mini_lambda.cpp | 95 ++++++--- example/virtual_member.cpp | 68 +++--- include/boost/proto/core.hpp | 1 + include/boost/proto/detail/deprecated.hpp | 249 ++++++++++++++++++++++ include/boost/proto/detail/local.hpp | 52 +++++ include/boost/proto/make_expr.hpp | 225 +------------------ include/boost/proto/repeat.hpp | 92 ++++++++ test/lambda.cpp | 30 ++- 8 files changed, 497 insertions(+), 315 deletions(-) create mode 100644 include/boost/proto/detail/deprecated.hpp create mode 100644 include/boost/proto/detail/local.hpp create mode 100644 include/boost/proto/repeat.hpp diff --git a/example/mini_lambda.cpp b/example/mini_lambda.cpp index 4e9ce82..4d790ae 100644 --- a/example/mini_lambda.cpp +++ b/example/mini_lambda.cpp @@ -46,7 +46,7 @@ struct placeholder_arity }; // The lambda grammar, with the transforms for calculating the max arity -struct Lambda +struct lambda_arity : proto::or_< proto::when< proto::terminal< placeholder<_> > @@ -57,17 +57,11 @@ struct Lambda > , proto::when< proto::nary_expr<_, proto::vararg<_> > - , proto::fold<_, mpl::int_<0>(), mpl::max()> + , proto::fold<_, mpl::int_<0>(), mpl::max()> > > {}; -// simple wrapper for calculating a lambda expression's arity. -template -struct lambda_arity - : boost::result_of -{}; - // The lambda context is the same as the default context // with the addition of special handling for lambda placeholders template @@ -105,16 +99,38 @@ struct lambda BOOST_PROTO_EXTENDS_ASSIGN() BOOST_PROTO_EXTENDS_SUBSCRIPT() - // Careful not to evaluate the return type of the nullary function - // unless we have a nullary lambda! - typedef typename mpl::eval_if< - typename lambda_arity::type - , mpl::identity - , proto::result_of::eval > > - >::type nullary_type; + // Calculate the arity of this lambda expression + static int const arity = boost::result_of::type::value; + + template + struct result; + + // Define nested result<> specializations to calculate the return + // type of this lambda expression. But be careful not to evaluate + // the return type of the nullary function unless we have a nullary + // lambda! + template + struct result + : mpl::eval_if_c< + 0 == arity + , proto::result_of::eval > > + , mpl::identity + > + {}; + + template + struct result + : proto::result_of::eval > > + {}; + + template + struct result + : proto::result_of::eval > > + {}; // Define our operator () that evaluates the lambda expression. - nullary_type operator ()() const + typename result::type + operator ()() const { fusion::tuple<> args; lambda_context > ctx(args); @@ -122,7 +138,7 @@ struct lambda } template - typename proto::result_of::eval > >::type + typename result::type operator ()(A0 const &a0) const { fusion::tuple args(a0); @@ -131,7 +147,7 @@ struct lambda } template - typename proto::result_of::eval > >::type + typename result::type operator ()(A0 const &a0, A1 const &a1) const { fusion::tuple args(a0, a1); @@ -166,23 +182,38 @@ struct construct_helper T operator()() const { return T(); } - template - T operator()(A0 const &a0) const - { return T(a0); } - - template - T operator()(A0 const &a0, A1 const &a1) const - { return T(a0, a1); } + // Generate BOOST_PROTO_MAX_ARITY overloads of the + // followig function call operator. +#define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a)\ + template \ + T operator()(A_const_ref_a(N)) const \ + { return T(a(N)); } +#define BOOST_PROTO_LOCAL_a BOOST_PROTO_a +#include BOOST_PROTO_LOCAL_ITERATE() }; // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the -// construct function template like the one defined above. -BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \ - construct \ - , lambda_domain \ - , (proto::tag::function) \ - , ((construct_helper)(typename)) \ -) +// following construct() function template. +#define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \ +template \ +typename proto::result_of::make_expr< \ + proto::tag::function \ + , lambda_domain \ + , construct_helper \ + , A_const_ref(N) \ +>::type const \ +construct(A_const_ref_a(N)) \ +{ \ + return proto::make_expr< \ + proto::tag::function \ + , lambda_domain \ + >( \ + construct_helper() \ + , ref_a(N) \ + ); \ +} +BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0) +#undef M0 struct S { diff --git a/example/virtual_member.cpp b/example/virtual_member.cpp index 3545431..110a38c 100644 --- a/example/virtual_member.cpp +++ b/example/virtual_member.cpp @@ -202,9 +202,8 @@ namespace mini_lambda ((keyword::catch_, catch_)) ) - BOOST_STATIC_CONSTANT( - int, arity = boost::result_of::type::value - ); + // Calculate the arity of this lambda expression + static int const arity = boost::result_of::type::value; // Define overloads of operator() that evaluate the lambda // expression for up to 3 arguments. @@ -214,53 +213,38 @@ namespace mini_lambda typename mpl::eval_if_c< 0 != arity , mpl::identity - , boost::result_of + , boost::result_of & + )> >::type operator()() const { BOOST_MPL_ASSERT_RELATION(arity, ==, 0); - fusion::vector0 args; + fusion::vector<> args; return grammar()(proto_base(), 0, args); } - template - typename boost::result_of & - )>::type - operator ()(A0 const &a0) const - { - BOOST_MPL_ASSERT_RELATION(arity, <=, 1); - fusion::vector1 args(a0); - return grammar()(proto_base(), 0, args); - } + #define LAMBDA_EVAL(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \ + template \ + typename boost::result_of & \ + )>::type \ + operator ()(A_const_ref_a(N)) const \ + { \ + BOOST_MPL_ASSERT_RELATION(arity, <=, N); \ + fusion::vector args(ref_a(N)); \ + return grammar()(proto_base(), 0, args); \ + } \ + /**/ - template - typename boost::result_of & - )>::type - operator ()(A0 const &a0, A1 const &a1) const - { - BOOST_MPL_ASSERT_RELATION(arity, <=, 2); - fusion::vector2 args(a0, a1); - return grammar()(proto_base(), 0, args); - } - - template - typename boost::result_of & - )>::type - operator ()(A0 const &a0, A1 const &a1, A2 const &a2) const - { - BOOST_MPL_ASSERT_RELATION(arity, <=, 3); - fusion::vector3 args(a0, a1, a2); - return grammar()(proto_base(), 0, args); - } + // Repeats LAMBDA_EVAL macro for N=1 to 3 inclusive (because + // there are only 3 placeholders) + BOOST_PROTO_REPEAT_FROM_TO(1, 4, LAMBDA_EVAL) + #undef LAMBDA_EVAL }; namespace placeholders diff --git a/include/boost/proto/core.hpp b/include/boost/proto/core.hpp index 0bfd167..1cbe080 100644 --- a/include/boost/proto/core.hpp +++ b/include/boost/proto/core.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/proto/detail/deprecated.hpp b/include/boost/proto/detail/deprecated.hpp new file mode 100644 index 0000000..c8bcbb0 --- /dev/null +++ b/include/boost/proto/detail/deprecated.hpp @@ -0,0 +1,249 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file deprecated.hpp +/// Definition of the deprecated BOOST_PROTO_DEFINE_FUCTION_TEMPLATE and +/// BOOST_PROTO_DEFINE_VARARG_FUCTION_TEMPLATE macros +// +// 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_DETAIL_DEPRECATED_HPP_EAN_11_25_2008 +#define BOOST_PROTO_DETAIL_DEPRECATED_HPP_EAN_11_25_2008 + +#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 + +/// 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_CHILD_(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) \ + >()( \ + 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_CHILD_, 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) \ + ) \ + /**/ + +#endif diff --git a/include/boost/proto/detail/local.hpp b/include/boost/proto/detail/local.hpp new file mode 100644 index 0000000..8886bbb --- /dev/null +++ b/include/boost/proto/detail/local.hpp @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file local.hpp +/// Contains macros to ease the generation of repetitious code constructs +// +// 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_LOCAL_MACRO +# error "local iteration target macro is not defined" +#endif + +#ifndef BOOST_PROTO_LOCAL_LIMITS +# define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY) +#endif + +#ifndef BOOST_PROTO_LOCAL_typename_A +# define BOOST_PROTO_LOCAL_typename_A BOOST_PROTO_typename_A +#endif + +#ifndef BOOST_PROTO_LOCAL_A +# define BOOST_PROTO_LOCAL_A BOOST_PROTO_A_const_ref +#endif + +#ifndef BOOST_PROTO_LOCAL_A_a +# define BOOST_PROTO_LOCAL_A_a BOOST_PROTO_A_const_ref_a +#endif + +#ifndef BOOST_PROTO_LOCAL_a +# define BOOST_PROTO_LOCAL_a BOOST_PROTO_ref_a +#endif + +#define BOOST_PP_LOCAL_LIMITS BOOST_PROTO_LOCAL_LIMITS + +#define BOOST_PP_LOCAL_MACRO(N) \ + BOOST_PROTO_LOCAL_MACRO( \ + N \ + , BOOST_PROTO_LOCAL_typename_A \ + , BOOST_PROTO_LOCAL_A \ + , BOOST_PROTO_LOCAL_A_a \ + , BOOST_PROTO_LOCAL_a \ + ) \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + +#undef BOOST_PROTO_LOCAL_MACRO +#undef BOOST_PROTO_LOCAL_LIMITS +#undef BOOST_PROTO_LOCAL_typename_A +#undef BOOST_PROTO_LOCAL_A +#undef BOOST_PROTO_LOCAL_A_a +#undef BOOST_PROTO_LOCAL_a diff --git a/include/boost/proto/make_expr.hpp b/include/boost/proto/make_expr.hpp index cf47de1..c4f04b4 100644 --- a/include/boost/proto/make_expr.hpp +++ b/include/boost/proto/make_expr.hpp @@ -17,37 +17,20 @@ #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 @@ -73,6 +56,7 @@ # include #endif #include + #include #include #ifdef _MSC_VER @@ -148,213 +132,6 @@ >::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_CHILD_(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) \ - >()( \ - 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_CHILD_, 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 diff --git a/include/boost/proto/repeat.hpp b/include/boost/proto/repeat.hpp new file mode 100644 index 0000000..acd57c9 --- /dev/null +++ b/include/boost/proto/repeat.hpp @@ -0,0 +1,92 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file repeat.hpp +/// Contains macros to ease the generation of repetitious code constructs +// +// 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_REPEAT_HPP_EAN_11_24_2008 +#define BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008 + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for BOOST_PROTO_MAX_ARITY +#include + +//////////////////////////////////////////// +/// INTERNAL ONLY +#define BOOST_PROTO_ref_a_aux(Z, N, DATA)\ + boost::ref(BOOST_PP_CAT(proto_a, N)) + +/// \brief Generates a sequence like typename A0, typename A1, ... +/// +#define BOOST_PROTO_typename_A(N)\ + BOOST_PP_ENUM_PARAMS(N, typename proto_A) + +/// \brief Generates a sequence like A0 const &, A1 const &, ... +/// +#define BOOST_PROTO_A_const_ref(N)\ + BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const & BOOST_PP_INTERCEPT) + +/// \brief Generates a sequence like A0 &, A1 &, ... +/// +#define BOOST_PROTO_A_ref(N)\ + BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, & BOOST_PP_INTERCEPT) + +/// \brief Generates a sequence like A0, A1, ... +/// +#define BOOST_PROTO_A(N)\ + BOOST_PP_ENUM_PARAMS(N, proto_A) + +/// \brief Generates a sequence like A0 const, A1 const, ... +/// +#define BOOST_PROTO_A_const(N)\ + BOOST_PP_ENUM_PARAMS(N, const proto_A) + +/// \brief Generates a sequence like A0 const &a0, A1 const &a0, ... +/// +#define BOOST_PROTO_A_const_ref_a(N)\ + BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const &proto_a) + +/// \brief Generates a sequence like A0 &a0, A1 &a0, ... +/// +#define BOOST_PROTO_A_ref_a(N)\ + BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, &proto_a) + +/// \brief Generates a sequence like boost::ref(a0), boost::ref(a1), ... +/// +#define BOOST_PROTO_ref_a(N)\ + BOOST_PP_ENUM(N, BOOST_PROTO_ref_a_aux, ~) + +/// \brief Generates a sequence like a0, a1, ... +/// +#define BOOST_PROTO_a(N)\ + BOOST_PP_ENUM_PARAMS(N, proto_a) + +//////////////////////////////////////////// +/// INTERNAL ONLY +#define BOOST_PROTO_invoke(Z, N, DATA)\ + BOOST_PP_TUPLE_ELEM(5,0,DATA)(N, BOOST_PP_TUPLE_ELEM(5,1,DATA), BOOST_PP_TUPLE_ELEM(5,2,DATA), BOOST_PP_TUPLE_ELEM(5,3,DATA), BOOST_PP_TUPLE_ELEM(5,4,DATA)) + +#define BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)\ + BOOST_PP_REPEAT_FROM_TO(FROM, TO, BOOST_PROTO_invoke, (MACRO, typename_A, A, A_a, a)) + +#define BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)\ + BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a) + +#define BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)\ + BOOST_PROTO_REPEAT_FROM_TO_EX(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a) + +#define BOOST_PROTO_REPEAT(MACRO)\ + BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO) + +#define BOOST_PROTO_LOCAL_ITERATE() + +#endif diff --git a/test/lambda.cpp b/test/lambda.cpp index 14df2a4..5edeee9 100644 --- a/test/lambda.cpp +++ b/test/lambda.cpp @@ -130,28 +130,24 @@ struct lambda return proto::eval(*this, ctx); } - template - typename proto::result_of::eval > >::type - operator ()(A0 const &a0) const - { - fusion::tuple args(a0); - lambda_context > ctx(args); - return proto::eval(*this, ctx); - } - - template - typename proto::result_of::eval > >::type - operator ()(A0 const &a0, A1 const &a1) const - { - fusion::tuple args(a0, a1); - lambda_context > ctx(args); - return proto::eval(*this, ctx); - } + #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \ + template \ + typename proto::result_of::eval > >::type \ + operator ()(A_const_ref_a(N)) const \ + { \ + fusion::tuple args(ref_a(N)); \ + lambda_context > ctx(args); \ + return proto::eval(*this, ctx); \ + } \ + /**/ + BOOST_PROTO_REPEAT_FROM_TO(1, 4, M0) + #undef M0 }; // Define some lambda placeholders lambda > >::type> const _1 = {{}}; lambda > >::type> const _2 = {{}}; +lambda > >::type> const _3 = {{}}; template lambda::type> const val(T const &t)