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