]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_erasure/include/boost/type_erasure/call.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_erasure / include / boost / type_erasure / call.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_CALL_HPP_INCLUDED
14#define BOOST_TYPE_ERASURE_CALL_HPP_INCLUDED
15
16#include <boost/assert.hpp>
17#include <boost/mpl/bool.hpp>
18#include <boost/mpl/eval_if.hpp>
19#include <boost/mpl/identity.hpp>
20#include <boost/type_traits/remove_cv.hpp>
21#include <boost/type_traits/remove_reference.hpp>
22#include <boost/preprocessor/cat.hpp>
23#include <boost/preprocessor/inc.hpp>
24#include <boost/preprocessor/iteration/iterate.hpp>
25#include <boost/preprocessor/repetition/repeat.hpp>
26#include <boost/preprocessor/repetition/enum.hpp>
27#include <boost/preprocessor/repetition/enum_trailing.hpp>
28#include <boost/preprocessor/repetition/enum_params.hpp>
29#include <boost/preprocessor/repetition/enum_binary_params.hpp>
30#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
31#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
32#include <boost/type_erasure/detail/access.hpp>
33#include <boost/type_erasure/detail/adapt_to_vtable.hpp>
34#include <boost/type_erasure/detail/extract_concept.hpp>
35#include <boost/type_erasure/detail/get_signature.hpp>
36#include <boost/type_erasure/detail/check_call.hpp>
37#include <boost/type_erasure/is_placeholder.hpp>
38#include <boost/type_erasure/concept_of.hpp>
39#include <boost/type_erasure/config.hpp>
40#include <boost/type_erasure/require_match.hpp>
41
42namespace boost {
43namespace type_erasure {
44
45template<class Concept, class Placeholder>
46class any;
47
48template<class Concept>
49class binding;
50
51namespace detail {
52
53template<class T>
54struct is_placeholder_arg :
55 ::boost::type_erasure::is_placeholder<
56 typename ::boost::remove_cv<
57 typename ::boost::remove_reference<T>::type
58 >::type
59 >
60{};
61
62template<class T, class Table>
63int maybe_get_table(const T& arg, const Table*& table, boost::mpl::true_)
64{
65 if(table == 0) {
66 table = &::boost::type_erasure::detail::access::table(arg);
67 }
68 return 0;
69}
70
71template<class T, class Table>
72int maybe_get_table(const T&, const Table*&, boost::mpl::false_) { return 0; }
73
74template<class T>
75::boost::type_erasure::detail::storage& convert_arg(any_base<T>& arg, boost::mpl::true_)
76{
77 return ::boost::type_erasure::detail::access::data(arg);
78}
79
80template<class Concept, class T>
81const ::boost::type_erasure::detail::storage&
82convert_arg(any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
83{
84 return ::boost::type_erasure::detail::access::data(arg);
85}
86
87template<class T>
88const ::boost::type_erasure::detail::storage&
89convert_arg(const any_base<T>& arg, boost::mpl::true_)
90{
91 return ::boost::type_erasure::detail::access::data(arg);
92}
93
94template<class Concept, class T>
95::boost::type_erasure::detail::storage&
96convert_arg(const any_base<any<Concept, T&> >& arg, boost::mpl::true_)
97{
98 return ::boost::type_erasure::detail::access::data(arg);
99}
100
101template<class Concept, class T>
102const ::boost::type_erasure::detail::storage&
103convert_arg(const any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
104{
105 return ::boost::type_erasure::detail::access::data(arg);
106}
107
108template<class Concept, class T>
109::boost::type_erasure::detail::storage&
110convert_arg(param<Concept, T>& arg, boost::mpl::true_)
111{
112 return ::boost::type_erasure::detail::access::data(arg);
113}
114
115template<class Concept, class T>
116const ::boost::type_erasure::detail::storage&
117convert_arg(param<Concept, const T&>& arg, boost::mpl::true_)
118{
119 return ::boost::type_erasure::detail::access::data(arg);
120}
121
122template<class Concept, class T>
123const ::boost::type_erasure::detail::storage&
124convert_arg(const param<Concept, T>& arg, boost::mpl::true_)
125{
126 return ::boost::type_erasure::detail::access::data(arg);
127}
128
129#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
130
131template<class Concept, class T>
132const ::boost::type_erasure::detail::storage&
133convert_arg(any_base<any<Concept, const T&> >&& arg, boost::mpl::true_)
134{
135 return ::boost::type_erasure::detail::access::data(arg);
136}
137
138template<class Concept, class T>
139::boost::type_erasure::detail::storage&
140convert_arg(any_base<any<Concept, T&> >&& arg, boost::mpl::true_)
141{
142 return ::boost::type_erasure::detail::access::data(arg);
143}
144
145template<class Concept, class T>
146::boost::type_erasure::detail::storage&&
147convert_arg(any_base<any<Concept, T> >&& arg, boost::mpl::true_)
148{
149 return ::boost::type_erasure::detail::access::data(std::move(arg));
150}
151
152template<class Concept, class T>
153::boost::type_erasure::detail::storage&&
154convert_arg(any_base<any<Concept, T&&> >& arg, boost::mpl::true_)
155{
156 return ::boost::type_erasure::detail::access::data(arg);
157}
158
159template<class Concept, class T>
160::boost::type_erasure::detail::storage&&
161convert_arg(const any_base<any<Concept, T&&> >& arg, boost::mpl::true_)
162{
163 return ::boost::type_erasure::detail::access::data(arg);
164}
165
166template<class Concept, class T>
167const ::boost::type_erasure::detail::storage&
168convert_arg(param<Concept, const T&>&& arg, boost::mpl::true_)
169{
170 return ::boost::type_erasure::detail::access::data(arg);
171}
172
173template<class Concept, class T>
174::boost::type_erasure::detail::storage&
175convert_arg(param<Concept, T&>&& arg, boost::mpl::true_)
176{
177 return ::boost::type_erasure::detail::access::data(arg);
178}
179
180template<class Concept, class T>
181::boost::type_erasure::detail::storage&&
182convert_arg(param<Concept, T>&& arg, boost::mpl::true_)
183{
184 return ::boost::type_erasure::detail::access::data(std::move(arg));
185}
186
187template<class Concept, class T>
188::boost::type_erasure::detail::storage&&
189convert_arg(param<Concept, T&&>& arg, boost::mpl::true_)
190{
191 return ::boost::type_erasure::detail::access::data(arg);
192}
193
194template<class Concept, class T>
195::boost::type_erasure::detail::storage&&
196convert_arg(const param<Concept, T&&>& arg, boost::mpl::true_)
197{
198 return ::boost::type_erasure::detail::access::data(arg);
199}
200
201template<class T>
202T&& convert_arg(T&& arg, boost::mpl::false_) { return std::forward<T>(arg); }
203
204#else
205
206template<class T>
207T& convert_arg(T& arg, boost::mpl::false_) { return arg; }
208
209#endif
210
211}
212
213#ifdef BOOST_TYPE_ERASURE_DOXYGEN
214
215/**
216 * Dispatches a type erased function.
217 *
218 * @c Op must be a primitive concept which is present in
219 * @c Concept. Its signature determines how the arguments of
220 * \call are handled. If the argument is a @ref placeholder,
221 * \call expects an @ref any using that @ref placeholder.
222 * This @ref any is unwrapped by \call. The type that
223 * it stores must be the same type specified by @c binding.
224 * Any arguments that are not placeholders in the signature
225 * of @c Op are passed through unchanged.
226 *
227 * If @c binding is not specified, it will be deduced from
228 * the arguments. Naturally this requires at least one
229 * argument to be an @ref any. In this case, all @ref any
230 * arguments must have the same @ref binding.
231 *
232 * \return The result of the operation. If the result type
233 * of the signature of @c Op is a placeholder, the
234 * result will be converted to the appropriate @ref
235 * any type.
236 *
237 * \throws bad_function_call if @ref relaxed is
238 * in @c Concept and there is a type mismatch.
239 *
240 * Example:
241 *
242 * @code
243 * typedef mpl::vector<
244 * copy_constructible<_b>,
245 * addable<_a, int, _b> > concept;
246 * any<concept, _a> a = ...;
247 * any<concept, _b> b(call(addable<_a, int, _b>(), a, 10));
248 * @endcode
249 *
250 * The signature of @ref addable is <code>_b(const _a&, const int&)</code>
251 */
252template<class Concept, class Op, class... U>
253typename ::boost::type_erasure::detail::call_impl<Sig, U..., Concept>::type
254call(const binding<Concept>& binding_arg, const Op&, U&&... args);
255
256/**
257 * \overload
258 */
259template<class Op, class... U>
260typename ::boost::type_erasure::detail::call_impl<Sig, U...>::type
261call(const Op&, U&&... args);
262
263#else
264
265namespace detail {
266
267template<class Sig, class Args, class Concept = void,
268 bool Check = ::boost::type_erasure::detail::check_call<Sig, Args>::type::value>
269struct call_impl {};
270
271template<class Op, class Args, class Concept = void>
272struct call_result :
273 call_impl<
274 typename ::boost::type_erasure::detail::get_signature<Op>::type,
275 Args,
276 Concept>
277{};
278
279template<class C1, class Args, class Concept>
280struct call_result<
281 ::boost::type_erasure::binding<C1>,
282 Args,
283 Concept
284>
285{};
286
287}
288
289#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
290
291namespace detail {
292
293template<class... T>
294void ignore(const T&...) {}
295
296template<class R, class... T, class... U>
297const ::boost::type_erasure::binding<
298 typename ::boost::type_erasure::detail::extract_concept<void(T...), U...>::type>*
299extract_table(R(*)(T...), const U&... arg)
300{
301 const ::boost::type_erasure::binding<
302 typename ::boost::type_erasure::detail::extract_concept<
303 void(T...), U...>::type>* result = 0;
304
305 // the order that we run maybe_get_table in doesn't matter
306 ignore(::boost::type_erasure::detail::maybe_get_table(
307 arg,
308 result,
309 ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
310
311 BOOST_ASSERT(result != 0);
312 return result;
313}
314
315template<class Sig, class Args, class Concept, bool ReturnsAny>
316struct call_impl_dispatch;
317
318template<class R, class... T, class... U, class Concept>
319struct call_impl_dispatch<R(T...), void(U...), Concept, false>
320{
321 typedef R type;
322 template<class F>
323 static R apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
324 {
325 return table->template find<F>()(
326 ::boost::type_erasure::detail::convert_arg(
327 ::std::forward<U>(arg),
328 ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
329 }
330};
331
332template<class R, class... T, class... U, class Concept>
333struct call_impl_dispatch<R(T...), void(U...), Concept, true>
334{
335 typedef ::boost::type_erasure::any<Concept, R> type;
336 template<class F>
337 static type apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
338 {
339 return type(table->template find<F>()(
340 ::boost::type_erasure::detail::convert_arg(
341 ::std::forward<U>(arg),
342 ::boost::type_erasure::detail::is_placeholder_arg<T>())...), *table);
343 }
344};
345
346template<class R, class... T, class... U, class Concept>
347struct call_impl<R(T...), void(U...), Concept, true> :
348 ::boost::type_erasure::detail::call_impl_dispatch<
349 R(T...),
350 void(U...),
351 Concept,
352 ::boost::type_erasure::detail::is_placeholder_arg<R>::value
353 >
354{
355};
356
357template<class R, class... T, class... U>
358struct call_impl<R(T...), void(U...), void, true> :
359 ::boost::type_erasure::detail::call_impl_dispatch<
360 R(T...),
361 void(U...),
362 typename ::boost::type_erasure::detail::extract_concept<
363 void(T...),
364 typename ::boost::remove_reference<U>::type...
365 >::type,
366 ::boost::type_erasure::detail::is_placeholder_arg<R>::value
367 >
368{
369};
370
371}
372
373template<
374 class Concept,
375 class Op,
376 class... U
377>
378typename ::boost::type_erasure::detail::call_result<
379 Op,
380 void(U&&...),
381 Concept
382>::type
383unchecked_call(
384 const ::boost::type_erasure::binding<Concept>& table,
385 const Op&,
386 U&&... arg)
387{
388 return ::boost::type_erasure::detail::call_impl<
389 typename ::boost::type_erasure::detail::get_signature<Op>::type,
390 void(U&&...),
391 Concept
392 >::template apply<
393 typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
394 >(&table, std::forward<U>(arg)...);
395}
396
397template<class Concept, class Op, class... U>
398typename ::boost::type_erasure::detail::call_result<
399 Op,
400 void(U&&...),
401 Concept
402>::type
403call(
404 const ::boost::type_erasure::binding<Concept>& table,
405 const Op& f,
406 U&&... arg)
407{
408 ::boost::type_erasure::require_match(table, f, std::forward<U>(arg)...);
409 return ::boost::type_erasure::unchecked_call(table, f, std::forward<U>(arg)...);
410}
411
412template<class Op, class... U>
413typename ::boost::type_erasure::detail::call_result<
414 Op,
415 void(U&&...)
416>::type
417unchecked_call(
418 const Op&,
419 U&&... arg)
420{
421 return ::boost::type_erasure::detail::call_impl<
422 typename ::boost::type_erasure::detail::get_signature<Op>::type,
423 void(U&&...)
424 >::template apply<
425 typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
426 >(::boost::type_erasure::detail::extract_table(
427 static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...),
428 std::forward<U>(arg)...);
429}
430
431template<class Op, class... U>
432typename ::boost::type_erasure::detail::call_result<
433 Op,
434 void(U&&...)
435>::type
436call(
437 const Op& f,
438 U&&... arg)
439{
440 ::boost::type_erasure::require_match(f, std::forward<U>(arg)...);
441 return ::boost::type_erasure::unchecked_call(f, std::forward<U>(arg)...);
442}
443
444
445#else
446
447#define BOOST_PP_FILENAME_1 <boost/type_erasure/call.hpp>
448#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
449#include BOOST_PP_ITERATE()
450
451#endif
452
453#endif
454
455}
456}
457
458#endif
459
460#else
461
462#define N BOOST_PP_ITERATION()
463
464#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
465
466#define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data) \
467 ::boost::type_erasure::detail::convert_arg( \
468 std::forward<BOOST_PP_CAT(U, n)>(BOOST_PP_CAT(arg, n)), \
469 ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
470
471#else
472
473#define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data) \
474 ::boost::type_erasure::detail::convert_arg( \
475 BOOST_PP_CAT(arg, n), \
476 ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
477
478#endif
479
480#define BOOST_TYPE_ERASURE_GET_TABLE(z, n, data) \
481 ::boost::type_erasure::detail::maybe_get_table( \
482 BOOST_PP_CAT(arg, n), \
483 result, \
484 ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>());
485
486namespace detail {
487
488#if N != 0
489
490template<
491 class R,
492 BOOST_PP_ENUM_PARAMS(N, class T),
493 BOOST_PP_ENUM_PARAMS(N, class U)>
494const ::boost::type_erasure::binding<
495 typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
496 BOOST_PP_ENUM_PARAMS(N, T),
497 BOOST_PP_ENUM_PARAMS(N, U)>::type>*
498BOOST_PP_CAT(extract_table, N)(R(*)(BOOST_PP_ENUM_PARAMS(N, T)), BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &arg))
499{
500 const ::boost::type_erasure::binding<
501 typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
502 BOOST_PP_ENUM_PARAMS(N, T),
503 BOOST_PP_ENUM_PARAMS(N, U)>::type>* result = 0;
504 BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_TABLE, ~)
505 BOOST_ASSERT(result != 0);
506 return result;
507}
508
509#endif
510
511template<
512 class R
513 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
514 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
515 class Concept
516#if N != 0
517 = typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
518 BOOST_PP_ENUM_PARAMS(N, T),
519 BOOST_PP_ENUM_PARAMS(N, U)
520 >::type
521#endif
522 ,
523 bool ReturnsAny = ::boost::type_erasure::detail::is_placeholder_arg<R>::value>
524struct BOOST_PP_CAT(call_impl, N);
525
526template<
527 class R
528 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
529 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
530 class Concept
531>
532struct BOOST_PP_CAT(call_impl, N)<
533 R
534 BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
535 BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
536 Concept,
537 false
538>
539{
540 typedef R type;
541 template<class F>
542 static R apply(const ::boost::type_erasure::binding<Concept>* table
543 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
544 {
545 return table->template find<F>()(
546 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~));
547 }
548};
549
550template<
551 class R
552 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
553 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
554 class Concept
555>
556struct BOOST_PP_CAT(call_impl, N)<
557 R
558 BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
559 BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
560 Concept,
561 true
562>
563{
564 typedef ::boost::type_erasure::any<Concept, R> type;
565 template<class F>
566 static type apply(const ::boost::type_erasure::binding<Concept>* table
567 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
568 {
569 return type(table->template find<F>()(
570 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~)), *table);
571 }
572};
573
574template<
575 class R
576 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
577 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
578 class Concept
579>
580struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), Concept, true>
581 : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U), Concept>
582{};
583
584#if N != 0
585
586template<
587 class R
588 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
589 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
590>
591struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), void, true>
592 : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
593{};
594
595#endif
596
597}
598
599#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
600#define RREF &
601#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING_PARAMS(N, x)
602#else
603#define RREF &&
604#define BOOST_TYPE_ERASURE_FORWARD_ARGS_I(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))
605#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_ARGS_I, (X, x))
606#endif
607
608template<
609 class Concept,
610 class Op
611 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
612>
613typename ::boost::type_erasure::detail::call_result<
614 Op,
615 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
616 Concept
617>::type
618unchecked_call(
619 const ::boost::type_erasure::binding<Concept>& table,
620 const Op&
621 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
622{
623 return ::boost::type_erasure::detail::call_impl<
624 typename ::boost::type_erasure::detail::get_signature<Op>::type,
625 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
626 Concept
627 >::template apply<
628 typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
629 >(&table BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
630}
631
632template<
633 class Concept,
634 class Op
635 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
636>
637typename ::boost::type_erasure::detail::call_result<
638 Op,
639 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
640 Concept
641>::type
642call(
643 const ::boost::type_erasure::binding<Concept>& table,
644 const Op& f
645 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
646{
647 ::boost::type_erasure::require_match(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
648 return ::boost::type_erasure::unchecked_call(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
649}
650
651#if N != 0
652
653template<
654 class Op
655 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
656>
657typename ::boost::type_erasure::detail::call_result<
658 Op,
659 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
660>::type
661unchecked_call(
662 const Op&
663 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
664{
665 return ::boost::type_erasure::detail::call_impl<
666 typename ::boost::type_erasure::detail::get_signature<Op>::type,
667 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
668 >::template apply<
669 typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
670 >(
671 ::boost::type_erasure::detail::BOOST_PP_CAT(extract_table, N)(
672 (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0,
673 BOOST_PP_ENUM_PARAMS(N, arg))
674 BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg)
675 );
676}
677
678template<
679 class Op
680 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
681>
682typename ::boost::type_erasure::detail::call_result<
683 Op,
684 void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
685>::type
686call(
687 const Op& f
688 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
689{
690 ::boost::type_erasure::require_match(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
691 return ::boost::type_erasure::unchecked_call(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
692}
693
694#endif
695
696#undef RREF
697#undef BOOST_TYPE_ERASURE_FORWARD_ARGS
698#undef BOOST_TYPE_ERASURE_FORWARD_ARGS_I
699
700#undef BOOST_TYPE_ERASURE_GET_TABLE
701#undef BOOST_TYPE_ERASURE_CONVERT_ARG
702#undef N
703
704#endif