#ifndef BOOST_SERIALIZATION_VOID_CAST_HPP #define BOOST_SERIALIZATION_VOID_CAST_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // void_cast.hpp: interface for run-time casting of void pointers. // (C) Copyright 2002-2009 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to 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) // gennadiy.rozental@tfn.com // See http://www.boost.org for updates, documentation, and revision history. #include // for ptrdiff_t #include #include #include #include #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275) #endif namespace boost { namespace serialization { class extended_type_info; // Given a void *, assume that it really points to an instance of one type // and alter it so that it would point to an instance of a related type. // Return the altered pointer. If there exists no sequence of casts that // can transform from_type to to_type, return a NULL. BOOST_SERIALIZATION_DECL(void const *) void_upcast( extended_type_info const & derived, extended_type_info const & base, void const * const t ); inline void * void_upcast( extended_type_info const & derived, extended_type_info const & base, void * const t ){ return const_cast(void_upcast( derived, base, const_cast(t) )); } BOOST_SERIALIZATION_DECL(void const *) void_downcast( extended_type_info const & derived, extended_type_info const & base, void const * const t ); inline void * void_downcast( extended_type_info const & derived, extended_type_info const & base, void * const t ){ return const_cast(void_downcast( derived, base, const_cast(t) )); } namespace void_cast_detail { class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster : private boost::noncopyable { friend BOOST_SERIALIZATION_DECL(void const *) boost::serialization::void_upcast( extended_type_info const & derived, extended_type_info const & base, void const * const ); friend BOOST_SERIALIZATION_DECL(void const *) boost::serialization::void_downcast( extended_type_info const & derived, extended_type_info const & base, void const * const ); protected: void recursive_register(bool includes_virtual_base = false) const; void recursive_unregister() const; virtual bool has_virtual_base() const = 0; public: // Data members const extended_type_info * m_derived; const extended_type_info * m_base; /*const*/ std::ptrdiff_t m_difference; void_caster const * const m_parent; // note that void_casters are keyed on value of // member extended type info records - NOT their // addresses. This is necessary in order for the // void cast operations to work across dll and exe // module boundries. bool operator<(const void_caster & rhs) const; const void_caster & operator*(){ return *this; } // each derived class must re-implement these; virtual void const * upcast(void const * const t) const = 0; virtual void const * downcast(void const * const t) const = 0; // Constructor void_caster( extended_type_info const * derived, extended_type_info const * base, std::ptrdiff_t difference = 0, void_caster const * const parent = 0 ) : m_derived(derived), m_base(base), m_difference(difference), m_parent(parent) {} virtual ~void_caster(){} }; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275 4511 4512) #endif template class void_caster_primitive : public void_caster { virtual void const * downcast(void const * const t) const { const Derived * d = boost::serialization::smart_cast( static_cast(t) ); return d; } virtual void const * upcast(void const * const t) const { const Base * b = boost::serialization::smart_cast( static_cast(t) ); return b; } virtual bool has_virtual_base() const { return false; } public: void_caster_primitive(); virtual ~void_caster_primitive(); }; template void_caster_primitive::void_caster_primitive() : void_caster( & type_info_implementation::type::get_const_instance(), & type_info_implementation::type::get_const_instance(), // note:I wanted to display from 0 here, but at least one compiler // treated 0 by not shifting it at all. reinterpret_cast( static_cast( reinterpret_cast(1) ) ) - 1 ) { recursive_register(); } template void_caster_primitive::~void_caster_primitive(){ recursive_unregister(); } template class void_caster_virtual_base : public void_caster { virtual bool has_virtual_base() const { return true; } public: virtual void const * downcast(void const * const t) const { const Derived * d = dynamic_cast( static_cast(t) ); return d; } virtual void const * upcast(void const * const t) const { const Base * b = dynamic_cast( static_cast(t) ); return b; } void_caster_virtual_base(); virtual ~void_caster_virtual_base(); }; #ifdef BOOST_MSVC #pragma warning(pop) #endif template void_caster_virtual_base::void_caster_virtual_base() : void_caster( & (type_info_implementation::type::get_const_instance()), & (type_info_implementation::type::get_const_instance()) ) { recursive_register(true); } template void_caster_virtual_base::~void_caster_virtual_base(){ recursive_unregister(); } template struct void_caster_base : public void_caster { typedef BOOST_DEDUCED_TYPENAME mpl::eval_if, mpl::identity< void_cast_detail::void_caster_virtual_base > ,// else mpl::identity< void_cast_detail::void_caster_primitive > >::type type; }; } // void_cast_detail template BOOST_DLLEXPORT inline const void_cast_detail::void_caster & void_cast_register( Derived const * /* dnull = NULL */, Base const * /* bnull = NULL */ ){ typedef BOOST_DEDUCED_TYPENAME mpl::eval_if, mpl::identity< void_cast_detail::void_caster_virtual_base > ,// else mpl::identity< void_cast_detail::void_caster_primitive > >::type typex; return singleton::get_const_instance(); } template class void_caster : public void_cast_detail::void_caster_base::type { }; } // namespace serialization } // namespace boost #ifdef BOOST_MSVC # pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_SERIALIZATION_VOID_CAST_HPP