Update contrib.
1 #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP
2 #define BOOST_SERIALIZATION_SHARED_PTR_HPP
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // shared_ptr.hpp: serialization for boost shared pointer
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)
17 // See http://www.boost.org for updates, documentation, and revision history.
21 #include <boost/config.hpp>
22 #include <boost/mpl/integral_c.hpp>
23 #include <boost/mpl/integral_c_tag.hpp>
25 #include <boost/detail/workaround.hpp>
26 #include <boost/shared_ptr.hpp>
27 #include <boost/throw_exception.hpp>
29 #include <boost/archive/archive_exception.hpp>
31 #include <boost/serialization/type_info_implementation.hpp>
32 #include <boost/serialization/split_free.hpp>
33 #include <boost/serialization/nvp.hpp>
34 #include <boost/serialization/version.hpp>
35 #include <boost/serialization/tracking.hpp>
36 #include <boost/static_assert.hpp>
38 #include <boost/serialization/void_cast_fwd.hpp>
40 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
41 // shared_ptr serialization traits
42 // version 1 to distinguish from boost 1.32 version. Note: we can only do this
43 // for a template when the compiler supports partial template specialization
45 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
47 namespace serialization{
49 struct version< ::boost::shared_ptr<T> > {
50 typedef mpl::integral_c_tag tag;
51 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
52 typedef BOOST_DEDUCED_TYPENAME mpl::int_<1> type;
54 typedef mpl::int_<1> type;
56 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
57 BOOST_STATIC_CONSTANT(unsigned int, value = 1);
59 BOOST_STATIC_CONSTANT(unsigned int, value = type::value);
62 // don't track shared pointers
64 struct tracking_level< ::boost::shared_ptr<T> > {
65 typedef mpl::integral_c_tag tag;
66 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
67 typedef BOOST_DEDUCED_TYPENAME mpl::int_< ::boost::serialization::track_never> type;
69 typedef mpl::int_< ::boost::serialization::track_never> type;
71 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
72 BOOST_STATIC_CONSTANT(int, value = ::boost::serialization::track_never);
74 BOOST_STATIC_CONSTANT(int, value = type::value);
78 #define BOOST_SERIALIZATION_SHARED_PTR(T)
80 // define macro to let users of these compilers do this
81 #define BOOST_SERIALIZATION_SHARED_PTR(T) \
82 BOOST_CLASS_VERSION( \
83 ::boost::shared_ptr< T >, \
86 BOOST_CLASS_TRACKING( \
87 ::boost::shared_ptr< T >, \
88 ::boost::serialization::track_never \
94 namespace serialization{
96 class extended_type_info;
100 struct null_deleter {
101 void operator()(void const *) const {}
104 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
105 // a common class for holding various types of shared pointers
107 class shared_ptr_helper {
108 typedef std::map<void*, shared_ptr<void> > collection_type;
109 typedef collection_type::const_iterator iterator_type;
110 // list of shared_pointers create accessable by raw pointer. This
111 // is used to "match up" shared pointers loaded at diferent
112 // points in the archive
113 collection_type m_pointers;
114 // return a void pointer to the most derived type
116 void * object_identifier(T * t) const {
117 const extended_type_info * true_type
118 = type_info_implementation<T>::type::get_derived_extended_type_info(*t);
119 // note:if this exception is thrown, be sure that derived pointer
120 // is either regsitered or exported.
121 if(NULL == true_type)
122 boost::throw_exception(
123 boost::archive::archive_exception(
124 boost::archive::archive_exception::unregistered_class
127 const boost::serialization::extended_type_info * this_type
128 = boost::serialization::type_info_implementation<T>::type::get_instance();
129 void * vp = void_downcast(*true_type, *this_type, t);
134 void reset(shared_ptr<T> & s, T * r){
139 // get pointer to the most derived object. This is effectively
140 // the object identifer
141 void * od = object_identifier(r);
143 iterator_type it = m_pointers.find(od);
145 if(it == m_pointers.end()){
147 m_pointers.insert(collection_type::value_type(od,s));
150 s = static_pointer_cast<T>((*it).second);
153 virtual ~shared_ptr_helper(){}
156 } // namespace detail
158 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
159 // utility function for creating/getting a helper - could be useful in general
160 // but shared_ptr is the only class (so far that needs it) and I don't have a
161 // convenient header to place it into.
162 template<class Archive, class H>
164 get_helper(Archive & ar){
165 extended_type_info * eti = type_info_implementation<H>::type::get_instance();
166 shared_ptr<void> sph;
167 ar.lookup_helper(eti, sph);
168 if(NULL == sph.get()){
169 sph = shared_ptr<H>(new H);
170 ar.insert_helper(eti, sph);
172 return * static_cast<H *>(sph.get());
175 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
176 // serialization for shared_ptr
178 template<class Archive, class T>
181 const boost::shared_ptr<T> &t,
182 const unsigned int /* file_version */
184 // The most common cause of trapping here would be serializing
185 // something like shared_ptr<int>. This occurs because int
186 // is never tracked by default. Wrap int in a trackable type
187 BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
188 const T * t_ptr = t.get();
189 ar << boost::serialization::make_nvp("px", t_ptr);
192 template<class Archive, class T>
195 boost::shared_ptr<T> &t,
196 const unsigned int file_version
198 // The most common cause of trapping here would be serializing
199 // something like shared_ptr<int>. This occurs because int
200 // is never tracked by default. Wrap int in a trackable type
201 BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
203 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
204 if(file_version < 1){
205 ar.register_type(static_cast<
206 boost_132::detail::sp_counted_base_impl<T *, boost::checked_deleter<T> > *
208 boost_132::shared_ptr<T> sp;
209 ar >> boost::serialization::make_nvp("px", sp.px);
210 ar >> boost::serialization::make_nvp("pn", sp.pn);
211 // got to keep the sps around so the sp.pns don't disappear
212 get_helper<Archive, boost_132::serialization::detail::shared_ptr_helper>(ar).append(sp);
218 ar >> boost::serialization::make_nvp("px", r);
220 get_helper<Archive, detail::shared_ptr_helper >(ar).reset(t,r);
223 template<class Archive, class T>
224 inline void serialize(
226 boost::shared_ptr<T> &t,
227 const unsigned int file_version
229 // correct shared_ptr serialization depends upon object tracking
232 boost::serialization::tracking_level<T>::value
233 != boost::serialization::track_never
235 boost::serialization::split_free(ar, t, file_version);
238 } // namespace serialization
241 #endif // BOOST_SERIALIZATION_SHARED_PTR_HPP