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
80namespace boost {
81namespace serialization{
82
83struct null_deleter {
84 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.
93void * const shared_ptr_helper_id = 0;
94
95template<class Archive, class T>
96inline 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
110template<class Archive, class T>
111inline 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(t: 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
146template<class Archive, class T>
147inline 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
167template<class Archive, class T>
168inline 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
200namespace boost {
201namespace 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
219namespace boost {
220namespace serialization{
221
222/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
223// serialization for std::shared_ptr
224
225template<class Archive, class T>
226inline 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
239template<class Archive, class T>
240inline 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
261template<class Archive, class T>
262inline 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

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