]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/doc/archive_reference.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / serialization / doc / archive_reference.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-10 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; UTF-8">
11 <link rel="stylesheet" type="text/css" href="../../../boost.css">
12 <link rel="stylesheet" type="text/css" href="style.css">
13 <title>Serialization - More on Archives</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">Archive Class Reference</h2>
24 </td>
25 </tr>
26 </table>
27 <hr>
28 <dl class="page-index">
29 <dt><a href="#trivial">Trivial Archive</a>
30 <dt><a href="#implementation">More Useful Archive Classes</a>
31 <dt><a href="#usage">Usage</a>
32 <dt><a href="#testing">Testing</a>
33 <dt><a href="#polymorphic">Polymorphic Archives</a>
34 </dl>
35
36 <h3><a name="trivial">Trivial Archive</a></h3>
37 The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
38 class must implement in order to be used to serialize
39 <a href="serialization.html"><strong>Serializable</strong></a> types.
40
41 Our discussion will focus on archives used for saving as the hierarchy is exactly analogous
42 for archives used for loading data.
43
44 <h4>Minimum Requirments</h4>
45
46 The simplest class which will model the <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
47 class will look like:
48
49 <pre><code>
50 #include &lt;cstddef&gt; // std::size_t
51 //////////////////////////////////////////////////////////////
52 // class trivial_oarchive
53 class trivial_oarchive {
54 public:
55 //////////////////////////////////////////////////////////
56 // public interface used by programs that use the
57 // serialization library
58 typedef boost::mpl::bool_&lt;true&gt; is_saving;
59 typedef boost::mpl::bool_&lt;false&gt; is_loading;
60 template&lt;class T&gt; void register_type(){}
61 template&lt;class T&gt; trivial_oarchive & operator&lt;&lt;(const T & t){
62 return *this;
63 }
64 template&lt;class T&gt; trivial_oarchive & operator&(const T & t){
65 return *this &lt;&lt; t;
66 }
67 void save_binary(void *address, std::size_t count){};
68 };
69 </code></pre>
70 The simplest possible input archive class is analogous to the above.
71 In the following discussion, only output archives will be addressed.
72 Input archives are exactly symmetrical to output archives.
73 <p>
74 This archive will compile and execute with any types which implement the
75 <a href="serialization.html"><strong>Serializable</strong></a> concept.
76 For an example see
77 <a href="../example/demo_trivial_archive.cpp" target="demo_trivial_archive">
78 <code style="white-space: normal">demo_trivial_archive.cpp</code></a>.
79 Of course this program won't produce any output as it is. But it provides
80 the starting point for a simple class which can be used to log formatted
81 output. See the implementation of a <a href="simple_log.html">simple
82 log archive</a> to how this has been done.
83
84 <h3><a name="implementation">More Useful Archive Classes</a></h3>
85 The above example is fine as far as it goes. But it doesn't implement
86 useful features such as serialization of pointers, class versioning
87 and others. This library implements a family of full featured archive
88 classes appropriate for a variety of purposes.
89
90 <p>
91 Our archives have been factored into a tree of classes in order to minimize
92 repetition of code. This is shown in the accompanying
93 <a target="class_diagram" href="class_diagram.html">class diagram</a>.
94
95 Any class which fulfills the following requirements will fit into
96 this hierarchy and implement all the features we require. Deriving from
97 the base class <a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
98 common_oarchive.hpp</a> provides all features we desire which
99 are missing from trivial_oarchive above.
100
101 <pre><code>
102 <a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
103 #include &lt;cstddef&gt; // std::size_t
104 #include &lt;boost/archive/detail/common_oarchive.hpp&gt;
105 </a>
106 /////////////////////////////////////////////////////////////////////////
107 // class complete_oarchive
108 class complete_oarchive :
109 public boost::archive::detail::common_oarchive&lt;complete_oarchive&gt;
110 {
111 // permit serialization system privileged access to permit
112 // implementation of inline templates for maximum speed.
113 friend class boost::archive::save_access;
114
115 // member template for saving primitive types.
116 // Specialize for any types/templates that require special treatment
117 template&lt;class T&gt;
118 void save(T &amp; t);
119
120 public:
121 //////////////////////////////////////////////////////////
122 // public interface used by programs that use the
123 // serialization library
124
125 // archives are expected to support this function
126 void save_binary(void *address, std::size_t count);
127 };
128 </code></pre>
129
130 Given a suitable definitions of <code style="white-space: normal">save</code>
131 and <code style="white-space: normal">save_binary</code>,
132 any program using serialization with a conforming C++ compiler should compile
133 and run with this archive class.
134
135 <h4>Optional Overrides</h4>
136
137 The <code style="white-space: normal">detail::common_oarchive</code> class contains
138 a number of functions that are used by various parts of the serialization library
139 to help render the archive in a particular form.
140
141 <dl>
142
143 <dt><h4><code>void save_start(char const *)</code></h4></dt>
144 <dd>
145 <strong>Default</strong>:Does nothing.<br>
146 <strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
147 by XML archive to inject "&lt;name&gt;" before data.
148 </dd>
149 <p>
150
151 <dt><h4><code>void save_end(char const *)</code></h4></dt>
152 <dd>
153 <strong>Default</strong>:Does nothing.<br>
154 <strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
155 by XML archive to inject "&lt;/name&gt;" after data.
156 <dd>
157 </dd>
158 <p>
159 <dt><h4><code>void end_preamble()</code></h4></dt>
160 <dd>
161 <strong>Default</strong>:Does nothing.<br>
162 <strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
163 It's not called when archive bookkeeping data is saved. This is used by XML archives
164 to determine when to inject a "&gt;" character at the end of an XML header. XML output archives
165 keep their own internal flag indicating that data being written is header data. This
166 internal flag is reset when an object start tag is written. When
167 <code style="white-space: normal">void end_preamble()</code> is invoked and this internal flag is set
168 a "&gt;" character is appended to the output and the internal flag is reset. The default
169 implementation for <code style="white-space: normal">void end_preamble()</code> is a no-op thereby permitting it
170 to be optimised away for archive classes that don't use it.
171 </dd>
172 <p>
173 <dt><h4><code>
174 template&lt;class T&gt;
175 void save_override(T & t, int);
176 </code></h4></dt>
177 <dd>
178 <strong>Default</strong>:Invokes <code style="white-space: normal">archive::save(Archive & ar, t)</code><br>
179 This is the main entry into the serialization library.<br>
180 <strong>Purpose</strong>:This can be specialized in cases where the data is to be written
181 to the archive in some special way. For example, XML archives implement special handling for
182 name-value pairs by overriding this function template for name-value pairs.
183 This replaces the default name-value pair handling, which is just to throw away the name,
184 with one appropriate for XML which writes out the start of an XML tag with the correct object name.
185 <p>
186 The second argument must be part of the function signature even though it is not used.
187 Its purpose is to be sure that code is portable to compilers which fail to correctly
188 implement partial function template ordering. For more information see
189 <a href="implementation.html#functiontemplateordering">this</a>.
190 </dd>
191
192 </dl>
193
194 <h4>Types used by the serialization library</h4>
195 The serialization library injects bookkeeping data into the serialization archive.
196 This data includes things like object ids, version numbers, class names etc. Each
197 of these objects is included in a wrapper so that the archive class can override the
198 implementation of <code style="white-space: normal">void save_override(T & t, int);</code>.
199 For example, in the XML archive, the override for this type renders an object_id equal to 23 as
200 "object_id=_23". The following table lists the types defined in the
201 <code style="white-space: normal">boost::archive namespace</code>
202 used internally by the serialization library:
203 <p>
204 <table border>
205 <tr><th align=left>type</th><th align=left><code style="white-space: normal">default<br>serialized as</code></th>
206 <tr><td><code style="white-space: normal">version_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
207 <tr><td><code style="white-space: normal">object_id_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
208 <tr><td><code style="white-space: normal">object_id_reference_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
209 <tr><td><code style="white-space: normal">class_id_type</code></td><td><code style="white-space: normal">int</code></td>
210 <tr><td><code style="white-space: normal">class_id_optional_type</code></td><td><code style="white-space: normal">nothing</code></td>
211 <tr><td><code style="white-space: normal">class_id_reference_type</code></td><td><code style="white-space: normal">int</code></td>
212 <tr><td><code style="white-space: normal">tracking_type</code></td><td><code style="white-space: normal">bool</code></td>
213 <tr><td><code style="white-space: normal">classname_type</code></td><td><code style="white-space: normal">string</code></td>
214 </table>
215 <p>
216 All of these are associated with a default serialization defined in terms of primitive types
217 so it isn't a requirement to define <code style="white-space: normal">save_override</code>
218 for these types.
219 <p>
220 These are defined in
221 <a href="../../../boost/archive/basic_archive.hpp" target="basic_archive_hpp"><code style="white-space: normal">basic_archive.hpp</code></a>.
222 All of these types have been assigned an
223 <a target="detail" href="traits.html#level">implementation level</a> of
224 <code style="white-space: normal">primitive</code> and are convertible to types such as int, unsigned int, etc.
225 so that they have default implementations. This is illustrated by
226 <a href="../../../boost/archive/basic_text_iarchive.hpp" target="basic_text_iarchive_hpp"><code style="white-space: normal">basic_text_iarchive.hpp</code></a>.
227 which relies upon the default. However, in some cases, overrides will have to be
228 explicitly provided for these types. For an example see
229 <a href="../../../boost/archive/basic_xml_iarchive.hpp" target="basic_xml_iarchive_hpp"><code style="white-space: normal">basic_xml_iarchive.hpp</code></a>.
230 <p>
231 In real practice, we probably won't be quite done.
232 One or more of the following issues may need to be addressed:
233 <ul>
234 <li>Many compilers fail to implement correct partial ordering of
235 function templates. The archives included with this library work around
236 this using argument overloading. This technique is described in
237 <a target="detail" href="implementation.html#functiontemplateordering">
238 another section of this manual</a>
239 <li>Even if we are using a conforming compiler, we might want our new archive class
240 to be portable to non-conforming compilers.
241 <li>Our archive format might require extra information inserted into it. For
242 example, XML archives need &lt;name ... &gt;...&lt;/name&gt; surrounding
243 all data objects.
244 <li>Addressing any of the above may generate more issues to be addressed.
245 <li>The archives included with the library are all templates which use a
246 <code style="white-space: normal">stream</code> or
247 <code style="white-space: normal">streambuf</code>
248 as a template parameter rather than simple classes.
249 Combined with the above, even more issues arise with non-conforming compilers.
250 </ul>
251 The attached <a target="class_diagram" href="class_diagram.html">class diagram</a>
252 shows the relationships between classes used to implement the serialization library.
253 <p>
254 A close examination of the archives included with the library illustrate
255 what it takes to make a portable archive that covers all data types.
256 <h3><a name="usage">Usage</a></h3>
257 The newly created archive will usually be stored in its own header module. All
258 that is necessary is to include the header and construct an instance of the new archive.
259 EXCEPT for one special case.
260 <ul>
261 <li>Instances of a derived class are serialized through a base class pointer.
262 <li>Such instances are not "registered" neither implicitly nor explicitly. That
263 is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used
264 to instantiate the serialization code for the included archives.
265 </ul>
266
267 To make this work, the following should be included after the archive
268 class definition.
269 <pre><code>
270 #define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
271 </code></pre>
272 Failure to do this will not inhibit the program from compiling, linking
273 and executing properly - except in one case. If an instance of a derived
274 class is serialized through a pointer to its base class, the program
275 will throw an
276 <a href="exceptions.html#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
277 exception.
278 <p>
279
280 <h4><a name="testing">Testing</h4>
281 Exhaustive testing of the library requires testing the different aspects of object
282 serialization with each archive. There are 46 different tests that can run with any archive.
283 There are 5 "standard archives" included with the system.
284 (3 in systems that don't support wide charactor i/o).
285 <p>
286 In addition, there are 28 other tests which aren't related to any particular archive class.
287 <p>
288 The default <code style="white-space: normal">bjam</code> testing setup will run all
289 the above described tests. This will result in as many as 46 archive tests * 5
290 standard archives + 28 general tests = 258 tests. Note that a complete test of the
291 library would include DLL vs static library, release vs debug so the actual total
292 would be closer to 1032 tests.
293 <p>
294 For each archive there is a header file in the test directory similar to the one below.
295 The name of this archive is passed to the test program by setting the
296 environmental variable <code style="white-space: normal">BOOST_ARCHIVE_TEST</code>
297 to the name of the header. Here is the header file
298 <code style="white-space: normal">test_archive.hpp</code> . Test header files for
299 other archives are similar.
300 <pre><code>
301 // text_archive test header
302 // include output archive header
303 #include &lt;boost/archive/text_oarchive.hpp&gt;
304 // set name of test output archive
305 typedef boost::archive::text_oarchive test_oarchive;
306 // set name of test output stream
307 typedef std::ofstream test_ostream;
308
309 // repeat the above for input archive
310 #include &lt;boost/archive/text_iarchive.hpp&gt;
311 typedef boost::archive::text_iarchive test_iarchive;
312 typedef std::ifstream test_istream;
313
314 // define open mode for streams
315 // binary archives should use std::ios_base::binary
316 #define TEST_STREAM_FLAGS (std::ios_base::openmode)0
317 </code></pre>
318
319 To test a new archive, for example, portable binary archives, with the gcc compiler,
320 make a header file <code style="white-space: normal">portable_binary_archive.hpp</code>
321 and invoke <code style="white-space: normal">bjam</code> with
322 <pre><code>
323 -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
324 </code></pre>
325 This process in encapsulated in the shell or cmd script
326 <code style="white-space: normal">library_test</code> whose command line is
327 <pre><code>
328 library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
329 </code></pre>
330 <h3><a name="polymorphic">Polymorphic Archives</a></h3>
331
332 <h4>Motivation</h4>
333
334 All archives described so far are implemented as templates. Code to save and load
335 data to archives is regenerated for each combination of archive class and data type.
336 Under these cirumstances, a good optimizing compiler that can expand
337 <code>inline</code> functions to enough depth will generate fast code.
338 However:
339 <ul>
340 <li>Much inline code may be replicated.
341 <li>If there are several archive classes, code will be regenerated for each archive class.
342 <li>If serialization code is placed in a library, that library must be rebuilt
343 each time a new archive class is created.
344 <li>If serialization code is placed in a DLL,
345 <ul>
346 <li>The DLL will contain versions of code for each known archive type.
347 This would result in loading of DLLs which contain
348 much code that is not used - basically defeating one of the main motivations
349 for choosing to use a DLL in the first place.
350 <li>If a new archive is created and an application shipped, all DLLs have to be
351 rebuilt, and reshipped along with the application which uses the new archive. Thus
352 the other main motivation for using a DLL is defeated.
353 </ul>
354 </ul>
355
356 <h4>Implementation</h4>
357 The solution is the pair <code>polymorphic_oarchive</code>
358 and <code>polymorphic_iarchive</code>. They present a common interface of virtual
359 functions - no templates - that is equivalent to the standard templated one.
360
361 This is shown in the accompanying
362 <a target="class_diagram" href="class_diagram.html">class diagram</a>
363 <p>
364 The accompanying demo program in files
365
366 <a target=demo_polymorphic_cp href="../example/demo_polymorphic.cpp"><code style="white-space: normal">demo_polymorphic.cpp</code></a>,
367 <a target=demo_polymorphic_A_hpp href="../example/demo_polymorphic_A.hpp"><code style="white-space: normal">demo_polymorphic_A.hpp</code></a>, and
368 <a target=demo_polymorphic_A_cpp href="../example/demo_polymorphic_A.cpp"><code style="white-space: normal">demo_polymorphic_A</code></a>
369 show how polymorphic archives are to be used. Note the following:
370 <ul>
371 <li><a target=demo_polymorphic_A_hpp href="../example/demo_polymorphic_A.hpp"><code style="white-space: normal">demo_polymorphic_A.hpp</code></a> and
372 <a target=demo_polymorphic_A_cpp href="../example/demo_polymorphic_A.cpp"><code style="white-space: normal">demo_polymorphic_A.cpp</code></a>
373 contain no templates and no reference to any specific archive implementation. That is, they will
374 only have to be compiled once for all archive implementations. This even applies to archives classes
375 created in the future.
376 <li>The main program <a target=demo_polymorphic_cp href="../example/demo_polymorphic.cpp"><code style="white-space: normal">demo_polymorphic.cpp</code></a>
377 specifies a specific archive implementation.
378 </ul>
379 As can be seen in the
380 <a target="class_diagram" href="class_diagram.html">class diagram</a>
381 and the header files, this implementation is just a composition of the polymorphic
382 interface and the standard template driven implementation. This composition is
383 accomplished by the templates
384 <a target=polymorphic_iarchive_route_hpp href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp"><code style="white-space: normal">polymorphic_iarchive_route.hpp</code></a>
385 and
386 <a target=polymorphic_oarchive_route_hpp href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp"><code style="white-space: normal">polymorphic_oarchive_route.hpp</code></a>
387 which redirect calls to the polymorphic archives to the specific archive.
388 As these contain no code specific to the particular implementation archive, they can be used to create
389 a polymorphic archive implementation from any functioning templated archive implementation.
390 <p>
391 As a convenience, small header files have been included which contain
392 a <code style="white-space: normal">typedef</code> for a polymorphic implementation for each corresponding
393 templated one. For example, the headers
394 <a target=polymorphic_text_iarchive_hpp href="../../../boost/archive/polymorphic_text_iarchive.hpp"><code style="white-space: normal">polymorphic_text_iarchive.hpp</code></a>
395 and
396 <a target=polymorphic_text_oarchive_hpp href="../../../boost/archive/polymorphic_text_oarchive.hpp"><code style="white-space: normal">polymorphic_text_oarchive.hpp</code></a>.
397 contain the <code style="white-space: normal">typedef</code> for the polymorphic implementation
398 of the standard text archive classes
399 <a target=text_iarchive_hpp href="../../../boost/archive/text_iarchive.hpp"><code style="white-space: normal">text_iarchive.hpp</code></a>
400 and
401 <a target=text_oarchive_hpp href="../../../boost/archive/text_oarchive.hpp"><code style="white-space: normal">text_oarchive.hpp</code></a>
402 respectively. All included polymorphic archives use the same naming scheme.
403
404 <h4>Usage</h4>
405 Polymorphic archives address the issues raised above regarding templated implementation.
406 That is, there is no replicated code, and no recompilation for new archives. This will
407 result in smaller executables for program which use more than one type of archive, and
408 smaller DLLS. There is a penalty for calling archive functions through a virtual function
409 dispatch table and there is no possibility for a compiler to <code style="white-space: normal">inline</code>
410 archive functions. This will result in a detectable degradation in performance for
411 saving and loading archives.
412 <p>
413 Note that the concept of polymophic archives is fundamentally incompatible with the
414 serialization of new types that are marked "primitive" by the user with:
415 <pre><code>
416 BOOST_CLASS_IMPLEMENTATION(my_primitive_type, boost::serialization::primitive_type)
417 </code></pre>
418
419 Code to implement serialization for these types is instantiated "on the fly" in the user's program.
420 But this conflicts with the whole purpose of the polymorphic archive. An attempt to
421 serialize such a primitive type will result in a compilation error since the common polymorhic
422 interface is static and cannot instantiate code for a new type.
423
424 <p>
425 The main utility of polymorphic archives will be to permit the building of class DLLs that will
426 include serialization code for all present and future archives with no redundant code.
427 <hr>
428 <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
429 Distributed under the Boost Software License, Version 1.0. (See
430 accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
431 </i></p>
432 </body>
433 </html>