]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/compute/include/boost/compute/functional/bind.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / functional / bind.hpp
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 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_BIND_HPP
12 #define BOOST_COMPUTE_FUNCTIONAL_BIND_HPP
13
14 #include <boost/mpl/int.hpp>
15 #include <boost/tuple/tuple.hpp>
16 #include <boost/type_traits/conditional.hpp>
17
18 #include <boost/compute/config.hpp>
19 #include <boost/compute/detail/meta_kernel.hpp>
20
21 namespace boost {
22 namespace compute {
23 namespace placeholders {
24
25 /// \internal_
26 template<int I>
27 struct placeholder : boost::integral_constant<int, I>
28 {
29 placeholder() { }
30 };
31
32 placeholder<0> const _1;
33 placeholder<1> const _2;
34
35 } // end placeholders namespace
36
37 /// Meta-function returning \c true if \c T is a placeholder type.
38 template<class T>
39 struct is_placeholder : boost::false_type
40 {
41 };
42
43 /// \internal_
44 template<int I>
45 struct is_placeholder<placeholders::placeholder<I> > : boost::true_type
46 {
47 };
48
49 namespace detail {
50
51 template<class Function, class BoundArgs, class Args>
52 struct invoked_bound_function
53 {
54 invoked_bound_function(Function f, BoundArgs bound_args, Args args)
55 : m_function(f),
56 m_bound_args(bound_args),
57 m_args(args)
58 {
59 }
60
61 // meta-function returning true if the N'th argument is a placeholder
62 template<int N>
63 struct is_placeholder_arg
64 {
65 typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
66
67 typedef typename is_placeholder<nth_bound_arg>::type type;
68 static const bool value = is_placeholder<nth_bound_arg>::value;
69 };
70
71 template<class Arg>
72 struct get_arg_type
73 {
74 typedef Arg type;
75 };
76
77 template<int I>
78 struct get_arg_type<placeholders::placeholder<I> >
79 {
80 typedef typename boost::tuples::element<I, Args>::type type;
81 };
82
83 // meta-function returning the type of the N'th argument when invoked
84 template<int N>
85 struct get_nth_arg_type
86 {
87 typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
88
89 typedef typename get_arg_type<nth_bound_arg>::type type;
90 };
91
92 template<int N>
93 typename get_nth_arg_type<N>::type get_nth_arg(
94 typename boost::enable_if_c<is_placeholder_arg<N>::value>::type* = 0
95 ) const
96 {
97 typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
98
99 return boost::get<nth_bound_arg::value>(m_args);
100 }
101
102 template<int N>
103 typename get_nth_arg_type<N>::type get_nth_arg(
104 typename boost::disable_if_c<is_placeholder_arg<N>::value>::type* = 0
105 ) const
106 {
107 return boost::get<N>(m_bound_args);
108 }
109
110 Function m_function;
111 BoundArgs m_bound_args;
112 Args m_args;
113 };
114
115 template<class Function, class BoundArgs, class Args>
116 inline meta_kernel& apply_invoked_bound_function(
117 meta_kernel &k,
118 const invoked_bound_function<Function, BoundArgs, Args> &expr,
119 typename boost::enable_if_c<
120 boost::tuples::length<BoundArgs>::value == 1
121 >::type* = 0
122 )
123 {
124 return k << expr.m_function(expr.template get_nth_arg<0>());
125 }
126
127 template<class Function, class BoundArgs, class Args>
128 inline meta_kernel& apply_invoked_bound_function(
129 meta_kernel &k,
130 const invoked_bound_function<Function, BoundArgs, Args> &expr,
131 typename boost::enable_if_c<
132 boost::tuples::length<BoundArgs>::value == 2
133 >::type* = 0
134 )
135 {
136 return k << expr.m_function(expr.template get_nth_arg<0>(),
137 expr.template get_nth_arg<1>());
138 }
139
140 template<class Function, class BoundArgs, class Args>
141 inline meta_kernel& apply_invoked_bound_function(
142 meta_kernel &k,
143 const invoked_bound_function<Function, BoundArgs, Args> &expr,
144 typename boost::enable_if_c<
145 boost::tuples::length<BoundArgs>::value == 3
146 >::type* = 0
147 )
148 {
149 return k << expr.m_function(expr.template get_nth_arg<0>(),
150 expr.template get_nth_arg<1>(),
151 expr.template get_nth_arg<2>());
152 }
153
154 template<class Function, class BoundArgs, class Args>
155 inline meta_kernel& operator<<(
156 meta_kernel &k,
157 const invoked_bound_function<Function, BoundArgs, Args> &expr
158 )
159 {
160 return apply_invoked_bound_function(k, expr);
161 }
162
163 template<class Function, class BoundArgs>
164 struct bound_function
165 {
166 typedef int result_type;
167
168 bound_function(Function f, BoundArgs args)
169 : m_function(f),
170 m_args(args)
171 {
172 }
173
174 template<class Arg1>
175 detail::invoked_bound_function<
176 Function,
177 BoundArgs,
178 boost::tuple<Arg1>
179 >
180 operator()(const Arg1 &arg1) const
181 {
182 return detail::invoked_bound_function<
183 Function,
184 BoundArgs,
185 boost::tuple<Arg1>
186 >(m_function, m_args, boost::make_tuple(arg1));
187 }
188
189 template<class Arg1, class Arg2>
190 detail::invoked_bound_function<
191 Function,
192 BoundArgs,
193 boost::tuple<Arg1, Arg2>
194 >
195 operator()(const Arg1 &arg1, const Arg2 &arg2) const
196 {
197 return detail::invoked_bound_function<
198 Function,
199 BoundArgs,
200 boost::tuple<Arg1, Arg2>
201 >(m_function, m_args, boost::make_tuple(arg1, arg2));
202 }
203
204 Function m_function;
205 BoundArgs m_args;
206 };
207
208 } // end detail namespace
209
210 #if !defined(BOOST_COMPUTE_NO_VARIADIC_TEMPLATES) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
211 /// Returns a function wrapper which invokes \p f with \p args when called.
212 ///
213 /// For example, to generate a unary function object which returns \c true
214 /// when its argument is less than \c 7:
215 /// \code
216 /// using boost::compute::less;
217 /// using boost::compute::placeholders::_1;
218 ///
219 /// auto less_than_seven = boost::compute::bind(less<int>(), _1, 7);
220 /// \endcode
221 template<class F, class... Args>
222 inline detail::bound_function<F, boost::tuple<Args...> >
223 bind(F f, Args... args)
224 {
225 typedef typename boost::tuple<Args...> ArgsTuple;
226
227 return detail::bound_function<F, ArgsTuple>(f, boost::make_tuple(args...));
228 }
229 #else
230 template<class F, class A1>
231 inline detail::bound_function<F, boost::tuple<A1> >
232 bind(F f, A1 a1)
233 {
234 typedef typename boost::tuple<A1> Args;
235
236 return detail::bound_function<F, Args>(f, boost::make_tuple(a1));
237 }
238
239 template<class F, class A1, class A2>
240 inline detail::bound_function<F, boost::tuple<A1, A2> >
241 bind(F f, A1 a1, A2 a2)
242 {
243 typedef typename boost::tuple<A1, A2> Args;
244
245 return detail::bound_function<F, Args>(f, boost::make_tuple(a1, a2));
246 }
247
248 template<class F, class A1, class A2, class A3>
249 inline detail::bound_function<F, boost::tuple<A1, A2, A3> >
250 bind(F f, A1 a1, A2 a2, A3 a3)
251 {
252 typedef typename boost::tuple<A1, A2, A3> Args;
253
254 return detail::bound_function<F, Args>(f, boost::make_tuple(a1, a2, a3));
255 }
256 #endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
257
258 } // end compute namespace
259 } // end boost namespace
260
261 #endif // BOOST_COMPUTE_FUNCTIONAL_BIND_HPP