1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_LAMBDA_GET_HPP
12 #define BOOST_COMPUTE_LAMBDA_GET_HPP
14 #include <boost/preprocessor/repetition.hpp>
16 #include <boost/compute/config.hpp>
17 #include <boost/compute/functional/get.hpp>
18 #include <boost/compute/lambda/placeholder.hpp>
25 // function wrapper for get<N>() in lambda expressions
29 template<class Expr, class Args>
32 typedef typename proto::result_of::child_c<Expr, 1>::type Arg;
33 typedef typename ::boost::compute::lambda::result_of<Arg, Args>::type T;
34 typedef typename ::boost::compute::detail::get_result_type<N, T>::type type;
37 template<class Context, class Arg>
38 struct make_get_result_type
40 typedef typename boost::remove_cv<
41 typename boost::compute::lambda::result_of<
42 Arg, typename Context::args_tuple
47 // returns the suffix string for get<N>() in lambda expressions
48 // (e.g. ".x" for get<0>() with float4)
50 struct make_get_suffix
52 static std::string value()
54 BOOST_STATIC_ASSERT(N < 16);
56 std::stringstream stream;
59 stream << ".s" << uint_(N);
62 stream << ".s" << char('a' + (N - 10));
69 // get<N>() specialization for std::pair<T1, T2>
70 template<class T1, class T2>
71 struct make_get_suffix<std::pair<T1, T2> >
73 static std::string value()
75 BOOST_STATIC_ASSERT(N < 2);
86 // get<N>() specialization for boost::tuple<T...>
87 #define BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX(z, n, unused) \
88 template<BOOST_PP_ENUM_PARAMS(n, class T)> \
89 struct make_get_suffix<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
91 static std::string value() \
93 BOOST_STATIC_ASSERT(N < n); \
94 return ".v" + boost::lexical_cast<std::string>(N); \
98 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX, ~)
100 #undef BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX
102 template<class Context, class Arg>
103 static void dispatch_apply_terminal(Context &ctx, const Arg &arg)
105 typedef typename make_get_result_type<Context, Arg>::type T;
107 proto::eval(arg, ctx);
108 ctx.stream << make_get_suffix<T>::value();
111 template<class Context, int I>
112 static void dispatch_apply_terminal(Context &ctx, placeholder<I>)
114 ctx.stream << ::boost::compute::get<N>()(::boost::get<I>(ctx.args));
117 template<class Context, class Arg>
118 static void dispatch_apply(Context &ctx, const Arg &arg, proto::tag::terminal)
120 dispatch_apply_terminal(ctx, proto::value(arg));
123 template<class Context, class Arg>
124 static void apply(Context &ctx, const Arg &arg)
126 dispatch_apply(ctx, arg, typename proto::tag_of<Arg>::type());
130 } // end detail namespace
133 template<size_t N, class Arg>
134 inline typename proto::result_of::make_expr<
135 proto::tag::function, detail::get_func<N>, const Arg&
139 return proto::make_expr<proto::tag::function>(
140 detail::get_func<N>(), ::boost::ref(arg)
144 } // end lambda namespace
145 } // end compute namespace
146 } // end boost namespace
148 #endif // BOOST_COMPUTE_LAMBDA_GET_HPP