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_RESULT_OF_HPP 12 #define BOOST_COMPUTE_LAMBDA_RESULT_OF_HPP 13 14 #include <boost/mpl/vector.hpp> 15 #include <boost/proto/proto.hpp> 16 17 #include <boost/compute/type_traits/common_type.hpp> 18 19 namespace boost { 20 namespace compute { 21 namespace lambda { 22 23 namespace mpl = boost::mpl; 24 namespace proto = boost::proto; 25 26 // meta-function returning the result type of a lambda expression 27 template<class Expr, 28 class Args = void, 29 class Tags = typename proto::tag_of<Expr>::type> 30 struct result_of 31 { 32 }; 33 34 // terminals 35 template<class Expr, class Args> 36 struct result_of<Expr, Args, proto::tag::terminal> 37 { 38 typedef typename proto::result_of::value<Expr>::type type; 39 }; 40 41 // binary operators 42 #define BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(tag) \ 43 template<class Expr, class Args> \ 44 struct result_of<Expr, Args, tag> \ 45 { \ 46 typedef typename proto::result_of::child_c<Expr, 0>::type left; \ 47 typedef typename proto::result_of::child_c<Expr, 1>::type right; \ 48 \ 49 typedef typename boost::common_type< \ 50 typename ::boost::compute::lambda::result_of< \ 51 left, \ 52 Args, \ 53 typename proto::tag_of<left>::type>::type, \ 54 typename ::boost::compute::lambda::result_of< \ 55 right, \ 56 Args, \ 57 typename proto::tag_of<right>::type>::type \ 58 >::type type; \ 59 }; 60 61 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::plus) 62 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::minus) 63 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::multiplies) 64 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::divides) 65 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::modulus) 66 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_and) 67 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_or) 68 BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_xor) 69 70 // comparision operators 71 #define BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(tag) \ 72 template<class Expr, class Args> \ 73 struct result_of<Expr, Args, tag> \ 74 { \ 75 typedef bool type; \ 76 }; 77 78 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::less) 79 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::greater) 80 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::less_equal) 81 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::greater_equal) 82 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::equal_to) 83 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::not_equal_to) 84 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::logical_and) 85 BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::logical_or) 86 87 // assignment operator 88 template<class Expr, class Args> 89 struct result_of<Expr, Args, proto::tag::assign> 90 { 91 typedef typename proto::result_of::child_c<Expr, 0>::type left; 92 typedef typename proto::result_of::child_c<Expr, 1>::type right; 93 94 typedef typename ::boost::compute::lambda::result_of< 95 right, Args, typename proto::tag_of<right>::type 96 >::type type; 97 }; 98 99 // functions 100 template<class Expr, class Args> 101 struct result_of<Expr, Args, proto::tag::function> 102 { 103 typedef typename proto::result_of::child_c<Expr, 0>::type func_expr; 104 typedef typename proto::result_of::value<func_expr>::type func; 105 106 typedef typename func::template lambda_result<Expr, Args>::type type; 107 }; 108 109 } // end lambda namespace 110 } // end compute namespace 111 } // end boost namespace 112 113 #endif // BOOST_COMPUTE_LAMBDA_RESULT_OF_HPP 114