Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:10:13

0001 // Boost.TypeErasure library
0002 //
0003 // Copyright 2011 Steven Watanabe
0004 //
0005 // Distributed under the Boost Software License Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // $Id$
0010 
0011 #if !defined(BOOST_PP_IS_ITERATING)
0012 
0013 #ifndef BOOST_TYPE_ERASURE_CALL_HPP_INCLUDED
0014 #define BOOST_TYPE_ERASURE_CALL_HPP_INCLUDED
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/mpl/eval_if.hpp>
0019 #include <boost/mpl/identity.hpp>
0020 #include <boost/type_traits/remove_cv.hpp>
0021 #include <boost/type_traits/remove_reference.hpp>
0022 #include <boost/preprocessor/cat.hpp>
0023 #include <boost/preprocessor/inc.hpp>
0024 #include <boost/preprocessor/iteration/iterate.hpp>
0025 #include <boost/preprocessor/repetition/repeat.hpp>
0026 #include <boost/preprocessor/repetition/enum.hpp>
0027 #include <boost/preprocessor/repetition/enum_trailing.hpp>
0028 #include <boost/preprocessor/repetition/enum_params.hpp>
0029 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0030 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0031 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0032 #include <boost/type_erasure/detail/access.hpp>
0033 #include <boost/type_erasure/detail/adapt_to_vtable.hpp>
0034 #include <boost/type_erasure/detail/extract_concept.hpp>
0035 #include <boost/type_erasure/detail/get_signature.hpp>
0036 #include <boost/type_erasure/detail/check_call.hpp>
0037 #include <boost/type_erasure/is_placeholder.hpp>
0038 #include <boost/type_erasure/concept_of.hpp>
0039 #include <boost/type_erasure/config.hpp>
0040 #include <boost/type_erasure/require_match.hpp>
0041 
0042 namespace boost {
0043 namespace type_erasure {
0044 
0045 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0046 
0047 template<class Concept, class Placeholder>
0048 class any;
0049 
0050 template<class Concept>
0051 class binding;
0052 
0053 #endif
0054 
0055 namespace detail {
0056 
0057 template<class T>
0058 struct is_placeholder_arg :
0059     ::boost::type_erasure::is_placeholder<
0060         typename ::boost::remove_cv<
0061             typename ::boost::remove_reference<T>::type
0062         >::type
0063     >
0064 {};
0065 
0066 template<class T, class Table>
0067 int maybe_get_table(const T& arg, const Table*& table, boost::mpl::true_)
0068 {
0069     if(table == 0) {
0070         table = &::boost::type_erasure::detail::access::table(arg);
0071     }
0072     return 0;
0073 }
0074 
0075 template<class T, class Table>
0076 int maybe_get_table(const T&, const Table*&, boost::mpl::false_) { return 0; }
0077 
0078 template<class T>
0079 ::boost::type_erasure::detail::storage& convert_arg(any_base<T>& arg, boost::mpl::true_)
0080 {
0081     return ::boost::type_erasure::detail::access::data(arg);
0082 }
0083 
0084 template<class Concept, class T>
0085 const ::boost::type_erasure::detail::storage&
0086 convert_arg(any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
0087 {
0088     return ::boost::type_erasure::detail::access::data(arg);
0089 }
0090 
0091 template<class T>
0092 const ::boost::type_erasure::detail::storage&
0093 convert_arg(const any_base<T>& arg, boost::mpl::true_)
0094 {
0095     return ::boost::type_erasure::detail::access::data(arg);
0096 }
0097 
0098 template<class Concept, class T>
0099 ::boost::type_erasure::detail::storage&
0100 convert_arg(const any_base<any<Concept, T&> >& arg, boost::mpl::true_)
0101 {
0102     return ::boost::type_erasure::detail::access::data(arg);
0103 }
0104 
0105 template<class Concept, class T>
0106 const ::boost::type_erasure::detail::storage&
0107 convert_arg(const any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
0108 {
0109     return ::boost::type_erasure::detail::access::data(arg);
0110 }
0111 
0112 template<class Concept, class T>
0113 ::boost::type_erasure::detail::storage&
0114 convert_arg(param<Concept, T>& arg, boost::mpl::true_)
0115 {
0116     return ::boost::type_erasure::detail::access::data(arg);
0117 }
0118 
0119 template<class Concept, class T>
0120 const ::boost::type_erasure::detail::storage&
0121 convert_arg(param<Concept, const T&>& arg, boost::mpl::true_)
0122 {
0123     return ::boost::type_erasure::detail::access::data(arg);
0124 }
0125 
0126 template<class Concept, class T>
0127 const ::boost::type_erasure::detail::storage&
0128 convert_arg(const param<Concept, T>& arg, boost::mpl::true_)
0129 {
0130     return ::boost::type_erasure::detail::access::data(arg);
0131 }
0132 
0133 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0134 
0135 template<class Concept, class T>
0136 const ::boost::type_erasure::detail::storage&
0137 convert_arg(any_base<any<Concept, const T&> >&& arg, boost::mpl::true_)
0138 {
0139     return ::boost::type_erasure::detail::access::data(arg);
0140 }
0141 
0142 template<class Concept, class T>
0143 ::boost::type_erasure::detail::storage&
0144 convert_arg(any_base<any<Concept, T&> >&& arg, boost::mpl::true_)
0145 {
0146     return ::boost::type_erasure::detail::access::data(arg);
0147 }
0148 
0149 template<class Concept, class T>
0150 ::boost::type_erasure::detail::storage&&
0151 convert_arg(any_base<any<Concept, T> >&& arg, boost::mpl::true_)
0152 {
0153     return ::boost::type_erasure::detail::access::data(std::move(arg));
0154 }
0155 
0156 template<class Concept, class T>
0157 ::boost::type_erasure::detail::storage&&
0158 convert_arg(any_base<any<Concept, T&&> >& arg, boost::mpl::true_)
0159 {
0160     return ::boost::type_erasure::detail::access::data(arg);
0161 }
0162 
0163 template<class Concept, class T>
0164 ::boost::type_erasure::detail::storage&&
0165 convert_arg(const any_base<any<Concept, T&&> >& arg, boost::mpl::true_)
0166 {
0167     return ::boost::type_erasure::detail::access::data(arg);
0168 }
0169 
0170 template<class Concept, class T>
0171 const ::boost::type_erasure::detail::storage&
0172 convert_arg(param<Concept, const T&>&& arg, boost::mpl::true_)
0173 {
0174     return ::boost::type_erasure::detail::access::data(arg);
0175 }
0176 
0177 template<class Concept, class T>
0178 ::boost::type_erasure::detail::storage&
0179 convert_arg(param<Concept, T&>&& arg, boost::mpl::true_)
0180 {
0181     return ::boost::type_erasure::detail::access::data(arg);
0182 }
0183 
0184 template<class Concept, class T>
0185 ::boost::type_erasure::detail::storage&&
0186 convert_arg(param<Concept, T>&& arg, boost::mpl::true_)
0187 {
0188     return ::boost::type_erasure::detail::access::data(std::move(arg));
0189 }
0190 
0191 template<class Concept, class T>
0192 ::boost::type_erasure::detail::storage&&
0193 convert_arg(param<Concept, T&&>& arg, boost::mpl::true_)
0194 {
0195     return ::boost::type_erasure::detail::access::data(arg);
0196 }
0197 
0198 template<class Concept, class T>
0199 ::boost::type_erasure::detail::storage&&
0200 convert_arg(const param<Concept, T&&>& arg, boost::mpl::true_)
0201 {
0202     return ::boost::type_erasure::detail::access::data(arg);
0203 }
0204 
0205 template<class T>
0206 T&& convert_arg(T&& arg, boost::mpl::false_) { return std::forward<T>(arg); }
0207 
0208 #else
0209 
0210 template<class T>
0211 T& convert_arg(T& arg, boost::mpl::false_) { return arg; }
0212 
0213 #endif
0214 
0215 }
0216 
0217 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
0218 
0219 /**
0220  * Dispatches a type erased function.
0221  *
0222  * @c Op must be a primitive concept which is present in
0223  * @c Concept.  Its signature determines how the arguments of
0224  * \call are handled.  If the argument is a @ref placeholder,
0225  * \call expects an @ref any using that @ref placeholder.
0226  * This @ref any is unwrapped by \call.  The type that
0227  * it stores must be the same type specified by @c binding.
0228  * Any arguments that are not placeholders in the signature
0229  * of @c Op are passed through unchanged.
0230  *
0231  * If @c binding is not specified, it will be deduced from
0232  * the arguments.  Naturally this requires at least one
0233  * argument to be an @ref any.  In this case, all @ref any
0234  * arguments must have the same @ref binding.
0235  *
0236  * \return The result of the operation.  If the result type
0237  *         of the signature of @c Op is a placeholder, the
0238  *         result will be converted to the appropriate @ref
0239  *         any type.
0240  *
0241  * \throws bad_function_call if @ref relaxed is
0242  *         in @c Concept and there is a type mismatch.
0243  *
0244  * Example:
0245  *
0246  * @code
0247  * typedef mpl::vector<
0248  *   copy_constructible<_b>,
0249  *   addable<_a, int, _b> > concept;
0250  * any<concept, _a> a = ...;
0251  * any<concept, _b> b(call(addable<_a, int, _b>(), a, 10));
0252  * @endcode
0253  *
0254  * The signature of @ref addable is <code>_b(const _a&, const int&)</code>
0255  */
0256 template<class Concept, class Op, class... U>
0257 typename ::boost::type_erasure::detail::call_impl<Sig, U..., Concept>::type
0258 call(const binding<Concept>& binding_arg, const Op&, U&&... args);
0259 
0260 /**
0261  * \overload
0262  */
0263 template<class Op, class... U>
0264 typename ::boost::type_erasure::detail::call_impl<Sig, U...>::type
0265 call(const Op&, U&&... args);
0266 
0267 #else
0268 
0269 namespace detail {
0270     
0271 template<class Sig, class Args, class Concept = void,
0272     bool Check = ::boost::type_erasure::detail::check_call<Sig, Args>::type::value>
0273 struct call_impl {};
0274 
0275 template<class Op, class Args, class Concept = void>
0276 struct call_result :
0277     call_impl<
0278         typename ::boost::type_erasure::detail::get_signature<Op>::type,
0279         Args,
0280         Concept>
0281 {};
0282 
0283 template<class C1, class Args, class Concept>
0284 struct call_result<
0285     ::boost::type_erasure::binding<C1>,
0286     Args,
0287     Concept
0288 >
0289 {};
0290 
0291 }
0292 
0293 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0294 
0295 namespace detail {
0296 
0297 template<class... T>
0298 void ignore(const T&...) {}
0299 
0300 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0301 
0302 template<class R, class... T, class... U>
0303 const ::boost::type_erasure::binding<
0304     typename ::boost::type_erasure::detail::extract_concept<void(T...), U...>::type>*
0305 extract_table(R(*)(T...), const U&... arg)
0306 {
0307     const ::boost::type_erasure::binding<
0308         typename ::boost::type_erasure::detail::extract_concept<
0309             void(T...), U...>::type>* result = 0;
0310 
0311     // the order that we run maybe_get_table in doesn't matter
0312     ignore(::boost::type_erasure::detail::maybe_get_table(
0313         arg,
0314         result,
0315         ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
0316 
0317     BOOST_ASSERT(result != 0);
0318     return result;
0319 }
0320 
0321 #else
0322 
0323 template<class R, class... T, class... U>
0324 const ::boost::type_erasure::binding<
0325     ::boost::type_erasure::detail::extract_concept_t< ::boost::mp11::mp_list<T...>, ::boost::mp11::mp_list<U...> > >*
0326 extract_table(R(*)(T...), const U&... arg)
0327 {
0328     const ::boost::type_erasure::binding<
0329         ::boost::type_erasure::detail::extract_concept_t<
0330             ::boost::mp11::mp_list<T...>, ::boost::mp11::mp_list<U...> > >* result = 0;
0331 
0332     // the order that we run maybe_get_table in doesn't matter
0333     ignore(::boost::type_erasure::detail::maybe_get_table(
0334         arg,
0335         result,
0336         ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
0337 
0338     BOOST_ASSERT(result != 0);
0339     return result;
0340 }
0341 
0342 #endif
0343 
0344 template<class Sig, class Args, class Concept, bool ReturnsAny>
0345 struct call_impl_dispatch;
0346 
0347 template<class R, class... T, class... U, class Concept>
0348 struct call_impl_dispatch<R(T...), void(U...), Concept, false>
0349 {
0350     typedef R type;
0351     template<class F>
0352     static R apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
0353     {
0354         return table->template find<F>()(
0355             ::boost::type_erasure::detail::convert_arg(
0356                 ::std::forward<U>(arg),
0357                 ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
0358     }
0359 };
0360 
0361 template<class R, class... T, class... U, class Concept>
0362 struct call_impl_dispatch<R(T...), void(U...), Concept, true>
0363 {
0364     typedef ::boost::type_erasure::any<Concept, R> type;
0365     template<class F>
0366     static type apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
0367     {
0368         return type(table->template find<F>()(
0369             ::boost::type_erasure::detail::convert_arg(
0370                 ::std::forward<U>(arg),
0371                 ::boost::type_erasure::detail::is_placeholder_arg<T>())...), *table);
0372     }
0373 };
0374 
0375 template<class R, class... T, class... U, class Concept>
0376 struct call_impl<R(T...), void(U...), Concept, true> :
0377     ::boost::type_erasure::detail::call_impl_dispatch<
0378         R(T...),
0379         void(U...),
0380         Concept,
0381         ::boost::type_erasure::detail::is_placeholder_arg<R>::value
0382     >
0383 {
0384 };
0385 
0386 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0387 
0388 template<class R, class... T, class... U>
0389 struct call_impl<R(T...), void(U...), void, true> :
0390     ::boost::type_erasure::detail::call_impl_dispatch<
0391         R(T...),
0392         void(U...),
0393         typename ::boost::type_erasure::detail::extract_concept<
0394             void(T...),
0395             typename ::boost::remove_reference<U>::type...
0396         >::type,
0397         ::boost::type_erasure::detail::is_placeholder_arg<R>::value
0398     >
0399 {
0400 };
0401 
0402 #else
0403 
0404 template<class R, class... T, class... U>
0405 struct call_impl<R(T...), void(U...), void, true> :
0406     ::boost::type_erasure::detail::call_impl_dispatch<
0407         R(T...),
0408         void(U...),
0409         ::boost::type_erasure::detail::extract_concept_t<
0410             ::boost::mp11::mp_list<T...>,
0411             ::boost::mp11::mp_list< ::boost::remove_reference_t<U>...>
0412         >,
0413         ::boost::type_erasure::detail::is_placeholder_arg<R>::value
0414     >
0415 {
0416 };
0417 
0418 #endif
0419 
0420 }
0421 
0422 template<
0423     class Concept,
0424     class Op,
0425     class... U
0426 >
0427 typename ::boost::type_erasure::detail::call_result<
0428     Op,
0429     void(U&&...),
0430     Concept
0431 >::type
0432 unchecked_call(
0433     const ::boost::type_erasure::binding<Concept>& table,
0434     const Op&,
0435     U&&... arg)
0436 {
0437     return ::boost::type_erasure::detail::call_impl<
0438         typename ::boost::type_erasure::detail::get_signature<Op>::type,
0439         void(U&&...),
0440         Concept
0441     >::template apply<
0442         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
0443     >(&table, std::forward<U>(arg)...);
0444 }
0445 
0446 template<class Concept, class Op, class... U>
0447 typename ::boost::type_erasure::detail::call_result<
0448     Op,
0449     void(U&&...),
0450     Concept
0451 >::type
0452 call(
0453     const ::boost::type_erasure::binding<Concept>& table,
0454     const Op& f,
0455     U&&... arg)
0456 {
0457     ::boost::type_erasure::require_match(table, f, std::forward<U>(arg)...);
0458     return ::boost::type_erasure::unchecked_call(table, f, std::forward<U>(arg)...);
0459 }
0460 
0461 template<class Op, class... U>
0462 typename ::boost::type_erasure::detail::call_result<
0463     Op,
0464     void(U&&...)
0465 >::type
0466 unchecked_call(
0467     const Op&,
0468     U&&... arg)
0469 {
0470     return ::boost::type_erasure::detail::call_impl<
0471         typename ::boost::type_erasure::detail::get_signature<Op>::type,
0472         void(U&&...)
0473     >::template apply<
0474         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
0475     >(::boost::type_erasure::detail::extract_table(
0476         static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...),
0477         std::forward<U>(arg)...);
0478 }
0479 
0480 template<class Op, class... U>
0481 typename ::boost::type_erasure::detail::call_result<
0482     Op,
0483     void(U&&...)
0484 >::type
0485 call(
0486     const Op& f,
0487     U&&... arg)
0488 {
0489     ::boost::type_erasure::require_match(f, std::forward<U>(arg)...);
0490     return ::boost::type_erasure::unchecked_call(f, std::forward<U>(arg)...);
0491 }
0492 
0493 
0494 #else
0495 
0496 #define BOOST_PP_FILENAME_1 <boost/type_erasure/call.hpp>
0497 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
0498 #include BOOST_PP_ITERATE()
0499 
0500 #endif
0501 
0502 #endif
0503 
0504 }
0505 }
0506 
0507 #endif
0508 
0509 #else
0510 
0511 #define N BOOST_PP_ITERATION()
0512 
0513 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0514 
0515 #define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data)                      \
0516     ::boost::type_erasure::detail::convert_arg(                         \
0517         std::forward<BOOST_PP_CAT(U, n)>(BOOST_PP_CAT(arg, n)),         \
0518         ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
0519 
0520 #else
0521 
0522 #define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data)                      \
0523     ::boost::type_erasure::detail::convert_arg(                         \
0524         BOOST_PP_CAT(arg, n),                                           \
0525         ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
0526 
0527 #endif
0528 
0529 #define BOOST_TYPE_ERASURE_GET_TABLE(z, n, data)                        \
0530     ::boost::type_erasure::detail::maybe_get_table(                     \
0531         BOOST_PP_CAT(arg, n),                                           \
0532         result,                                                         \
0533         ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>());
0534 
0535 namespace detail {
0536 
0537 #if N != 0
0538 
0539 template<
0540     class R,
0541     BOOST_PP_ENUM_PARAMS(N, class T),
0542     BOOST_PP_ENUM_PARAMS(N, class U)>
0543 const ::boost::type_erasure::binding<
0544     typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
0545         BOOST_PP_ENUM_PARAMS(N, T),
0546         BOOST_PP_ENUM_PARAMS(N, U)>::type>*
0547 BOOST_PP_CAT(extract_table, N)(R(*)(BOOST_PP_ENUM_PARAMS(N, T)), BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &arg))
0548 {
0549     const ::boost::type_erasure::binding<
0550         typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
0551             BOOST_PP_ENUM_PARAMS(N, T),
0552             BOOST_PP_ENUM_PARAMS(N, U)>::type>* result = 0;
0553     BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_TABLE, ~)
0554     BOOST_ASSERT(result != 0);
0555     return result;
0556 }
0557 
0558 #endif
0559 
0560 template<
0561     class R
0562     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0563     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
0564     class Concept
0565 #if N != 0
0566         = typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
0567             BOOST_PP_ENUM_PARAMS(N, T),
0568             BOOST_PP_ENUM_PARAMS(N, U)
0569         >::type
0570 #endif
0571     ,
0572     bool ReturnsAny = ::boost::type_erasure::detail::is_placeholder_arg<R>::value>
0573 struct BOOST_PP_CAT(call_impl, N);
0574 
0575 template<
0576     class R
0577     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0578     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
0579     class Concept
0580 >
0581 struct BOOST_PP_CAT(call_impl, N)<
0582     R
0583     BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
0584     BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
0585     Concept,
0586     false
0587 >
0588 {
0589     typedef R type;
0590     template<class F>
0591     static R apply(const ::boost::type_erasure::binding<Concept>* table
0592         BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
0593     {
0594         return table->template find<F>()(
0595             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~));
0596     }
0597 };
0598 
0599 template<
0600     class R
0601     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0602     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
0603     class Concept
0604 >
0605 struct BOOST_PP_CAT(call_impl, N)<
0606     R
0607     BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
0608     BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
0609     Concept,
0610     true
0611 >
0612 {
0613     typedef ::boost::type_erasure::any<Concept, R> type;
0614     template<class F>
0615     static type apply(const ::boost::type_erasure::binding<Concept>* table
0616         BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
0617     {
0618         return type(table->template find<F>()(
0619             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~)), *table);
0620     }
0621 };
0622 
0623 template<
0624     class R
0625     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0626     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
0627     class Concept
0628 >
0629 struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), Concept, true>
0630   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U), Concept>
0631 {};
0632 
0633 #if N != 0
0634 
0635 template<
0636     class R
0637     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0638     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0639 >
0640 struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), void, true>
0641   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
0642 {};
0643 
0644 #endif
0645 
0646 }
0647 
0648 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0649 #define RREF &
0650 #define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING_PARAMS(N, x)
0651 #else
0652 #define RREF &&
0653 #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))
0654 #define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_ARGS_I, (X, x))
0655 #endif
0656 
0657 template<
0658     class Concept,
0659     class Op
0660     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0661 >
0662 typename ::boost::type_erasure::detail::call_result<
0663     Op,
0664     void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
0665     Concept
0666 >::type
0667 unchecked_call(
0668     const ::boost::type_erasure::binding<Concept>& table,
0669     const Op&
0670     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0671 {
0672     return ::boost::type_erasure::detail::call_impl<
0673         typename ::boost::type_erasure::detail::get_signature<Op>::type,
0674         void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
0675         Concept
0676     >::template apply<
0677         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
0678     >(&table BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0679 }
0680 
0681 template<
0682     class Concept,
0683     class Op
0684     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0685 >
0686 typename ::boost::type_erasure::detail::call_result<
0687     Op,
0688     void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
0689     Concept
0690 >::type
0691 call(
0692     const ::boost::type_erasure::binding<Concept>& table,
0693     const Op& f
0694     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0695 {
0696     ::boost::type_erasure::require_match(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0697     return ::boost::type_erasure::unchecked_call(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0698 }
0699 
0700 #if N != 0
0701 
0702 template<
0703     class Op
0704     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0705 >
0706 typename ::boost::type_erasure::detail::call_result<
0707     Op,
0708     void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
0709 >::type
0710 unchecked_call(
0711     const Op&
0712     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0713 {
0714     return ::boost::type_erasure::detail::call_impl<
0715         typename ::boost::type_erasure::detail::get_signature<Op>::type,
0716         void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
0717     >::template apply<
0718         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
0719     >(
0720         ::boost::type_erasure::detail::BOOST_PP_CAT(extract_table, N)(
0721             (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0,
0722             BOOST_PP_ENUM_PARAMS(N, arg))
0723         BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg)
0724     );
0725 }
0726 
0727 template<
0728     class Op
0729     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0730 >
0731 typename ::boost::type_erasure::detail::call_result<
0732     Op,
0733     void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
0734 >::type
0735 call(
0736     const Op& f
0737     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0738 {
0739     ::boost::type_erasure::require_match(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0740     return ::boost::type_erasure::unchecked_call(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0741 }
0742 
0743 #endif
0744 
0745 #undef RREF
0746 #undef BOOST_TYPE_ERASURE_FORWARD_ARGS
0747 #undef BOOST_TYPE_ERASURE_FORWARD_ARGS_I
0748 
0749 #undef BOOST_TYPE_ERASURE_GET_TABLE
0750 #undef BOOST_TYPE_ERASURE_CONVERT_ARG
0751 #undef N
0752 
0753 #endif