// Boost.TypeErasure library // // Copyright 2015 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_DYNAMIC_VTABLE_HPP_INCLUDED #define BOOST_TYPE_ERASURE_DETAIL_DYNAMIC_VTABLE_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace type_erasure { namespace detail { #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) template struct dynamic_binding_impl { const std::type_info * type; dynamic_binding_impl() = default; constexpr dynamic_binding_impl(const std::type_info * t) : type(t) {} }; template struct dynamic_binding_element { typedef const std::type_info * type; }; template struct append_to_key { template void operator()(P) { key->push_back(static_cast*>(table)->type); } const Table * table; key_type * key; }; template struct dynamic_vtable : dynamic_binding_impl

... { dynamic_vtable() = default; constexpr dynamic_vtable(typename dynamic_binding_element

::type ...t) : dynamic_binding_impl

(t)... {} template typename F::type lookup(F*) const { key_type key; #ifndef BOOST_TYPE_ERASURE_USE_MP11 typedef typename ::boost::type_erasure::detail::get_placeholders >::type placeholders; #else typedef typename ::boost::type_erasure::detail::get_placeholders >::type placeholders; #endif typedef typename ::boost::mpl::fold< placeholders, ::boost::mpl::map0<>, ::boost::type_erasure::detail::counting_map_appender >::type placeholder_map; key.push_back(&typeid(typename ::boost::type_erasure::detail::rebind_placeholders::type)); ::boost::mpl::for_each(append_to_key{this, &key}); return reinterpret_cast(lookup_function_impl(key)); } template void init() { *this = dynamic_vtable(&typeid(typename boost::mpl::at::type)...); } template void convert_from(const Src& src) { #ifndef BOOST_TYPE_ERASURE_USE_MP11 *this = dynamic_vtable( (&src.lookup((::boost::type_erasure::typeid_::type>*)0)())...); #else *this = dynamic_vtable( (&src.lookup((::boost::type_erasure::typeid_< ::boost::mp11::mp_second< ::boost::mp11::mp_map_find > >*)0)())...); #endif } }; template struct make_dynamic_vtable_impl; template struct make_dynamic_vtable_impl > { typedef dynamic_vtable type; }; template struct make_dynamic_vtable : make_dynamic_vtable_impl::type> {}; #else template struct dynamic_vtable_initializer { dynamic_vtable_initializer(const std::type_info**& ptr) : types(&ptr) {} template void operator()(P) { *(*types)++ = &typeid(typename ::boost::mpl::at::type); } const ::std::type_info*** types; }; template struct dynamic_vtable { const ::std::type_info * types[(::boost::mpl::size::value)]; struct append_to_key { append_to_key(const std::type_info * const * t, key_type* k) : types(t), key(k) {} template void operator()(P) { key->push_back(types[(::boost::mpl::index_of::type::value)]); } const std::type_info * const * types; key_type * key; }; template typename F::type lookup(F*) const { key_type key; typedef typename ::boost::type_erasure::detail::get_placeholders >::type placeholders; typedef typename ::boost::mpl::fold< placeholders, ::boost::mpl::map0<>, ::boost::type_erasure::detail::counting_map_appender >::type placeholder_map; key.push_back(&typeid(typename ::boost::type_erasure::detail::rebind_placeholders::type)); ::boost::mpl::for_each(append_to_key(types, &key)); return reinterpret_cast(lookup_function_impl(key)); } template void init() { const std::type_info* ptr = types; ::boost::mpl::for_each(dynamic_vtable_initializer(ptr)); } template struct converter { converter(const std::type_info**& t, const Src& s) : types(&t), src(&s) {} template void operator()(P) { *(*types)++ = &src->lookup((::boost::type_erasure::typeid_::type>*)0)(); } const std::type_info*** types; const Src * src; }; template void convert_from(const Src& src) { const ::std::type_info** ptr = types; ::boost::mpl::for_each(converter(ptr, src)); } }; template struct make_dynamic_vtable { typedef dynamic_vtable type; }; #endif } } } #endif