• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_FUNCTIONAL_DETAIL_UNPACK_HPP
12 #define BOOST_COMPUTE_FUNCTIONAL_DETAIL_UNPACK_HPP
13 
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>
19 
20 namespace boost {
21 namespace compute {
22 namespace detail {
23 
24 template<class Function, class Arg, size_t Arity>
25 struct invoked_unpacked
26 {
invoked_unpackedboost::compute::detail::invoked_unpacked27     invoked_unpacked(const Function &f, const Arg &arg)
28         : m_function(f),
29           m_arg(arg)
30     {
31     }
32 
33     Function m_function;
34     Arg m_arg;
35 };
36 
37 template<class Function, class Arg, size_t Arity>
38 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, Arity> &expr);
39 
40 template<class Function, class Arg>
operator <<(meta_kernel & k,const invoked_unpacked<Function,Arg,1> & expr)41 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 1> &expr)
42 {
43     return k << expr.m_function(get<0>()(expr.m_arg));
44 }
45 
46 template<class Function, class Arg>
operator <<(meta_kernel & k,const invoked_unpacked<Function,Arg,2> & expr)47 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 2> &expr)
48 {
49     return k << expr.m_function(get<0>()(expr.m_arg), get<1>()(expr.m_arg));
50 }
51 
52 template<class Function, class Arg>
operator <<(meta_kernel & k,const invoked_unpacked<Function,Arg,3> & expr)53 inline meta_kernel& operator<<(meta_kernel &k, const invoked_unpacked<Function, Arg, 3> &expr)
54 {
55     return k << expr.m_function(get<0>()(expr.m_arg), get<1>()(expr.m_arg), get<2>()(expr.m_arg));
56 }
57 
58 template<class Function>
59 struct unpacked
60 {
61     template<class T, class Enable = void>
62     struct aggregate_length
63     {
64         BOOST_STATIC_CONSTANT(size_t, value = boost::tuples::length<T>::value);
65     };
66 
67     template<class T>
68     struct aggregate_length<T, typename enable_if<is_vector_type<T> >::type>
69     {
70         BOOST_STATIC_CONSTANT(size_t, value = vector_size<T>::value);
71     };
72 
73     template<class TupleArg, size_t TupleSize>
74     struct result_impl {};
75 
76     template<class TupleArg>
77     struct result_impl<TupleArg, 1>
78     {
79         typedef typename detail::get_result_type<0, TupleArg>::type T1;
80 
81         typedef typename boost::compute::result_of<Function(T1)>::type type;
82     };
83 
84     template<class TupleArg>
85     struct result_impl<TupleArg, 2>
86     {
87         typedef typename detail::get_result_type<0, TupleArg>::type T1;
88         typedef typename detail::get_result_type<1, TupleArg>::type T2;
89 
90         typedef typename boost::compute::result_of<Function(T1, T2)>::type type;
91     };
92 
93     template<class TupleArg>
94     struct result_impl<TupleArg, 3>
95     {
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;
99 
100         typedef typename boost::compute::result_of<Function(T1, T2, T3)>::type type;
101     };
102 
103     template<class Signature>
104     struct result {};
105 
106     template<class This, class Arg>
107     struct result<This(Arg)>
108     {
109         typedef typename result_impl<Arg, aggregate_length<Arg>::value>::type type;
110     };
111 
unpackedboost::compute::detail::unpacked112     unpacked(const Function &f)
113         : m_function(f)
114     {
115     }
116 
117     template<class Arg>
118     detail::invoked_unpacked<
119         Function, Arg, aggregate_length<typename Arg::result_type>::value
120     >
operator ()boost::compute::detail::unpacked121     operator()(const Arg &arg) const
122     {
123         return detail::invoked_unpacked<
124                    Function,
125                    Arg,
126                    aggregate_length<typename Arg::result_type>::value
127                 >(m_function, arg);
128     }
129 
130     Function m_function;
131 };
132 
133 template<class Function>
unpack(const Function & f)134 inline unpacked<Function> unpack(const Function &f)
135 {
136     return unpacked<Function>(f);
137 }
138 
139 } // end detail namespace
140 } // end compute namespace
141 } // end boost namespace
142 
143 #endif // BOOST_COMPUTE_FUNCTIONAL_DETAIL_UNPACK_HPP
144