#ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP #define BOOST_ARCHIVE_SHARED_PTR_HELPER_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 // shared_ptr.hpp: serialization for boost shared pointer // (C) Copyright 2004 Robert Ramey and Martin Ecker // 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) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include namespace boost_132 { template class shared_ptr; } namespace boost { template class shared_ptr; namespace serialization { class extended_type_info; template inline void load( Archive & ar, boost::shared_ptr &t, const unsigned int file_version ); } namespace archive{ namespace detail { struct null_deleter { void operator()(void const *) const {} }; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // a common class for holding various types of shared pointers class shared_ptr_helper { typedef std::map > collection_type; typedef collection_type::const_iterator iterator_type; // list of shared_pointers create accessable by raw pointer. This // is used to "match up" shared pointers loaded at different // points in the archive. Note, we delay construction until // it is actually used since this is by default included as // a "mix-in" even if shared_ptr isn't used. collection_type * m_pointers; #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else template friend inline void boost::serialization::load( Archive & ar, boost::shared_ptr &t, const unsigned int file_version ); #endif // list of loaded pointers. This is used to be sure that the pointers // stay around long enough to be "matched" with other pointers loaded // by the same archive. These are created with a "null_deleter" so that // when this list is destroyed - the underlaying raw pointers are not // destroyed. This has to be done because the pointers are also held by // new system which is disjoint from this set. This is implemented // by a change in load_construct_data below. It makes this file suitable // only for loading pointers into a 1.33 or later boost system. std::list > * m_pointers_132; // return a void pointer to the most derived type template void * object_identifier(T * t) const { const boost::serialization::extended_type_info * true_type = boost::serialization::type_info_implementation::type ::get_derived_extended_type_info(*t); // note:if this exception is thrown, be sure that derived pointer // is either registered or exported. if(NULL == true_type) boost::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::unregistered_class ) ); const boost::serialization::extended_type_info * this_type = boost::serialization::type_info_implementation::type::get_instance(); void * vp = void_downcast(*true_type, *this_type, t); return vp; } template void reset(shared_ptr & s, T * r){ if(NULL == r){ s.reset(); return; } // get pointer to the most derived object. This is effectively // the object identifer void * od = object_identifier(r); if(NULL == m_pointers) m_pointers = new collection_type; iterator_type it = m_pointers->find(od); if(it == m_pointers->end()){ s.reset(r); m_pointers->insert(collection_type::value_type(od,s)); } else{ s = static_pointer_cast((*it).second); } } void append(const boost_132::shared_ptr & t){ if(NULL == m_pointers_132) m_pointers_132 = new std::list >; m_pointers_132->push_back(t); } public: shared_ptr_helper() : m_pointers(NULL), m_pointers_132(NULL) {} ~shared_ptr_helper(){ if(NULL != m_pointers) delete m_pointers; if(NULL != m_pointers_132) delete m_pointers_132; } }; } // namespace detail } // namespace serialization } // namespace boost #endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP