1 #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP
2 #define BOOST_SERIALIZATION_SHARED_PTR_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 2004 Robert Ramey and Martin Ecker
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 <cstddef> // NULL
20 #include <memory>
21
22 #include <boost/config.hpp>
23 #include <boost/mpl/integral_c.hpp>
24 #include <boost/mpl/integral_c_tag.hpp>
25
26 #include <boost/detail/workaround.hpp>
27 #include <boost/shared_ptr.hpp>
28
29 #include <boost/serialization/shared_ptr_helper.hpp>
30 #include <boost/serialization/split_free.hpp>
31 #include <boost/serialization/nvp.hpp>
32 #include <boost/serialization/version.hpp>
33 #include <boost/serialization/tracking.hpp>
34
35 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
36 // boost:: shared_ptr serialization traits
37 // version 1 to distinguish from boost 1.32 version. Note: we can only do this
38 // for a template when the compiler supports partial template specialization
39
40 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
41 namespace boost {
42 namespace serialization{
43 template<class T>
44 struct version< ::boost::shared_ptr< T > > {
45 typedef mpl::integral_c_tag tag;
46 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
47 typedef typename mpl::int_<1> type;
48 #else
49 typedef mpl::int_<1> type;
50 #endif
51 BOOST_STATIC_CONSTANT(int, value = type::value);
52 };
53 // don't track shared pointers
54 template<class T>
55 struct tracking_level< ::boost::shared_ptr< T > > {
56 typedef mpl::integral_c_tag tag;
57 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
58 typedef typename mpl::int_< ::boost::serialization::track_never> type;
59 #else
60 typedef mpl::int_< ::boost::serialization::track_never> type;
61 #endif
62 BOOST_STATIC_CONSTANT(int, value = type::value);
63 };
64 }}
65 #define BOOST_SERIALIZATION_SHARED_PTR(T)
66 #else
67 // define macro to let users of these compilers do this
68 #define BOOST_SERIALIZATION_SHARED_PTR(T) \
69 BOOST_CLASS_VERSION( \
70 ::boost::shared_ptr< T >, \
71 1 \
72 ) \
73 BOOST_CLASS_TRACKING( \
74 ::boost::shared_ptr< T >, \
75 ::boost::serialization::track_never \
76 ) \
77 /**/
78 #endif
79
80 namespace boost {
81 namespace serialization{
82
83 struct null_deleter {
operator ()boost::serialization::null_deleter84 void operator()(void const *) const {}
85 };
86
87 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
88 // serialization for boost::shared_ptr
89
90 // Using a constant means that all shared pointers are held in the same set.
91 // Thus we detect handle multiple pointers to the same value instances
92 // in the archive.
93 void * const shared_ptr_helper_id = 0;
94
95 template<class Archive, class T>
save(Archive & ar,const boost::shared_ptr<T> & t,const unsigned int)96 inline void save(
97 Archive & ar,
98 const boost::shared_ptr< T > &t,
99 const unsigned int /* file_version */
100 ){
101 // The most common cause of trapping here would be serializing
102 // something like shared_ptr<int>. This occurs because int
103 // is never tracked by default. Wrap int in a trackable type
104 BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
105 const T * t_ptr = t.get();
106 ar << boost::serialization::make_nvp("px", t_ptr);
107 }
108
109 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
110 template<class Archive, class T>
load(Archive & ar,boost::shared_ptr<T> & t,const unsigned int file_version)111 inline void load(
112 Archive & ar,
113 boost::shared_ptr< T > &t,
114 const unsigned int file_version
115 ){
116 // something like shared_ptr<int>. This occurs because int
117 // is never tracked by default. Wrap int in a trackable type
118 BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
119 T* r;
120 if(file_version < 1){
121 ar.register_type(static_cast<
122 boost_132::detail::sp_counted_base_impl<T *, null_deleter > *
123 >(NULL));
124 boost_132::shared_ptr< T > sp;
125 ar >> boost::serialization::make_nvp("px", sp.px);
126 ar >> boost::serialization::make_nvp("pn", sp.pn);
127 // got to keep the sps around so the sp.pns don't disappear
128 boost::serialization::shared_ptr_helper<boost::shared_ptr> & h =
129 ar.template get_helper< shared_ptr_helper<boost::shared_ptr> >(
130 shared_ptr_helper_id
131 );
132 h.append(sp);
133 r = sp.get();
134 }
135 else{
136 ar >> boost::serialization::make_nvp("px", r);
137 }
138 shared_ptr_helper<boost::shared_ptr> & h =
139 ar.template get_helper<shared_ptr_helper<boost::shared_ptr> >(
140 shared_ptr_helper_id
141 );
142 h.reset(t,r);
143 }
144 #else
145
146 template<class Archive, class T>
load(Archive & ar,boost::shared_ptr<T> & t,const unsigned int)147 inline void load(
148 Archive & ar,
149 boost::shared_ptr< T > &t,
150 const unsigned int /*file_version*/
151 ){
152 // The most common cause of trapping here would be serializing
153 // something like shared_ptr<int>. This occurs because int
154 // is never tracked by default. Wrap int in a trackable type
155 BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
156 T* r;
157 ar >> boost::serialization::make_nvp("px", r);
158
159 boost::serialization::shared_ptr_helper<boost::shared_ptr> & h =
160 ar.template get_helper<shared_ptr_helper<boost::shared_ptr> >(
161 shared_ptr_helper_id
162 );
163 h.reset(t,r);
164 }
165 #endif
166
167 template<class Archive, class T>
serialize(Archive & ar,boost::shared_ptr<T> & t,const unsigned int file_version)168 inline void serialize(
169 Archive & ar,
170 boost::shared_ptr< T > &t,
171 const unsigned int file_version
172 ){
173 // correct shared_ptr serialization depends upon object tracking
174 // being used.
175 BOOST_STATIC_ASSERT(
176 boost::serialization::tracking_level< T >::value
177 != boost::serialization::track_never
178 );
179 boost::serialization::split_free(ar, t, file_version);
180 }
181
182 } // namespace serialization
183 } // namespace boost
184
185 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
186 // std::shared_ptr serialization traits
187 // version 1 to distinguish from boost 1.32 version. Note: we can only do this
188 // for a template when the compiler supports partial template specialization
189
190 #ifndef BOOST_NO_CXX11_SMART_PTR
191 #include <boost/static_assert.hpp>
192
193 // note: we presume that any compiler/library which supports C++11
194 // std::pointers also supports template partial specialization
195 // trap here if such presumption were to turn out to wrong!!!
196 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
197 BOOST_STATIC_ASSERT(false);
198 #endif
199
200 namespace boost {
201 namespace serialization{
202 template<class T>
203 struct version< ::std::shared_ptr< T > > {
204 typedef mpl::integral_c_tag tag;
205 typedef mpl::int_<1> type;
206 BOOST_STATIC_CONSTANT(int, value = type::value);
207 };
208 // don't track shared pointers
209 template<class T>
210 struct tracking_level< ::std::shared_ptr< T > > {
211 typedef mpl::integral_c_tag tag;
212 typedef mpl::int_< ::boost::serialization::track_never> type;
213 BOOST_STATIC_CONSTANT(int, value = type::value);
214 };
215 }}
216 // the following just keeps older programs from breaking
217 #define BOOST_SERIALIZATION_SHARED_PTR(T)
218
219 namespace boost {
220 namespace serialization{
221
222 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
223 // serialization for std::shared_ptr
224
225 template<class Archive, class T>
save(Archive & ar,const std::shared_ptr<T> & t,const unsigned int)226 inline void save(
227 Archive & ar,
228 const std::shared_ptr< T > &t,
229 const unsigned int /* file_version */
230 ){
231 // The most common cause of trapping here would be serializing
232 // something like shared_ptr<int>. This occurs because int
233 // is never tracked by default. Wrap int in a trackable type
234 BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
235 const T * t_ptr = t.get();
236 ar << boost::serialization::make_nvp("px", t_ptr);
237 }
238
239 template<class Archive, class T>
load(Archive & ar,std::shared_ptr<T> & t,const unsigned int)240 inline void load(
241 Archive & ar,
242 std::shared_ptr< T > &t,
243 const unsigned int /*file_version*/
244 ){
245 // The most common cause of trapping here would be serializing
246 // something like shared_ptr<int>. This occurs because int
247 // is never tracked by default. Wrap int in a trackable type
248 BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
249 T* r;
250 ar >> boost::serialization::make_nvp("px", r);
251 //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load;
252 boost::serialization::shared_ptr_helper<std::shared_ptr> & h =
253 ar.template get_helper<
254 shared_ptr_helper<std::shared_ptr>
255 >(
256 shared_ptr_helper_id
257 );
258 h.reset(t,r);
259 }
260
261 template<class Archive, class T>
serialize(Archive & ar,std::shared_ptr<T> & t,const unsigned int file_version)262 inline void serialize(
263 Archive & ar,
264 std::shared_ptr< T > &t,
265 const unsigned int file_version
266 ){
267 // correct shared_ptr serialization depends upon object tracking
268 // being used.
269 BOOST_STATIC_ASSERT(
270 boost::serialization::tracking_level< T >::value
271 != boost::serialization::track_never
272 );
273 boost::serialization::split_free(ar, t, file_version);
274 }
275
276 } // namespace serialization
277 } // namespace boost
278
279 #endif // BOOST_NO_CXX11_SMART_PTR
280
281 #endif // BOOST_SERIALIZATION_SHARED_PTR_HPP
282