Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:03

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
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 // function wrapper for get<N>() in lambda expressions
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     // returns the suffix string for get<N>() in lambda expressions
0048     // (e.g. ".x" for get<0>() with float4)
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     // get<N>() specialization for std::pair<T1, T2>
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     // get<N>() specialization for boost::tuple<T...>
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 } // end detail namespace
0131 
0132 // get<N>()
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 } // end lambda namespace
0145 } // end compute namespace
0146 } // end boost namespace
0147 
0148 #endif // BOOST_COMPUTE_LAMBDA_GET_HPP