File indexing completed on 2025-12-16 10:10:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 template<class Sig, class F = _self>
0062 struct callable
0063 {
0064
0065
0066
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
0210 #define BOOST_PP_FILENAME_1 <boost/type_erasure/callable.hpp>
0211
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