1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_FUNCTIONAL_DETAIL_UNPACK_HPP
12 #define BOOST_COMPUTE_FUNCTIONAL_DETAIL_UNPACK_HPP
14 #include <boost/compute/functional/get.hpp>
15 #include <boost/compute/type_traits/is_vector_type.hpp>
16 #include <boost/compute/type_traits/result_of.hpp>
17 #include <boost/compute/type_traits/vector_size.hpp>
18 #include <boost/compute/detail/meta_kernel.hpp>
24 template<class Function, class Arg, size_t Arity>
25 struct invoked_unpacked
27 invoked_unpacked(const Function &f, const Arg &arg)
37 template<class Function, class Arg, size_t Arity>
38 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, Arity> &expr);
40 template<class Function, class Arg>
41 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 1> &expr)
43 return k << expr.m_function(get<0>()(expr.m_arg));
46 template<class Function, class Arg>
47 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 2> &expr)
49 return k << expr.m_function(get<0>()(expr.m_arg), get<1>()(expr.m_arg));
52 template<class Function, class Arg>
53 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 3> &expr)
55 return k << expr.m_function(get<0>()(expr.m_arg), get<1>()(expr.m_arg), get<2>()(expr.m_arg));
58 template<class Function>
61 template<class T, class Enable = void>
62 struct aggregate_length
64 BOOST_STATIC_CONSTANT(size_t, value = boost::tuples::length<T>::value);
68 struct aggregate_length<T, typename enable_if<is_vector_type<T> >::type>
70 BOOST_STATIC_CONSTANT(size_t, value = vector_size<T>::value);
73 template<class TupleArg, size_t TupleSize>
74 struct result_impl {};
76 template<class TupleArg>
77 struct result_impl<TupleArg, 1>
79 typedef typename detail::get_result_type<0, TupleArg>::type T1;
81 typedef typename boost::compute::result_of<Function(T1)>::type type;
84 template<class TupleArg>
85 struct result_impl<TupleArg, 2>
87 typedef typename detail::get_result_type<0, TupleArg>::type T1;
88 typedef typename detail::get_result_type<1, TupleArg>::type T2;
90 typedef typename boost::compute::result_of<Function(T1, T2)>::type type;
93 template<class TupleArg>
94 struct result_impl<TupleArg, 3>
96 typedef typename detail::get_result_type<0, TupleArg>::type T1;
97 typedef typename detail::get_result_type<1, TupleArg>::type T2;
98 typedef typename detail::get_result_type<2, TupleArg>::type T3;
100 typedef typename boost::compute::result_of<Function(T1, T2, T3)>::type type;
103 template<class Signature>
106 template<class This, class Arg>
107 struct result<This(Arg)>
109 typedef typename result_impl<Arg, aggregate_length<Arg>::value>::type type;
112 unpacked(const Function &f)
118 detail::invoked_unpacked<
119 Function, Arg, aggregate_length<typename Arg::result_type>::value
121 operator()(const Arg &arg) const
123 return detail::invoked_unpacked<
126 aggregate_length<typename Arg::result_type>::value
133 template<class Function>
134 inline unpacked<Function> unpack(const Function &f)
136 return unpacked<Function>(f);
139 } // end detail namespace
140 } // end compute namespace
141 } // end boost namespace
143 #endif // BOOST_COMPUTE_FUNCTIONAL_DETAIL_UNPACK_HPP