Chris@102: #ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP Chris@102: #define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP Chris@102: Chris@102: // MS compatible compilers support #pragma once Chris@102: #if defined(_MSC_VER) Chris@102: # pragma once Chris@102: #endif Chris@102: Chris@102: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@102: // shared_ptr_helper.hpp: serialization for boost shared pointern Chris@102: Chris@102: // (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo Chris@102: // Use, modification and distribution is subject to the Boost Software Chris@102: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@102: // http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: // See http://www.boost.org for updates, documentation, and revision history. Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include // NULL Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include // must be the last headern Chris@102: Chris@102: namespace boost_132 { Chris@102: template class shared_ptr; Chris@102: } Chris@102: namespace boost { Chris@102: namespace serialization { Chris@102: Chris@102: #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS Chris@102: template class SPT > Chris@102: void load( Chris@102: Archive & ar, Chris@102: SPT< class U > &t, Chris@102: const unsigned int file_version Chris@102: ); Chris@102: #endif Chris@102: Chris@102: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@102: // a common class for holding various types of shared pointers Chris@102: Chris@102: template class SPT> Chris@102: class shared_ptr_helper { Chris@102: typedef std::map< Chris@102: const void *, // address of object Chris@102: SPT // address shared ptr to single instance Chris@102: > object_shared_pointer_map; Chris@102: Chris@102: // list of shared_pointers create accessable by raw pointer. This Chris@102: // is used to "match up" shared pointers loaded at different Chris@102: // points in the archive. Note, we delay construction until Chris@102: // it is actually used since this is by default included as Chris@102: // a "mix-in" even if shared_ptr isn't used. Chris@102: object_shared_pointer_map * m_o_sp; Chris@102: Chris@102: struct null_deleter { Chris@102: void operator()(void const *) const {} Chris@102: }; Chris@102: Chris@102: #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(BOOST_MSVC) Chris@102: public: Chris@102: #else Chris@102: template Chris@102: friend void boost::serialization::load( Chris@102: Archive & ar, Chris@102: SPT< U > &t, Chris@102: const unsigned int file_version Chris@102: ); Chris@102: #endif Chris@102: Chris@102: #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP Chris@102: // list of loaded pointers. This is used to be sure that the pointers Chris@102: // stay around long enough to be "matched" with other pointers loaded Chris@102: // by the same archive. These are created with a "null_deleter" so that Chris@102: // when this list is destroyed - the underlaying raw pointers are not Chris@102: // destroyed. This has to be done because the pointers are also held by Chris@102: // new system which is disjoint from this set. This is implemented Chris@102: // by a change in load_construct_data below. It makes this file suitable Chris@102: // only for loading pointers into a 1.33 or later boost system. Chris@102: std::list > * m_pointers_132; Chris@102: BOOST_ARCHIVE_DECL(void) Chris@102: append(const boost_132::shared_ptr & t){ Chris@102: if(NULL == m_pointers_132) Chris@102: m_pointers_132 = new std::list >; Chris@102: m_pointers_132->push_back(t); Chris@102: } Chris@102: #endif Chris@102: Chris@102: struct non_polymorphic { Chris@102: template Chris@102: static const boost::serialization::extended_type_info * Chris@102: get_object_type(U & ){ Chris@102: return & boost::serialization::singleton< Chris@102: typename Chris@102: boost::serialization::type_info_implementation< U >::type Chris@102: >::get_const_instance(); Chris@102: } Chris@102: }; Chris@102: struct polymorphic { Chris@102: template Chris@102: static const boost::serialization::extended_type_info * Chris@102: get_object_type(U & u){ Chris@102: return boost::serialization::singleton< Chris@102: typename Chris@102: boost::serialization::type_info_implementation< U >::type Chris@102: >::get_const_instance().get_derived_extended_type_info(u); Chris@102: } Chris@102: }; Chris@102: Chris@102: public: Chris@102: template Chris@102: void reset(SPT< T > & s, T * t){ Chris@102: if(NULL == t){ Chris@102: s.reset(); Chris@102: return; Chris@102: } Chris@102: const boost::serialization::extended_type_info * this_type Chris@102: = & boost::serialization::type_info_implementation< T >::type Chris@102: ::get_const_instance(); Chris@102: Chris@102: // get pointer to the most derived object's eti. This is effectively Chris@102: // the object type identifer Chris@102: typedef typename mpl::if_< Chris@102: is_polymorphic< T >, Chris@102: polymorphic, Chris@102: non_polymorphic Chris@102: >::type type; Chris@102: Chris@102: const boost::serialization::extended_type_info * true_type Chris@102: = type::get_object_type(*t); Chris@102: Chris@102: // note:if this exception is thrown, be sure that derived pointern Chris@102: // is either registered or exported. Chris@102: if(NULL == true_type) Chris@102: boost::serialization::throw_exception( Chris@102: boost::archive::archive_exception( Chris@102: boost::archive::archive_exception::unregistered_class, Chris@102: this_type->get_debug_info() Chris@102: ) Chris@102: ); Chris@102: // get void pointer to the most derived type Chris@102: // this uniquely identifies the object referred to Chris@102: // oid = "object identifier" Chris@102: const void * oid = void_downcast( Chris@102: *true_type, Chris@102: *this_type, Chris@102: t Chris@102: ); Chris@102: if(NULL == oid) Chris@102: boost::serialization::throw_exception( Chris@102: boost::archive::archive_exception( Chris@102: boost::archive::archive_exception::unregistered_cast, Chris@102: true_type->get_debug_info(), Chris@102: this_type->get_debug_info() Chris@102: ) Chris@102: ); Chris@102: Chris@102: // make tracking array if necessary Chris@102: if(NULL == m_o_sp) Chris@102: m_o_sp = new object_shared_pointer_map; Chris@102: Chris@102: typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); Chris@102: Chris@102: // if it's a new object Chris@102: if(i == m_o_sp->end()){ Chris@102: s.reset(t); Chris@102: std::pair result; Chris@102: result = m_o_sp->insert(std::make_pair(oid, s)); Chris@102: BOOST_ASSERT(result.second); Chris@102: } Chris@102: // if the object has already been seen Chris@102: else{ Chris@102: s = SPT(i->second, t); Chris@102: } Chris@102: } Chris@102: Chris@102: shared_ptr_helper() : Chris@102: m_o_sp(NULL) Chris@102: #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP Chris@102: , m_pointers_132(NULL) Chris@102: #endif Chris@102: {} Chris@102: virtual ~shared_ptr_helper(){ Chris@102: if(NULL != m_o_sp) Chris@102: delete m_o_sp; Chris@102: #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP Chris@102: if(NULL != m_pointers_132) Chris@102: delete m_pointers_132; Chris@102: #endif Chris@102: } Chris@102: }; Chris@102: Chris@102: } // namespace serialization Chris@102: } // namespace boost Chris@102: Chris@102: #include // pops abi_suffix.hpp pragmas Chris@102: Chris@102: #endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP