File indexing completed on 2025-01-18 09:30:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_LAMBDA_GET_HPP
0012 #define BOOST_COMPUTE_LAMBDA_GET_HPP
0013
0014 #include <boost/preprocessor/repetition.hpp>
0015
0016 #include <boost/compute/config.hpp>
0017 #include <boost/compute/functional/get.hpp>
0018 #include <boost/compute/lambda/placeholder.hpp>
0019
0020 namespace boost {
0021 namespace compute {
0022 namespace lambda {
0023 namespace detail {
0024
0025
0026 template<size_t N>
0027 struct get_func
0028 {
0029 template<class Expr, class Args>
0030 struct lambda_result
0031 {
0032 typedef typename proto::result_of::child_c<Expr, 1>::type Arg;
0033 typedef typename ::boost::compute::lambda::result_of<Arg, Args>::type T;
0034 typedef typename ::boost::compute::detail::get_result_type<N, T>::type type;
0035 };
0036
0037 template<class Context, class Arg>
0038 struct make_get_result_type
0039 {
0040 typedef typename boost::remove_cv<
0041 typename boost::compute::lambda::result_of<
0042 Arg, typename Context::args_tuple
0043 >::type
0044 >::type type;
0045 };
0046
0047
0048
0049 template<class T>
0050 struct make_get_suffix
0051 {
0052 static std::string value()
0053 {
0054 BOOST_STATIC_ASSERT(N < 16);
0055
0056 std::stringstream stream;
0057
0058 if(N < 10){
0059 stream << ".s" << uint_(N);
0060 }
0061 else if(N < 16){
0062 stream << ".s" << char('a' + (N - 10));
0063 }
0064
0065 return stream.str();
0066 }
0067 };
0068
0069
0070 template<class T1, class T2>
0071 struct make_get_suffix<std::pair<T1, T2> >
0072 {
0073 static std::string value()
0074 {
0075 BOOST_STATIC_ASSERT(N < 2);
0076
0077 if(N == 0){
0078 return ".first";
0079 }
0080 else {
0081 return ".second";
0082 }
0083 };
0084 };
0085
0086
0087 #define BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX(z, n, unused) \
0088 template<BOOST_PP_ENUM_PARAMS(n, class T)> \
0089 struct make_get_suffix<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
0090 { \
0091 static std::string value() \
0092 { \
0093 BOOST_STATIC_ASSERT(N < n); \
0094 return ".v" + boost::lexical_cast<std::string>(N); \
0095 } \
0096 };
0097
0098 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX, ~)
0099
0100 #undef BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX
0101
0102 template<class Context, class Arg>
0103 static void dispatch_apply_terminal(Context &ctx, const Arg &arg)
0104 {
0105 typedef typename make_get_result_type<Context, Arg>::type T;
0106
0107 proto::eval(arg, ctx);
0108 ctx.stream << make_get_suffix<T>::value();
0109 }
0110
0111 template<class Context, int I>
0112 static void dispatch_apply_terminal(Context &ctx, placeholder<I>)
0113 {
0114 ctx.stream << ::boost::compute::get<N>()(::boost::get<I>(ctx.args));
0115 }
0116
0117 template<class Context, class Arg>
0118 static void dispatch_apply(Context &ctx, const Arg &arg, proto::tag::terminal)
0119 {
0120 dispatch_apply_terminal(ctx, proto::value(arg));
0121 }
0122
0123 template<class Context, class Arg>
0124 static void apply(Context &ctx, const Arg &arg)
0125 {
0126 dispatch_apply(ctx, arg, typename proto::tag_of<Arg>::type());
0127 }
0128 };
0129
0130 }
0131
0132
0133 template<size_t N, class Arg>
0134 inline typename proto::result_of::make_expr<
0135 proto::tag::function, detail::get_func<N>, const Arg&
0136 >::type const
0137 get(const Arg &arg)
0138 {
0139 return proto::make_expr<proto::tag::function>(
0140 detail::get_func<N>(), ::boost::ref(arg)
0141 );
0142 }
0143
0144 }
0145 }
0146 }
0147
0148 #endif