Squashed 'third_party/boostorg/serialization/' content from commit 738695b
Change-Id: I48528198ad1f62b90288d249eb2243d4db02fd5d
git-subtree-dir: third_party/boostorg/serialization
git-subtree-split: 738695b70733f9d592a570fb17a505d6a029b48a
diff --git a/doc/serialization.html b/doc/serialization.html
new file mode 100644
index 0000000..8252930
--- /dev/null
+++ b/doc/serialization.html
@@ -0,0 +1,930 @@
+<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
+Use, modification and distribution is subject to the Boost Software
+License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+-->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" type="text/css" href="../../../boost.css">
+<link rel="stylesheet" type="text/css" href="style.css">
+<title>Serialization - Serialization of Classes</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center">Serialization</h1>
+ <h2 align="center">Serializable Concept</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<dl class="page-index">
+ <dt><a href="#primitiveoperators">Primitive Types</a>
+ <dt><a href="#classoperators">Class Types</a>
+ <dl class="page-index">
+ <dt><a href="#member">Member Function</a>
+ <dt><a href="#free">Free Function</a>
+ <dl class="page-index">
+ <dt><a href="#namespaces">Namespaces for Free Function Overrides</a>
+ </dl>
+ <dt><a href="#classmembers">Class Members</a>
+ <dl class="page-index">
+ <dt><a href="#base">Base Classes</a>
+ <dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
+ <dt><a href="#templates">Templates</a>
+ </dl>
+ <dt><a href="#versioning">Versioning</a>
+ <dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
+ <code style="white-space: normal">save/load</code></a>
+ <dl class="page-index">
+ <dt><a href="#splittingmemberfunctions">Member Functions</a>
+ <dt><a href="#splittingfreefunctions">Free Functions</a>
+ </dl>
+ </dl>
+ <dt><a href="#pointeroperators">Pointers</a>
+ <dl class="page-index">
+ <dt><a href="#constructors">Non-Default Constructors</a>
+ <dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
+ <dl class="page-index">
+ <dt><a href="#registration">Registration</a>
+ <dt><a href="#export">Export</a>
+ <dt><a href="#instantiation">Instantiation</a>
+ <dt><a href="#selectivetracking">Selective Tracking</a>
+ <dt><a href="#runtimecasting">Runtime Casting</a>
+ </dl>
+ </dl>
+ <dt><a href="#references">References</a>
+ <dt><a href="#arrays">Arrays</a>
+ <dt><a href="traits.html">Class Serialization Traits</a>
+ <dt><a href="wrappers.html">Serialization Wrappers</a>
+ <dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
+</dl>
+
+A type <code style="white-space: normal">T</code> is <strong>Serializable</strong>
+if and only if one of the following is true:
+<ul>
+ <li>it is a primitive type.<br>
+ By <i>primitive type</i> we mean a C++ built-in type and <i>ONLY</i>
+ a C++ built-in type. Arithmetic (including characters), bool, enum are primitive types.
+ Below in <a target="detail" href="traits.html#Traits">serialization traits</a>,
+ we define a "primitive" implementation level in a different way for a
+ different purpose. This can be a source of confusion.
+ <li>It is a class type and one of the following has been declared according
+ to the prototypes detailed below:
+ <ul>
+ <li>a class member function <code style="white-space: normal">serialize</code>
+ <li>a global function <code style="white-space: normal">serialize</code>
+ </ul>
+ <li>it is a pointer to a <strong>Serializable</strong> type.
+ <li>it is a reference to a <strong>Serializable</strong> type.
+ <li>it is a native C++ Array of <strong>Serializable</strong> type.
+</ul>
+
+<h2><a name="primitiveoperators">Primitive Types</a></h2>
+The template operators &, <<, and >> of the archive classes
+described above will generate code to save/load all primitive types
+to/from an archive. This code will usually just add the
+data to the archive according to the archive format.
+For example, a four byte integer is appended to a binary archive
+as 4 binary bytes while a to a text archive it would be
+rendered as a space followed by a string representation.
+
+<h2><a name="classoperators">Class Types</a></h2>
+For class/struct types, the template operators &, <<, and >>
+will generate code that invokes the programmer's serialization code for the
+particular data type. There is no default. An attempt to serialize a
+class/struct for which no serialization has been explicitly specified
+will result in a compile time error. The serialiation of a class can
+be specified via either a class member function or a free funcation which
+takes a reference to an instance of the class as an argument.
+
+<h3><a name="member">Member Function</a></h3>
+The serialization library invokes the following code to save or load a class instance
+to/from and archive.
+<pre><code>
+template<class Archive, class T>
+inline void serialize(
+ Archive & ar,
+ T & t,
+ const unsigned int file_version
+){
+ // invoke member function for class T
+ t.serialize(ar, file_version);
+}
+</code></pre>
+That is, the default definition of template <code style="white-space: normal">serialize</code>
+presumes the existence of a class member function template of the following
+signature:
+<pre><code>
+template<class Archive>
+void serialize(Archive &ar, const unsigned int version){
+ ...
+}
+</code></pre>
+If such a member function is not declared, a compile time error will occur. In order
+that the member function generated by this template can be called to
+append the data to an archive, it either must be public or the class must
+be made accessible to the serialization library by including:
+<pre><code>
+friend class boost::serialization::access;
+</code></pre>
+in the class definition. This latter method should be preferred over the option
+of making the member function public. This will prevent serialization functions from
+being called from outside the library. This is almost certainly an error. Unfortunately,
+it may appear to function but fail in a way that is very difficult to find.
+<p>
+It may not be immediately obvious how this one template serves for both
+saving data to an archive as well as loading data from the archive.
+The key is that the <code style="white-space: normal">&</code> operator is
+defined as <code style="white-space: normal"><<</code>
+for output archives and as <code style="white-space: normal">>></code> input archives. The
+"polymorphic" behavior of the <code style="white-space: normal">&</code> permits the same template
+to be used for both save and load operations. This is very convenient in that it
+saves a lot of typing and guarantees that the saving and loading of class
+data members are always in sync. This is the key to the whole serialization
+system.
+
+<h3><a name="free">Free Function</a></h3>
+Of course we're not restricted to using the default implementation described
+above. We can override the default one with our own. Doing this will
+permit us to implement serialization of a class without altering
+the class definition itself. We call this <strong>non-intrusive</strong>
+serialization. Suppose our class is named <code style="white-space: normal">my_class</code>, the
+override would be specified as:
+<pre><code>
+// namespace selection
+
+template<class Archive>
+inline void serialize(
+ Archive & ar,
+ my_class & t,
+ const unsigned int file_version
+){
+ ...
+}
+</code></pre>
+
+Note that we have called this override "non-intrusive". This is slightly
+inaccurate. It does not require that the class have special functions, that
+it be derived from some common base class or any other fundamental design changes.
+However, it will require access to the class members that are to
+be saved and loaded. If these members are <code style="white-space: normal">private</code>, it won't be
+possible to serialize them. So in some instances, minor modifications to the
+class to be serialized will be necessary even when using this "non-intrusive"
+method. In practice this may not be such a problem as many libraries
+(E.G. STL) expose enough information to permit implementation of non-intrusive
+serialization with absolutly no changes to the library.
+
+<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
+For maximum portability, include any free functions templates and definitions in the
+namespace <code style="white-space: normal">boost::serialization</code>. If portability is not a concern and the
+compiler being used supports ADL (Argument Dependent Lookup) the free functions and
+templates can be in any of the following namespaces:
+<ul>
+<li><code style="white-space: normal">boost::serialization</code>
+<li>namespace of the archive class
+<li>namespace of the type being serialized
+</ul>
+<p>
+Note that, at first glance, this suggestion may seem to be wrong for compilers which implement
+two phase lookup. In fact, the serialization library used a perhaps overly clever
+method to support this rule even for such compilers. Those with an interest in studying
+this further will find more information in
+<a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
+
+<h3><a name="classmembers">Serialization of Class Members</a></h3>
+Regardless of which of the above methods is used, the body of the serialize function must
+specify the data to be saved/loaded by sequential application of the archive
+<code style="white-space: normal">operator &</code> to all the data members of the class.
+<pre><code>
+{
+ // save/load class member variables
+ ar & member1;
+ ar & member2;
+}
+</code></pre>
+
+<h4><a name="base">Base Classes</a></h4>
+The header file
+<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
+base_object.hpp
+</a>
+includes the template:
+<pre><code>
+template<class Base, class Derived>
+Base & base_object(Derived &d);
+</code></pre>
+which should be used to create a reference to an object of the base
+which can be used as an argument to the archive serialization operators.
+So for a class of <strong>Serializable</strong> type
+<code style="white-space: normal">T</code> the base class state should be
+serialized like this:
+<pre><code>
+{
+ // invoke serialization of the base class
+ ar & boost::serialization::base_object<base_class_of_T>(*this);
+ // save/load class member variables
+ ar & member1;
+ ar & member2;
+}
+</code></pre>
+Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
+This might seem to work but may fail to invoke code necessary for
+proper serialization.
+<p>
+Note that this is <strong>NOT</strong> the same as calling the <code style="white-space: normal">serialize</code>
+function of the base class. This might seem to work but will circumvent
+certain code used for tracking of objects, and registering base-derived
+relationships and other bookkeeping that is required for the serialization
+system to function as designed. For this reason, all <code style="white-space: normal">serialize</code>
+member functions should be <code style="white-space: normal">private</code>.
+
+<h4><a name="const"><code style="white-space: normal">const</code> Members</a></h4>
+Saving <code style="white-space: normal">const</code> members to an archive
+requires no special considerations.
+Loading <code style="white-space: normal">const</code> members can be addressed by using a
+<code style="white-space: normal">const_cast</code>:
+<pre><code>
+ ar & const_cast<T &>(t);
+</code></pre>
+Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
+keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
+is constructed and not changed thereafter. However, this may
+be most appropriate in many cases. Ultimately, it comes down to
+the question about what <code style="white-space: normal">const</code> means in the context
+of serialization.
+
+<h4><a name="templates"></a>Templates</h4>
+Implementation of serialization for templates is exactly the same process
+as for normal classes and requires no additional considerations. Among
+other things, this implies that serialization of compositions of templates
+are automatically generated when required if serialization of the
+component templates is defined. For example, this library includes
+definition of serialization for <code style="white-space: normal">boost::shared_ptr<T></code> and for
+<code style="white-space: normal">std::list<T></code>. If I have defined serialization for my own
+class <code style="white-space: normal">my_t</code>, then serialization for
+<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
+for use.
+<p>
+For an example that shows how this idea might be implemented for your own
+class templates, see
+<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
+demo_auto_ptr.cpp</a>.
+This shows how non-intrusive serialization
+for the template <code style="white-space: normal">auto_ptr</code> from the standard library
+can be implemented.
+<p>
+A somewhat trickier addition of serialization to a standard template
+can be found in the example
+<a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
+shared_ptr.hpp
+</a>
+<!--
+Only the most minimal change to
+<code>shared_count.hpp</code>
+(to gain access to some private members) was necessary to achieve this.
+This should demonstrate how easy it is to non-intrusively
+implement serialization to any data type or template.
+-->
+<p>
+In the specification of serialization for templates, its common
+to split <code style="white-space: normal">serialize</code>
+into a <code style="white-space: normal">load/save</code> pair.
+Note that the convenience macro described
+<a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
+isn't helpful in these cases as the number and kind of
+template class arguments won't match those used when splitting
+<code style="white-space: normal">serialize</code> for a simple class. Use the override
+syntax instead.
+
+<h3><a name="versioning">Versioning</a></h3>
+It will eventually occur that class definitions change after archives have
+been created. When a class instance is saved, the current version
+in included in the class information stored in the archive. When the class instance
+is loaded from the archive, the original version number is passed as an
+argument to the loading function. This permits the load function to include
+logic to accommodate older definitions for the class and reconcile them
+with latest version. Save functions always save the current version. So this
+results in automatically converting older format archives to the newest versions.
+Version numbers are maintained independently for each class. This results in
+a simple system for permitting access to older files and conversion of same.
+The current version of the class is assigned as a
+<a href="traits.html">Class Serialization Trait</a> described later in this manual.
+<pre><code>
+{
+ // invoke serialization of the base class
+ ar & boost::serialization::base_object<base_class_of_T>(*this);
+ // save/load class member variables
+ ar & member1;
+ ar & member2;
+ // if its a recent version of the class
+ if(1 < file_version)
+ // save load recently added class members
+ ar & member3;
+}
+</code></pre>
+
+<h3><a name="splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
+There are times when it is inconvenient to use the same
+template for both save and load functions. For example, this might occur if versioning
+gets complex.
+
+<h4><a name="splittingmemberfunctions">Splitting Member Functions</a></h4>
+For member functions this can be addressed by including
+the header file <a href="../../../boost/serialization/split_member.hpp" target="split_member_hpp">
+boost/serialization/split_member.hpp</a> including code like this in the class:
+<pre><code>
+template<class Archive>
+void save(Archive & ar, const unsigned int version) const
+{
+ // invoke serialization of the base class
+ ar << boost::serialization::base_object<const base_class_of_T>(*this);
+ ar << member1;
+ ar << member2;
+ ar << member3;
+}
+
+template<class Archive>
+void load(Archive & ar, const unsigned int version)
+{
+ // invoke serialization of the base class
+ ar >> boost::serialization::base_object<base_class_of_T>(*this);
+ ar >> member1;
+ ar >> member2;
+ if(version > 0)
+ ar >> member3;
+}
+
+template<class Archive>
+void serialize(
+ Archive & ar,
+ const unsigned int file_version
+){
+ boost::serialization::split_member(ar, *this, file_version);
+}
+</code></pre>
+This splits the serialization into two separate functions <code style="white-space: normal">save</code>
+and <code style="white-space: normal">load</code>. Since the new <code style="white-space: normal">serialize</code> template
+is always the same it can be generated by invoking the macro
+BOOST_SERIALIZATION_SPLIT_MEMBER() defined in the header file
+<a href="../../../boost/serialization/split_member.hpp" target="split_member_hpp">
+boost/serialization/split_member.hpp
+</a>.
+So the entire <code style="white-space: normal">serialize</code> function above can be replaced with:
+<pre><code>
+BOOST_SERIALIZATION_SPLIT_MEMBER()
+</code></pre>
+<h4><a name="splittingfreefunctions">Splitting Free Functions</a></h4>
+The situation is same for non-intrusive serialization with the free
+<code style="white-space: normal">serialize</code> function template.
+
+<a name="BOOST_SERIALIZATION_SPLIT_FREE">
+To use <code style="white-space: normal">save</code> and
+<code style="white-space: normal">load</code> function templates rather than
+<code style="white-space: normal">serialize</code>:
+<pre><code>
+namespace boost { namespace serialization {
+template<class Archive>
+void save(Archive & ar, const my_class & t, unsigned int version)
+{
+ ...
+}
+template<class Archive>
+void load(Archive & ar, my_class & t, unsigned int version)
+{
+ ...
+}
+}}
+</code></pre>
+include the header file
+<a href="../../../boost/serialization/split_free.hpp" target="split_free_hpp">
+boost/serialization/split_free.hpp
+</a>.
+and override the free <code style="white-space: normal">serialize</code> function template:
+<pre><code>
+namespace boost { namespace serialization {
+template<class Archive>
+inline void serialize(
+ Archive & ar,
+ my_class & t,
+ const unsigned int file_version
+){
+ split_free(ar, t, file_version);
+}
+}}
+</code></pre>
+To shorten typing, the above template can be replaced with
+the macro:
+<pre><code>
+BOOST_SERIALIZATION_SPLIT_FREE(my_class)
+</code></pre>
+
+Note that although the functionality to split the <code style="white-space: normal">
+serialize</code> function into <code style="white-space: normal">save/load</code>
+has been provided, the usage of the <code style="white-space: normal">serialize</code>
+function with the corresponding <code style="white-space: normal">&</code> operator
+is preferred. The key to the serialization implementation is that objects are saved
+and loaded in exactly the same sequence. Using the <code style="white-space: normal">&</code>
+operator and <code style="white-space: normal">serialize</code>
+function guarantees that this is always the case and will minimize the
+occurrence of hard to find errors related to synchronization of
+<code style="white-space: normal">save</code> and <code style="white-space: normal">load</code>
+functions.
+<p>
+Also note that <code style="white-space: normal">BOOST_SERIALIZATION_SPLIT_FREE</code>
+must be used outside of any namespace.
+
+<h2><a name="pointeroperators">Pointers</a></h2>
+A pointer to any class instance can be serialized with any of the archive
+save/load operators.
+<p>
+To properly save and restore an object through a pointer the
+following situations must be addressed:
+<ol>
+ <li>If the same object is saved multiple times through different
+ pointers, only one copy of the object need be saved.
+ <li>If an object is loaded multiple times through different pointers,
+ only one new object should be created and all returned pointers
+ should point to it.
+ <li>The system must detect the case where an object is first
+ saved through a pointer then the object itself is saved.
+ Without taking extra precautions, loading would result in the
+ creation of multiple copies of the original object. This system detects
+ this case when saving and throws an exception - see below.
+ <li>An object of a derived class may be stored through a
+ pointer to the base class. The true type of the object must
+ be determined and saved. Upon restoration the correct type
+ must be created and its address correctly cast to the base
+ class. That is, polymorphic pointers have to be considered.
+ <li>NULL pointers must be dectected when saved and restored
+ to NULL when deserialized.
+</ol>
+
+This serialization library addresses all of the above
+considerations. The process of saving and loading an object
+through a pointer is non-trivial. It can be summarized as
+follows:
+<p>Saving a pointer:
+<ol>
+ <li>determine the true type of the object being pointed to.
+ <li>write a special tag to the archive
+ <li>if the object pointed to has not already been written
+ to the archive, do so now
+</ol>
+Loading a pointer:
+<ol>
+ <li>read a tag from the archive.
+ <li>determine the type of object to be created
+ <li>if the object has already been loaded, return its address.
+ <li>otherwise, create a new instance of the object
+ <li>read the data back in using the operators described above
+ <li>return the address of the newly created object.
+</ol>
+
+Given that class instances are saved/loaded to/from the archive
+only once, regardless of how many times they are serialized with
+the <code style="white-space: normal"><<</code>
+and <code style="white-space: normal">>></code> operators
+<ul>
+ <li>Loading the same pointer object multiple times
+ results in only one object being created, thereby replicating
+ the original pointer configuration.
+ <li>Structures, such as collections of polymorphic pointers,
+ are handled with no special effort on the part of users of this library.
+</ul>
+Serialization of pointers of derived types through a pointer to the
+base class may require a little extra "help". Also, the programmer
+may desire to modify the process described above for his own reasons.
+For example, it might be desired to suppress the tracking of objects
+as it is known a priori that the application in question can never
+create duplicate objects. Serialization of pointers can be "fine tuned"
+via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
+as described in
+<a target="detail" href="special.html#derivedpointers">
+another section of this manual
+</a>
+
+<h3><a name="constructors">Non-Default Constructors</a></h3>
+Serialization of pointers is implemented in the library with code
+similar to the following:
+<pre><code>
+// load data required for construction and invoke constructor in place
+template<class Archive, class T>
+inline void load_construct_data(
+ Archive & ar, T * t, const unsigned int file_version
+){
+ // default just uses the default constructor to initialize
+ // previously allocated memory.
+ ::new(t)T();
+}
+</code></pre>
+The default <code style="white-space: normal">load_construct_data</code> invokes the
+default constructor "in-place" to initialize the memory.
+<p>
+If there is no such default constructor, the function templates
+<code style="white-space: normal">load_construct_data</code> and
+perhaps <code style="white-space: normal">save_construct_data</code>
+will have to be overridden. Here is a simple example:
+<pre><code>
+class my_class {
+private:
+ friend class boost::serialization::access;
+ const int m_attribute; // some immutable aspect of the instance
+ int m_state; // mutable state of this instance
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int file_version){
+ ar & m_state;
+ }
+public:
+ // no default construct guarentees that no invalid object
+ // ever exists
+ my_class(int attribute) :
+ m_attribute(attribute),
+ m_state(0)
+ {}
+};
+</code></pre>
+the overrides would be:
+<pre><code>
+namespace boost { namespace serialization {
+template<class Archive>
+inline void save_construct_data(
+ Archive & ar, const my_class * t, const unsigned int file_version
+){
+ // save data required to construct instance
+ ar << t->m_attribute;
+}
+
+template<class Archive>
+inline void load_construct_data(
+ Archive & ar, my_class * t, const unsigned int file_version
+){
+ // retrieve data from archive required to construct new instance
+ int attribute;
+ ar >> attribute;
+ // invoke inplace constructor to initialize instance of my_class
+ ::new(t)my_class(attribute);
+}
+}} // namespace ...
+</code></pre>
+In addition to the deserialization of pointers, these overrides are used
+in the deserialization of STL containers whose element type has no default
+constructor.
+
+<h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
+<h4><a name="registration">Registration</a></h4>
+Consider the following:
+<pre><code>
+class base {
+ ...
+};
+class derived_one : public base {
+ ...
+};
+class derived_two : public base {
+ ...
+};
+main(){
+ ...
+ base *b;
+ ...
+ ar & b;
+}
+</code></pre>
+When saving <code style="white-space: normal">b</code> what kind of object should be saved?
+When loading <code style="white-space: normal">b</code> what kind of object should be created?
+Should it be an object of class <code style="white-space: normal">derived_one</code>,
+<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
+<p>
+It turns out that the kind of object serialized depends upon whether the base class
+(<code style="white-space: normal">base</code> in this case) is polymophic or not.
+If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
+virtual functions, then an object of the type <code style="white-space: normal">base</code>
+will be serialized. Information in any derived classes will be lost. If this is what is desired
+(it usually isn't) then no other effort is required.
+<p>
+
+If the base class is polymorphic, an object of the most derived type
+(<code style="white-space: normal">derived_one</code>
+or <code style="white-space: normal">derived_two</code>
+in this case) will be serialized. The question of which type of object is to be
+serialized is (almost) automatically handled by the library.
+<p>
+The system "registers" each class in an archive the first time an object of that
+class it is serialized and assigns a sequential number to it. Next time an
+object of that class is serialized in that same archive, this number is written
+in the archive. So every class is identified uniquely within the archive.
+When the archive is read back in, each new sequence number is re-associated with
+the class being read. Note that this implies that "registration" has to occur
+during both save and load so that the class-integer table built on load
+is identical to the class-integer table built on save. In fact, the key to
+whole serialization system is that things are always saved and loaded in
+the same sequence. This includes "registration".
+<p>
+Expanding our previous example:
+<pre><code>
+main(){
+ derived_one d1;
+ derived_two d2:
+ ...
+ ar & d1;
+ ar & d2;
+ // A side effect of serialization of objects d1 and d2 is that
+ // the classes derived_one and derived_two become known to the archive.
+ // So subsequent serialization of those classes by base pointer works
+ // without any special considerations.
+ base *b;
+ ...
+ ar & b;
+}
+</code></pre>
+When <code style="white-space: normal">b</code> is read it is
+preceded by a unique (to the archive) class identifier which
+has previously been related to class <code style="white-space: normal">derived_one</code> or
+<code style="white-space: normal">derived_two</code>.
+<p>
+If a derived class has NOT been automatically "registered" as described
+above, an <a target="detail" href="exceptions.html#unregistered_class">
+<code style="white-space: normal">unregistered_class</code></a> exception
+will be thrown when serialization is invoked.
+<p>
+This can be addressed by registering the derived class explicitly. All archives are
+derived from a base class which implements the following template:
+<pre><code>
+template<class T>
+register_type();
+</code></pre>
+So our problem could just as well be addressed by writing:
+<pre><code>
+main(){
+ ...
+ ar.template register_type<derived_one>();
+ ar.template register_type<derived_two>();
+ base *b;
+ ...
+ ar & b;
+}
+</code></pre>
+Note that if the serialization function is split between save and load, both
+functions must include the registration. This is required to keep the save
+and corresponding load in syncronization.
+
+<h4><a name="export">Export</a></h4>
+The above will work but may be inconvenient. We don't always know which derived
+classes we are going to serialize when we write the code to serialize through
+a base class pointer. Every time a new derived class is written we have to
+go back to all the places where the base class is serialized and update the
+code.
+<p>
+So we have another method:
+<pre><code>
+#include <boost/serialization/export.hpp>
+...
+BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
+BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
+
+main(){
+ ...
+ base *b;
+ ...
+ ar & b;
+}
+</code></pre>
+The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
+with a class. In the above example we've used a string rendering
+of the class name. If a object of such an "exported" class is serialized
+through a pointer and is otherwise unregistered, the "export" string is
+included in the archive. When the archive
+is later read, the string literal is used to find the class which
+should be created by the serialization library.
+This permits each class to be in a separate header file along with its
+string identifier. There is no need to maintain a separate "pre-registration"
+of derived classes that might be serialized. This method of
+registration is referred to as "key export". More information on this
+topic is found in the section Class Traits -
+<a target="detail" href="traits.html#export">Export Key</a>.
+<p>
+<h4><a name="instantiation">Instantiation</a></h4>
+Registration by means of any of the above methods fulfill another role
+whose importance might not be obvious. This system relies on templated
+functions of the form <code style="white-space: normal">template<class Archive, class T></code>.
+This means that serialization code must be instantiated for each
+combination of archive and data type that is serialized in the program.
+<p>
+Polymorphic pointers of derived classes may never be referred to
+explictly by the program so normally code to serialize such classes
+would never be instantiated. So in addition to including export key
+strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
+instantiates the class serialization code for all archive classes used
+by the program.
+
+<h4><a name="selectivetracking">Selective Tracking</a></h4>
+Whether or not an object is tracked is determined by its
+<a target="detail" href="traits.html#tracking">object tracking trait</a>.
+The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
+That is, track objects if and only if they are serialized through pointers anywhere
+in the program. Any objects that are "registered" by any of the above means are presumed
+to be serialized through pointers somewhere in the program and therefore
+would be tracked. In certain situations this could lead to an inefficiency.
+Suppose we have a class module used by multiple programs. Because
+some programs serializes polymorphic pointers to objects of this class, we
+<a target="detail" href="traits.html#export">export</a> a class
+identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
+class header. When this module is included by another program,
+objects of this class will always be tracked even though it
+may not be necessary. This situation could be addressed by using
+<a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
+in those programs.
+<p>
+It could also occur that even though a program serializes through
+a pointer, we are more concerned with efficiency than avoiding the
+the possibility of creating duplicate objects. It could be
+that we happen to know that there will be no duplicates. It could
+also be that the creation of a few duplicates is benign and not
+worth avoiding given the runtime cost of tracking duplicates.
+Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
+can be used.
+<h4><a name="runtimecasting">Runtime Casting</a></h4>
+In order to properly translate between base and derived pointers
+at runtime, the system requires each base/derived pair be found
+in a table. A side effect of serializing a base object with
+<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
+is to ensure that the base/derived pair is added to the table
+before the <code style="white-space: normal">main</code> function is entered.
+This is very convenient and results in a clean syntax. The only
+problem is that it can occur where a derived class serialized
+through a pointer has no need to invoke the serialization of
+its base class. In such a case, there are two choices. The obvious
+one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
+and specify an empty function for the base class serialization.
+The alternative is to "register" the Base/Derived relationship
+explicitly by invoking the template
+<code style="white-space: normal">void_cast_register<Derived, Base>();</code>.
+Note that this usage of the term "register" is not related
+to its usage in the previous section. Here is an example of how this is done:
+<pre><code>
+#include <sstream>
+#include <boost/serialization/serialization.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/export.hpp>
+
+class base {
+ friend class boost::serialization::access;
+ //...
+ // only required when using method 1 below
+ // no real serialization required - specify a vestigial one
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int file_version){}
+};
+
+class derived : public base {
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int file_version){
+ // method 1 : invoke base class serialization
+ ar & boost::serialization::base_object<base>(*this);
+ // method 2 : explicitly register base/derived relationship
+ boost::serialization::void_cast_register<derived, base>(
+ static_cast<derived *>(NULL),
+ static_cast<base *>(NULL)
+ )
+ }
+};
+
+BOOST_CLASS_EXPORT_GUID(derived, "derived")
+
+main(){
+ //...
+ std::stringstream ss;
+ boost::archive::text_iarchive ar(ss);
+ base *b;
+ ar >> b;
+}
+</code></pre>
+<p>
+
+In order for this template to be invoked in code compiled by non-conforming
+compilers, the following syntax may be used:
+<pre><code>
+boost::serialization::void_cast_register(
+ static_cast<Derived *>(NULL),
+ static_cast<Base *>(NULL)
+);
+</code></pre>
+For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
+
+<h3><a name="references"></a>References</h3>
+Classes that contain reference members will generally require
+non-default constructors as references can only be set when
+an instance is constructed. The example of the previous section
+is slightly more complex if the class has reference members.
+This raises the question of how and where the objects being
+referred to are stored and how are they created. Also there is the question about
+references to polymorphic base classes. Basically, these
+are the same questions that arise regarding pointers. This is
+no surprise as references are really a special kind of pointer.
+We address these questions by serializing references as though
+they were pointers.
+<pre><code>
+class object;
+class my_class {
+private:
+ friend class boost::serialization::access;
+ int member1;
+ object & member2;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int file_version);
+public:
+ my_class(int m, object & o) :
+ member1(m),
+ member2(o)
+ {}
+};
+</code></pre>
+the overrides would be:
+<pre><code>
+namespace boost { namespace serialization {
+template<class Archive>
+inline void save_construct_data(
+ Archive & ar, const my_class * t, const unsigned int file_version
+){
+ // save data required to construct instance
+ ar << t.member1;
+ // serialize reference to object as a pointer
+ ar << & t.member2;
+}
+
+template<class Archive>
+inline void load_construct_data(
+ Archive & ar, my_class * t, const unsigned int file_version
+){
+ // retrieve data from archive required to construct new instance
+ int m;
+ ar >> m;
+ // create and load data through pointer to object
+ // tracking handles issues of duplicates.
+ object * optr;
+ ar >> optr;
+ // invoke inplace constructor to initialize instance of my_class
+ ::new(t)my_class(m, *optr);
+}
+}} // namespace ...
+</code></pre>
+
+<h3><a name="arrays"></a>Arrays</h3>
+If <code style="white-space: normal">T</code> is a serializable type,
+then any native C++ array of type T is a serializable type.
+That is, if <code style="white-space: normal">T</code>
+is a serializable type, then the following
+is automatically available and will function as expected:
+<pre><code>
+T t[4];
+ar << t;
+ ...
+ar >> t;
+</code></pre>
+
+<h2><a href="traits.html">Class Serialization Traits</a></h2>
+
+<h2><a href="wrappers.html">Serialization Wrappers</a></h2>
+
+<h2><a name="models"></a>Models - Serialization Implementations Included in the Library</h2>
+The facilities described above are sufficient to implement
+serialization for all STL containers. In fact, this has been done
+and has been included in the library. For example, in order to use
+the included serialization code for <code style="white-space: normal">std::list</code>, use:
+<pre><code>
+#include <boost/serialization/list.hpp>
+</code></pre>
+rather than
+<pre><code>
+#include <list>
+</code></pre>
+Since the former includes the latter, this is all that is necessary.
+The same holds true for all STL collections as well as templates
+required to support them (e.g. <code style="white-space: normal">std::pair</code>).
+<p>
+As of this writing, the library contains serialization of the following boost classes:
+<ul>
+ <li>optional
+ <li>variant
+ <li>scoped_ptr
+ <li>shared_ptr
+ <li>auto_ptr (demo)
+</ul>
+Others are being added to the list so check the boost files section and headers for
+new implementations!
+<hr>
+<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
+Distributed under the Boost Software License, Version 1.0. (See
+accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+</i></p>
+</body>
+</html>