comparison DEPENDENCIES/generic/include/boost/serialization/shared_ptr_helper.hpp @ 102:f46d142149f5

Whoops, finish that update
author Chris Cannam
date Mon, 07 Sep 2015 11:13:41 +0100
parents
children
comparison
equal deleted inserted replaced
101:c530137014c0 102:f46d142149f5
1 #ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP
2 #define BOOST_SERIALIZATION_SHARED_PTR_HELPER_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_helper.hpp: serialization for boost shared pointern
11
12 // (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo
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 <map>
20 #include <list>
21 #include <utility>
22 #include <cstddef> // NULL
23
24 #include <boost/config.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include <boost/type_traits/is_polymorphic.hpp>
27 #include <boost/mpl/if.hpp>
28
29 #include <boost/serialization/singleton.hpp>
30 #include <boost/serialization/extended_type_info.hpp>
31 #include <boost/serialization/throw_exception.hpp>
32 #include <boost/serialization/type_info_implementation.hpp>
33 #include <boost/archive/archive_exception.hpp>
34 #include <boost/archive/detail/decl.hpp>
35
36 #include <boost/archive/detail/abi_prefix.hpp> // must be the last headern
37
38 namespace boost_132 {
39 template<class T> class shared_ptr;
40 }
41 namespace boost {
42 namespace serialization {
43
44 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
45 template<class Archive, template<class U> class SPT >
46 void load(
47 Archive & ar,
48 SPT< class U > &t,
49 const unsigned int file_version
50 );
51 #endif
52
53 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
54 // a common class for holding various types of shared pointers
55
56 template<template<class T> class SPT>
57 class shared_ptr_helper {
58 typedef std::map<
59 const void *, // address of object
60 SPT<void> // address shared ptr to single instance
61 > object_shared_pointer_map;
62
63 // list of shared_pointers create accessable by raw pointer. This
64 // is used to "match up" shared pointers loaded at different
65 // points in the archive. Note, we delay construction until
66 // it is actually used since this is by default included as
67 // a "mix-in" even if shared_ptr isn't used.
68 object_shared_pointer_map * m_o_sp;
69
70 struct null_deleter {
71 void operator()(void const *) const {}
72 };
73
74 #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(BOOST_MSVC)
75 public:
76 #else
77 template<class Archive, class U>
78 friend void boost::serialization::load(
79 Archive & ar,
80 SPT< U > &t,
81 const unsigned int file_version
82 );
83 #endif
84
85 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
86 // list of loaded pointers. This is used to be sure that the pointers
87 // stay around long enough to be "matched" with other pointers loaded
88 // by the same archive. These are created with a "null_deleter" so that
89 // when this list is destroyed - the underlaying raw pointers are not
90 // destroyed. This has to be done because the pointers are also held by
91 // new system which is disjoint from this set. This is implemented
92 // by a change in load_construct_data below. It makes this file suitable
93 // only for loading pointers into a 1.33 or later boost system.
94 std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
95 BOOST_ARCHIVE_DECL(void)
96 append(const boost_132::shared_ptr<const void> & t){
97 if(NULL == m_pointers_132)
98 m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >;
99 m_pointers_132->push_back(t);
100 }
101 #endif
102
103 struct non_polymorphic {
104 template<class U>
105 static const boost::serialization::extended_type_info *
106 get_object_type(U & ){
107 return & boost::serialization::singleton<
108 typename
109 boost::serialization::type_info_implementation< U >::type
110 >::get_const_instance();
111 }
112 };
113 struct polymorphic {
114 template<class U>
115 static const boost::serialization::extended_type_info *
116 get_object_type(U & u){
117 return boost::serialization::singleton<
118 typename
119 boost::serialization::type_info_implementation< U >::type
120 >::get_const_instance().get_derived_extended_type_info(u);
121 }
122 };
123
124 public:
125 template<class T>
126 void reset(SPT< T > & s, T * t){
127 if(NULL == t){
128 s.reset();
129 return;
130 }
131 const boost::serialization::extended_type_info * this_type
132 = & boost::serialization::type_info_implementation< T >::type
133 ::get_const_instance();
134
135 // get pointer to the most derived object's eti. This is effectively
136 // the object type identifer
137 typedef typename mpl::if_<
138 is_polymorphic< T >,
139 polymorphic,
140 non_polymorphic
141 >::type type;
142
143 const boost::serialization::extended_type_info * true_type
144 = type::get_object_type(*t);
145
146 // note:if this exception is thrown, be sure that derived pointern
147 // is either registered or exported.
148 if(NULL == true_type)
149 boost::serialization::throw_exception(
150 boost::archive::archive_exception(
151 boost::archive::archive_exception::unregistered_class,
152 this_type->get_debug_info()
153 )
154 );
155 // get void pointer to the most derived type
156 // this uniquely identifies the object referred to
157 // oid = "object identifier"
158 const void * oid = void_downcast(
159 *true_type,
160 *this_type,
161 t
162 );
163 if(NULL == oid)
164 boost::serialization::throw_exception(
165 boost::archive::archive_exception(
166 boost::archive::archive_exception::unregistered_cast,
167 true_type->get_debug_info(),
168 this_type->get_debug_info()
169 )
170 );
171
172 // make tracking array if necessary
173 if(NULL == m_o_sp)
174 m_o_sp = new object_shared_pointer_map;
175
176 typename object_shared_pointer_map::iterator i = m_o_sp->find(oid);
177
178 // if it's a new object
179 if(i == m_o_sp->end()){
180 s.reset(t);
181 std::pair<typename object_shared_pointer_map::iterator, bool> result;
182 result = m_o_sp->insert(std::make_pair(oid, s));
183 BOOST_ASSERT(result.second);
184 }
185 // if the object has already been seen
186 else{
187 s = SPT<T>(i->second, t);
188 }
189 }
190
191 shared_ptr_helper() :
192 m_o_sp(NULL)
193 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
194 , m_pointers_132(NULL)
195 #endif
196 {}
197 virtual ~shared_ptr_helper(){
198 if(NULL != m_o_sp)
199 delete m_o_sp;
200 #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
201 if(NULL != m_pointers_132)
202 delete m_pointers_132;
203 #endif
204 }
205 };
206
207 } // namespace serialization
208 } // namespace boost
209
210 #include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
211
212 #endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP