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_CALLABLE_HPP_INCLUDED
0014 #define BOOST_TYPE_ERASURE_CALLABLE_HPP_INCLUDED
0015 
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/utility/declval.hpp>
0018 #include <boost/mpl/vector.hpp>
0019 #include <boost/mpl/push_back.hpp>
0020 #include <boost/preprocessor/cat.hpp>
0021 #include <boost/preprocessor/dec.hpp>
0022 #include <boost/preprocessor/iteration/iterate.hpp>
0023 #include <boost/preprocessor/repetition/enum.hpp>
0024 #include <boost/preprocessor/repetition/enum_params.hpp>
0025 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0026 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0027 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0028 #include <boost/type_erasure/config.hpp>
0029 #include <boost/type_erasure/call.hpp>
0030 #include <boost/type_erasure/concept_interface.hpp>
0031 #include <boost/type_erasure/rebind_any.hpp>
0032 #include <boost/type_erasure/param.hpp>
0033 
0034 namespace boost {
0035 namespace type_erasure {
0036 
0037 template<class Sig, class F = _self>
0038 struct callable;
0039 
0040 namespace detail {
0041 
0042 template<class Sig>
0043 struct result_of_callable;
0044 
0045 }
0046 
0047 #if defined(BOOST_TYPE_ERASURE_DOXYGEN)
0048 
0049 /**
0050  * The @ref callable concept allows an @ref any to hold function objects.
0051  * @c Sig is interpreted in the same way as for Boost.Function, except
0052  * that the arguments and return type are allowed to be placeholders.
0053  * @c F must be a @ref placeholder.
0054  *
0055  * Multiple instances of @ref callable can be used
0056  * simultaneously.  Overload resolution works normally.
0057  * Note that unlike Boost.Function, @ref callable
0058  * does not provide result_type.  It does, however,
0059  * support @c boost::result_of.
0060  */
0061 template<class Sig, class F = _self>
0062 struct callable
0063 {
0064     /**
0065      * @c R is the result type of @c Sig and @c T is the argument
0066      * types of @c Sig.
0067      */
0068     static R apply(F& f, T... arg);
0069 };
0070 
0071 #elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
0072     !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0073     !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
0074 
0075 template<class R, class... T, class F>
0076 struct callable<R(T...), F>
0077 {
0078     static R apply(F& f, T... arg)
0079     {
0080         return f(std::forward<T>(arg)...);
0081     }
0082 };
0083 
0084 template<class... T, class F>
0085 struct callable<void(T...), F>
0086 {
0087     static void apply(F& f, T... arg)
0088     {
0089         f(std::forward<T>(arg)...);
0090     }
0091 };
0092 
0093 template<class R, class F, class Base, class Enable, class... T>
0094 struct concept_interface<callable<R(T...), F>, Base, F, Enable>
0095   : Base
0096 {
0097     template<class Sig>
0098     struct result :
0099         ::boost::type_erasure::detail::result_of_callable<Sig>
0100     {};
0101     typedef void _boost_type_erasure_is_callable;
0102     typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
0103     typedef char (&_boost_type_erasure_callable_size)[1];
0104     _boost_type_erasure_callable_size
0105     _boost_type_erasure_deduce_callable(
0106         typename ::boost::type_erasure::as_param<Base, T>::type...);
0107     typename ::boost::type_erasure::rebind_any<Base, R>::type
0108     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
0109     {
0110         return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
0111             ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
0112     }
0113 };
0114 
0115 template<class R, class F, class Base, class Enable, class... T>
0116 struct concept_interface<callable<R(T...), const F>, Base, F, Enable>
0117   : Base
0118 {
0119     template<class Sig>
0120     struct result :
0121         ::boost::type_erasure::detail::result_of_callable<Sig>
0122     {};
0123     typedef void _boost_type_erasure_is_callable;
0124     typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
0125     typedef char (&_boost_type_erasure_callable_size)[1];
0126     _boost_type_erasure_callable_size
0127     _boost_type_erasure_deduce_callable(
0128         typename ::boost::type_erasure::as_param<Base, T>::type...) const;
0129     typename ::boost::type_erasure::rebind_any<Base, R>::type operator()(
0130         typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
0131     {
0132         return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
0133             ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
0134     }
0135 };
0136 
0137 template<class R, class F, class Base, class... T>
0138 struct concept_interface<
0139     callable<R(T...), F>,
0140     Base,
0141     F,
0142     typename Base::_boost_type_erasure_is_callable
0143 >
0144   : Base
0145 {
0146     typedef typename ::boost::mpl::push_back<
0147         typename Base::_boost_type_erasure_callable_results,
0148         R
0149     >::type _boost_type_erasure_callable_results;
0150     typedef char (&_boost_type_erasure_callable_size)[
0151         ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
0152     using Base::_boost_type_erasure_deduce_callable;
0153     _boost_type_erasure_callable_size
0154     _boost_type_erasure_deduce_callable(
0155         typename ::boost::type_erasure::as_param<Base, T>::type...);
0156     using Base::operator();
0157     typename ::boost::type_erasure::rebind_any<Base, R>::type
0158     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
0159     {
0160         return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
0161             ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
0162     }
0163 };
0164 
0165 template<class R, class F, class Base, class... T>
0166 struct concept_interface<
0167     callable<R(T...), const F>,
0168     Base,
0169     F,
0170     typename Base::_boost_type_erasure_is_callable
0171 >
0172   : Base
0173 {
0174     typedef typename ::boost::mpl::push_back<
0175         typename Base::_boost_type_erasure_callable_results,
0176         R
0177     >::type _boost_type_erasure_callable_results;
0178     typedef char (&_boost_type_erasure_callable_size)[
0179         ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
0180     using Base::_boost_type_erasure_deduce_callable;
0181     _boost_type_erasure_callable_size
0182     _boost_type_erasure_deduce_callable(
0183         typename ::boost::type_erasure::as_param<Base, T>::type...) const;
0184     using Base::operator();
0185     typename ::boost::type_erasure::rebind_any<Base, R>::type
0186     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
0187     {
0188         return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
0189             ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
0190     }
0191 };
0192 
0193 namespace detail {
0194 
0195 template<class This, class... T>
0196 struct result_of_callable<This(T...)>
0197 {
0198     typedef typename ::boost::mpl::at_c<
0199         typename This::_boost_type_erasure_callable_results,
0200         sizeof(::boost::declval<This>().
0201             _boost_type_erasure_deduce_callable(::boost::declval<T>()...)) - 1
0202     >::type type;
0203 };
0204 
0205 }
0206 
0207 #else
0208 
0209 /** INTERNAL ONLY */
0210 #define BOOST_PP_FILENAME_1 <boost/type_erasure/callable.hpp>
0211 /** INTERNAL ONLY */
0212 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_DEC(BOOST_TYPE_ERASURE_MAX_ARITY))
0213 #include BOOST_PP_ITERATE()
0214 
0215 #endif
0216 
0217 }
0218 }
0219 
0220 #endif
0221 
0222 #else
0223 
0224 #define N BOOST_PP_ITERATION()
0225 #define BOOST_TYPE_ERASURE_DECLVAL(z, n, data) ::boost::declval<BOOST_PP_CAT(T, n)>()
0226 
0227 #define BOOST_TYPE_ERASURE_REBIND(z, n, data)\
0228     typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type BOOST_PP_CAT(arg, n)
0229 
0230 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0231 #define BOOST_TYPE_ERASURE_FORWARD(z, n, data) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n)
0232 #define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) BOOST_PP_CAT(arg, n)
0233 #else
0234 #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))
0235 #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))
0236 #endif
0237 
0238 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F>
0239 struct callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>
0240 {
0241     static R apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
0242     {
0243         return f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
0244     }
0245 };
0246 
0247 template<BOOST_PP_ENUM_PARAMS(N, class T) BOOST_PP_COMMA_IF(N) class F>
0248 struct callable<void(BOOST_PP_ENUM_PARAMS(N, T)), F>
0249 {
0250     static void apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
0251     {
0252         f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
0253     }
0254 };
0255 
0256 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
0257 struct concept_interface<
0258     callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
0259     Base,
0260     F,
0261     Enable
0262 >
0263   : Base
0264 {
0265     template<class Sig>
0266     struct result :
0267         ::boost::type_erasure::detail::result_of_callable<Sig>
0268     {};
0269     typedef void _boost_type_erasure_is_callable;
0270     typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
0271     typedef char (&_boost_type_erasure_callable_size)[1];
0272     _boost_type_erasure_callable_size
0273     _boost_type_erasure_deduce_callable(
0274         BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
0275     typename ::boost::type_erasure::rebind_any<Base, R>::type
0276     operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
0277     {
0278         return ::boost::type_erasure::call(
0279             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
0280             *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
0281     }
0282 };
0283 
0284 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
0285 struct concept_interface<
0286     callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
0287     Base,
0288     F,
0289     Enable
0290 >
0291   : Base
0292 {
0293     template<class Sig>
0294     struct result :
0295         ::boost::type_erasure::detail::result_of_callable<Sig>
0296     {};
0297     typedef void _boost_type_erasure_is_callable;
0298     typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
0299     typedef char (&_boost_type_erasure_callable_size)[1];
0300     _boost_type_erasure_callable_size
0301     _boost_type_erasure_deduce_callable(
0302         BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
0303     typename ::boost::type_erasure::rebind_any<Base, R>::type
0304     operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
0305     {
0306         return ::boost::type_erasure::call(
0307             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
0308             *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
0309     }
0310 };
0311 
0312 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
0313 struct concept_interface<
0314     callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
0315     Base,
0316     F,
0317     typename Base::_boost_type_erasure_is_callable
0318 >
0319   : Base
0320 {
0321     typedef typename ::boost::mpl::push_back<
0322         typename Base::_boost_type_erasure_callable_results,
0323         R
0324     >::type _boost_type_erasure_callable_results;
0325     typedef char (&_boost_type_erasure_callable_size)[
0326         ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
0327     using Base::_boost_type_erasure_deduce_callable;
0328     _boost_type_erasure_callable_size
0329     _boost_type_erasure_deduce_callable(
0330         BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
0331     using Base::operator();
0332     typename ::boost::type_erasure::rebind_any<Base, R>::type
0333     operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
0334     {
0335         return ::boost::type_erasure::call(
0336             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
0337             *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
0338     }
0339 };
0340 
0341 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
0342 struct concept_interface<
0343     callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
0344     Base,
0345     F,
0346     typename Base::_boost_type_erasure_is_callable
0347 >
0348   : Base
0349 {
0350     typedef typename ::boost::mpl::push_back<
0351         typename Base::_boost_type_erasure_callable_results,
0352         R
0353     >::type _boost_type_erasure_callable_results;
0354     typedef char (&_boost_type_erasure_callable_size)[
0355         ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
0356     using Base::_boost_type_erasure_deduce_callable;
0357     _boost_type_erasure_callable_size
0358     _boost_type_erasure_deduce_callable(
0359         BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
0360     using Base::operator();
0361     typename ::boost::type_erasure::rebind_any<Base, R>::type
0362     operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
0363     {
0364         return ::boost::type_erasure::call(
0365             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
0366             *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
0367     }
0368 };
0369 
0370 namespace detail {
0371 
0372 template<class This BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
0373 struct result_of_callable<This(BOOST_PP_ENUM_PARAMS(N, T))>
0374 {
0375     typedef typename ::boost::mpl::at_c<
0376         typename This::_boost_type_erasure_callable_results,
0377         sizeof(::boost::declval<This>().
0378             _boost_type_erasure_deduce_callable(
0379                 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_DECLVAL, ~))) - 1
0380     >::type type;
0381 };
0382 
0383 }
0384 
0385 #undef BOOST_TYPE_ERASURE_DECLVAL
0386 #undef BOOST_TYPE_ERASURE_REBIND
0387 #undef N
0388 
0389 #endif