#ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP #define BOOST_SERIALIZATION_SHARED_PTR_132_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 2002 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) // See http://www.boost.org for updates, documentation, and revision history. // note: totally unadvised hack to gain access to private variables // in shared_ptr and shared_count. Unfortunately its the only way to // do this without changing shared_ptr and shared_count // the best we can do is to detect a conflict here #include #include #include #include #include #include #include #include // mark base class as an (uncreatable) base class BOOST_IS_ABSTRACT(boost_132::detail::sp_counted_base) ///////////////////////////////////////////////////////////// // Maintain a couple of lists of loaded shared pointers of the old previous // version (1.32) namespace boost_132 { namespace serialization { namespace detail { struct null_deleter { void operator()(void const *) const {} }; class shared_ptr_helper{ typedef std::list > collection_type; typedef collection_type::iterator iterator_type; // 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. collection_type m_pointers; public: void append(const boost_132::shared_ptr & t){ m_pointers.push_back(t); } virtual ~shared_ptr_helper(){} }; } // namespace detail } // namespace serialization } // namespace boost_132 ///////////////////////////////////////////////////////////// // sp_counted_base_impl serialization namespace boost { namespace serialization { template inline void serialize( Archive & /* ar */, boost_132::detail::sp_counted_base_impl & /* t */, const unsigned int /*file_version*/ ){ // register the relationship between each derived class // its polymorphic base boost::serialization::void_cast_register< boost_132::detail::sp_counted_base_impl, boost_132::detail::sp_counted_base >( static_cast *>(NULL), static_cast(NULL) ); } template inline void save_construct_data( Archive & ar, const boost_132::detail::sp_counted_base_impl *t, const unsigned int /* file_version */ ){ // variables used for construction ar << boost::serialization::make_nvp("ptr", t->ptr); } template inline void load_construct_data( Archive & ar, boost_132::detail::sp_counted_base_impl * t, const unsigned int /* file_version */ ){ P ptr_; ar >> boost::serialization::make_nvp("ptr", ptr_); // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); // placement // note: the original ::new... above is replaced by the one here. This one // creates all new objects with a null_deleter so that after the archive // is finished loading and the shared_ptrs are destroyed - the underlying // raw pointers are NOT deleted. This is necessary as they are used by the // new system as well. ::new(t)boost_132::detail::sp_counted_base_impl< P, boost_132::serialization::detail::null_deleter >( ptr_, boost_132::serialization::detail::null_deleter() ); // placement new // compensate for that fact that a new shared count always is // initialized with one. the add_ref_copy below will increment it // every time its serialized so without this adjustment // the use and weak counts will be off by one. t->use_count_ = 0; } } // serialization } // namespace boost ///////////////////////////////////////////////////////////// // shared_count serialization namespace boost { namespace serialization { template inline void save( Archive & ar, const boost_132::detail::shared_count &t, const unsigned int /* file_version */ ){ ar << boost::serialization::make_nvp("pi", t.pi_); } template inline void load( Archive & ar, boost_132::detail::shared_count &t, const unsigned int /* file_version */ ){ ar >> boost::serialization::make_nvp("pi", t.pi_); if(NULL != t.pi_) t.pi_->add_ref_copy(); } } // serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) ///////////////////////////////////////////////////////////// // implement serialization for shared_ptr namespace boost { namespace serialization { template inline void save( Archive & ar, const boost_132::shared_ptr &t, const unsigned int /* file_version */ ){ // only the raw pointer has to be saved // the ref count is maintained automatically as shared pointers are loaded ar.register_type(static_cast< boost_132::detail::sp_counted_base_impl > * >(NULL)); ar << boost::serialization::make_nvp("px", t.px); ar << boost::serialization::make_nvp("pn", t.pn); } template inline void load( Archive & ar, boost_132::shared_ptr &t, const unsigned int /* file_version */ ){ // only the raw pointer has to be saved // the ref count is maintained automatically as shared pointers are loaded ar.register_type(static_cast< boost_132::detail::sp_counted_base_impl > * >(NULL)); ar >> boost::serialization::make_nvp("px", t.px); ar >> boost::serialization::make_nvp("pn", t.pn); } template inline void serialize( Archive & ar, boost_132::shared_ptr &t, const unsigned int file_version ){ // correct shared_ptr serialization depends upon object tracking // being used. BOOST_STATIC_ASSERT( boost::serialization::tracking_level::value != boost::serialization::track_never ); boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost // note: change below uses null_deleter // This macro is used to export GUIDS for shared pointers to allow // the serialization system to export them properly. David Tonge #define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ typedef boost_132::detail::sp_counted_base_impl< \ T *, \ boost::checked_deleter< T > \ > __shared_ptr_ ## T; \ BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ BOOST_CLASS_EXPORT_GUID(T, K) \ /**/ #define BOOST_SHARED_POINTER_EXPORT(T) \ BOOST_SHARED_POINTER_EXPORT_GUID( \ T, \ BOOST_PP_STRINGIZE(T) \ ) \ /**/ #endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP