]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //---------------------------------------------------------------------------// |
2 | // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com> | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0 | |
5 | // See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt | |
7 | // | |
8 | // See http://boostorg.github.com/compute for more information. | |
9 | //---------------------------------------------------------------------------// | |
10 | ||
11 | #ifndef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP | |
12 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP | |
13 | ||
14 | #include <boost/preprocessor/repetition.hpp> | |
15 | ||
16 | #include <boost/compute/config.hpp> | |
17 | #include <boost/compute/types/tuple.hpp> | |
18 | ||
19 | namespace boost { | |
20 | namespace compute { | |
21 | namespace lambda { | |
22 | namespace detail { | |
23 | ||
24 | // function wrapper for make_tuple() in lambda expressions | |
25 | struct make_tuple_func | |
26 | { | |
27 | template<class Expr, class Args, int N> | |
28 | struct make_tuple_result_type; | |
29 | ||
30 | #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG(z, n, unused) \ | |
31 | typedef typename proto::result_of::child_c<Expr, BOOST_PP_INC(n)>::type BOOST_PP_CAT(Arg, n); | |
32 | ||
33 | #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE(z, n, unused) \ | |
34 | typedef typename lambda::result_of<BOOST_PP_CAT(Arg, n), Args>::type BOOST_PP_CAT(T, n); | |
35 | ||
36 | #define BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE(z, n, unused) \ | |
37 | template<class Expr, class Args> \ | |
38 | struct make_tuple_result_type<Expr, Args, n> \ | |
39 | { \ | |
40 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG, ~) \ | |
41 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE, ~) \ | |
42 | typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> type; \ | |
43 | }; | |
44 | ||
45 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE, ~) | |
46 | ||
47 | #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG | |
48 | #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE | |
49 | #undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE | |
50 | ||
51 | template<class Expr, class Args> | |
52 | struct lambda_result | |
53 | { | |
54 | typedef typename make_tuple_result_type< | |
55 | Expr, Args, proto::arity_of<Expr>::value - 1 | |
56 | >::type type; | |
57 | }; | |
58 | ||
59 | #define BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE(z, n, unused) \ | |
60 | typedef typename lambda::result_of< \ | |
61 | BOOST_PP_CAT(Arg, n), typename Context::args_tuple \ | |
62 | >::type BOOST_PP_CAT(T, n); | |
63 | ||
64 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG(z, n, unused) \ | |
65 | BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n) | |
66 | ||
67 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG(z, n, unused) \ | |
68 | BOOST_PP_EXPR_IF(n, ctx.stream << ", ";) proto::eval(BOOST_PP_CAT(arg, n), ctx); | |
69 | ||
70 | #define BOOST_COMPUTE_MAKE_TUPLE_APPLY(z, n, unused) \ | |
71 | template<class Context, BOOST_PP_ENUM_PARAMS(n, class Arg)> \ | |
72 | static void apply(Context &ctx, BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG, ~)) \ | |
73 | { \ | |
74 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE, ~) \ | |
75 | typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \ | |
76 | ctx.stream.template inject_type<tuple_type>(); \ | |
77 | ctx.stream << "((" << type_name<tuple_type>() << "){"; \ | |
78 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG, ~) \ | |
79 | ctx.stream << "})"; \ | |
80 | } | |
81 | ||
82 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_APPLY, ~) | |
83 | ||
84 | #undef BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE | |
85 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG | |
86 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG | |
87 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY | |
88 | }; | |
89 | ||
90 | } // end detail namespace | |
91 | ||
92 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG(z, n, unused) \ | |
93 | BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n) | |
94 | ||
95 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE(z, n, unused) \ | |
96 | BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) & | |
97 | ||
98 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG(z, n, unused) \ | |
99 | BOOST_PP_COMMA_IF(n) ::boost::ref(BOOST_PP_CAT(arg, n)) | |
100 | ||
101 | #define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE(z, n, unused) \ | |
102 | template<BOOST_PP_ENUM_PARAMS(n, class Arg)> \ | |
103 | inline typename proto::result_of::make_expr< \ | |
104 | proto::tag::function, \ | |
105 | detail::make_tuple_func, \ | |
106 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE, ~) \ | |
107 | >::type \ | |
108 | make_tuple(BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG, ~)) \ | |
109 | { \ | |
110 | return proto::make_expr<proto::tag::function>( \ | |
111 | detail::make_tuple_func(), \ | |
112 | BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG, ~) \ | |
113 | ); \ | |
114 | } | |
115 | ||
116 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE, ~) | |
117 | ||
118 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG | |
119 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE | |
120 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG | |
121 | #undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE | |
122 | ||
123 | } // end lambda namespace | |
124 | } // end compute namespace | |
125 | } // end boost namespace | |
126 | ||
127 | #endif // BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP |