123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- //---------------------------------------------------------------------------//
- // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
- //
- // 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_GET_HPP
- #define BOOST_COMPUTE_LAMBDA_GET_HPP
- #include <boost/preprocessor/repetition.hpp>
- #include <boost/compute/config.hpp>
- #include <boost/compute/functional/get.hpp>
- #include <boost/compute/lambda/placeholder.hpp>
- namespace boost {
- namespace compute {
- namespace lambda {
- namespace detail {
- // function wrapper for get<N>() in lambda expressions
- template<size_t N>
- struct get_func
- {
- template<class Expr, class Args>
- struct lambda_result
- {
- typedef typename proto::result_of::child_c<Expr, 1>::type Arg;
- typedef typename ::boost::compute::lambda::result_of<Arg, Args>::type T;
- typedef typename ::boost::compute::detail::get_result_type<N, T>::type type;
- };
- template<class Context, class Arg>
- struct make_get_result_type
- {
- typedef typename boost::remove_cv<
- typename boost::compute::lambda::result_of<
- Arg, typename Context::args_tuple
- >::type
- >::type type;
- };
- // returns the suffix string for get<N>() in lambda expressions
- // (e.g. ".x" for get<0>() with float4)
- template<class T>
- struct make_get_suffix
- {
- static std::string value()
- {
- BOOST_STATIC_ASSERT(N < 16);
- std::stringstream stream;
- if(N < 10){
- stream << ".s" << uint_(N);
- }
- else if(N < 16){
- stream << ".s" << char('a' + (N - 10));
- }
- return stream.str();
- }
- };
- // get<N>() specialization for std::pair<T1, T2>
- template<class T1, class T2>
- struct make_get_suffix<std::pair<T1, T2> >
- {
- static std::string value()
- {
- BOOST_STATIC_ASSERT(N < 2);
- if(N == 0){
- return ".first";
- }
- else {
- return ".second";
- }
- };
- };
- // get<N>() specialization for boost::tuple<T...>
- #define BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX(z, n, unused) \
- template<BOOST_PP_ENUM_PARAMS(n, class T)> \
- struct make_get_suffix<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
- { \
- static std::string value() \
- { \
- BOOST_STATIC_ASSERT(N < n); \
- return ".v" + boost::lexical_cast<std::string>(N); \
- } \
- };
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX, ~)
- #undef BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX
- template<class Context, class Arg>
- static void dispatch_apply_terminal(Context &ctx, const Arg &arg)
- {
- typedef typename make_get_result_type<Context, Arg>::type T;
- proto::eval(arg, ctx);
- ctx.stream << make_get_suffix<T>::value();
- }
- template<class Context, int I>
- static void dispatch_apply_terminal(Context &ctx, placeholder<I>)
- {
- ctx.stream << ::boost::compute::get<N>()(::boost::get<I>(ctx.args));
- }
- template<class Context, class Arg>
- static void dispatch_apply(Context &ctx, const Arg &arg, proto::tag::terminal)
- {
- dispatch_apply_terminal(ctx, proto::value(arg));
- }
- template<class Context, class Arg>
- static void apply(Context &ctx, const Arg &arg)
- {
- dispatch_apply(ctx, arg, typename proto::tag_of<Arg>::type());
- }
- };
- } // end detail namespace
- // get<N>()
- template<size_t N, class Arg>
- inline typename proto::result_of::make_expr<
- proto::tag::function, detail::get_func<N>, const Arg&
- >::type const
- get(const Arg &arg)
- {
- return proto::make_expr<proto::tag::function>(
- detail::get_func<N>(), ::boost::ref(arg)
- );
- }
- } // end lambda namespace
- } // end compute namespace
- } // end boost namespace
- #endif // BOOST_COMPUTE_LAMBDA_GET_HPP
|