Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / archive / shared_ptr_helper.hpp
1 #ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
2 #define BOOST_ARCHIVE_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 <set>
20 #include <list>
21 #include <utility>
22 #include <cstddef> // NULL
23
24 #include <boost/config.hpp>
25 #include <boost/shared_ptr.hpp>
26
27 #include <boost/type_traits/is_polymorphic.hpp>
28 #include <boost/serialization/type_info_implementation.hpp>
29 #include <boost/serialization/shared_ptr_132.hpp>
30 #include <boost/serialization/throw_exception.hpp>
31
32 #include <boost/archive/archive_exception.hpp>
33 #include <boost/archive/detail/decl.hpp>
34
35 #include <boost/archive/detail/abi_prefix.hpp> // must be the last headern
36
37 namespace boost_132 {
38     template<class T> class shared_ptr;
39 }
40 namespace boost {
41     template<class T> class shared_ptr;
42     namespace serialization {
43         class extended_type_info;
44         template<class Archive, class T>
45         inline void load(
46             Archive & ar,
47             boost::shared_ptr< T > &t,
48             const unsigned int file_version
49         );
50     }
51 namespace archive{
52 namespace detail {
53
54 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
55 // a common class for holding various types of shared pointers
56
57 class shared_ptr_helper {
58     struct collection_type_compare {
59         bool operator()(
60             const shared_ptr<const void> &lhs,
61             const shared_ptr<const void> &rhs
62         )const{
63             return lhs.get() < rhs.get();
64         }
65     };
66     typedef std::set<
67         boost::shared_ptr<const void>,
68         collection_type_compare
69     > collection_type;
70     typedef collection_type::const_iterator iterator_type;
71     // list of shared_pointers create accessable by raw pointer. This
72     // is used to "match up" shared pointers loaded at different
73     // points in the archive. Note, we delay construction until
74     // it is actually used since this is by default included as
75     // a "mix-in" even if shared_ptr isn't used.
76     collection_type * m_pointers;
77
78     struct null_deleter {
79         void operator()(void const *) const {}
80     };
81
82     struct void_deleter {
83         const boost::serialization::extended_type_info * m_eti;
84         void_deleter(const boost::serialization::extended_type_info *eti) :
85             m_eti(eti)
86         {}
87         void operator()(void *vp) const {
88             m_eti->destroy(vp);
89         }
90     };
91
92 #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
93 public:
94 #else
95     template<class Archive, class T>
96     friend inline void boost::serialization::load(
97         Archive & ar,
98         boost::shared_ptr< T > &t,
99         const unsigned int file_version
100     );
101 #endif
102
103 //  #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
104     // list of loaded pointers.  This is used to be sure that the pointers
105     // stay around long enough to be "matched" with other pointers loaded
106     // by the same archive.  These are created with a "null_deleter" so that
107     // when this list is destroyed - the underlaying raw pointers are not
108     // destroyed.  This has to be done because the pointers are also held by
109     // new system which is disjoint from this set.  This is implemented
110     // by a change in load_construct_data below.  It makes this file suitable
111     // only for loading pointers into a 1.33 or later boost system.
112     std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
113 //  #endif
114
115     // returns pointer to object and an indicator whether this is a
116     // new entry (true) or a previous one (false)
117     BOOST_ARCHIVE_DECL(shared_ptr<void>) 
118     get_od(
119         const void * od,
120         const boost::serialization::extended_type_info * true_type, 
121         const boost::serialization::extended_type_info * this_type
122     );
123
124     BOOST_ARCHIVE_DECL(void)
125     append(const boost::shared_ptr<const void> &);
126
127     template<class T>
128     struct non_polymorphic {
129         static const boost::serialization::extended_type_info * 
130         get_object_identifier(T &){
131             return & boost::serialization::singleton<
132                 BOOST_DEDUCED_TYPENAME 
133                 boost::serialization::type_info_implementation< T >::type
134             >::get_const_instance();
135         }
136     };
137     template<class T>
138     struct polymorphic {
139         static const boost::serialization::extended_type_info * 
140         get_object_identifier(T & t){
141             return boost::serialization::singleton<
142                 BOOST_DEDUCED_TYPENAME 
143                 boost::serialization::type_info_implementation< T >::type
144             >::get_const_instance().get_derived_extended_type_info(t);
145         }
146     };
147 public:
148     template<class T>
149     void reset(shared_ptr< T > & s, T * t){
150         if(NULL == t){
151             s.reset();
152             return;
153         }
154         const boost::serialization::extended_type_info * this_type
155             = & boost::serialization::type_info_implementation< T >::type
156                     ::get_const_instance();
157
158         // get pointer to the most derived object.  This is effectively
159         // the object identifern
160         typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
161             is_polymorphic< T >,
162             mpl::identity<polymorphic< T > >,
163             mpl::identity<non_polymorphic< T > >
164         >::type type;
165
166         const boost::serialization::extended_type_info * true_type
167             = type::get_object_identifier(*t);
168
169         // note:if this exception is thrown, be sure that derived pointern
170         // is either registered or exported.
171         if(NULL == true_type)
172             boost::serialization::throw_exception(
173                 archive_exception(
174                     archive_exception::unregistered_class,
175                     this_type->get_debug_info()
176                 )
177             );
178         shared_ptr<void> r =
179             get_od(
180                 static_cast<const void *>(t), 
181                 true_type,
182                 this_type
183             );
184         if(!r){
185             s.reset(t);
186             const void * od = void_downcast(
187                 *true_type,
188                 *this_type,
189                 static_cast<const void *>(t)
190             );
191             shared_ptr<const void> sp(s, od);
192             append(sp);
193         }
194         else{
195             s = shared_ptr< T >(
196                 r,
197                 static_cast<T *>(r.get())
198             );
199         }
200     }
201
202 //  #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
203     BOOST_ARCHIVE_DECL(void)
204     append(const boost_132::shared_ptr<const void> & t);
205 //  #endif
206 public:
207     BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
208     shared_ptr_helper();
209     BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
210     ~shared_ptr_helper();
211 };
212
213 } // namespace detail
214 } // namespace archive
215 } // namespace boost
216
217 #include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
218
219 #endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP