File indexing completed on 2025-01-30 10:01:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
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