Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:22

0001 // Boost.TypeErasure library
0002 //
0003 // Copyright 2018 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_DETAIL_MEMBER11_HPP_INCLUDED
0012 #define BOOST_TYPE_ERASURE_DETAIL_MEMBER11_HPP_INCLUDED
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/config/workaround.hpp>
0016 
0017 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && \
0018     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
0019     !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0020     !defined(BOOST_NO_CXX11_DECLTYPE) && \
0021     !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
0022 
0023 #include <boost/preprocessor/cat.hpp>
0024 #include <boost/preprocessor/control/if.hpp>
0025 #include <boost/preprocessor/punctuation/is_begin_parens.hpp>
0026 #include <boost/vmd/is_empty.hpp>
0027 #include <boost/type_traits/remove_reference.hpp>
0028 #include <boost/type_traits/remove_cv.hpp>
0029 #include <boost/mpl/if.hpp>
0030 #include <boost/type_erasure/detail/const.hpp>
0031 #include <boost/type_erasure/detail/macro.hpp>
0032 #include <boost/type_erasure/rebind_any.hpp>
0033 #include <boost/type_erasure/param.hpp>
0034 #include <boost/type_erasure/is_placeholder.hpp>
0035 #include <boost/type_erasure/call.hpp>
0036 
0037 namespace boost {
0038 namespace type_erasure {
0039 namespace detail {
0040 
0041 template<class P, template<class ...> class Interface, class Sig, class Concept, class Base, class ID>
0042 using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference<P>::value,
0043     typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref<P>::value,
0044         Interface<Sig, Concept, Base, const ID>,
0045         Base
0046     >::type,
0047     Interface<Sig, Concept, Base, ID>
0048 >::type;
0049 
0050 
0051 struct dummy {};
0052 
0053 template<class Sig>
0054 struct choose_member_impl;
0055 
0056 template<class R, class C, class... T>
0057 struct choose_member_impl<R (C::*)(T...) const>
0058 {
0059     template<class P, template<class> class M, template<class,class> class S> 
0060     using apply = ::boost::mpl::vector1<S<R(T...), const P> >;
0061 };
0062 
0063 template<class R, class C, class... T>
0064 struct choose_member_impl<R (C::*)(T...)>
0065 {
0066     template<class P, template<class> class M, template<class,class> class S> 
0067     using apply = M<R(P&, T...)>;
0068 };
0069 
0070 template<class Sig, class P, template<class> class M, template<class, class> class Self>
0071 using choose_member_impl_t =
0072     typename ::boost::type_erasure::detail::choose_member_impl<
0073         Sig (::boost::type_erasure::detail::dummy::*)
0074     >::template apply<P, M, Self>;
0075 
0076 template<class Sig, class T, class ID>
0077 struct member_interface_chooser
0078 {
0079     template<class Base, template<class, class> class C, template<class...> class M>
0080     using apply = Base;
0081 };
0082 
0083 template<class R, class T, class... A>
0084 struct member_interface_chooser<R(A...), T, T>
0085 {
0086     template<class Base, template<class, class> class C, template<class...> class M>
0087     using apply = ::boost::type_erasure::detail::choose_member_interface<
0088         ::boost::type_erasure::placeholder_of_t<Base>,
0089         M,
0090         R(A...), C<R(A...), T>, Base, T>;
0091 };
0092 
0093 template<class R, class T, class... A>
0094 struct member_interface_chooser<R(A...), const T, T>
0095 {
0096     template<class Base, template<class, class> class C, template<class...> class M>
0097     using apply = M<R(A...), C<R(A...), const T>, Base, const T>;
0098 };
0099 
0100 template<class Sig, class T, template<class, class> class C, template<class...> class M>
0101 struct member_choose_interface
0102 {
0103     template<class Concept, class Base, class ID>
0104     using apply = typename ::boost::type_erasure::detail::member_interface_chooser<Sig, T, ID>::template apply<Base, C, M>;
0105 };
0106 
0107 }
0108 }
0109 }
0110 
0111 #define BOOST_TYPE_ERASURE_MEMBER_I(concept_name, function_name)            \
0112 template<class Sig, class T = ::boost::type_erasure::_self>                 \
0113 struct concept_name;                                                        \
0114                                                                             \
0115 namespace boost_type_erasure_impl {                                         \
0116                                                                             \
0117 template<class Sig, class T>                                                \
0118 using concept_name ## self = concept_name<Sig, T>;                          \
0119                                                                             \
0120 template<class Sig, class Concept, class Base, class ID, class Enable = void>\
0121 struct concept_name ## _member_interface;                                   \
0122                                                                             \
0123 template<class R, class... A, class Concept, class Base, class ID, class V> \
0124 struct concept_name ## _member_interface<R(A...), Concept, Base, ID, V> : Base\
0125 {                                                                           \
0126     typedef void _boost_type_erasure_has_member ## function_name;           \
0127     ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a)\
0128     { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
0129 };                                                                          \
0130                                                                             \
0131 template<class R, class... A, class Concept, class Base, class ID>          \
0132 struct concept_name ## _member_interface<R(A...), Concept, Base, ID,        \
0133     typename Base::_boost_type_erasure_has_member ## function_name> : Base  \
0134 {                                                                           \
0135     using Base::function_name;                                              \
0136     ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a)\
0137     { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
0138 };                                                                          \
0139                                                                             \
0140 template<class R, class... A, class Concept, class Base, class ID, class V> \
0141 struct concept_name ## _member_interface<R(A...), Concept, Base, const ID, V> : Base\
0142 {                                                                           \
0143     typedef void _boost_type_erasure_has_member ## function_name;           \
0144     ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a) const\
0145     { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
0146 };                                                                          \
0147                                                                             \
0148 template<class R, class... A, class Concept, class Base, class ID>          \
0149 struct concept_name ## _member_interface<R(A...), Concept, Base, const ID,  \
0150     typename Base::_boost_type_erasure_has_member ## function_name> : Base  \
0151 {                                                                           \
0152     using Base::function_name;                                              \
0153     ::boost::type_erasure::rebind_any_t<Base, R> function_name(::boost::type_erasure::as_param_t<Base, A>... a) const\
0154     { return ::boost::type_erasure::call(Concept(), *this, std::forward<A>(a)...); }\
0155 };                                                                          \
0156                                                                             \
0157 template<class Sig>                                                         \
0158 struct concept_name ## member;                                              \
0159                                                                             \
0160 template<class R, class T0, class... T>                                     \
0161 struct concept_name ## member<R(T0, T...)> {                                \
0162     static R apply(T0 t0, T... t)                                           \
0163     { return t0.function_name(std::forward<T>(t)...); }                     \
0164 };                                                                          \
0165                                                                             \
0166 template<class T0, class... T>                                              \
0167 struct concept_name ## member<void(T0, T...)> {                             \
0168     static void apply(T0 t0, T... t)                                        \
0169     { t0.function_name(std::forward<T>(t)...); }                            \
0170 };                                                                          \
0171                                                                             \
0172 }                                                                           \
0173                                                                             \
0174 template<class Sig, class T>                                                \
0175 struct concept_name :                                                       \
0176     ::boost::type_erasure::detail::choose_member_impl_t<Sig, T,             \
0177         boost_type_erasure_impl::concept_name##member,                      \
0178         boost_type_erasure_impl::concept_name##self                         \
0179     >                                                                       \
0180 {};                                                                         \
0181                                                                             \
0182 template<class Sig, class T>                                                \
0183 ::boost::type_erasure::detail::member_choose_interface<Sig, T, concept_name,\
0184     boost_type_erasure_impl::concept_name ## _member_interface>             \
0185 boost_type_erasure_find_interface(concept_name<Sig, T>);
0186 
0187 #define BOOST_TYPE_ERASURE_MEMBER_SIMPLE(name, ...) \
0188     BOOST_TYPE_ERASURE_MEMBER_I(has_ ## name, name)
0189 
0190 #define BOOST_TYPE_ERASURE_MEMBER_NS_I(concept_name, name)  \
0191     BOOST_TYPE_ERASURE_MEMBER_I(concept_name, name)
0192 
0193 #define BOOST_TYPE_ERASURE_MEMBER_NS(concept_name, name)    \
0194     BOOST_TYPE_ERASURE_OPEN_NAMESPACE(concept_name)         \
0195     BOOST_TYPE_ERASURE_MEMBER_NS_I(BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(concept_name)), concept_name), name) \
0196     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(concept_name)
0197 
0198 #define BOOST_TYPE_ERASURE_MEMBER_NAMED(concept_name, name, ...)    \
0199     BOOST_PP_IF(BOOST_PP_IS_BEGIN_PARENS(concept_name),             \
0200         BOOST_TYPE_ERASURE_MEMBER_NS,                               \
0201         BOOST_TYPE_ERASURE_MEMBER_I)                                \
0202     (concept_name, name)
0203 
0204 #define BOOST_TYPE_ERASURE_MEMBER_CAT(x, y) x y
0205 
0206 #define BOOST_TYPE_ERASURE_MEMBER(name, ...)            \
0207     BOOST_TYPE_ERASURE_MEMBER_CAT(                      \
0208         BOOST_PP_IF(BOOST_VMD_IS_EMPTY(__VA_ARGS__),    \
0209             BOOST_TYPE_ERASURE_MEMBER_SIMPLE,           \
0210             BOOST_TYPE_ERASURE_MEMBER_NAMED),           \
0211         (name, __VA_ARGS__))
0212 
0213 #endif
0214 
0215 #endif