williamr@2: #ifndef BOOST_SERIALIZATION_VOID_CAST_HPP williamr@2: #define BOOST_SERIALIZATION_VOID_CAST_HPP williamr@2: williamr@2: // MS compatible compilers support #pragma once williamr@2: #if defined(_MSC_VER) && (_MSC_VER >= 1020) williamr@2: # pragma once williamr@2: #endif williamr@2: williamr@2: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 williamr@2: // void_cast.hpp: interface for run-time casting of void pointers. williamr@2: williamr@2: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . williamr@2: // Use, modification and distribution is subject to the Boost Software williamr@2: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // gennadiy.rozental@tfn.com williamr@2: williamr@2: // See http://www.boost.org for updates, documentation, and revision history. williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include // must be the last header williamr@2: williamr@2: #ifdef BOOST_MSVC williamr@2: # pragma warning(push) williamr@2: # pragma warning(disable : 4251 4231 4660 4275) williamr@2: #endif williamr@2: williamr@2: namespace boost { williamr@2: namespace serialization { williamr@2: williamr@2: class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info; williamr@2: williamr@2: // Given a void *, assume that it really points to an instance of one type williamr@2: // and alter it so that it would point to an instance of a related type. williamr@2: // Return the altered pointer. If there exists no sequence of casts that williamr@2: // can transform from_type to to_type, return a NULL. williamr@2: williamr@2: BOOST_SERIALIZATION_DECL(void const *) williamr@2: void_upcast( williamr@2: extended_type_info const & derived_type, williamr@2: extended_type_info const & base_type, williamr@2: void const * const t, williamr@2: bool top = true williamr@2: ); williamr@2: williamr@2: inline void * williamr@2: void_upcast( williamr@2: extended_type_info const & derived_type_, williamr@2: extended_type_info const & base_type_, williamr@2: void * const t williamr@2: ){ williamr@2: return const_cast(void_upcast( williamr@2: derived_type_, williamr@2: base_type_, williamr@2: const_cast(t) williamr@2: )); williamr@2: } williamr@2: williamr@2: BOOST_SERIALIZATION_DECL(void const *) williamr@2: void_downcast( williamr@2: extended_type_info const & derived_type, williamr@2: extended_type_info const & base_type, williamr@2: void const * const t, williamr@2: bool top = true williamr@2: ); williamr@2: williamr@2: inline void * williamr@2: void_downcast( williamr@2: extended_type_info const & derived_type_, williamr@2: extended_type_info const & base_type_, williamr@2: void * const t williamr@2: ){ williamr@2: return const_cast(void_downcast( williamr@2: derived_type_, williamr@2: base_type_, williamr@2: const_cast(t) williamr@2: )); williamr@2: } williamr@2: williamr@2: namespace void_cast_detail { williamr@2: williamr@2: // note: can't be abstract because an instance is used as a search argument williamr@2: class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster williamr@2: { williamr@2: friend struct void_caster_compare ; williamr@2: friend williamr@2: BOOST_SERIALIZATION_DECL(void const *) williamr@2: boost::serialization::void_upcast( williamr@2: const extended_type_info & derived_type, williamr@2: const extended_type_info & base_type, williamr@2: const void * t, williamr@2: bool top williamr@2: ); williamr@2: friend williamr@2: BOOST_SERIALIZATION_DECL(void const *) williamr@2: boost::serialization::void_downcast( williamr@2: const extended_type_info & derived_type, williamr@2: const extended_type_info & base_type, williamr@2: const void * t, williamr@2: bool top williamr@2: ); williamr@2: // each derived class must re-implement these; williamr@2: virtual void const * upcast(void const * t) const = 0; williamr@2: virtual void const * downcast(void const * t) const = 0; williamr@2: // Data members williamr@2: extended_type_info const & m_derived_type; williamr@2: extended_type_info const & m_base_type; williamr@2: protected: williamr@2: static void static_register(const void_caster *); williamr@2: public: williamr@2: // Constructor williamr@2: void_caster( williamr@2: extended_type_info const & derived_type_, williamr@2: extended_type_info const & base_type_ williamr@2: ); williamr@2: // predicate used to determine if this void caster includes williamr@2: // a particular eti * williamr@2: bool includes(const extended_type_info * eti) const; williamr@2: virtual ~void_caster(); williamr@2: private: williamr@2: // cw 8.3 requires this!! williamr@2: void_caster& operator=(void_caster const&); williamr@2: }; williamr@2: williamr@2: template williamr@2: class void_caster_primitive : williamr@2: public void_caster williamr@2: { williamr@2: virtual void const* downcast( void const * t ) const { williamr@2: Derived * d = boost::smart_cast( williamr@2: static_cast(t) williamr@2: ); williamr@2: return d; williamr@2: } williamr@2: virtual void const* upcast(void const * t) const { williamr@2: Base * b = boost::smart_cast( williamr@2: static_cast(t) williamr@2: ); williamr@2: return b; williamr@2: } williamr@2: williamr@2: public: williamr@2: static const void_caster_primitive instance; williamr@2: void_caster_primitive() BOOST_USED; williamr@2: }; williamr@2: williamr@2: template williamr@2: void_caster_primitive::void_caster_primitive() : williamr@2: void_caster( williamr@2: * type_info_implementation::type::get_instance(), williamr@2: * type_info_implementation::type::get_instance() williamr@2: ) williamr@2: { williamr@2: this->static_register(& instance); williamr@2: } williamr@2: williamr@2: // the purpose of this class is to create to->from and from->to instances williamr@2: // of void_caster_primitive for each related pair of types. This has to be williamr@2: // done a pre-execution time - hence the usage of static variable. williamr@2: template williamr@2: const void_caster_primitive williamr@2: void_caster_primitive::instance; williamr@2: williamr@2: } // void_cast_detail williamr@2: williamr@2: // Register a base/derived pair. This indicates that it is possible williamr@2: // to upcast a void pointer from Derived to Base and downcast a williamr@2: // void pointer from Base to Derived. Note bogus arguments to workaround williamr@2: // bug in msvc 6.0 williamr@2: template williamr@2: BOOST_DLLEXPORT williamr@2: inline const void_cast_detail::void_caster & void_cast_register( williamr@2: const Derived * dnull, williamr@2: const Base * bnull williamr@2: ) BOOST_USED; williamr@2: template williamr@2: BOOST_DLLEXPORT williamr@2: inline const void_cast_detail::void_caster & void_cast_register( williamr@2: const Derived * /* dnull = NULL */, williamr@2: const Base * /* bnull = NULL */ williamr@2: ){ williamr@2: return void_cast_detail::void_caster_primitive< williamr@2: const Derived, williamr@2: const Base williamr@2: >::instance; williamr@2: } williamr@2: williamr@2: } // namespace serialization williamr@2: } // namespace boost williamr@2: williamr@2: #include // pops abi_suffix.hpp pragmas williamr@2: williamr@2: #endif // BOOST_SERIALIZATION_VOID_CAST_HPP