1 | #ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP |
2 | #define BOOST_SERIALIZATION_SHARED_PTR_132_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.hpp: serialization for boost shared pointer |
11 | |
12 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . |
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 | // note: totally unadvised hack to gain access to private variables |
20 | // in shared_ptr and shared_count. Unfortunately its the only way to |
21 | // do this without changing shared_ptr and shared_count |
22 | // the best we can do is to detect a conflict here |
23 | #include <boost/config.hpp> |
24 | |
25 | #include <list> |
26 | #include <cstddef> // NULL |
27 | |
28 | #include <boost/serialization/assume_abstract.hpp> |
29 | #include <boost/serialization/split_free.hpp> |
30 | #include <boost/serialization/nvp.hpp> |
31 | #include <boost/serialization/tracking.hpp> |
32 | #include <boost/serialization/void_cast.hpp> |
33 | |
34 | // mark base class as an (uncreatable) base class |
35 | #include <boost/serialization/detail/shared_ptr_132.hpp> |
36 | |
37 | ///////////////////////////////////////////////////////////// |
38 | // Maintain a couple of lists of loaded shared pointers of the old previous |
39 | // version (1.32) |
40 | |
41 | namespace boost_132 { |
42 | namespace serialization { |
43 | namespace detail { |
44 | |
45 | struct null_deleter { |
46 | void operator()(void const *) const {} |
47 | }; |
48 | |
49 | } // namespace detail |
50 | } // namespace serialization |
51 | } // namespace boost_132 |
52 | |
53 | ///////////////////////////////////////////////////////////// |
54 | // sp_counted_base_impl serialization |
55 | |
56 | namespace boost { |
57 | namespace serialization { |
58 | |
59 | template<class Archive, class P, class D> |
60 | inline void serialize( |
61 | Archive & /* ar */, |
62 | boost_132::detail::sp_counted_base_impl<P, D> & /* t */, |
63 | const unsigned int /*file_version*/ |
64 | ){ |
65 | // register the relationship between each derived class |
66 | // its polymorphic base |
67 | boost::serialization::void_cast_register< |
68 | boost_132::detail::sp_counted_base_impl<P, D>, |
69 | boost_132::detail::sp_counted_base |
70 | >( |
71 | static_cast<boost_132::detail::sp_counted_base_impl<P, D> *>(NULL), |
72 | static_cast<boost_132::detail::sp_counted_base *>(NULL) |
73 | ); |
74 | } |
75 | |
76 | template<class Archive, class P, class D> |
77 | inline void save_construct_data( |
78 | Archive & ar, |
79 | const |
80 | boost_132::detail::sp_counted_base_impl<P, D> *t, |
81 | const unsigned int /* file_version */ |
82 | ){ |
83 | // variables used for construction |
84 | ar << boost::serialization::make_nvp("ptr" , t->ptr); |
85 | } |
86 | |
87 | template<class Archive, class P, class D> |
88 | inline void load_construct_data( |
89 | Archive & ar, |
90 | boost_132::detail::sp_counted_base_impl<P, D> * t, |
91 | const unsigned int /* file_version */ |
92 | ){ |
93 | P ptr_; |
94 | ar >> boost::serialization::make_nvp("ptr" , ptr_); |
95 | // ::new(t)boost_132::detail::sp_counted_base_impl<P, D>(ptr_, D()); |
96 | // placement |
97 | // note: the original ::new... above is replaced by the one here. This one |
98 | // creates all new objects with a null_deleter so that after the archive |
99 | // is finished loading and the shared_ptrs are destroyed - the underlying |
100 | // raw pointers are NOT deleted. This is necessary as they are used by the |
101 | // new system as well. |
102 | ::new(t)boost_132::detail::sp_counted_base_impl< |
103 | P, |
104 | boost_132::serialization::detail::null_deleter |
105 | >( |
106 | ptr_, boost_132::serialization::detail::null_deleter() |
107 | ); // placement new |
108 | // compensate for that fact that a new shared count always is |
109 | // initialized with one. the add_ref_copy below will increment it |
110 | // every time its serialized so without this adjustment |
111 | // the use and weak counts will be off by one. |
112 | t->use_count_ = 0; |
113 | } |
114 | |
115 | } // serialization |
116 | } // namespace boost |
117 | |
118 | ///////////////////////////////////////////////////////////// |
119 | // shared_count serialization |
120 | |
121 | namespace boost { |
122 | namespace serialization { |
123 | |
124 | template<class Archive> |
125 | inline void save( |
126 | Archive & ar, |
127 | const boost_132::detail::shared_count &t, |
128 | const unsigned int /* file_version */ |
129 | ){ |
130 | ar << boost::serialization::make_nvp(name: "pi" , t: t.pi_); |
131 | } |
132 | |
133 | template<class Archive> |
134 | inline void load( |
135 | Archive & ar, |
136 | boost_132::detail::shared_count &t, |
137 | const unsigned int /* file_version */ |
138 | ){ |
139 | ar >> boost::serialization::make_nvp(name: "pi" , t&: t.pi_); |
140 | if(NULL != t.pi_) |
141 | t.pi_->add_ref_copy(); |
142 | } |
143 | |
144 | } // serialization |
145 | } // namespace boost |
146 | |
147 | BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) |
148 | |
149 | ///////////////////////////////////////////////////////////// |
150 | // implement serialization for shared_ptr< T > |
151 | |
152 | namespace boost { |
153 | namespace serialization { |
154 | |
155 | template<class Archive, class T> |
156 | inline void save( |
157 | Archive & ar, |
158 | const boost_132::shared_ptr< T > &t, |
159 | const unsigned int /* file_version */ |
160 | ){ |
161 | // only the raw pointer has to be saved |
162 | // the ref count is maintained automatically as shared pointers are loaded |
163 | ar.register_type(static_cast< |
164 | boost_132::detail::sp_counted_base_impl<T *, boost::checked_deleter< T > > * |
165 | >(NULL)); |
166 | ar << boost::serialization::make_nvp("px" , t.px); |
167 | ar << boost::serialization::make_nvp("pn" , t.pn); |
168 | } |
169 | |
170 | template<class Archive, class T> |
171 | inline void load( |
172 | Archive & ar, |
173 | boost_132::shared_ptr< T > &t, |
174 | const unsigned int /* file_version */ |
175 | ){ |
176 | // only the raw pointer has to be saved |
177 | // the ref count is maintained automatically as shared pointers are loaded |
178 | ar.register_type(static_cast< |
179 | boost_132::detail::sp_counted_base_impl<T *, boost::checked_deleter< T > > * |
180 | >(NULL)); |
181 | ar >> boost::serialization::make_nvp("px" , t.px); |
182 | ar >> boost::serialization::make_nvp("pn" , t.pn); |
183 | } |
184 | |
185 | template<class Archive, class T> |
186 | inline void serialize( |
187 | Archive & ar, |
188 | boost_132::shared_ptr< T > &t, |
189 | const unsigned int file_version |
190 | ){ |
191 | // correct shared_ptr serialization depends upon object tracking |
192 | // being used. |
193 | BOOST_STATIC_ASSERT( |
194 | boost::serialization::tracking_level< T >::value |
195 | != boost::serialization::track_never |
196 | ); |
197 | boost::serialization::split_free(ar, t, file_version); |
198 | } |
199 | |
200 | } // serialization |
201 | } // namespace boost |
202 | |
203 | // note: change below uses null_deleter |
204 | // This macro is used to export GUIDS for shared pointers to allow |
205 | // the serialization system to export them properly. David Tonge |
206 | #define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ |
207 | typedef boost_132::detail::sp_counted_base_impl< \ |
208 | T *, \ |
209 | boost::checked_deleter< T > \ |
210 | > __shared_ptr_ ## T; \ |
211 | BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ |
212 | BOOST_CLASS_EXPORT_GUID(T, K) \ |
213 | /**/ |
214 | |
215 | #define BOOST_SHARED_POINTER_EXPORT(T) \ |
216 | BOOST_SHARED_POINTER_EXPORT_GUID( \ |
217 | T, \ |
218 | BOOST_PP_STRINGIZE(T) \ |
219 | ) \ |
220 | /**/ |
221 | |
222 | #endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP |
223 | |