]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/compute/include/boost/compute/functional/bind.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / functional / bind.hpp
CommitLineData
7c673cae
FG
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
21namespace boost {
22namespace compute {
23namespace placeholders {
24
25/// \internal_
26template<int I>
27struct placeholder : boost::integral_constant<int, I>
28{
29 placeholder() { }
30};
31
32placeholder<0> const _1;
33placeholder<1> const _2;
34
35} // end placeholders namespace
36
37/// Meta-function returning \c true if \c T is a placeholder type.
38template<class T>
39struct is_placeholder : boost::false_type
40{
41};
42
43/// \internal_
44template<int I>
45struct is_placeholder<placeholders::placeholder<I> > : boost::true_type
46{
47};
48
49namespace detail {
50
51template<class Function, class BoundArgs, class Args>
52struct 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
115template<class Function, class BoundArgs, class Args>
116inline 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
127template<class Function, class BoundArgs, class Args>
128inline 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
140template<class Function, class BoundArgs, class Args>
141inline 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
154template<class Function, class BoundArgs, class Args>
155inline 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
163template<class Function, class BoundArgs>
164struct 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
221template<class F, class... Args>
222inline detail::bound_function<F, boost::tuple<Args...> >
223bind(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
230template<class F, class A1>
231inline detail::bound_function<F, boost::tuple<A1> >
232bind(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
239template<class F, class A1, class A2>
240inline detail::bound_function<F, boost::tuple<A1, A2> >
241bind(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
248template<class F, class A1, class A2, class A3>
249inline detail::bound_function<F, boost::tuple<A1, A2, A3> >
250bind(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