1 #ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
2 #define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
4 // MS compatible compilers support #pragma once
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // shared_ptr_helper.hpp: serialization for boost shared pointern
12 // (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo
13 // Use, modification and distribution is subject to the Boost Software
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
17 // See http://www.boost.org for updates, documentation, and revision history.
22 #include <cstddef> // NULL
24 #include <boost/config.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include <boost/type_traits/is_polymorphic.hpp>
27 #include <boost/mpl/if.hpp>
29 #include <boost/serialization/singleton.hpp>
30 #include <boost/serialization/extended_type_info.hpp>
31 #include <boost/serialization/throw_exception.hpp>
32 #include <boost/serialization/type_info_implementation.hpp>
33 #include <boost/archive/archive_exception.hpp>
36 template<class T> class shared_ptr;
39 namespace serialization {
41 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
42 template<class Archive, template<class U> class SPT >
46 const unsigned int file_version
50 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
51 // a common class for holding various types of shared pointers
53 template<template<class T> class SPT>
54 class shared_ptr_helper {
56 const void *, // address of object
57 SPT<const void> // address shared ptr to single instance
58 > object_shared_pointer_map;
60 // list of shared_pointers create accessable by raw pointer. This
61 // is used to "match up" shared pointers loaded at different
62 // points in the archive. Note, we delay construction until
63 // it is actually used since this is by default included as
64 // a "mix-in" even if shared_ptr isn't used.
65 object_shared_pointer_map * m_o_sp;
68 void operator()(void const *) const {}
71 #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
72 || defined(BOOST_MSVC) \
73 || defined(__SUNPRO_CC)
76 template<class Archive, class U>
77 friend void boost::serialization::load(
80 const unsigned int file_version
84 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
85 // list of loaded pointers. This is used to be sure that the pointers
86 // stay around long enough to be "matched" with other pointers loaded
87 // by the same archive. These are created with a "null_deleter" so that
88 // when this list is destroyed - the underlaying raw pointers are not
89 // destroyed. This has to be done because the pointers are also held by
90 // new system which is disjoint from this set. This is implemented
91 // by a change in load_construct_data below. It makes this file suitable
92 // only for loading pointers into a 1.33 or later boost system.
93 std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
95 append(const boost_132::shared_ptr<const void> & t){
96 if(NULL == m_pointers_132)
97 m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >;
98 m_pointers_132->push_back(t);
102 struct non_polymorphic {
104 static const boost::serialization::extended_type_info *
105 get_object_type(U & ){
106 return & boost::serialization::singleton<
108 boost::serialization::type_info_implementation< U >::type
109 >::get_const_instance();
114 static const boost::serialization::extended_type_info *
115 get_object_type(U & u){
116 return boost::serialization::singleton<
118 boost::serialization::type_info_implementation< U >::type
119 >::get_const_instance().get_derived_extended_type_info(u);
125 void reset(SPT< T > & s, T * t){
130 const boost::serialization::extended_type_info * this_type
131 = & boost::serialization::type_info_implementation< T >::type
132 ::get_const_instance();
134 // get pointer to the most derived object's eti. This is effectively
135 // the object type identifer
136 typedef typename mpl::if_<
142 const boost::serialization::extended_type_info * true_type
143 = type::get_object_type(*t);
145 // note:if this exception is thrown, be sure that derived pointern
146 // is either registered or exported.
147 if(NULL == true_type)
148 boost::serialization::throw_exception(
149 boost::archive::archive_exception(
150 boost::archive::archive_exception::unregistered_class,
151 this_type->get_debug_info()
154 // get void pointer to the most derived type
155 // this uniquely identifies the object referred to
156 // oid = "object identifier"
157 const void * oid = void_downcast(
163 boost::serialization::throw_exception(
164 boost::archive::archive_exception(
165 boost::archive::archive_exception::unregistered_cast,
166 true_type->get_debug_info(),
167 this_type->get_debug_info()
171 // make tracking array if necessary
173 m_o_sp = new object_shared_pointer_map;
175 typename object_shared_pointer_map::iterator i = m_o_sp->find(oid);
177 // if it's a new object
178 if(i == m_o_sp->end()){
180 std::pair<typename object_shared_pointer_map::iterator, bool> result;
181 result = m_o_sp->insert(std::make_pair(oid, s));
182 BOOST_ASSERT(result.second);
184 // if the object has already been seen
186 s = SPT<T>(i->second, t);
190 shared_ptr_helper() :
192 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
193 , m_pointers_132(NULL)
196 virtual ~shared_ptr_helper(){
199 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
200 if(NULL != m_pointers_132)
201 delete m_pointers_132;
206 } // namespace serialization
209 #endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP