diff options
Diffstat (limited to 'boost/type_erasure/builtin.hpp')
-rw-r--r-- | boost/type_erasure/builtin.hpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/boost/type_erasure/builtin.hpp b/boost/type_erasure/builtin.hpp new file mode 100644 index 0000000000..812b34face --- /dev/null +++ b/boost/type_erasure/builtin.hpp @@ -0,0 +1,142 @@ +// 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 <boost/mpl/vector.hpp> +#include <boost/type_erasure/detail/storage.hpp> +#include <boost/type_erasure/placeholder.hpp> +#include <boost/type_erasure/constructible.hpp> +#include <boost/type_erasure/rebind_any.hpp> +#include <typeinfo> + +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<class T = _self> +struct destructible +{ + /** INTERNAL ONLY */ + typedef void (*type)(detail::storage&); + /** INTERNAL ONLY */ + static void value(detail::storage& arg) + { + delete static_cast<T*>(arg.data); + } + /** INTERNAL ONLY */ + static void apply(detail::storage& arg) + { + delete static_cast<T*>(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<class T = _self> +struct copy_constructible : + ::boost::mpl::vector<constructible<T(const T&)>, destructible<T> > +{}; + +/** + * Enables assignment of @ref any types. + */ +template<class T = _self, class U = T> +struct assignable +{ + static void apply(T& dst, const U& src) { dst = src; } +}; + +/** INTERNAL ONLY */ +template<class T, class U, class Base> +struct concept_interface<assignable<T, U>, Base, T> : Base +{ + using Base::_boost_type_erasure_deduce_assign; + assignable<T, U>* _boost_type_erasure_deduce_assign( + typename ::boost::type_erasure::rebind_any<Base, const U&>::type) + { + return 0; + } +}; + +/** + * 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<class T = _self> +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<class C> +struct get_null_vtable_entry; + +template<class T> +struct get_null_vtable_entry< ::boost::type_erasure::typeid_<T> > +{ + typedef typeid_<void> type; +}; + +struct null_destroy { + static void value(::boost::type_erasure::detail::storage&) {} +}; + +template<class T> +struct get_null_vtable_entry< ::boost::type_erasure::destructible<T> > +{ + typedef ::boost::type_erasure::detail::null_destroy type; +}; + +} + +} +} + +#endif |