// Boost.TypeErasure library // // Copyright 2011 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_BUILTIN_HPP_INCLUDED #define BOOST_TYPE_ERASURE_BUILTIN_HPP_INCLUDED #include #include #include #include #include #include #include #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES # include // std::move #endif #include namespace boost { namespace type_erasure { /** * The @ref destructible concept enables forwarding to * the destructor of the contained type. This is required * whenever an @ref any is created by value. * * \note The @ref destructible concept rarely needs to * be specified explicitly, because it is included in * the @ref copy_constructible concept. * * \note @ref destructible may not be specialized and * may not be passed to \call as it depends on the * implementation details of @ref any. */ template struct destructible { /** INTERNAL ONLY */ typedef void (*type)(detail::storage&); /** INTERNAL ONLY */ static void value(detail::storage& arg) { delete static_cast(arg.data); } /** INTERNAL ONLY */ static void apply(detail::storage& arg) { delete static_cast(arg.data); } }; /** * The @ref copy_constructible concept allows objects to * be copied and destroyed. * * \note This concept is defined to match C++ 2003, * [lib.copyconstructible]. It is not equivalent to * the concept of the same name in C++11. */ template struct copy_constructible : ::boost::mpl::vector, destructible > {}; #ifdef BOOST_TYPE_ERASURE_DOXYGEN /** * Enables assignment of @ref any types. */ template struct assignable { static void apply(T& dst, U src); }; #else /** * Enables assignment of @ref any types. */ template struct assignable : ::boost::mpl::vector > {}; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES /** INTERNAL ONLY */ template struct assignable { static void apply(T& dst, U&& src) { dst = std::forward(src); } }; #endif /** INTERNAL ONLY */ template struct assignable { static void apply(T& dst, U& src) { dst = src; } }; /** INTERNAL ONLY */ template struct concept_interface, Base, T, typename ::boost::enable_if_c< ::boost::is_reference::value>::type> : Base { using Base::_boost_type_erasure_deduce_assign; assignable* _boost_type_erasure_deduce_assign( typename ::boost::type_erasure::as_param::type) { return 0; } }; #endif /** * Enables runtime type information. This is required * if you want to use \any_cast or \typeid_of. * * \note @ref typeid_ cannot be specialized because several * library components including \any_cast would not work * correctly if its behavior changed. There is no need * to specialize it anyway, since it works for all types. * @ref typeid_ also cannot be passed to \call. To access it, * use \typeid_of. */ template struct typeid_ { /** INTERNAL ONLY */ typedef const std::type_info& (*type)(); /** INTERNAL ONLY */ static const std::type_info& value() { return typeid(T); } /** INTERNAL ONLY */ static const std::type_info& apply() { return typeid(T); } }; namespace detail { template struct get_null_vtable_entry; template struct get_null_vtable_entry< ::boost::type_erasure::typeid_ > { typedef typeid_ type; }; struct null_destroy { static void value(::boost::type_erasure::detail::storage&) {} }; template struct get_null_vtable_entry< ::boost::type_erasure::destructible > { typedef ::boost::type_erasure::detail::null_destroy type; }; } } } #endif