]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/callable.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / callable.hpp
1 // Boost.TypeErasure library
2 //
3 // Copyright 2011 Steven Watanabe
4 //
5 // Distributed under the Boost Software License Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // $Id$
10
11 #if !defined(BOOST_PP_IS_ITERATING)
12
13 #ifndef BOOST_TYPE_ERASURE_CALLABLE_HPP_INCLUDED
14 #define BOOST_TYPE_ERASURE_CALLABLE_HPP_INCLUDED
15
16 #include <boost/detail/workaround.hpp>
17 #include <boost/utility/declval.hpp>
18 #include <boost/mpl/vector.hpp>
19 #include <boost/mpl/push_back.hpp>
20 #include <boost/preprocessor/cat.hpp>
21 #include <boost/preprocessor/dec.hpp>
22 #include <boost/preprocessor/iteration/iterate.hpp>
23 #include <boost/preprocessor/repetition/enum.hpp>
24 #include <boost/preprocessor/repetition/enum_params.hpp>
25 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
26 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
27 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
28 #include <boost/type_erasure/config.hpp>
29 #include <boost/type_erasure/call.hpp>
30 #include <boost/type_erasure/concept_interface.hpp>
31 #include <boost/type_erasure/rebind_any.hpp>
32 #include <boost/type_erasure/param.hpp>
33
34 namespace boost {
35 namespace type_erasure {
36
37 template<class Sig, class F = _self>
38 struct callable;
39
40 namespace detail {
41
42 template<class Sig>
43 struct result_of_callable;
44
45 }
46
47 #if defined(BOOST_TYPE_ERASURE_DOXYGEN)
48
49 /**
50 * The @ref callable concept allows an @ref any to hold function objects.
51 * @c Sig is interpreted in the same way as for Boost.Function, except
52 * that the arguments and return type are allowed to be placeholders.
53 * @c F must be a @ref placeholder.
54 *
55 * Multiple instances of @ref callable can be used
56 * simultaneously. Overload resolution works normally.
57 * Note that unlike Boost.Function, @ref callable
58 * does not provide result_type. It does, however,
59 * support @c boost::result_of.
60 */
61 template<class Sig, class F = _self>
62 struct callable
63 {
64 /**
65 * @c R is the result type of @c Sig and @c T is the argument
66 * types of @c Sig.
67 */
68 static R apply(F& f, T... arg);
69 };
70
71 #elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
72 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
73 !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
74
75 template<class R, class... T, class F>
76 struct callable<R(T...), F>
77 {
78 static R apply(F& f, T... arg)
79 {
80 return f(std::forward<T>(arg)...);
81 }
82 };
83
84 template<class... T, class F>
85 struct callable<void(T...), F>
86 {
87 static void apply(F& f, T... arg)
88 {
89 f(std::forward<T>(arg)...);
90 }
91 };
92
93 template<class R, class F, class Base, class Enable, class... T>
94 struct concept_interface<callable<R(T...), F>, Base, F, Enable>
95 : Base
96 {
97 template<class Sig>
98 struct result :
99 ::boost::type_erasure::detail::result_of_callable<Sig>
100 {};
101 typedef void _boost_type_erasure_is_callable;
102 typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
103 typedef char (&_boost_type_erasure_callable_size)[1];
104 _boost_type_erasure_callable_size
105 _boost_type_erasure_deduce_callable(
106 typename ::boost::type_erasure::as_param<Base, T>::type...);
107 typename ::boost::type_erasure::rebind_any<Base, R>::type
108 operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
109 {
110 return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
111 ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
112 }
113 };
114
115 template<class R, class F, class Base, class Enable, class... T>
116 struct concept_interface<callable<R(T...), const F>, Base, F, Enable>
117 : Base
118 {
119 template<class Sig>
120 struct result :
121 ::boost::type_erasure::detail::result_of_callable<Sig>
122 {};
123 typedef void _boost_type_erasure_is_callable;
124 typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
125 typedef char (&_boost_type_erasure_callable_size)[1];
126 _boost_type_erasure_callable_size
127 _boost_type_erasure_deduce_callable(
128 typename ::boost::type_erasure::as_param<Base, T>::type...) const;
129 typename ::boost::type_erasure::rebind_any<Base, R>::type operator()(
130 typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
131 {
132 return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
133 ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
134 }
135 };
136
137 template<class R, class F, class Base, class... T>
138 struct concept_interface<
139 callable<R(T...), F>,
140 Base,
141 F,
142 typename Base::_boost_type_erasure_is_callable
143 >
144 : Base
145 {
146 typedef typename ::boost::mpl::push_back<
147 typename Base::_boost_type_erasure_callable_results,
148 R
149 >::type _boost_type_erasure_callable_results;
150 typedef char (&_boost_type_erasure_callable_size)[
151 ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
152 using Base::_boost_type_erasure_deduce_callable;
153 _boost_type_erasure_callable_size
154 _boost_type_erasure_deduce_callable(
155 typename ::boost::type_erasure::as_param<Base, T>::type...);
156 using Base::operator();
157 typename ::boost::type_erasure::rebind_any<Base, R>::type
158 operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
159 {
160 return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
161 ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
162 }
163 };
164
165 template<class R, class F, class Base, class... T>
166 struct concept_interface<
167 callable<R(T...), const F>,
168 Base,
169 F,
170 typename Base::_boost_type_erasure_is_callable
171 >
172 : Base
173 {
174 typedef typename ::boost::mpl::push_back<
175 typename Base::_boost_type_erasure_callable_results,
176 R
177 >::type _boost_type_erasure_callable_results;
178 typedef char (&_boost_type_erasure_callable_size)[
179 ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
180 using Base::_boost_type_erasure_deduce_callable;
181 _boost_type_erasure_callable_size
182 _boost_type_erasure_deduce_callable(
183 typename ::boost::type_erasure::as_param<Base, T>::type...) const;
184 using Base::operator();
185 typename ::boost::type_erasure::rebind_any<Base, R>::type
186 operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
187 {
188 return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
189 ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
190 }
191 };
192
193 namespace detail {
194
195 template<class This, class... T>
196 struct result_of_callable<This(T...)>
197 {
198 typedef typename ::boost::mpl::at_c<
199 typename This::_boost_type_erasure_callable_results,
200 sizeof(::boost::declval<This>().
201 _boost_type_erasure_deduce_callable(::boost::declval<T>()...)) - 1
202 >::type type;
203 };
204
205 }
206
207 #else
208
209 /** INTERNAL ONLY */
210 #define BOOST_PP_FILENAME_1 <boost/type_erasure/callable.hpp>
211 /** INTERNAL ONLY */
212 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_DEC(BOOST_TYPE_ERASURE_MAX_ARITY))
213 #include BOOST_PP_ITERATE()
214
215 #endif
216
217 }
218 }
219
220 #endif
221
222 #else
223
224 #define N BOOST_PP_ITERATION()
225 #define BOOST_TYPE_ERASURE_DECLVAL(z, n, data) ::boost::declval<BOOST_PP_CAT(T, n)>()
226
227 #define BOOST_TYPE_ERASURE_REBIND(z, n, data)\
228 typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type BOOST_PP_CAT(arg, n)
229
230 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
231 #define BOOST_TYPE_ERASURE_FORWARD(z, n, data) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n)
232 #define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) BOOST_PP_CAT(arg, n)
233 #else
234 #define BOOST_TYPE_ERASURE_FORWARD(z, n, data) ::std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
235 #define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) ::std::forward<typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type>(BOOST_PP_CAT(arg, n))
236 #endif
237
238 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F>
239 struct callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>
240 {
241 static R apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
242 {
243 return f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
244 }
245 };
246
247 template<BOOST_PP_ENUM_PARAMS(N, class T) BOOST_PP_COMMA_IF(N) class F>
248 struct callable<void(BOOST_PP_ENUM_PARAMS(N, T)), F>
249 {
250 static void apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
251 {
252 f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
253 }
254 };
255
256 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
257 struct concept_interface<
258 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
259 Base,
260 F,
261 Enable
262 >
263 : Base
264 {
265 template<class Sig>
266 struct result :
267 ::boost::type_erasure::detail::result_of_callable<Sig>
268 {};
269 typedef void _boost_type_erasure_is_callable;
270 typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
271 typedef char (&_boost_type_erasure_callable_size)[1];
272 _boost_type_erasure_callable_size
273 _boost_type_erasure_deduce_callable(
274 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
275 typename ::boost::type_erasure::rebind_any<Base, R>::type
276 operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
277 {
278 return ::boost::type_erasure::call(
279 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
280 *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
281 }
282 };
283
284 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
285 struct concept_interface<
286 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
287 Base,
288 F,
289 Enable
290 >
291 : Base
292 {
293 template<class Sig>
294 struct result :
295 ::boost::type_erasure::detail::result_of_callable<Sig>
296 {};
297 typedef void _boost_type_erasure_is_callable;
298 typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
299 typedef char (&_boost_type_erasure_callable_size)[1];
300 _boost_type_erasure_callable_size
301 _boost_type_erasure_deduce_callable(
302 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
303 typename ::boost::type_erasure::rebind_any<Base, R>::type
304 operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
305 {
306 return ::boost::type_erasure::call(
307 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
308 *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
309 }
310 };
311
312 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
313 struct concept_interface<
314 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
315 Base,
316 F,
317 typename Base::_boost_type_erasure_is_callable
318 >
319 : Base
320 {
321 typedef typename ::boost::mpl::push_back<
322 typename Base::_boost_type_erasure_callable_results,
323 R
324 >::type _boost_type_erasure_callable_results;
325 typedef char (&_boost_type_erasure_callable_size)[
326 ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
327 using Base::_boost_type_erasure_deduce_callable;
328 _boost_type_erasure_callable_size
329 _boost_type_erasure_deduce_callable(
330 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
331 using Base::operator();
332 typename ::boost::type_erasure::rebind_any<Base, R>::type
333 operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
334 {
335 return ::boost::type_erasure::call(
336 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
337 *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
338 }
339 };
340
341 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
342 struct concept_interface<
343 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
344 Base,
345 F,
346 typename Base::_boost_type_erasure_is_callable
347 >
348 : Base
349 {
350 typedef typename ::boost::mpl::push_back<
351 typename Base::_boost_type_erasure_callable_results,
352 R
353 >::type _boost_type_erasure_callable_results;
354 typedef char (&_boost_type_erasure_callable_size)[
355 ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
356 using Base::_boost_type_erasure_deduce_callable;
357 _boost_type_erasure_callable_size
358 _boost_type_erasure_deduce_callable(
359 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
360 using Base::operator();
361 typename ::boost::type_erasure::rebind_any<Base, R>::type
362 operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
363 {
364 return ::boost::type_erasure::call(
365 callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
366 *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
367 }
368 };
369
370 namespace detail {
371
372 template<class This BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
373 struct result_of_callable<This(BOOST_PP_ENUM_PARAMS(N, T))>
374 {
375 typedef typename ::boost::mpl::at_c<
376 typename This::_boost_type_erasure_callable_results,
377 sizeof(::boost::declval<This>().
378 _boost_type_erasure_deduce_callable(
379 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_DECLVAL, ~))) - 1
380 >::type type;
381 };
382
383 }
384
385 #undef BOOST_TYPE_ERASURE_DECLVAL
386 #undef BOOST_TYPE_ERASURE_REBIND
387 #undef N
388
389 #endif