//---------------------------------------------------------------------------// // Copyright (c) 2013-2014 Kyle Lutz // // 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 // // See http://boostorg.github.com/compute for more information. //---------------------------------------------------------------------------// #ifndef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP #include #include #include namespace boost { namespace compute { namespace lambda { namespace detail { // function wrapper for make_tuple() in lambda expressions struct make_tuple_func { template struct make_tuple_result_type; #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG(z, n, unused) \ typedef typename proto::result_of::child_c::type BOOST_PP_CAT(Arg, n); #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE(z, n, unused) \ typedef typename lambda::result_of::type BOOST_PP_CAT(T, n); #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE(z, n, unused) \ template \ struct make_tuple_result_type \ { \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG, ~) \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE, ~) \ typedef boost::tuple type; \ }; BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE, ~) #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE template struct lambda_result { typedef typename make_tuple_result_type< Expr, Args, proto::arity_of::value - 1 >::type type; }; #define BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE(z, n, unused) \ typedef typename lambda::result_of< \ BOOST_PP_CAT(Arg, n), typename Context::args_tuple \ >::type BOOST_PP_CAT(T, n); #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG(z, n, unused) \ BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n) #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG(z, n, unused) \ BOOST_PP_EXPR_IF(n, ctx.stream << ", ";) proto::eval(BOOST_PP_CAT(arg, n), ctx); #define BOOST_COMPUTE_MAKE_TUPLE_APPLY(z, n, unused) \ template \ static void apply(Context &ctx, BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG, ~)) \ { \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE, ~) \ typedef typename boost::tuple tuple_type; \ ctx.stream.template inject_type(); \ ctx.stream << "((" << type_name() << "){"; \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG, ~) \ ctx.stream << "})"; \ } BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_APPLY, ~) #undef BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY }; } // end detail namespace #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG(z, n, unused) \ BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n) #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE(z, n, unused) \ BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) & #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG(z, n, unused) \ BOOST_PP_COMMA_IF(n) ::boost::ref(BOOST_PP_CAT(arg, n)) #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE(z, n, unused) \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, \ detail::make_tuple_func, \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE, ~) \ >::type \ make_tuple(BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG, ~)) \ { \ return proto::make_expr( \ detail::make_tuple_func(), \ BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG, ~) \ ); \ } BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE, ~) #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE } // end lambda namespace } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP