]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/callable.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / callable.hpp
CommitLineData
7c673cae
FG
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
34namespace boost {
35namespace type_erasure {
36
37template<class Sig, class F = _self>
38struct callable;
39
40namespace detail {
41
42template<class Sig>
43struct 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 */
61template<class Sig, class F = _self>
62struct 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
75template<class R, class... T, class F>
76struct callable<R(T...), F>
77{
78 static R apply(F& f, T... arg)
79 {
80 return f(std::forward<T>(arg)...);
81 }
82};
83
84template<class... T, class F>
85struct callable<void(T...), F>
86{
87 static void apply(F& f, T... arg)
88 {
89 f(std::forward<T>(arg)...);
90 }
91};
92
93template<class R, class F, class Base, class Enable, class... T>
94struct 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
115template<class R, class F, class Base, class Enable, class... T>
116struct 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
137template<class R, class F, class Base, class... T>
138struct 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
165template<class R, class F, class Base, class... T>
166struct 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
193namespace detail {
194
195template<class This, class... T>
196struct 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
238template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F>
239struct 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
247template<BOOST_PP_ENUM_PARAMS(N, class T) BOOST_PP_COMMA_IF(N) class F>
248struct 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
256template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
257struct 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
284template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
285struct 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
312template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
313struct 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
341template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
342struct 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
370namespace detail {
371
372template<class This BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
373struct 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