// Boost.TypeErasure library // // Copyright 2018 Steven Watanabe // // Distributed under the Boost Software License Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // $Id$ #ifndef BOOST_TYPE_ERASURE_DETAIL_MEMBER11_HPP_INCLUDED #define BOOST_TYPE_ERASURE_DETAIL_MEMBER11_HPP_INCLUDED #include #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ !defined(BOOST_NO_CXX11_DECLTYPE) && \ !BOOST_WORKAROUND(BOOST_MSVC, == 1800) #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace type_erasure { namespace detail { template class interface, class Sig, class Concept, class Base, class ID> using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference

::value, typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref

::value, interface, Base >::type, interface >::type; struct dummy {}; template struct choose_member_impl; template struct choose_member_impl { template class M, template class S> using apply = ::boost::mpl::vector1 >; }; template struct choose_member_impl { template class M, template class S> using apply = M; }; template class M, template class Self> using choose_member_impl_t = typename ::boost::type_erasure::detail::choose_member_impl< Sig (::boost::type_erasure::detail::dummy::*) >::template apply; template struct member_interface_chooser { template class C, template class M> using apply = Base; }; template struct member_interface_chooser { template class C, template class M> using apply = ::boost::type_erasure::detail::choose_member_interface< ::boost::type_erasure::placeholder_of_t, M, R(A...), C, Base, T>; }; template struct member_interface_chooser { template class C, template class M> using apply = M, Base, const T>; }; template class C, template class M> struct member_choose_interface { template using apply = typename ::boost::type_erasure::detail::member_interface_chooser::template apply; }; } } } #define BOOST_TYPE_ERASURE_MEMBER_I(concept_name, function_name) \ template \ struct concept_name; \ \ namespace boost_type_erasure_impl { \ \ template \ using concept_name ## self = concept_name; \ \ template\ struct concept_name ## _member_interface; \ \ template \ struct concept_name ## _member_interface : Base\ { \ typedef void _boost_type_erasure_has_member ## function_name; \ ::boost::type_erasure::rebind_any_t function_name(::boost::type_erasure::as_param_t... a)\ { return ::boost::type_erasure::call(Concept(), *this, std::forward(a)...); }\ }; \ \ template \ struct concept_name ## _member_interface : Base \ { \ using Base::function_name; \ ::boost::type_erasure::rebind_any_t function_name(::boost::type_erasure::as_param_t... a)\ { return ::boost::type_erasure::call(Concept(), *this, std::forward(a)...); }\ }; \ \ template \ struct concept_name ## _member_interface : Base\ { \ typedef void _boost_type_erasure_has_member ## function_name; \ ::boost::type_erasure::rebind_any_t function_name(::boost::type_erasure::as_param_t... a) const\ { return ::boost::type_erasure::call(Concept(), *this, std::forward(a)...); }\ }; \ \ template \ struct concept_name ## _member_interface : Base \ { \ using Base::function_name; \ ::boost::type_erasure::rebind_any_t function_name(::boost::type_erasure::as_param_t... a) const\ { return ::boost::type_erasure::call(Concept(), *this, std::forward(a)...); }\ }; \ \ template \ struct concept_name ## member; \ \ template \ struct concept_name ## member { \ static R apply(T0 t0, T... t) \ { return t0.function_name(std::forward(t)...); } \ }; \ \ template \ struct concept_name ## member { \ static void apply(T0 t0, T... t) \ { t0.function_name(std::forward(t)...); } \ }; \ \ } \ \ template \ struct concept_name : \ ::boost::type_erasure::detail::choose_member_impl_t \ {}; \ \ template \ ::boost::type_erasure::detail::member_choose_interface \ boost_type_erasure_find_interface(concept_name); #define BOOST_TYPE_ERASURE_MEMBER_SIMPLE(name, ...) \ BOOST_TYPE_ERASURE_MEMBER_I(has_ ## name, name) #define BOOST_TYPE_ERASURE_MEMBER_NS_I(concept_name, name) \ BOOST_TYPE_ERASURE_MEMBER_I(concept_name, name) #define BOOST_TYPE_ERASURE_MEMBER_NS(concept_name, name) \ BOOST_TYPE_ERASURE_OPEN_NAMESPACE(concept_name) \ BOOST_TYPE_ERASURE_MEMBER_NS_I(BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(concept_name)), concept_name), name) \ BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(concept_name) #define BOOST_TYPE_ERASURE_MEMBER_NAMED(concept_name, name, ...) \ BOOST_PP_IF(BOOST_PP_IS_BEGIN_PARENS(concept_name), \ BOOST_TYPE_ERASURE_MEMBER_NS, \ BOOST_TYPE_ERASURE_MEMBER_I) \ (concept_name, name) #define BOOST_TYPE_ERASURE_MEMBER_CAT(x, y) x y #define BOOST_TYPE_ERASURE_MEMBER(name, ...) \ BOOST_TYPE_ERASURE_MEMBER_CAT( \ BOOST_PP_IF(BOOST_VMD_IS_EMPTY(__VA_ARGS__), \ BOOST_TYPE_ERASURE_MEMBER_SIMPLE, \ BOOST_TYPE_ERASURE_MEMBER_NAMED), \ (name, __VA_ARGS__)) #endif #endif