]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/doc/shared_ptr.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / serialization / doc / shared_ptr.html
1 <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <!--
4 (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 -->
9 <head>
10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
11 <link rel="stylesheet" type="text/css" href="../../../boost.css">
12 <link rel="stylesheet" type="text/css" href="style.css">
13 <title>Template serialization - shared_ptr</title>
14 </head>
15 <body link="#0000ff" vlink="#800080">
16 <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
17 <tr>
18 <td valign="top" width="300">
19 <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
20 </td>
21 <td valign="top">
22 <h1 align="center">Serialization</h1>
23 <h2 align="center">Template serialization - <code style="white-space: normal">shared_ptr&lt;class T&gt;</code></h2>
24 </td>
25 </tr>
26 </table>
27 <hr>
28 All the code snippets included below are defined within the
29 <code style="white-space: normal">boost::serialization</code> namespace.
30 <p>
31 <code style="white-space: normal">shared_ptr&lt;T&gt;</code> is defined in
32 <a href="../../../boost/shared_ptr.hpp" target=shared_ptr.hpp>shared_ptr.hpp</a>.
33 <p>
34 The general class outline for a <code style="white-space: normal">shared_ptr&lt;T&gt;</code> is:
35 <dl>
36 <dt><code style="white-space: normal">shared_ptr&lt;T&gt;</code> contains:
37 <dl>
38 <dt><code style="white-space: normal">T *px;</code>
39 <dt><code style="white-space: normal">shared_count pn;</code> which contains a pointer to:
40 <dl>
41 <dt><code style="white-space: normal">sp_counted_base_impl&lt;T, ...&gt;</code> which is
42 derived from the polymorphic abstract class
43 <dl>
44 <dt><code style="white-space: normal">sp_counted_base</code>
45 </dl>
46 </dl>
47 </dl>
48 </dl>
49 The serialization process proceeds down the tree above.
50 <p>
51 The first cut at implementing serialization for <code style="white-space: normal">shared_ptr</code>
52 just serializes the relevant members of <code style="white-space: normal">shared_ptr</code>.
53 It's almost trivial:
54 <pre><code>
55 template&lt;class Archive, class T&gt;
56 inline void serialize(
57 Archive &amp; ar,
58 shared_ptr&lt;T&gt; &amp; t,
59 const unsigned int file_version,
60 int
61 ){
62 ar &amp; t.px; // save the raw pointer
63 ar &amp; t.pn; // save the shared reference count
64 }
65 </code></pre>
66 So far so good. Now for the serialization of <code style="white-space: normal">shared_count</code>:
67 <pre><code>
68 template&lt;class Archive&gt;
69 inline void save(
70 Archive &amp; ar,
71 const boost::detail::shared_count &amp; t,
72 const unsigned int file_version
73 ){
74 ar &lt;&lt; t.pi_;
75 }
76
77 template&lt;class Archive&gt;
78 inline void load(
79 Archive &amp; ar,
80 boost::detail::shared_count &amp; t,
81 const unsigned int file_version
82 ){
83 ar &gt;&gt; t.pi_;
84 }
85 </code></pre>
86 A key feature of this library is the ability to specify serialization
87 of a class or template without changing the class or template declaration
88 or definition. This is referred to as <i>non-intrusive</i> serialization.
89 <p>
90 The <code style="white-space: normal">pi_</code>member of shared count is a pointer to an
91 instance of <code style="white-space: normal">sp_counted_base_impl<T, ...></code>. Since this class
92 doesn't have a default constructor, serialization requires
93 specification of the following overload:
94 <pre><code>
95 template&lt;class Archive, class P, class D>
96 inline void save_construct_data(
97 Archive &amp; ar,
98 const boost::detail::sp_counted_base_impl<P, D> * t,
99 const unsigned int file_version
100 ){
101 // variables used for construction
102 ar &lt;&lt; t->ptr;
103 ar &lt;&lt; *t;
104 }
105
106 template<class Archive, class P, class D>
107 inline void load_construct_data(
108 Archive &amp; ar,
109 boost::detail::sp_counted_base_impl<P, D> * t,
110 const unsigned int file_version
111 ){
112 P ptr_;
113 ar &gt;&gt; ptr_;
114 // placement new
115 ::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
116 ar &gt;&gt;; *t;
117 }
118 </code></pre>
119 The statement <code style="white-space: normal">ar &gt;&gt; ptr_</code> is key. This deserializes
120 the same pointer deserialzed above. Default object tracking will ensure
121 that no more than one instance of the object is created and that the
122 pointer returned by multiple deserializations are all the same. Hence,
123 regardless of how many instances of <code style="white-space: normal">shared_ptr/shared_count</code>
124 corresponding to a particular object are created, they will all point
125 to the same object.
126 <p>
127 Since <code style="white-space: normal">sp_counted_base_impl&lt;P, D&gt;</code> is derived from
128 <code style="white-space: normal">sp_counted_base</code>, the following is needed:
129
130 <pre><code>
131 template&lt;class Archive, class P, class D&gt;
132 inline void serialize(
133 Archive &amp; ar,
134 boost::detail::sp_counted_base_impl&lt;P, D&gt; &amp; t,
135 const unsigned int file_version,
136 int
137 ){
138 ar & boost::serialization::base_object&lt;
139 boost::detail::sp_counted_base
140 &gt;(*this);
141 }
142 </code></pre>
143 which will in turn require serialization of its base class:
144 <pre><code>
145 inline void serialize(
146 Archive &amp; ar,
147 boost::detail::sp_counted &amp; t,
148 const unsigned int file_version,
149 int
150 ){
151 }
152 </code></pre>
153 It would seem we're done, but running the test program,
154 <a href="../example/demo_shared_ptr.cpp" target="demo_shared_ptr_cpp">
155 demo_shared_ptr.cpp
156 </a>,
157 with this code produces the following output.
158 <pre><code>
159 a = 0x003017A0 use count = 2
160 a1 = 0x003017A0 use count = 2
161 unique element count = 1
162 a = 0x00000000 use count = 0
163 a1 = 0x00000000 use count = 0
164 unique element count = 0
165 a = 0x00303060 use count = 1
166 a1 = 0x00303060 use count = 1
167 unique element count = 1
168 </code></pre>
169 This indicates that we're not quite done. Due to default object
170 tracking, <code style="white-space: normal">sp_counted_base_impl&lt;P, D&gt;</code> is only
171 created once regardless of how many shared pointers point to the
172 same object. Of course, it has to be this way. The reference
173 count starts at 1 and is never incrememented. Code must be added
174 to the serialization functions to maintain the proper reference
175 count.
176 <p>
177 The process of serialization of an empty base class -
178 <code style="white-space: normal">sp_counted_base</code> - seems like additional overhead.
179 Examination of code in
180 <a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
181 base_object.hpp
182 </a>
183 reveals that <code style="white-space: normal">base_object.hpp</code> provides two functions:
184 <ul>
185 <li>invokes serialization of the base class data
186 <li>as a side effect, "registers" the fact base/derived relationship
187 so that conversions of pointers between base and derived classes can be
188 made at runtime.
189 </ul>
190 In this case we need only the latter function so we can replace the
191 base object serialization with:
192 <pre><code>
193 // register the relationship between each derived class
194 // its polymorphic base
195 void_cast_register&lt;
196 boost::detail::sp_counted_base_impl&lt;P, D&gt;
197 boost::detail::sp_counted_base,
198 &gt;();
199 </code></pre>
200 and we don't have to include a trival serializer for <code style="white-space: normal">sp_counted_base</code>.
201 <p>
202 Finally we need to specify name-value pair wrappers if we want to be able
203 to use this serialization with XML archives.
204 <p>
205 Actually, even this is really just a start. Among the issues not addressed in
206 this implementation are:
207 <ul>
208 <li><code style="white-space: normal">weak_ptr</code> is not addressed. I haven't even looked into this.
209 <li>Other smart pointers that might interact with <code style="white-space: normal">shared_ptr</code>
210 haven't been addressed at all. To be confident that the implementation is
211 complete and correct, all these should be addressed as well.
212 <li>Exception handling hasn't been exhaustively considered.
213 <li>Other issues yet to be discovered.
214 </ul>
215 One thing that has been considered is export of shared_ptr. The header which
216 declares shared pointer serialization includes some special macros for exporting
217 shared pointers:
218 <code><pre>
219 BOOST_SHARED_POINTER_EXPORT(T)
220 BOOST_SHARED_POINTER_EXPORT_GUID(T, K)
221 </pre></code>
222 These are specialized versions of the macros used for exporting classes serialized through raw pointers.
223 <p>
224 Clear, complete, correct and exception safe serialization of smart pointers is going to
225 be a challenge. I hope that this implementation provides a useful
226 starting point for such an effort.
227 <hr>
228 <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
229 Distributed under the Boost Software License, Version 1.0. (See
230 accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
231 </i></p>
232 </body>
233 </html>