1#ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
2#define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
3
4// MS compatible compilers support #pragma once
5#if defined(_MSC_VER)
6# pragma once
7#endif
8
9/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10// shared_ptr_helper.hpp: serialization for boost shared pointern
11
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)
16
17// See http://www.boost.org for updates, documentation, and revision history.
18
19#include <map>
20#include <list>
21#include <utility>
22#include <cstddef> // NULL
23
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>
28
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>
34#include <boost/archive/detail/decl.hpp>
35
36#include <boost/archive/detail/abi_prefix.hpp> // must be the last headern
37
38namespace boost_132 {
39 template<class T> class shared_ptr;
40}
41namespace boost {
42namespace serialization {
43
44#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
45template<class Archive, template<class U> class SPT >
46void load(
47 Archive & ar,
48 SPT< class U > &t,
49 const unsigned int file_version
50);
51#endif
52
53/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
54// a common class for holding various types of shared pointers
55
56template<template<class T> class SPT>
57class shared_ptr_helper {
58 typedef std::map<
59 const void *, // address of object
60 SPT<const void> // address shared ptr to single instance
61 > object_shared_pointer_map;
62
63 // list of shared_pointers create accessable by raw pointer. This
64 // is used to "match up" shared pointers loaded at different
65 // points in the archive. Note, we delay construction until
66 // it is actually used since this is by default included as
67 // a "mix-in" even if shared_ptr isn't used.
68 object_shared_pointer_map * m_o_sp;
69
70 struct null_deleter {
71 void operator()(void const *) const {}
72 };
73
74#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
75|| defined(BOOST_MSVC) \
76|| defined(__SUNPRO_CC)
77public:
78#else
79 template<class Archive, class U>
80 friend void boost::serialization::load(
81 Archive & ar,
82 SPT< U > &t,
83 const unsigned int file_version
84 );
85#endif
86
87 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
88 // list of loaded pointers. This is used to be sure that the pointers
89 // stay around long enough to be "matched" with other pointers loaded
90 // by the same archive. These are created with a "null_deleter" so that
91 // when this list is destroyed - the underlaying raw pointers are not
92 // destroyed. This has to be done because the pointers are also held by
93 // new system which is disjoint from this set. This is implemented
94 // by a change in load_construct_data below. It makes this file suitable
95 // only for loading pointers into a 1.33 or later boost system.
96 std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
97 BOOST_ARCHIVE_DECL void
98 append(const boost_132::shared_ptr<const void> & t){
99 if(NULL == m_pointers_132)
100 m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >;
101 m_pointers_132->push_back(x: t);
102 }
103 #endif
104
105 struct non_polymorphic {
106 template<class U>
107 static const boost::serialization::extended_type_info *
108 get_object_type(U & ){
109 return & boost::serialization::singleton<
110 typename
111 boost::serialization::type_info_implementation< U >::type
112 >::get_const_instance();
113 }
114 };
115 struct polymorphic {
116 template<class U>
117 static const boost::serialization::extended_type_info *
118 get_object_type(U & u){
119 return boost::serialization::singleton<
120 typename
121 boost::serialization::type_info_implementation< U >::type
122 >::get_const_instance().get_derived_extended_type_info(u);
123 }
124 };
125
126public:
127 template<class T>
128 void reset(SPT< T > & s, T * t){
129 if(NULL == t){
130 s.reset();
131 return;
132 }
133 const boost::serialization::extended_type_info * this_type
134 = & boost::serialization::type_info_implementation< T >::type
135 ::get_const_instance();
136
137 // get pointer to the most derived object's eti. This is effectively
138 // the object type identifer
139 typedef typename mpl::if_<
140 is_polymorphic< T >,
141 polymorphic,
142 non_polymorphic
143 >::type type;
144
145 const boost::serialization::extended_type_info * true_type
146 = type::get_object_type(*t);
147
148 // note:if this exception is thrown, be sure that derived pointern
149 // is either registered or exported.
150 if(NULL == true_type)
151 boost::serialization::throw_exception(
152 e: boost::archive::archive_exception(
153 boost::archive::archive_exception::unregistered_class,
154 this_type->get_debug_info()
155 )
156 );
157 // get void pointer to the most derived type
158 // this uniquely identifies the object referred to
159 // oid = "object identifier"
160 const void * oid = void_downcast(
161 *true_type,
162 *this_type,
163 t
164 );
165 if(NULL == oid)
166 boost::serialization::throw_exception(
167 e: boost::archive::archive_exception(
168 boost::archive::archive_exception::unregistered_cast,
169 true_type->get_debug_info(),
170 this_type->get_debug_info()
171 )
172 );
173
174 // make tracking array if necessary
175 if(NULL == m_o_sp)
176 m_o_sp = new object_shared_pointer_map;
177
178 typename object_shared_pointer_map::iterator i = m_o_sp->find(oid);
179
180 // if it's a new object
181 if(i == m_o_sp->end()){
182 s.reset(t);
183 std::pair<typename object_shared_pointer_map::iterator, bool> result;
184 result = m_o_sp->insert(std::make_pair(oid, s));
185 BOOST_ASSERT(result.second);
186 }
187 // if the object has already been seen
188 else{
189 s = SPT<T>(i->second, t);
190 }
191 }
192
193 shared_ptr_helper() :
194 m_o_sp(NULL)
195 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
196 , m_pointers_132(NULL)
197 #endif
198 {}
199 virtual ~shared_ptr_helper(){
200 if(NULL != m_o_sp)
201 delete m_o_sp;
202 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
203 if(NULL != m_pointers_132)
204 delete m_pointers_132;
205 #endif
206 }
207};
208
209} // namespace serialization
210} // namespace boost
211
212#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
213
214#endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
215

source code of boost/boost/serialization/shared_ptr_helper.hpp