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 2012 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 #ifndef BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
0013 
0014 #include <boost/detail/workaround.hpp>
0015 #include <boost/preprocessor/repetition/enum.hpp>
0016 #include <boost/preprocessor/repetition/enum_trailing.hpp>
0017 #include <boost/preprocessor/repetition/enum_params.hpp>
0018 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
0019 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
0020 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0021 #include <boost/preprocessor/cat.hpp>
0022 #include <boost/preprocessor/control/if.hpp>
0023 #include <boost/preprocessor/punctuation/is_begin_parens.hpp>
0024 #include <boost/vmd/is_empty.hpp>
0025 #include <boost/type_traits/remove_reference.hpp>
0026 #include <boost/type_traits/remove_cv.hpp>
0027 #include <boost/mpl/eval_if.hpp>
0028 #include <boost/mpl/identity.hpp>
0029 #include <boost/mpl/int.hpp>
0030 #include <boost/mpl/next.hpp>
0031 #include <boost/type_erasure/detail/macro.hpp>
0032 #include <boost/type_erasure/detail/const.hpp>
0033 #include <boost/type_erasure/config.hpp>
0034 #include <boost/type_erasure/derived.hpp>
0035 #include <boost/type_erasure/rebind_any.hpp>
0036 #include <boost/type_erasure/param.hpp>
0037 #include <boost/type_erasure/is_placeholder.hpp>
0038 #include <boost/type_erasure/call.hpp>
0039 #include <boost/type_erasure/concept_interface.hpp>
0040 
0041 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
0042     defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
0043     defined(BOOST_TYPE_ERASURE_DOXYGEN) || \
0044     BOOST_WORKAROUND(BOOST_MSVC, == 1800)
0045 
0046 namespace boost {
0047 namespace type_erasure {
0048 namespace detail {
0049 
0050 template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
0051 struct first_placeholder {
0052     typedef typename ::boost::mpl::eval_if<is_placeholder<T0>,
0053         ::boost::mpl::identity<T0>,
0054         first_placeholder<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)>
0055     >::type type;
0056 };
0057 
0058 template<>
0059 struct first_placeholder<> {};
0060 
0061 template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
0062 struct first_placeholder_index :
0063     ::boost::mpl::eval_if<is_placeholder<T0>,
0064         ::boost::mpl::int_<0>,
0065         ::boost::mpl::next<first_placeholder_index<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)> >
0066     >::type
0067 {};
0068 
0069 }
0070 }
0071 }
0072 
0073 /** INTERNAL ONLY */
0074 #define BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(seq, N) \
0075     BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, T))>
0076 
0077 /** INTERNAL ONLY */
0078 #define BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE(z, n, data) \
0079     typename ::boost::remove_cv<typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type>::type
0080 
0081 /** INTERNAL ONLY */
0082 #define BOOST_TYPE_ERASURE_FREE_PARAM_TYPE(z, n, data)                      \
0083     typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
0084         ::boost::type_erasure::detail::maybe_const_this_param<BOOST_PP_CAT(T, n), Base>,    \
0085         ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>           \
0086     >::type BOOST_PP_CAT(t, n)
0087 
0088 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0089 
0090 /** INTERNAL ONLY */
0091 #define BOOST_TYPE_ERASURE_FREE_FORWARD_I(z, n, data) ::std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(t, n))
0092 /** INTERNAL ONLY */
0093 #define BOOST_TYPE_ERASURE_FREE_FORWARD(n) BOOST_PP_ENUM(n, BOOST_TYPE_ERASURE_FREE_FORWARD_I, ~)
0094 /** INTERNAL ONLY */
0095 #define BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I(z, n, data) \
0096     ::std::forward<typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
0097         ::boost::type_erasure::detail::maybe_const_this_param<BOOST_PP_CAT(T, n), Base>,    \
0098         ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>           \
0099     >::type>(BOOST_PP_CAT(t, n))
0100 
0101 #else
0102 
0103 #define BOOST_TYPE_ERASURE_FREE_FORWARD(n) BOOST_PP_ENUM_PARAMS(n, t)
0104 #define BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I(z, n, data) BOOST_PP_CAT(t, n)
0105 
0106 #endif
0107 
0108 /** INTERNAL ONLY */
0109 #define BOOST_TYPE_ERASURE_FREE_II(qual_name, concept_name, function_name, N)  \
0110     BOOST_TYPE_ERASURE_OPEN_NAMESPACE(qual_name)                        \
0111                                                                         \
0112     template<class Sig>                                                 \
0113     struct concept_name;                                                \
0114                                                                         \
0115     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>         \
0116     struct concept_name<R(BOOST_PP_ENUM_PARAMS(N, T))> {                \
0117         static R apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t))            \
0118         { return function_name(BOOST_TYPE_ERASURE_FREE_FORWARD(N)); }   \
0119     };                                                                  \
0120                                                                         \
0121     template<BOOST_PP_ENUM_PARAMS(N, class T)>                          \
0122     struct concept_name<void(BOOST_PP_ENUM_PARAMS(N, T))> {             \
0123         static void apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t))         \
0124         { function_name(BOOST_TYPE_ERASURE_FREE_FORWARD(N)); }          \
0125     };                                                                  \
0126                                                                         \
0127     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name)                       \
0128                                                                         \
0129     namespace boost {                                                   \
0130     namespace type_erasure {                                            \
0131                                                                         \
0132     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Base> \
0133     struct concept_interface<                                           \
0134         BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N),             \
0135         Base,                                                           \
0136         typename ::boost::type_erasure::detail::first_placeholder<      \
0137             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type  \
0138     > : Base {                                                          \
0139         typedef typename ::boost::type_erasure::detail::first_placeholder_index<    \
0140             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type  \
0141             _boost_type_erasure_free_p_idx;                             \
0142         friend typename ::boost::type_erasure::rebind_any<Base, R>::type function_name(  \
0143             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_PARAM_TYPE, ~))    \
0144         {                                                               \
0145             return ::boost::type_erasure::call(                         \
0146                 BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N)()    \
0147                 BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I, ~)); \
0148         }                                                               \
0149     };                                                                  \
0150                                                                         \
0151     }                                                                   \
0152     }
0153 
0154 /** INTERNAL ONLY */
0155 #define BOOST_TYPE_ERASURE_FREE_I(namespace_name, concept_name, function_name, N)\
0156     BOOST_TYPE_ERASURE_FREE_II(namespace_name, concept_name, function_name, N)
0157 
0158 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
0159 
0160 /**
0161  * \brief Defines a primitive concept for a free function.
0162  *
0163  * \param concept_name is the name of the concept to declare.
0164  *        If it is omitted it defaults to <code>has_ ## function_name</code>
0165  * \param function_name is the name of the function.
0166  *
0167  * The declaration of the concept is
0168  * \code
0169  * template<class Sig>
0170  * struct concept_name;
0171  * \endcode
0172  * where Sig is a function type giving the
0173  * signature of the function.
0174  *
0175  * This macro can only be used at namespace scope.
0176  *
0177  * Example:
0178  *
0179  * \code
0180  * BOOST_TYPE_ERASURE_FREE(to_string)
0181  * typedef has_to_string<std::string(_self const&)> to_string_concept;
0182  * \endcode
0183  *
0184  * In C++03, the macro can only be used in the global namespace and
0185  * is defined as:
0186  *
0187  * \code
0188  * #define BOOST_TYPE_ERASURE_FREE(qualified_name, function_name, N)
0189  * \endcode
0190  *
0191  * Example:
0192  *
0193  * \code
0194  * BOOST_TYPE_ERASURE_FREE((boost)(has_to_string), to_string, 1)
0195  * \endcode
0196  *
0197  * For backwards compatibility, this form is always accepted.
0198  */
0199 #define BOOST_TYPE_ERASURE_FREE(concept_name, function_name)
0200 
0201 #else
0202 
0203 #define BOOST_TYPE_ERASURE_FREE(qualified_name, function_name, N)                           \
0204     BOOST_TYPE_ERASURE_FREE_I(                                                              \
0205         qualified_name,                                                                     \
0206         BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(qualified_name)), qualified_name), \
0207         function_name,                                                                      \
0208         N)
0209 
0210 #endif
0211 
0212 #else
0213 
0214 namespace boost {
0215 namespace type_erasure {
0216     
0217 template<int... N>
0218 struct index_list {};
0219 
0220 namespace detail {
0221     
0222 template<class... T>
0223 struct first_placeholder;
0224 
0225 template<class T0, class... T>
0226 struct first_placeholder<T0, T...> {
0227     typedef typename ::boost::mpl::eval_if<is_placeholder<T0>,
0228         ::boost::mpl::identity<T0>,
0229         first_placeholder<T...>
0230     >::type type;
0231 };
0232 
0233 template<>
0234 struct first_placeholder<> {};
0235 
0236 template<class... T>
0237 struct first_placeholder_index;
0238 
0239 template<class T0, class... T>
0240 struct first_placeholder_index<T0, T...> :
0241     ::boost::mpl::eval_if<is_placeholder<T0>,
0242         ::boost::mpl::int_<0>,
0243         ::boost::mpl::next<first_placeholder_index<T...> >
0244     >::type
0245 {};
0246 
0247 template<class Sig>
0248 struct transform_free_signature;
0249 
0250 template<class T, int N>
0251 struct push_back_index;
0252 
0253 template<int... N, int X>
0254 struct push_back_index<index_list<N...>, X>
0255 {
0256     typedef index_list<N..., X> type;
0257 };
0258 
0259 template<int N>
0260 struct make_index_list {
0261     typedef typename push_back_index<
0262         typename make_index_list<N-1>::type,
0263         N-1
0264     >::type type;
0265 };
0266 
0267 template<>
0268 struct make_index_list<0> {
0269     typedef index_list<> type;
0270 };
0271 
0272 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && \
0273     !defined(BOOST_NO_CXX11_DECLTYPE)
0274 
0275 template<int N>
0276 using make_index_list_t = typename ::boost::type_erasure::detail::make_index_list<N>::type;
0277 
0278 #if BOOST_WORKAROUND(BOOST_MSVC, == 1900)
0279 
0280 template<class... T>
0281 struct first_placeholder_index_ :
0282     ::boost::type_erasure::detail::first_placeholder_index<
0283         ::boost::remove_cv_t< ::boost::remove_reference_t<T> >...
0284     >
0285 {};
0286 template<class... T>
0287 using first_placeholder_index_t =
0288     typename ::boost::type_erasure::detail::first_placeholder_index_<T...>::type;
0289 
0290 #else
0291 
0292 template<class... T>
0293 using first_placeholder_index_t =
0294     typename ::boost::type_erasure::detail::first_placeholder_index<
0295         ::boost::remove_cv_t< ::boost::remove_reference_t<T> >...
0296     >::type;
0297 
0298 #endif
0299 
0300 template<class Base, class Tn, int I, class... T>
0301 using free_param_t =
0302     typename ::boost::mpl::eval_if_c<(::boost::type_erasure::detail::first_placeholder_index_t<T...>::value == I),
0303             ::boost::type_erasure::detail::maybe_const_this_param<Tn, Base>, \
0304             ::boost::type_erasure::as_param<Base, Tn>
0305     >::type;
0306 
0307 template<class Sig, class ID>
0308 struct free_interface_chooser
0309 {
0310     template<class Base, template<class> class C, template<class...> class F>
0311     using apply = Base;
0312 };
0313 
0314 template<class R, class... A>
0315 struct free_interface_chooser<
0316     R(A...),
0317     typename ::boost::type_erasure::detail::first_placeholder<
0318         ::boost::remove_cv_t< ::boost::remove_reference_t<A> >...>::type>
0319 {
0320     template<class Base, template<class> class C, template<class...> class F>
0321     using apply = F<R(A...), Base,
0322         ::boost::type_erasure::detail::make_index_list_t<sizeof...(A)> >;
0323 };
0324 
0325 template<class Sig, template<class> class C, template<class...> class F>
0326 struct free_choose_interface {
0327     template<class Concept, class Base, class ID>
0328     using apply = typename free_interface_chooser<Sig, ID>::template apply<Base, C, F>;
0329 };
0330 
0331 /** INTERNAL ONLY */
0332 #define BOOST_TYPE_ERASURE_FREE_I(concept_name, function_name)              \
0333 template<class Sig>                                                         \
0334 struct concept_name;                                                        \
0335                                                                             \
0336 namespace boost_type_erasure_impl {                                         \
0337                                                                             \
0338 template<class Sig, class Base, class Idx>                                  \
0339 struct concept_name ## _free_interface;                                     \
0340 template<class R, class... T, class Base, int... I>                         \
0341 struct concept_name ## _free_interface<R(T...), Base, ::boost::type_erasure::index_list<I...> > : Base {\
0342     friend ::boost::type_erasure::rebind_any_t<Base, R>                     \
0343     function_name(                                                          \
0344         ::boost::type_erasure::detail::free_param_t<Base, T, I, T...>... t) \
0345     {                                                                       \
0346         return ::boost::type_erasure::call(                                 \
0347             concept_name<R(T...)>(),                                        \
0348             std::forward< ::boost::type_erasure::detail::free_param_t<Base, T, I, T...> >(t)...);\
0349     }                                                                       \
0350 };                                                                          \
0351                                                                             \
0352 template<class Sig>                                                         \
0353 struct concept_name ## free;                                                \
0354                                                                             \
0355 template<class R, class... T>                                               \
0356 struct concept_name ## free<R(T...)> {                                      \
0357     static R apply(T... t)                                                  \
0358     { return function_name(std::forward<T>(t)...); }                        \
0359 };                                                                          \
0360                                                                             \
0361 template<class... T>                                                        \
0362 struct concept_name ## free<void(T...)> {                                   \
0363     static void apply(T... t)                                               \
0364     { function_name(std::forward<T>(t)...); }                               \
0365 };                                                                          \
0366                                                                             \
0367 }                                                                           \
0368                                                                             \
0369 template<class Sig>                                                         \
0370 struct concept_name :                                                       \
0371     boost_type_erasure_impl::concept_name##free<Sig>                        \
0372 {};                                                                         \
0373                                                                             \
0374 template<class Sig>                                                         \
0375 ::boost::type_erasure::detail::free_choose_interface<Sig, concept_name,     \
0376     boost_type_erasure_impl::concept_name ## _free_interface>               \
0377 boost_type_erasure_find_interface(concept_name<Sig>);
0378 
0379 #define BOOST_TYPE_ERASURE_FREE_SIMPLE(name, ...) \
0380     BOOST_TYPE_ERASURE_FREE_I(has_ ## name, name)
0381 
0382 #define BOOST_TYPE_ERASURE_FREE_NS_I(concept_name, name)  \
0383     BOOST_TYPE_ERASURE_FREE_I(concept_name, name)
0384 
0385 #define BOOST_TYPE_ERASURE_FREE_NS(concept_name, name)      \
0386     BOOST_TYPE_ERASURE_OPEN_NAMESPACE(concept_name)         \
0387     BOOST_TYPE_ERASURE_FREE_NS_I(BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(concept_name)), concept_name), name) \
0388     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(concept_name)
0389 
0390 #define BOOST_TYPE_ERASURE_FREE_NAMED(concept_name, name, ...)  \
0391     BOOST_PP_IF(BOOST_PP_IS_BEGIN_PARENS(concept_name),         \
0392         BOOST_TYPE_ERASURE_FREE_NS,                             \
0393         BOOST_TYPE_ERASURE_FREE_I)                              \
0394     (concept_name, name)
0395 
0396 #define BOOST_TYPE_ERASURE_FREE_CAT(x, y) x y
0397 
0398 #define BOOST_TYPE_ERASURE_FREE(name, ...)              \
0399     BOOST_TYPE_ERASURE_FREE_CAT(                        \
0400         BOOST_PP_IF(BOOST_VMD_IS_EMPTY(__VA_ARGS__),    \
0401             BOOST_TYPE_ERASURE_FREE_SIMPLE,             \
0402             BOOST_TYPE_ERASURE_FREE_NAMED),             \
0403         (name, __VA_ARGS__))
0404 
0405 #else
0406 
0407 /** INTERNAL ONLY */
0408 #define BOOST_TYPE_ERASURE_FREE_II(qual_name, concept_name, function_name)  \
0409     BOOST_TYPE_ERASURE_OPEN_NAMESPACE(qual_name)                        \
0410                                                                         \
0411     template<class Sig>                                                 \
0412     struct concept_name;                                                \
0413                                                                         \
0414     template<class R, class... T>                                       \
0415     struct concept_name<R(T...)> {                                      \
0416         static R apply(T... t)                                          \
0417         { return function_name(std::forward<T>(t)...); }                \
0418     };                                                                  \
0419                                                                         \
0420     template<class... T>                                                \
0421     struct concept_name<void(T...)> {                                   \
0422         static void apply(T... t)                                       \
0423         { function_name(std::forward<T>(t)...); }                       \
0424     };                                                                  \
0425                                                                         \
0426     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name)                       \
0427                                                                         \
0428     namespace boost {                                                   \
0429     namespace type_erasure {                                            \
0430                                                                         \
0431     template<class Sig, class Base, class Idx>                          \
0432     struct inject ## concept_name;                                      \
0433     template<class R, class... T, class Base, int... I>                 \
0434     struct inject ## concept_name<R(T...), Base, index_list<I...> > : Base {\
0435         typedef typename ::boost::type_erasure::detail::first_placeholder_index<    \
0436             typename ::boost::remove_cv<                                \
0437                 typename ::boost::remove_reference<T>::type             \
0438             >::type...                                                  \
0439         >::type _boost_type_erasure_free_p_idx;                         \
0440         friend typename ::boost::type_erasure::rebind_any<Base, R>::type\
0441         function_name(                                                  \
0442             typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == I), \
0443                 ::boost::type_erasure::detail::maybe_const_this_param<T, Base>, \
0444                 ::boost::type_erasure::as_param<Base, T>                \
0445             >::type... t)                                               \
0446        {                                                                \
0447             return ::boost::type_erasure::call(                         \
0448                 BOOST_TYPE_ERASURE_QUALIFIED_NAME(qual_name)<R(T...)>(),\
0449                 std::forward<typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == I), \
0450                     ::boost::type_erasure::detail::maybe_const_this_param<T, Base>, \
0451                     ::boost::type_erasure::as_param<Base, T>            \
0452                 >::type>(t)...);                                        \
0453         }                                                               \
0454     };                                                                  \
0455                                                                         \
0456     template<class R, class... T, class Base>                           \
0457     struct concept_interface<                                           \
0458         BOOST_TYPE_ERASURE_QUALIFIED_NAME(qual_name)<R(T...)>,          \
0459         Base,                                                           \
0460         typename ::boost::type_erasure::detail::first_placeholder<      \
0461             typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type...>::type  \
0462     > :  inject ## concept_name<R(T...), Base, typename ::boost::type_erasure::detail::make_index_list<sizeof...(T)>::type>\
0463     {};                                                                 \
0464                                                                         \
0465     }                                                                   \
0466     }
0467 
0468     
0469 /** INTERNAL ONLY */
0470 #define BOOST_TYPE_ERASURE_FREE_I(namespace_name, concept_name, function_name)              \
0471     BOOST_TYPE_ERASURE_FREE_II(namespace_name, concept_name, function_name)
0472 
0473 #define BOOST_TYPE_ERASURE_FREE(qualified_name, function_name, ...)                         \
0474     BOOST_TYPE_ERASURE_FREE_I(                                                              \
0475         qualified_name,                                                                     \
0476         BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(qualified_name)), qualified_name), \
0477         function_name)
0478 
0479 #endif
0480 
0481 }
0482 }
0483 }
0484 
0485 #endif
0486 
0487 #endif