1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013 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_PLACEHOLDERS_HPP 12 #define BOOST_COMPUTE_LAMBDA_PLACEHOLDERS_HPP 13 14 #include <boost/mpl/has_xxx.hpp> 15 16 #include <boost/compute/lambda/context.hpp> 17 #include <boost/compute/lambda/result_of.hpp> 18 19 namespace boost { 20 namespace compute { 21 namespace lambda { 22 23 namespace mpl = boost::mpl; 24 namespace proto = boost::proto; 25 26 // lambda placeholders 27 expression<proto::terminal<placeholder<0> >::type> const _1; 28 expression<proto::terminal<placeholder<1> >::type> const _2; 29 expression<proto::terminal<placeholder<2> >::type> const _3; 30 31 namespace detail { 32 33 BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) 34 35 template<class T, bool HasResultType> 36 struct terminal_type_impl; 37 38 template<class T> 39 struct terminal_type_impl<T, true> 40 { 41 typedef typename T::result_type type; 42 }; 43 44 template<class T> 45 struct terminal_type_impl<T, false> 46 { 47 typedef T type; 48 }; 49 50 template<class T> 51 struct terminal_type 52 { 53 typedef typename terminal_type_impl<T, has_result_type<T>::value>::type type; 54 }; 55 56 } // end detail namespace 57 58 // result_of placeholders 59 template<class Args> 60 struct result_of<expression<proto::terminal<placeholder<0> >::type>, Args, proto::tag::terminal> 61 { 62 typedef typename boost::tuples::element<0, Args>::type arg_type; 63 64 typedef typename detail::terminal_type<arg_type>::type type; 65 }; 66 67 template<class Args> 68 struct result_of<expression<proto::terminal<placeholder<1> >::type>, Args, proto::tag::terminal> 69 { 70 typedef typename boost::tuples::element<1, Args>::type arg_type; 71 72 typedef typename detail::terminal_type<arg_type>::type type; 73 }; 74 75 template<class Args> 76 struct result_of<expression<proto::terminal<placeholder<2> >::type>, Args, proto::tag::terminal> 77 { 78 typedef typename boost::tuples::element<2, Args>::type arg_type; 79 80 typedef typename detail::terminal_type<arg_type>::type type; 81 }; 82 83 } // end lambda namespace 84 85 // lift lambda placeholders up to the boost::compute namespace 86 using lambda::_1; 87 using lambda::_2; 88 using lambda::_3; 89 90 } // end compute namespace 91 } // end boost namespace 92 93 #endif // BOOST_COMPUTE_LAMBDA_PLACEHOLDERS_HPP 94