From: bangerth © Copyright Robert Ramey 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)
+
+This archive will compile and execute with any types which implement the
+Serializable concept.
+For an example see
+
+
+Our archives have been factored in to a tree of classes in order to minimize
+repetition of code. This is shown in the accompanying
+class diagram.
+
+Any class which fullfills the following requirements will fit into
+this hierarchy and implement all the features we require. Deriving from
+the base class
+common_oarchive.hpp provides all features we desire which
+are missing from trivial_oarchive above.
+
+
+
+
+
+
+The second argument must be part of the function signature even this it is not used.
+Its purpose is to be sure that code is portable to compilers which fail to correctly
+implement partial function template ordering. For more information see
+this.
+
+
+All of these are associated with a default serialization defined in terms of primitive types
+so it isn't a requirement to define
+These are defined in
+
+In real practice, we probably won't be quite done.
+One or more of the following issues may need to be addressed:
+
+A close examination of the archives included with the library illustrate
+what it takes to make a portable archive that covers all data types.
+
+
+
+In addition, there are 28 other tests which aren't related to any particular archive class.
+
+The default
+For each archive there is a header file in the test directory similar to the one below.
+The name of this archive is passed to the test program by setting the
+environmental variable
+The accompanying demo program in files
+
+
+As a convenience, small header files have been included which contain
+
+The main utility of polymorphic archives will be to permit the buiding of class DLLs that will
+include serialization code for all present and future archives with no redundant code.
+ © Copyright Robert Ramey 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)
+
+
+ Returns a reference to
+ Returns a reference to
+ When an object is loaded to a temporary variable and later moved to another location,
+ this function must be called in order communicate this fact. This permits the
+ archive to properly implement object tracking. Object tracking is required in order
+ to correctly implement serialization of pointers to instances of derived classes.
+
+The existence of the
+In some cases, an archive may alter (and later restore)
+the codecvt facet of the stream locale. To suppress this action,
+include the
+XML archives contain nested tags signifying the start and end of data fields.
+These tags are normally checked for agreement with the object name when
+data is loaded. If a mismatch occurs an exception is thrown. It's possible
+that this may not be desired behavior. To suppress this checking of XML
+tags, use
+The
+The normal character version ( © Copyright Robert Ramey 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)
+ © Copyright Robert Ramey 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)
+
+ This class implements the © Copyright Robert Ramey 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)
+ The C++ Standard IOStreams provides the std::codecvt
+ facet to handle specifically these cases. On reading from or
+ writing to a file, the std::basic_filebuf can call out to
+ the codecvt facet to convert data representations from external
+ format (ie. UTF-8) to internal format (ie. UCS-4) and
+ vice-versa. utf8_codecvt_facet is a specialization of
+ std::codecvt specifically designed to handle the case
+ of translating between UTF-8 and UCS-4.
+
+
+ © Copyright Robert Ramey 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)
+
+
+source => 8 bit bytes => 6 bit integers => encode to base64 characters => insert line breaks => destination
+
+We would prefer the solution that is:
+
+Templated constructor have the form:
+
+Unfortunately, some systems which fail to properly support partial function template
+ordering cannot support the concept of a templated constructor as implemented above.
+A special"wrapper" macro has been created to work around this problem. With this "wrapper"
+the above example is modified to:
+
+Iterators which fulfill the above requirements should be composable and the above sample
+code should implement our binary to base64 conversion.
+
+
+The standard stream iterators don't quite work for us. On systems which implement © Copyright Robert Ramey 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)
+
+This derivation from the xml archive writes output in xml without the extra
+information required to read the data back into the application. It might be
+used to export one's data as simple xml for other applications or for logging
+data while debugging.
+
+To this end it is derived from the included xml archive and the save functions for
+some types are specialized for this application.
+
+The serialization library is
+implemented using the Curiously Recurring Template
+Pattern (CRTP). Also, all common code is factored out into
+separate modules to minimize code repetition. This makes derivation from
+an existing archive less straight forward than it would otherwise be.
+
+This example illustrates several issues that have to be addressed when doing
+something like this
+ © Copyright Robert Ramey 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)
+
+
+ The load function traps any exceptions that occur between the time an object
+ is created and its pointer is stored. Should an exception occur while
+ reading an archive, the created object is deleted and the de-serialized
+ pointer is set to NULL. This ensures that there are no memory leaks.
+ The fact that there are no other copies of this pointer ensures that
+ no pointers are left invalid. The object's destructor should
+ be able to delete any other existing objects in the normal manner
+ without problem.
+ test_delete_pointer.cpp
+ illustrates this case.
+
+
+
+
+
+ © Copyright Robert Ramey 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)
+
+ Should it ever occur that an older program attempts to read newer archives whose
+format has changed, this exception is thrown.
+
+
+This includes
+an attempt to read past the end of the file. Text files need a terminating
+new line character at the end of the file which is appended when the
+archive destructor is invoked. Be sure that an output archive on a stream
+is destroyed before opening an input archive on that same stream. That is,
+rather than using something like:
+
+Another one is the passing of uninitialized data. In general, the behavior
+of the serialization library when passed uninitialized data is undefined.
+If it can be detected, it will invoke an assertion in debug builds.
+Otherwise, depending on the type of archive, it may pass through without
+incident or it may result in an archive with unexpected data in it.
+This, in turn, can result in the throwing of this exception.
+
+ © Copyright Robert Ramey 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)
+
+Generally, there will be one and only one
+
+The second argument is a const string which is the external
+name of the type to which this record corresponds.
+It may sometimes be referred to as a GUID - a Global Unique IDentifier.
+It is passed through archives from one program invocation to
+another to uniquely identify the types that the archive contains.
+If the "export" facility is not going to be used,
+this value may be NULL.
+
+These functions are called by constructors and
+destructors of classes which implement
+
+
+
+ © Copyright Robert Ramey 2005-2009.
+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)
+
+ © Copyright Robert Ramey 2002-2009. 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)
+
+
+By convention' these header files are named:
+
+boost/serialization/xxx.hpp
+
+where xxx is the name of the header file which contains the type to be serialized.
+For example, the declaration
+
+
+The following discussion is based on the
+class diagram.
+
+
+The trade offs related to library implementation via pre-compiled code and templated
+headers are well known. This library uses both. It uses templated headers
+to generate code to serialize user and primitive types and it uses pre-compiled
+library code for that part of the code which only depends upon the archive type.
+Building of the library generates and compiles code for all archives implemented.
+
+
+This is a ripe topic in itself. Its touched upon by the
+boost iterator libraries,
+View Template Library, and others.
+
+The code for these iterators is really independent of this library. But since it
+hasn't been and probably won't be reviewed outside of this context. I've left in a directory
+local to the serialization library:
+boost/archive/iterators.
+These iterators are described in
+Dataflow Iterators.
+ © Copyright Robert Ramey 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)
+ © Copyright Robert Ramey 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)
+
+This depends upon undefined behavior of a compiler already
+determined to be non-conforming. In other words, there is no
+guarantee that this will work on all compilers. If a compiler does not
+correctly support PFTO and this method cannot be used to workaround
+it, non-intrusive serialization cannot be supported for that compiler.
+As of this writing, such a compiler has not been encountered.
+
+It turns out that using this "trick" can create problems with
+compilers that DO correctly support PFTO. For this reason we
+define a macro
+Note that the code conversion included for wide character text and XML
+archives could alter
+To produce wide character text output (i.e. 16 bit characters on Win32 systems),
+do the following.
+
+This compiler does not have RTTI or exception handling turned on by default. Although
+they are not strictly necessary to use the serialization package, the example and test
+program presume that they are enabled. So be sure your command line or IDE settings
+enable these features if you want to build and run these programs.
+
+This compiler can treat Revised 1 November, 2004
+ © Copyright Robert Ramey 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)
+
+If a group of function objects were all derived from the
+same polymorphic base class - perhaps via multiple inheritance,
+the the function object effectively becomes a "variable" which
+encapsulates code.
+
+This case study would show how to do this.
+
+
+This case study would show how to make a useful archive adaptor.
+
+
+It would also be possible to make a "generic runtime helper"
+which would effectively extend the API of the library. Previously
+the library included such a helper class. It was removed
+in favor of the current implementation. But this functionality
+should be added back in with another adaptor which would
+become part of the library.
+
+ Revised 1 November, 2008
+ © Copyright Robert Ramey 2002-2008.
+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)
+ Here, we use the term "serialization" to mean
+the reversible deconstruction of an arbitrary set of C++ data structures
+to a sequence of bytes. Such a system can be used to reconstitute
+an equivalent structure in another program context. Depending on
+the context, this might used implement object persistence, remote
+parameter passing or other facility. In this system we use the term
+"archive" to refer to a specific rendering of this
+stream of bytes. This could be a file of binary data, text data,
+XML, or some other created by the user of this library.
+ Revised 1 November, 2004
+ © Copyright Robert Ramey 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)
+
+The downside of this is that one has to know which archives are going
+to be used with hidden serializations. This is an effect of using template
+driven code. One can invoke explicity instantiation for all known templates and
+presume that the linker will exclude unreferenced code. This should
+work but is platform dependent.
+ © Copyright Robert Ramey 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 found that persistence is often used to refer
+to something quite different. Examples are storage of class
+instances (objects) in database schema [4]
+This library will be useful in other contexts besides implementing persistence. The
+most obvious case is that of marshalling data for transmission to another system.
+
+Archive classes are NOT derived from
+streams even though they have similar syntax rules.
+
+Treating strings as STL vectors would result in minimal code size. This was
+not done because:
+
+
+
+
+
+
+
+
+
+ Serialization
+ Acknowledgments
+
+
+
+&
syntax used to implement both save and
+ load in one fuction specification.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Archive Class Reference
+
+
+
+Trivial Archive
+The Archive concept specifies the functions that a
+class must implement to in order to be used to serialize
+Serializable types.
+
+Our discussion will focus on archives used for saving as the hierarchy is exactly analogous
+for archives used for loading data.
+
+Minimum Requirments
+
+The simplest class which will model the Archive concept specifies the functions that a
+class will look like:
+
+
+The simplest possible input archive class is analogous to the above.
+In the following discussion, only output archives will be addressed.
+Input archives are exactly symmetrical to output archives.
+
+#include <cstddef> // std::size_t
+//////////////////////////////////////////////////////////////
+// class trivial_oarchive
+class trivial_oarchive {
+public:
+ //////////////////////////////////////////////////////////
+ // public interface used by programs that use the
+ // serialization library
+ typedef boost::mpl::bool_<true> is_saving;
+ typedef boost::mpl::bool_<false> is_loading;
+ template<class T> register_type(){}
+ template<class T> trivial_oarchive & operator<<(const T & t){
+ return *this;
+ }
+ template<class T> trivial_oarchive & operator&(const T & t){
+ return *this << t;
+ }
+ void save_binary(void *address, std::size_t count){};
+};
+
demo_trivial_archive.cpp
.
+Of course this program won't produce any output as it is. But it provides
+the starting point for a simple class which can be used to log formated
+output. See the implementation of a simple
+log archive to how this has been done.
+
+More Useful Archive Classes
+The above example is fine as far as it goes. But it doesn't implement
+useful features such as serialization of pointers, class versioning
+and others. This library implements a family of full featuared archive
+classes appropriate for a variety of purposes.
+
+
+
+Given a suitable definitions of
+
+#include <cstddef> // std::size_t
+#include <boost/archive/detail/common_oarchive.hpp>
+
+/////////////////////////////////////////////////////////////////////////
+// class complete_oarchive
+class complete_oarchive :
+ public boost::archive::detail::common_oarchive<complete_oarchive>
+{
+ // permit serialization system privileged access to permit
+ // implementation of inline templates for maximum speed.
+ friend class boost::archive::save_access;
+
+ // member template for saving primitive types.
+ // Specialize for any types/templates that special treatment
+ template<class T>
+ void save(T & t);
+
+public:
+ //////////////////////////////////////////////////////////
+ // public interface used by programs that use the
+ // serialization library
+
+ // archives are expected to support this function
+ void save_binary(void *address, std::size_t count);
+};
+
save
+and save_binary
,
+any program using serialization with a conforming C++ compiler should compile
+and run with this archive class.
+
+Optional Overrides
+
+The detail::common_oarchive
class contains
+a number of functions that are used by various parts of the serialization library
+to help render the archive in a particular form.
+
+
+
+
+
+void save_start()
+Purpose:To inject/retrieve an object name into the archive. Used
+by XML archive to inject "<name " before data.
+void save_end()
+Purpose:To inject/retrieve an object name into the archive. Used
+by XML archive to inject "</name>" after data.
+void end_preamble()
+Purpose:Called each time user data is saved.
+It's not called when archive bookkeeping data is saved. This is used by XML archives
+to determine when to inject a ">" character at end of XML header. XML output archives
+keep their own internal flag indicating that data being written is header data. This
+internal flag is reset when an object start tag is written. When
+void end_preamble()
is invoked and this internal flag is set
+a ">" character is appended to the output and the internal flag is reset. The default
+implementation for void end_preamble()
is a no-op there by permitting it
+to be optimised away for archive classes that don't use it.
+
+template<class T>
+void save_override(T & t, int);
+
archive::save(Archive & ar, t)
+This is the main entry into the serialization library.
+Purpose:This can be specialized in cases where the data is to be written
+to the archive in some special way. For example, XML archives implement special handling for
+name-value pairs by overriding this function template for name-value pairs.
+This replaces the default name-value pair handling, which is just to throw away the name,
+with one appropriate for XML which writes out the start of an XML tag with the correct object name.
+Types used by the serialization library
+The serialization library injects bookkeeping data into the serialization archive.
+This data includes things like object ids, version numbers, class names etc. Each
+of these objects is included in a wrapper so that the archive class can override the
+implementation of void save_override(T & t, int);
.
+For example, in the XML archive, the override for this type renders an object_id equal to 23 as
+"object_id=_23". The following table lists the types defined in the
+boost::archive namespace
+used internally by the serialization library:
+
+
+type
+default
serialized asversion_type
+unsigned int
object_id_type
+unsigned int
object_id_reference_type
+unsigned int
class_id_type
+int
class_id_optional_type
+nothing
class_id_reference_type
+int
tracking_type
+bool
classname_type
+string
save_override
+for these types.
+basic_archive.hpp
.
+All of these types have been assigned an
+implementation level of
+primitive
and are convertible to types such as int, unsigned int, etc.
+so that they have default implementations. This is illustrated by
+basic_text_iarchive.hpp
.
+which relies upon the default. However, in some cases, overrides will have to be
+explicitly provided for these types. For an example see
+basic_xml_iarchive.hpp
.
+
+
+The attached class diagram
+shows the relationships between classes used to implement the serialization library.
+stream
or
+ streambuf
+ as a template parameter rather than simple classes.
+ Combined with the above, even more issues arise with non-conforming compilers.
+Usage
+The newly created archive will usually be stored in its own header module. All
+that is necessary is to include the header and construct an instance of the new archive.
+EXCEPT for one special case.
+
+
+
+To make this work, the following should be included after the archive
+class definition.
+BOOT_CLASS_EXPORT
is used
+ to instantiate the serialization code for the included archives.
+
+Failure to do this will not inhibit the program from compiling, linking
+and executing properly - except in one case. If an instance of a derived
+class is serialized through a pointer to its base class, the program
+will throw an
+
+#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
+
unregistered_class
+exception.
+Testing
+Exhaustive testing of the library requires testing the different aspects of object
+serialization with each archive. There are 46 different tests that can run with any archive.
+There are 5 "standard archives" included with the system.
+(3 in systems don't support wide charactor i/o).
+bjam
testing setup will run all
+the above described tests. This will result in as many as 46 archive tests * 5
+standard archives + 28 general tests = 258 tests. Note that a complete test of the
+library would include DLL vs static library, release vs debug so the actual total
+would be closer to 1032 tests.
+BOOST_ARCHIVE_TEST
+to the name of the header. Here is the header file
+test_archive.hpp
. Test header files for
+other archives are similar.
+
+
+To test a new archive, for example, portable binary archives, with the gcc compiler,
+make a header file
+// text_archive test header
+// include output archive header
+#include <boost/archive/text_oarchive.hpp>
+// set name of test output archive
+typedef boost::archive::text_oarchive test_oarchive;
+// set name of test output stream
+typedef std::ofstream test_ostream;
+
+// repeat the above for input archive
+#include <boost/archive/text_iarchive.hpp>
+typedef boost::archive::text_iarchive test_iarchive;
+typedef std::ifstream test_istream;
+
+// define open mode for streams
+// binary archives should use std::ios_base::binary
+#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
+
portable_binary_archive.hpp
+and invoke bjam
with
+
+This process in encapsulated in the shell or cmd script
+
+-sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
+
library_test
whose command line is
+
+
+library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
+
Polymorphic Archives
+
+Motivation
+
+All archives described so far are implemented as templates. Code to save and load
+data to archives is regenerated for each combination of archive class and data type.
+Under these cirumstances, a good optimizing compiler that can expand
+inline
functions to enough depth will generate fast code.
+However:
+
+
+
+
+
+Implementation
+The solution is the the pair polymorphic_oarchive
+and polymorphic_iarchive
. They present a common interface of virtual
+functions - no templates - that is equivalent to the standard templated one.
+
+This is shown in the accompanying
+class diagram
+demo_polymorphic.cpp
,
+demo_polymorphic_A.hpp
, and
+demo_polymorphic_A
+show how polymorphic archives are to be used. Note the following:
+
+
+As can be seen in the
+class diagram
+and the header files, this implementation is just a composition of the polymorphic
+interface and the standard template driven implementation. This composition is
+accomplished by the templates
+demo_polymorphic_A.hpp
and
+demo_polymorphic_A.cpp
+contain no templates and no reference to any specific archive implementation. That is, they will
+only have to be compiled once for all archive implementations. The even applies to archives classes
+created in the future.
+ demo_polymorphic.cpp
+specifies a specific archive implementation.
+polymorphic_iarchive_route.hpp
+and
+polymorphic_oarchive_route.hpp
.
+As these contain no code specific to the particular implementation archive, they can be used to create
+a polymorphic archive implementation from any functioning templated archive implementation.
+typedef
for polymorphic implementation for each corresponding
+templated one. For example, the headers
+polymorphic_text_iarchive.hpp
+and
+polymorphic_text_oarchive.hpp
.
+contain the typedef
for the polymorphic implementation
+of the standard text archive classes
+text_iarchive.hpp
+and
+text_oarchive.hpp
+respectively. All included polymorphic archives use the same naming scheme.
+Usage
+Polymorphic archives address the issues raised above regarding templated implementation.
+That is, there is no replicated code, and no recompilation for new archives. This will
+result in smaller executables for program which use more than one type of archive, and
+smaller DLLS. There is a
+penalty for calling archive functions through a virtual function dispatch table and there
+is no possibility for a compiler to inline
archive functions. This will result
+in a detectable degradation in performance for saving and loading archives.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Archive Concepts
+
+
+Notation
+In the following descriptions
+
+
+SA
is an type modeling the Saving Archive Concept
+ sa
is an instance of type SA.
+ LA
is an type modeling the Loading Archive Concept
+ la
is an instance of type LA.
+ T
is an Serializable Type
+ x
is an instance of type T Typeu,v
is a pointer to a an instance of type T
+ count
is an instance of a type that can be converted to std::size_t
.
+Saving Archive Concept
+Associated Types
+Intuitively, a type modeling this concept will generate a sequence of bytes
+corresponding to an arbitrary set of C++ data structures. Each type modeling the
+Saving Archive concept (SA) may be associated with another type modeling the
+Loading Archive Concept(LA).
+This associated type will perform the inverse operation.
+That is, given a sequence of bytes generated by SA, it will generate a set of
+C++ data structures that is equivalent to the original.
+The notion of equivalence is defined by the implementations of the pair of archives and the
+way the data are rendered serializable.
+Valid Expressions
+
+
+
+
+ SA::is_saving
+
+ SA::is_loading
+
+ sa << x
+
+ sa & x
+ x
along with other information to sa
.
+ This other information is defined by the implementation of the archive.
+ Typically this information is that which is required by a corresponding
+ Loading Archive type to properly restore the value of x
.
+ sa
.
+
+ sa.save_binary(u, count)
+
size_t(count)
bytes found at
+ u
.
+
+ sa.register_type<T>()
+
+ sa.register_type(u)
+ sa
is a template argument.
+ For more information, see Template Invocation syntax
+
+ sa.get_library_version()
+
Loading Archive Concept
+Associated Types
+Each model of this concept presumes the
+existence of a corresponding type modeling the
+Saving Archive Concept.
+The purpose of an instance of this concept is to convert a sequence of bytes
+generated by this corresponding type to a set of C++ data structures
+equivalent to the original.
+Valid Expressions
+
+
+
+There are archives based on text, binary and XML file
+formats but all have the above interface. Given that all archives present
+the same public interface, specifcation of serialization is exactly the same
+for all archives. Archive classes have other members not mentioned here.
+However they are related to the internal functioning of the library and
+are not meant to be called by users of an archive. Implementation of new
+archives is discussed in
+New Archives - Implementation.
+
+
+ LA::is_saving
+
+ LA::is_loading
+
+ la >> x
+
+ la & x
+ x
to a value retrieved from la
.
+ la
.
+
+ la.load_binary(u, count)
+
la
size_t(count)
bytes and stores
+ them in memory starting at u
.
+
+ la.register_type<T>()
+
+ la.register_type(u)
+ la
is a template argument.
+ For more information, see Template Invocation syntax
+
+ la.get_library_version()
+
+ la.reset_object_address(v, u)
+
+ la.delete_created_pointers()
+
<<
+and >>
suggests
+a relationship between archives and C++ i/o streams. Archives are not
+C++ i/o streams. All the archives included with this system take a stream
+as an argument in the constructor and that stream is used for output or input.
+However, this is not a requirement of the serialization functions or the
+archive interface. It just turns out that the archives written so far have
+found it useful to base their implementation on streams.
+
+Archive Models
+This library includes various implementations of the Archive concept.
+
+An archive is defined by two complementary classes. One is for saving data while
+the other is for loading it.
+
+This library includes a number of archive implementations that are "ready to go" for the
+most common requirements. These classes implement the archive concept for differing data formats.
+They can be used "as is" or as a basis for developing one's own particular type of archive.
+An archive is defined by two complementary classes. One is for saving data while the other is for loading it.
+
+To invoke serialization using one of
+these archives, one or more of the following header files must be
+included in the code module containing the serialization code.
+
+
+All of these archives implement the same inteface. Hence, it should suffice to describe only one
+of them in detail. For this purpose we will use the text archive.
+
+
+
+// a portable text archive
+boost::archive::text_oarchive // saving
+boost::archive::text_iarchive // loading
+
+// a portable text archive using a wide character stream
+boost::archive::text_woarchive // saving
+boost::archive::text_wiarchive // loading
+
+// a portable XML archive
+boost::archive::xml_oarchive // saving
+boost::archive::xml_iarchive // loading
+
+// a portable XML archive which uses wide characters - use for utf-8 output
+boost::archive::xml_woarchive // saving
+boost::archive::xml_wiarchive // loading
+
+// a non-portable native binary archive
+boost::archive::binary_oarchive // saving
+boost::archive::binary_iarchive // loading
+
+
+
+
+
+
+namespace boost {
+namespace archive {
+
+enum archive_flags {
+ no_header = 1, // suppress archive header info
+ no_codecvt = 2, // suppress alteration of codecvt facet
+ no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
+};
+
+} // archive
+} // boost
+
+
+
+namespace boost {
+namespace archive {
+
+class text_oarchive : ...
+{
+ ...
+public:
+ ... // implementation of the Saving Archive concept
+ text_oarchive(std::ostream & os, unsigned int flags = 0);
+ ~text_oarchive();
+};
+
+} // archive
+} // boost
+
+
+
+
+
+text_oarchive(std::ostream & os, unsigned int flags = 0);
+
stream
as
+an argument and optional flags. For most applications there will be no need to use flags.
+Flags are defined by enum archive_flags
enumerator.
+Multiple flags can be combined with the |
operator.
+
+By default, archives prepend
+output with initial data which helps identify them as archives produced by this system.
+This permits a more graceful handling of the case where an attempt is made to load an archive
+from an invalid file format. In addition to this, each type of archive might have
+its own information. For example, native binary archives include information about
+sizes of native types and endianess to gracefully handle the case where it has been
+erroneously assumed that such an archive is portable across platforms. In some cases,
+where this extra overhead might be considered objectionable, it can be suppressed with the
+no_header
flag.
+no_codecvt
flag.
+no_xml_tag_checking
flag.
+
+~text_oarchive();
+
+
+
+namespace boost {
+namespace archive {
+
+class text_iarchive : ...
+{
+ ...
+public:
+ ... // implementation of the Loading Archive concept
+ text_iarchive(std::istream & is, unsigned int flags = 0);
+ ~text_iarchive();
+};
+
+} //namespace archive
+) //namespace boost
+
+
+
+
+
+text_iarchive(std::istream & is, unsigned int flags = 0);
+
stream
as
+an argument and optional flags. If flags are used, they should be the same
+as those used when the archive was created. Function and usage of flags is described
+above.
+
+~text_iarchive();
+
binary_oarchive
and
+binary_iarchive
classes are
+implemented in terms of the more basic
+std::streambuf
. So, in addition
+to the common class interface described above, they include the following
+constructors:
+
+
+
+
+binary_oarchive(std::streambuf & bsb, unsigned int flags = 0);
+
+binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
+
Exceptions
+All of the archive classes included may throw exceptions. The list of exceptions that might
+be thrown can be found in section Archive Exceptions
+of this documentation.
+
+Character Sets
+This library includes two archive classes for XML. The wide character
+version (xml_w?archive
) renders its output as UTF-8 which can
+handle any wide character without loss of information.
+std::string
data is converted from multi-byte format to wide
+character format using the current
+locale
. Hence this version should give a fair rendering of all
+C++ data for all cases. This could result in some unexpected behavior.
+Suppose an std::string
+is created with the locale
character
+set to hebrew characters. On output this is converted to wide characters.
+On input however, there could be a problem if the locale
is
+not set the same as when the archive is created.
+xml_?archive
) renders
+std::string
output without any conversion. Though this may work
+fine for serialization, it may create difficulties if the XML archive is used
+for some other purpose.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Bibliography
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Text Archive Class Diagram
+
+
+
+This diagram shows the relationship between the various classes that implement saving (output
+serialization) for text archives. The hierachy and organization is similar for loading and for
+other types of archives as well. In the diagram, classes written in blue
+implement saving for a given archive type. (in this case its text archives).
+Users include classes in red to save their data from a partcular
+type of archive. Other classes whose names are in black implement the library and should
+never change. They are in
+
+
+basic_oarchive ->
+ |
+ |
+ | interface_oarchive<text_oarchive> ->
+ | /
+ | /
+ | _________/
+ | /
+ | /
+ | /
+common_oarchive<text_oarchive> ->
+ |
+ |
+basic_text_oarchive<text_oarchive> ->
+ |
+ |
+ | basic_text_oprimitive<basic_ostream> ->
+ | /
+ | /
+ | _________/ interface_oarchive<polymorphic_oarchive> ->
+ | / |
+ | / |
+ | / |
+text_oarchive_impl<text_oarchive> -> polymorphic_oarchive_impl ->
+ | \ |
+ | \ |
+ | \_____________________________________ polymorphic_oarchive ->
+ | \ /
+ | \ /
+ | \ /
+text_oarchive -> polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> > ->
+ |
+ |
+ |
+ polymorphic_text_oarchive ->
+
+
+
namespace boost::archive::detail
+
+
+
+ basic_oarchive
+
+ interface_oarchive<text_oarchive>
+
polymorphic_oarchive
+ as well as for archive implementations.
+
+
+ common_oarchive<text_oarchive>
+
basic_oarchive
and the template interface used by archive
+ class implementations.
+
+
+ basic_text_oarchive<text_oarchive>
+
+ basic_text_oprimitive<basic_ostream>
+
+ text_oarchive_impl<text_oarchive>
+
+ text_oarchive
+
text_oarchive_impl<text_oarchive>
.
+ We can't use typedef
because a
+ typedef
can't refer to it self in its definition.
+ This is the class name that is used to serialize to a text archive.
+
+ interface_oarchive<polymorphic_oarchive>
+
common_oarchive
uses.
+
+
+ polymorphic_oarchive
+
save(T &t)
+ for all primitive types T. This is the class that is used to do pre-compile serialization of classes
+ for all archives present and future.
+
+
+ polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> >
+
polymorphic_oarchive
in terms of a specific
+ concrete class. Virtual function calls are routed to the implementing class. In this example,
+ that implementing class would be text_oarchive_impl.
+
+
+ polymorphic_text_oarchive
+
polymorphic_oarchive_route<text_oarchive_impl&'t;text_oarchive> >
+
+
+
+
+
+
+
+
+
+
+
+utf8_codecvt_facet
+template<
+ typename InternType = wchar_t,
+ typename ExternType = char
+> utf8_codecvt_facet
+
+
+
+Rationale
+
+
+ UTF-8 is a method of encoding Unicode text in environments where
+ where data is stored as 8-bit characters and some ascii characters
+ are considered special (i.e. Unix filesystem filenames) and tend
+ to appear more commonly than other characters. While
+ UTF-8 is convenient and efficient for storing data on filesystems,
+ it was not meant to be manipulated in memory by
+ applications. While some applications (such as Unix's 'cat') can
+ simply ignore the encoding of data, others should convert
+ from UTF-8 to UCS-4 (the more canonical representation of Unicode)
+ on reading from file, and reversing the process on writing out to
+ file.
+
+ Template Parameters
+
+
+
+
+
+
+
+
+Parameter Description Default
+
+
+
+InternType
+The internal type used to represent UCS-4 characters.
+wchar_t
+
+
+ExternType
+The external type used to represent UTF-8 octets.
+char_t
+Requirements
+
+ utf8_codecvt_facet defaults to using char as
+ it's external data type and wchar_t as it's internal
+ datatype, but on some architectures wchar_t is
+ not large enough to hold UCS-4 characters. In order to use
+ another internal type.You must also specialize std::codecvt
+ to handle your internal and external types.
+ (std::codecvt<char,wchar_t,std::mbstate_t> is required to be
+ supplied by any standard-conforming compiler).
+
+
+Example Use
+ The following is a simple example of using this facet:
+
+
+ //...
+ // My encoding type
+ typedef wchar_t ucs4_t;
+
+ std::locale old_locale;
+ std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);
+
+ // Set a New global locale
+ std::locale::global(utf8_locale);
+
+ // Send the UCS-4 data out, converting to UTF-8
+ {
+ std::wofstream ofs("data.ucd");
+ ofs.imbue(utf8_locale);
+ std::copy(ucs4_data.begin(),ucs4_data.end(),
+ std::ostream_iterator<ucs4_t,ucs4_t>(ofs));
+ }
+
+ // Read the UTF-8 data back in, converting to UCS-4 on the way in
+ std::vector<ucs4_t> from_file;
+ {
+ std::wifstream ifs("data.ucd");
+ ifs.imbue(utf8_locale);
+ ucs4_t item = 0;
+ while (ifs >> item) from_file.push_back(item);
+ }
+ //...
+
+
+
+History
+
+ This code was originally written as an iterator adaptor over
+ containers for use with UTF-8 encoded strings in memory.
+ Dietmar Kuehl suggested that it would be better provided as a
+ codecvt facet.
+
+Resources
+
+
+
+
+
+
+
+
+
+
+Copyright © 2001
+Ronald Garcia,
+Indiana University
+(garcia@osl.iu.edu)
+
+Andrew Lumsdaine,
+Indiana University
+(lums@osl.iu.edu)Contents
+
+
+
+
+
+
+
diff --git a/deal.II/contrib/boost/libs/serialization/doc/dataflow.html b/deal.II/contrib/boost/libs/serialization/doc/dataflow.html
new file mode 100644
index 0000000000..3bc14454c4
--- /dev/null
+++ b/deal.II/contrib/boost/libs/serialization/doc/dataflow.html
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
extended_type_info
+
+
void_cast
+ utf8_codecvt_facet
+ BOOST_STRONG_TYPEDEF
+ state_saver
+ smart_cast
+ BOOST_STATIC_WARNING
+ singleton
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Dataflow Iterators
+
+Motivation
+Consider the problem of translating an arbitrary length sequence of 8 bit bytes
+to base64 text. Such a process can be summarized as:
+
+
+The approach that comes closest to meeting these requirements is that described
+and implemented with Iterator Adaptors.
+The fundamental feature of an Iterator Adaptor template that makes in interesting to
+us is that it takes as a parameter a base iterator from which it derives its
+input. This suggests that something like the following might be possible.
+
+Indeed, this seems to be exactly the kind of problem that iterator adaptors are
+intended to address. The Iterator Adaptor library already includes
+modules which can be configured to implement some of the operations above. For example,
+included is
+transform_iterator, which can be used to implement 6 bit integer => base64 code.
+
+
+typedef
+ insert_linebreaks< // insert line breaks every 72 characters
+ base64_from_binary< // convert binary values ot base64 characters
+ transform_width< // retrieve 6 bit integers from a sequence of 8 bit bytes
+ const char *,
+ 6,
+ 8
+ >
+ >
+ ,72
+ >
+ base64_text; // compose all the above operations in to a new iterator
+
+std::copy(
+ base64_text(address),
+ base64_text(address + count),
+ ostream_iterator<CharType>(os)
+);
+
Dataflow Iterators
+Unfortunately, not all iterators which inherit from Iterator Adaptors are guarenteed
+to meet the composability goals stated above. To accomplish this purpose, they have
+to be written with some additional considerations in mind.
+
+We define a Dataflow Iterator as an class inherited from iterator_adaptor
which
+fulfills as a small set of additional requirements.
+
+Templated Constructors
+
+When these constructors are applied to our example of above, the following code is generated:
+
+template<class T>
+dataflow_iterator(T start) :
+ iterator_adaptor(Base(start))
+{}
+
+The recursive application of this template is what automatically generates the
+constructor
+std::copy(
+ insert_linebreaks(
+ base64_from_binary(
+ transform_width(
+ address
+ ),
+ )
+ ),
+ insert_linebreaks(
+ base64_from_binary(
+ transform_width(
+ address + count
+ )
+ )
+ )
+ ostream_iterator<char>(os)
+);
+
base64_text(const char *)
in our example above. The original
+Iterator Adaptors include a make_xxx_iterator
to fulfill this function.
+However, I believe these are unwieldy to use compared to the above solution usiing
+Templated constructors.
+
+This macro is defined in <boost/serialization/pfto.hpp>.
+For more information about this topic, check the source.
+
+
+std::copy(
+ base64_text(BOOST_MAKE_PFTO_WRAPPER(address)),
+ base64_text(BOOST_MAKE_PFTO_WRAPPER(address + count)),
+ ostream_iterator<char>(os)
+);
+
Dereferencing
+Dereferencing some iterators can cause problems. For example, a natural
+way to write a remove_whitespace
iterator is to increment past the initial
+whitespaces when the iterator is constructed. This will fail if the iterator passed to the
+constructor "points" to the end of a string. The
+
+filter_iterator
is implemented
+in this way so it can't be used in our context. So, for implementation of this iterator,
+space removal is deferred until the iterator actually is dereferenced.
+
+Comparison
+The default implementation of iterator equality of iterator_adaptor
just
+invokes the equality operator on the base iterators. Generally this is satisfactory.
+However, this implies that other operations (E. G. dereference) do not prematurely
+increment the base iterator. Avoiding this can be surprisingly tricky in some cases.
+(E.G. transform_width)
+
+Iterators Included in the Library
+Dataflow iterators for the serialization library are all defined in the hamespace
+boost::archive::iterators
included here are:
+
+
+boost::filter_iterator
wchar_t
+as unsigned short integers (E.G. VC 6) they didn't function as I expected. I also made some
+adjustments to be consistent with our concept of Dataflow Iterators. Like the rest of our
+iterators, they are found in the namespace boost::archive::interators
to avoid
+conflict the standard library version.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Derivation from an Existing Archive
+
+
+
+
+Log Archive
+It may happen that one wants to create a new archive class by derivation from one
+of the included ones. Included is a sample program that shows how to derive a
+new archive from one of the ones included with the library. The first example is
+
+demo_log.cpp.
+
+
+
+xml_oarchive_impl
+ NOT xml_oarchive
+As described in the comments in
+xml_oarchive.hpp.
+xml_oarchive
really a shorthand name for
+xml_oarchive_impl<xml_oarchive>
. So we should derive
+from xml_oarchive_impl<log_archive>
rather
+than xml_oarchive
.
+
+
+class log_archive :
+ // don't derive from xml_oarchive !!!
+ public xml_oarchive_impl<log_archive>
+{
+...
+
log_archive
between the <>
+This is required so that base classes can downcast their this
pointer
+to the most derived class. This is referred to as Curiously Recurring
+Template Pattern (CRTP) [11].
+It is used to implement static polymorphism.
+
+
+
+ friend class detail::common_oarchive<log_archive>;
+ friend class basic_xml_oarchive<log_archive>;
+ friend class boost::serialization::save_access;
+
save_override
+for saving primitives. Usage of a function name in a derived class
+"hides" similarly named functions of the base class. That is,
+function name overloading doesn't automatically
+include base classes. To address this, we can use:
+
+which should work on conforming compilers. However, I have found
+that the following equivalent works on more compilers.
+
+ using xml_oarchive_impl<derived_t>::save;
+ void save(const unsigned int t);
+ ...
+
+so it's what I use.
+
+ // default fall through for any types not specified here
+ template<class T>
+ void save(const T & t){
+ xml_oarchive_impl<derived_t>::save(t);
+ }
+ void save(const unsigned int t);
+ ...
+
+for just this purpose. Failure to include required template definitions
+will result in undefined symbol errors when the program is linked.
+
+// explicitly instantiate for this type of binary stream
+#include <boost/archive/basic_binary_oprimitive.ipp>
+
+Base classes using CRTP must be templates with a parameter corresponding to
+the most derived class. As presented here, this class doesn't qualify, so
+it cannot be used as a base class. In order to derive further from this class,
+it would have to be reorganized along the lines of the original xml_oarchive
.
+Specifically, it would look something like:
+
+
+
+template<class Archive>
+class log_archive_impl :
+ // don't derive from xml_oarchive !!!
+ public xml_oarchive_impl<Archive>
+{
+ ...
+);
+
+// do not derived from this class !!!
+class log_archive :
+ public log_archive_impl<log_archive>
+{
+public:
+ log_archive(std::ostream & os, unsigned int flags = 0) :
+ log_archive_impl<xml_oarchive>(os, flags)
+ {}
+};
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Exception Safety
+
+The process of loading an archive may result in the creation of new objects. That
+same process may throw an exception at some point. In order to prevent memory leaks
+and invalid pointers, these situations must be considered. Unfortunately, there is
+no simple universal solution to this problem. The manner of addressing this must
+depend on the design of the data structures to be serialized. Below, we discuss
+varying scenarios in increasing order of difficulty. This discussion presumes that
+the class member functions are exception safe before considering serialization.
+That is, the destructor could be called at anytime without referencing
+an invalid pointer, or creating a memory leak.
+
+
+class contains no pointers
+ No problem here.
+ class contains only owned pointers
+ From here on, we have to make a distinction between pointers used
+ to manage heap storage (owned pointers) and pointers used to refer
+ to related objects (referenced pointers). Programs containing owned
+ pointers must contain code for deleting these objects and returning the
+ deallocated storage to the heap. Programs containing referenced pointers
+ must be designed to ensure that no such referenced pointers are de-referenced
+ after the object pointed to has been destroyed and its storage returned
+ to the heap. If a pointer is stored in only one place, it must be an owned
+ pointer.
+ class contains one or more referenced pointers
+ This situation can be further subdivided into two cases
+
+
+ owned pointers are always serialized before referenced pointers
+ Object tracking will ensure that no new objects will be created
+ by the loading of a referenced pointer.
+ If an exception occurs, referenced pointers will not need to be deleted
+ so there will be no memory leaks. The destructor of this class won't attempt to
+ delete these pointers so there will be no problem with dangling references.
+ owned pointers are handled exactly as described above.
+ class contains referenced pointers which might be created by load
+ If a referenced pointer is loaded before its corresponding owned
+ pointer, the object will be allocated on the heap. In certain cases
+ it cannot be known which pointers were created by their owners and which
+ were created by the load function. To address this:
+
+
+ demo_exception.cpp
+ is a program that illustrates this case.
+ try/catch
block.
+ delete_created_pointers()
to delete any pointers
+ created by the class load. Without out other action, objects created in
+ this way would end up as memory leaks as they are not considered owned
+ pointers and hence aren't destroyed.
+ Other cases
+ Situations not covered above are pointers for which the classifications of
+ referenced and owned are not applicable. This might occur where
+ pointers are created by one class but consumed and deleted by another. These
+ may be addressed with an ad hoc analysis similar to the above. As the
+ situation becomes more complex this becomes more difficult and error prone.
+ Eventually, it will be have to addressed by building heap management into the
+ pointer itself - that is into boost::shared_ptr
.
+ The library includes serialization of boost::shared_ptr
. As
+ previously mentioned, this required a tiny alteration in one of the
+ boost::shared_ptr
implementation files in order to permit
+ access by the serialization system.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Archive Exceptions
+
+
+
+
+Archive operators can throw a unregistered_class
+ invalid_signature
+ unsupported_version
+ unsupported_class_version
+ pointer_conflict
+ incompatible_native_format
+ array_size_too_short
+ stream_error
+ invalid_class_name
+ unregistered_class
+ multiple_code_instantiation
+ xml_archive_parsing_error
+ xml_archive_tag_mismatch
+ xml_archive_tag_name_error
+boost::archive_exception
+object which can be caught by an application program. These exceptions are defined
+in the files
+archive_exception.hpp
+and
+basic_xml_archive.hpp.
+
+
+namespace boost {
+namespace archive {
+
+class archive_exception : public std::exception
+{
+public:
+ typedef enum {
+ unregistered_class, // attempt to serialize a pointer of an
+ // an unregistered class
+ invalid_signature, // first line of archive does not contain
+ // expected string
+ unsupported_version, // archive created with library version subsequent
+ // to this one
+ pointer_conflict // an attempt has been made to directly serialize
+ // an object after having already serialized the same
+ // object through a pointer. Were this permitted,
+ // it the archive load would result in the creation
+ // of extraneous object.
+ incompatible_native_format, // attempt to read native binary format
+ // on incompatible platform
+ array_size_too_short, // array being loaded doesn't fit in array allocated
+ stream_error // i/o error on stream
+ invalid_class_name, // class name greater than the maximum permitted.
+ // most likely a corrupted archive or an attempt
+ // to insert virus via buffer overrun method.
+ unregistered_cast, // base - derived relationship not registered with
+ // void_cast_register
+ unsupported_class_version, // type saved with a version # greater than the
+ // one used by the program. This indicates that the proggram
+ // needs to be rebuilt.
+ multiple_code_instantiation // code for implementing serialization for some
+ // type has been instantiated in more than one module.
+ } exception_code;
+ exception_code code;
+ archive_exception(exception_code c) : code(c) {}
+ virtual const char *what( ) const throw();
+};
+
+class xml_archive_exception : public virtual archive_exception
+{
+public:
+ typedef enum {
+ xml_archive_parsing_error, // archive doesn't contain expected data
+ xml_archive_tag_mismatch, // start/end tag in archive doesn't match program
+ xml_archive_tag_name_error // tag name contains invalid characters
+
+ } exception_code;
+ xml_archive_exception(exception_code c){}
+ virtual const char *what( ) const throw();
+};
+
+} // archive
+} // boost
+
+An attempt has been made to serialize a polymorphic class through a pointer
+without either registering it or associating it with an export key. This can also occur
+when using a new archive how class name has not been added to the system with the
+unregistered_class
BOOST_ARCHIVE_CUSTOM_ARCHIVE_TYPES
macro.
+
+
+Archives are initiated with a known string. If this string is not found when
+the archive is opened, It is presumed that this file is not a valid archive and this
+exception is thrown.
+
+invalid_signature
+This system assigns a version number of 3 to all archives created. Note that this is in
+no way related to version number of classes used by application programs. This refers
+to the version of the serialization system used to create the archive. Future versions
+of this serialization system will be able to identify archives created under previous
+(i.e. this) system and alter the loading procedure accordingly. Hence, future enhancements
+to this serialization system should not obsolete any existing archive files. It is only
+necessary to increment this version number when the newer system creates archives
+incompatible in format with the current one.
+unsupported_version
+An attempt has been made to load a class whose version has been incremented since the
+program was written. Suppose that a class has been assigned version number 3 and the program
+has been built and sent to third parties. Now suppose that the definition of that class
+has been altered, the version number has been incremented to 4 and new archives have been
+built. If one attempts to load these new archives with the original program, this
+exception will be thrown.
+
+unsupported_class_version
+To understand what this exception means consider the following scenario
+pointer_conflict
+An object is saved first through a pointer then directly. Upon loading back
+in the same sequence, we first create an new object and load in its data. Then
+we load the data into another existing object. Where we started with one
+object during save, we have two objects after restore. In a more realistic
+situation, it could be very difficult to find this error. Fortunately,
+these situations can be detected when the archive is created. When
+this occurs, this exception is thrown.
+
+
+template<class Archive>
+void T::save(Archive &ar) const
+{
+ const A * aptr = &a;
+ ar << aptr; // save an instance of object of class A through a pointer
+ ...
+ ar << a; // save an instance of an object of class A
+ assert(aptr == &a); // this must be true
+}
+
+template<class Archive>
+void T::load(Archive &ar)
+{
+ A * aptr;
+ ar >> aptr; // create and initialize a new instance of class A
+ ...
+ ar >> a; // restore state of on object of class A
+ assert(aptr == &a); // this won't be true
+}
+
+The library currently supports char text, wide char text and native binary
+archive files. At the beginning of every archive, a signature is written indicating
+the type of archive. This exception is thrown when an attempt is made to read
+an archive written in a different format.
+
+incompatible_native_format
+An attempt has been made to read an array that is larger than the array size.
+This should only occur when the size of an array in code is reduced after an
+archive has already been created.
+
+array_size_too_short
+An error has occured during stream input or ouput. Aside from the common
+situations such as a corrupted or truncated input file, there are
+several less obvious ones that sometimes occur.
+stream_error
+use
+
+std::stringstream ss;
+std::vector<V> v;
+boost::archive::text_oarchive oa(ss);
+oa << v;
+boost::archive::text_iarchive ia(ss);
+ia >> v;
+
+
+std::stringstream ss;
+std::vector<V> v;
+{
+ boost::archive::text_oarchive oa(ss);
+ oa << v;
+}
+{
+ boost::archive::text_iarchive ia(ss);
+ ia >> v;
+}
+
+Class name length greater than the maximum permitted. Most likely cause is a corrupted
+archive or an attempt to insert virus via buffer overrun method.
+
+invalid_class_name
+In order to support casting between pointers of base and derived classes
+at runtime, a collection of legitimate conversions is maintained by the system.
+Normally this collection is maintained without any explicit action
+on the part of the user of the library. However, there are special cases
+where this might have to be done explicitly and could be overlooked. This
+is described in Runtime Casting.
+This exception is thrown if an attempt is made to convert between two pointers
+whose relationship has not been registered,
+
+unregistered_cast
+This exception is thrown when it is detected that the serialization of the same type
+has been instantiated more that once. This might occur when
+serialization code is instantiated in both the mainline and one or more DLLS.
+
+multiple_code_instantiation
+The XML generated by the serialization process is intimately coupled to the
+C++ class structure, relationships between objects and the serialization
+specifications. If these become out of sync in any way, the XML may not map
+to the loading serialization and this exception might be thrown. This might
+occur for one of the following reasons:
+xml_archive_parsing_error
+
+
+
+This exception will be thrown if the start or end tag of and XML element doesn't match
+the name specified for the object in the program.
+
+xml_archive_tag_mismatch
+This exception will be thrown if the tag name contains invalid characters. Valid characters
+for an XML tag are: upper and lower case letters, digits, and the following punctuation: .(period),
+_(underscore), :(colon), and -(hyphen).
+
+xml_archive_tag_name_error
+
+
+
+
+
+
+
+
+
+ Serialization
+
+ extended_type_info
+
+
+
+Motivation
+The serialization library needs a system like
+type_info/typeid()
to perform
+the following functions
+
+
+The problem with
+std::type_info
+
+std::typeid()
+ is not available in all environments. Support for this function depends upon
+ runtime typing(RTTI) support from the compiler. This may be non-existent
+ or not enabled for reasons such as a percieved inefficiency.
+ std::type_info
includes a string
+ containing type name. This would seem to satisfy 2) above.
+ But the format of this string is not consistent accross compilers, libraries,
+ and operating systems. This makes it unusable for support of portable archives.
+ Features
+
+extended_type_info
is an implementation
+of std::type_info
functionality with the
+following features:
+
+
+
+Exported types are maintained in a global table so that given a string key, the
+corresponding type can be found. This facility is used by the serialization library
+in order to construct types serialized through a base class pointer.
+
+extended_type_info
records - one for each type
+ serialized.
+ typeid()
to find the external identifier
+ of a class while another might not.
+Runtime Interface
+
+
+namespace boost {
+namespace serialization {
+
+class extended_type_info
+{
+protected:
+ // this class can't be used as is. It's just the
+ // common functionality for all type_info replacement
+ // systems. Hence, make these protected
+ extended_type_info(
+ const unsigned int type_info_key,
+ const char * key
+ );
+ ~extended_type_info();
+ void key_register();
+ void key_unregister();
+public:
+ const char * get_key() const;
+ bool operator<(const extended_type_info &rhs) const;
+ bool operator==(const extended_type_info &rhs) const;
+ bool operator!=(const extended_type_info &rhs) const {
+ return !(operator==(rhs));
+ }
+ // for plugins
+ virtual void * construct(unsigned int count = 0, ...) const;
+ virtual void destroy(void const * const p) const;
+ static const extended_type_info * find(const char *key);
+};
+
+} // namespace serialization
+} // namespace boost
+
extended_type_info
+instance created for each type. However, this is enforced only at the executable
+module level. That is, if a program includes some shared libraries or DLLS,
+there may be more than one instance of this class correponding to a particular type.
+For this reason the comparison functions below can't just compare the addresses of
+this instance but rather must be programmed to compare the the actual information
+the instances contain.
+
+
+
+
+
+extended_type_info(unsigned int type_info_key, const char *key);
+
+void key_register();
+void key_unregister();
+
extended_type_info
records.
+This table is used when loading pointers to objects serialized
+through a base class pointer. In this case, the archive
+contains a string which is looked up in this table to
+determine which extended_type_info
+to use for creating a new object.
+extended_type_info
+to add and remove entries from this table.
+
+const char *get_key() const;
+
extended_type_info
+instance. If no key has been associated with the instance, then a NULL is returned.
+
+bool operator<(const extended_type_info & rhs) const;
+bool operator==(const extended_type_info & rhs) const;
+bool operator!=(const extended_type_info & rhs) const;
+
+extended_type_info
+
+
+objects. They impose a strict total ordering on all
+extended_type_info
records.
+
+virtual void * construct(unsigned int count = 0, ...) const;
+
+extended_type_info
+
+
+record corresponds. This function takes variable list of up to 4 arguments
+of any type. These arguments are passed to the type's constructor
+at runtime. In order to use the facility,
+one must declare a type sequence for the constructor arguments.
+Arguments for this function must match in number and type
+with those specified when the type was exported.
+This function permits one to create instances of
+any exported type given only the exported GUID assigned
+with BOOST_CLASS_EXPORT.
+If these types are defined in DLLS or shared libraries. When these modules
+are loaded at runtime, these constructor can be called until the module
+is unloaded. These modules are referred to as plugin.
+
+
+virtual void destroy(void const * const p) const;
+
+static const extended_type_info * find(const char *key);
+
extended_type_info
+object.
+
+Requirements for and Implementation
+In order to be used by the serialization library, an implementation of
+extended_type_info
,
+(referred to as ETI here), must be derived from
+
+
+extended_type_info
+
+
+and also implement the following:
+
+
+
+
+
+
+template<class ETI>
+const extended_type_info *
+ETI::get_derived_extended_type_info(const T & t) const;
+
extended_type_info
+instance that corresponds to
+the "true type" of the type T. The "true type" is the lowest type in the
+hierarchy of classes. The type T can always be cast to the "true type" with
+a static cast. Implemention of this function will vary among type id systems
+and sometimes will make presumptions about the type T than can be identified
+with a particular extended_type_info
implementation.
+
+virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
+
extended_type_info
implementation.
+
+virtual bool ETI::is_equal(const extended_type_info &rhs) const;
+
extended_type_info
implementation.
+Return true
if the types referred
+to are the same. Otherwise return
+false
+
+const char ETI::get_key() const;
+
+virtual void * construct(unsigned int count, ...) const;
+
+virtual void * destroy(void const * const ptr ) ) const;
+
Models
+The serialization library includes two distinct
+extended_type_info
+implementatio's.
+
is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled
+by the compiler.
+
+extended_type_info_typeid
+is implemented in a way that doesn't rely on the existence RTTI.
+Instead, it requires that all polymorphic types be explictly exported.
+In addition, if the export facility is to be used to serialize types
+through base class pointers, those types are required to implement
+a virtual function with the signature:
+
+
+extended_type_info_no_rtti
+which returns a unique string the most derived object this class.
+This function must be virtual in order to implement the functionality required by
+
+virtual const char * get_key();
+
ETI::get_derived_extended_type_info
+as described above.
+
+Example
+The test program test_no_rtti
+implements this function in terms of the
+extended_type_info
API above to return the export key associated with the class.
+This requires that non-abstract types be exported. It also demonstrates the
+inter-operability with between two different implementations of
+extended_type_info
.
+
+Requirements for Each Type
+Each type to be managed by the system must be
+"registered" individually. This is accomplished by instantiating
+templates. For example, if the type T is to use the type_info system
+one would include the following code:
+
+
+
+For those using the serialization library, this step can be skipped
+as it is done automatically. The serialization library includes
+the macro:
+
+
+namespace boost {
+namespace serialization {
+template
+struct extended_type_info_typeid>T>;
+template
+struct extended_type_info_typeid>const T>;
+} // serialization
+} // boost
+
+
+which is used to specify which
+BOOST_CLASS_TYPE_INFO(
+ my_type,
+ extended_type_info_typeid>my_class>
+)
+
extended_type_info
system is to
+be used for a given type.
+extended_type_info
includes a facility for constructing
+instances of types without knowing what the exact types are. This is done
+with the function
+
+virtual void * extended_type_info::construct(unsigned int count = 0, ...) const;
+
+. For example:
+
+
+
+struct base {
+...
+};
+struct derived : public base {
+...
+};
+...
+extended_type_info *eti = extended_type_info::find("my_class")
+base * b = eti->construct(...);
+
+The construct
takes an argument count and up to
+four parameters of any type. The arguments are passed to the
+constructor of "my_class".
+
+
+A complete example of this can be found
+here
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serialization
+
+ Tips and Tricks
+
+This section will be used to list answers to questions raise in the mailing
+lists. Most of these are due to subtle aspects of the library which are
+overlooked even though they might be described in the documenation. Often,
+these issues are very easy to address - but can be excruciating difficult to
+find. Should you have such an experience, feel free to vent your frustration
+in a constructive way by adding in your own item. The best way to do this
+is to create a "TRAK" item
+which includes the text you want to add to this list.
+
+
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Code Structure
+
+
+
+
+This library includes a large number of files. The are organized and classified
+according to purpose listed in the above index.
+namespace
of a classes and templates is syncronized
+with the directory in which the file is found. For example, the class declaration
+
+is included with the following declaration
+
+boost::archive::text_oarchive
+
+
+
+
+#include <boost/archive/text_oarchive.hpp>
+
Files Included by User Programs
+Using this library entails including headers listed in this section.
+It should not be necessary to explictly include any other header files.
+
+
+Archive Implementations
+These header files contain declarations used to save and restore data to each type
+of archive. Include the archives according to the facilities the code module requires.
+
+
+
+
+
+
+Serialization Declarations
+To specify how a type is serialized, one codes templates for serialization functions.
+In the simplest cases, this does not require the inclusion of any header files for this purpose.
+In most cases one or more of the following header files will have to be included in order
+to complete or refine the description of the serializaition implementation for a given class.
+
+
+
+
+
+This group will be required less frequently. The are used to override aspects of
+the default implementation of the serialization process for specified types.
+
+
+
+
+
+
+Serialization Implementations
+This group of headers includes templates which implement serialization for Standard
+Library or Boost Library templates. Any program which uses these templates can
+invoke serialization of objects of these types just by including the corresponding header.
+
+
+includes the code to implement serialization of the STL
+
+#include <boost/serialization/list.hpp>
+
std::list
type. While
+
+
+
+includes code to implement serialization of the BOOST
+#include <boost/serialization/shared_ptr.hpp>
+
boost::shared_ptr
type.
+
+Note that including the serialization header for a type automatically includes the
+appropriate header of the type to be serialized.
+
+As of this writing, the library includes templates of all STL library templates as well
+as templates for boost::optional
,
+boost::shared_ptr
, and
+boost::scoped_ptr
.
+Presumably, this list will expand with the passage of time.
+
+
+Files Which Implement the Library
+
+
+Archive Development
+These header files contain declarations for basic types used to create
+concrete archive types that are made available to users above. Users wishing
+to make their own type of archive may want to examine these headers to
+see how the archives included with the libary have been constructed.
+
+
+
+
+
+
+class_id_type
and others to
+record information in archives that is required to reconstruct the original
+data structure. These are handled exactly as any other serializable type.
+That is, the can be handled as simple primitives such as they are in simple
+text files, or with special code as they are in xml archives.
+basic_xml_oarchive.hpp
+includes code to guarentee that any object not attached to a name will
+trap during compile time. On the other hand, basic_text_oarchive.hpp
+contains code to strip out and ingore any names attached to objects.
+Archive Internals
+
+The interface (see Archive Concepts)
+and implementation are factored out into separate classes to minimize code duplication.
+
+These files are found in the directory
+boost/archive/detail.
+These are included as necessary by the archive class implemenations listed above.
+This has the unfortunate side effect of making the implementation less transparent.
+of the library in order to implement either a class serialization or a new
+archive type. Users should never find it necessary to change these files.
+save_override
in the most derived
+archive class.
+save_override
is declared and implemented in each class in
+the archive hierarchy.
+
+
+
+Note the usage of
+Partial Function Template Ordering
+to permit the correct save implementation to be selected.
+
+
+
+
+template
Archive Library Code Modules
+Parts of the library are implemented as library code. All of this code is to be found in
+libs/serialization/src.
+in the form of *.cpp. The directory
+boost/archive/impl
+contains *.ipp files which implement templates. These templates are instantiated
+only by archive implementation so are generally not included in user code modules.
+
+
+An example of this is the usage of the spirit library in the library.
+It takes a long time to compile and includes lots of other files. Having this
+only in the library is much more convenient that having to include in every
+program which uses xml serialization.
+
+
+Dataflow Iterators
+In the course of developing this library, it became convenient to make a set
+of composable iterator adaptors for handling archive text. Applications include
+escaping and unescaping xml text, implementi'g to/from base64 conversion among
+others.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ History
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ base64
character encoding.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Implementation Notes
+
+
+
+
+Partial Function Template Ordering
+Not all C++ compilers correctly support partial function template ordering (PFTO).
+For these compilers, the following code will fail to compile:
+
+The serialization library works around this issue by using a different
+default definition of the first template:
+
+template<class Archive, class T>
+void serialize(
+ Archive & ar,
+ T & t,
+ const unsigned int file_version
+){
+ ...
+}
+
+template<class Archive, class T>
+void serialize(
+ Archive & ar,
+ my_template<T> & t,
+ const unsigned int file_version
+){
+ ...
+}
+
+Now, the second template is not matched with the first one so there
+is no PFTO and no compile error. When the serialization library invokes
+
+template<class Archive, class T>
+void serialize(
+ Archive & ar,
+ T & t,
+ const unsigned long int file_version // Note: change to long
+){
+ ...
+}
+
+the function declaration is first matched against templates with
+an integer for the third argument. If there is a match, the matching
+template is instantiated and later invoked. If there is no match,
+an attempt is made to match other templates by converting arguments to other types.
+In this case the third argument can be converted to long to match
+the first template - which is the default. So in this case, the first
+template will be instantiated and later invoked. We have managed to
+use function overloading to achieve the same effect as PFTO
+were it correctly implemented.
+
+serialize(ar, t, 0);
+
BOOST_PTFO
which
+is defined to be long
+for non-conforming compilers and nothing for conforming ones. So
+the default definition is really:
+The serialization library works around this issue by using a different
+default definition of the first template:
+
+
+
+template<class Archive, class T>
+void serialize(
+ Archive & ar,
+ T & t,
+ const unsigned BOOST_PFTO int file_version // Note: change to BOOST_PFTO
+){
+ ...
+}
+
Character Encoding
+The whole question of character encoding combined with wide characters
+is much more complicated than it would seem to be. The current library
+defines in 3 formats (text, binary, and XML), wide and narrow characters,
+an attempts to be portable between compiler libraries. The results of
+a rather long consideration of all these factors has been to set
+default encoding according to the following rules.
+
+
+This character encoding is implemented by changing the text_?archive
) will produce
+ text output in the current stream locale
. Generally this will
+ produce no changes in string data.
+ ios::binary
.
+ Failure to do so will result in 0x0d characters (carriage-return)
+ characters being removed from the input stream if they are followed
+ by a 0x0a character (line-feed). This could corrupt the input
+ and make the file unreadable. On UNIX systems the ios::binary
+ is not required and is ignored if used.
+ locale
.
+ locale
of the
+i/o stream used by an archive when the archive is constructed, the stream
+local is changed back to its original value. This action can be overridden
+by specifying boost::archive::no_codecvt
+when the archive is opened. In this case, the stream locale
will
+not be changed by the serialization library.
+std::string
data stored in archives.
+Suppose a normal (multi-byte) character string
+is written to a wide character stream. Our system uses the current locale
+to translate it to a wide character string before writing it out.
+Upon reading, it is translated back to a (multi-byte)string.
+If the locale
on the platform that reads the archive is different than
+the locale
on the platform that wrote the stream, the actual string data
+may be altered by the serialization process. To avoid this, either
+avoid usage of locale
dependent multi-byte strings or be sure that
+the locale
is set correctly before reading the archive.
+
+
+Naturally, the input process has to be symmetrical.
+locale
to use
+ boost::archive::codecvt_null<OStream::char_type>
+ no_codecvt
.
+Partial Template Specialization
+Compilers which fail to support partial template specialization will fail to compile
+the following code. To make this compiler, the const
has to be removed.
+
+
+void f(A const* a, text_oarchive& oa)
+{
+ oa << a;
+}
+
Template Invocation syntax
+Some compilers may not recognize the syntax:
+
+for "registering" derived pointers of polymorphic classes. The actual
+function prototype is:
+
+ar.template register_type<T>();
+
+so that one may write
+template<T>
+void register_type(T * t = NULL);
+
ar.register_type(static_cast<T *>(NULL))
instead of
+the syntax described above.
+
+Specific Compiler/Library Issues
+
+GCC 3.X, 4.X
+
+
+
+
+ -Wno-non-virtual-dtor
+ -Wno-ctor-dtor-privacy
+
GCC 2.95
+All of the above plus:
+
+
+Intel C++ 8.0
+No known issues. All tests compile and run in debug and release modes.
+
+Visual C++ 8.0
+This compiler emits warnings for calls to functions from the standard
+library which are deemed security risks. The serialization depends upon
+making some of these calls so programs which use the serialization library
+will get warning messages. These messages can be suppressed from the command
+line by including the following switch:
+
+
+
+ /wd4996
+
Visual C++ 7.1
+Derivation from an archive class defined in a DLL as described in ... will not work.
+This is due to the way that VC++ handles templated code with __decl(dllexport) and
+__decl(dllimport) specifications. Basically, this compiler requires that all the
+instantiations have the same specification - even though they have different
+template arguments. The example
+demo_portable_iarchive.cpp
would have to reformulated as a library or dll
+similar to the pre-defined archives in order to function.
+wchar_t
as either
+a short integer or an intrinsic type.
+If /Zc:wchar_t
is specified on the
+compile command line, wchar_t
will be
+considered an intrinsic type - otherwise
+it will be treated as a synonym for a 16 bit integer. The library can be used
+either way - BUT - both the libray AND the application
+must be compiled with the same switch settings. Note that BJAM
+includes this switch by default. So if want to use the libraries that
+BJAM
builds, you should include this switch
+when you compile your own applications.
+Using the Visual C++ IDE
+The library includes a VC++ 7.1 "Solution" - BoostSerializationLibrary
+along with of a set of project files - one for each demo and test. Consider the following if you
+decided to use these configurations.
+
+
+
+bin
subdirectory
+ within one's main boost directory. Below this there is a whole structure which maintains
+ object and library files according to the type of build. The easiest way to build this is to
+ invoke the runtest script which uses bjam. (see below) If the libraries are not in these locations,
+ the projects will have to be modified accordingly.
+ BOOST_ALL_DYN_LINK=1
.
+ Note that for the executables to run, the PATH
+ environmental variable will have to include the directories that contain the DLL versions of
+ the boost libraries.
+
+
+ This will build the serialization library and run the tests on your system. If there are more than a
+ a couple of test failures, you likely won't be able to get your own projects working. If most of the
+ tests pass, you can be confident that your own projects will work once you get your project settings
+ in sync with those included here.
+Visual C++ 7.0
+
+
+shared_ptr
serialization depends upon
+ compiler support for partial template specialization. This compiler doesn't implement this
+ feature. In order to serialize shared_ptr<A>
,
+ invoke the macro BOOST_SERIALIZATION_SHARED_PTR(A)
+ in the header code.
+ std::map
. In order to serialize
+ instances of this type include the invocation of BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
+ for the key type of the map.
+Visual C++ 6.5
+all the above issues for Visual C++ 7.0 plus:
+
+
+demo_pimpl
. Hence,
+ this program will fail to compile. In this case the problem can't be worked around and
+ still demonstrate this facility.
+ wchar_t
as a separate type. It defines
+ wchar_t
as an alias for short int
. In general things will still
+ function. However certain customization, such as overloading archive operators for
+ saving/loading wide character arrays would produce surprises in this environment.
+
+
+ Working around this in the implementation of the library for this compiler
+ entailed a ridiculous amount of effort. Even so, the effort wasn't entirely successful.
+ With this compiler, this message will still appear under the following conditions:
+
+
+ Borland 5.64 and 5.51
+
+
+enum
data members cannot be serialized.
+ Conversion to/from integers will work around the problem.
+ friend
declarations as described in
+ Class Serialization - Member Function, the
+ will compile but fail at runtime.
+ Comeau 4.3.3
+
+
+
+Code Warrior 9.x
+
+
+
+Code Warrior 8.3
+all the above issues for Code Warrior 9.x plus:
+
+
+
+TRU64
+All tests and demos pass except for test_variant. Boost Variant doesn't function
+wih this compiler
+
+Dinkumware Library
+Several compilers, including Visual C++ 6.0, use an older dinkumware library.
+These platforms have several issues:
+
+
+
+imbue
function is called before the the
+ stream is opened. In order to use this library with this environment to generate UTF-8
+ files, one cannot depend on the "automatic" setting of locale that archives implement. The
+ stream locale must be set explicitly on the stream before an archive is opened on it. The
+ archive should be opened with the no_codecvt
flag. Note this problem will
+ occur on all compilers shipped with this library.
+ STLPort 4.5.3
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Proposed Case Studies
+
+
+
+These are not part of the library itself, but rather
+techiques on how to use the library to address specific situations.
+
+Serializing a Function Object
+An example on how to serialize a function object. I believe this
+could be done by serializing pointer to the object in question. Since
+the Serialization library resurrects pointer of the correct type
+this should be easily implementable.
+Archive Adaptors
+
+Often users want to add their own special functionality to an
+existing archive. Examples of this are performance enhancements
+for specific types, Adjustment of output syntax for xml archives,
+and logging/debug output as archives are written and/or read.
+If this functionalty is implemented as an "adaptor" template
+which takes the base class as a template argument, such functionality
+appended to any archive for which that funtionality makes sense.
+For example, an adaptor for generating an xml schema could be
+appended to both wide narrow character versions of xml archives.
+Archive Helpers
+Some types are not serializable as they stand. That is - they
+do not fullfill the requirements of the "Serializable Concept".
+The iconic example of this is boost::shared_ptr. Sometimes
+these types could be made serializable by adding code inside
+the library. Of course, doing that would create a lifetime
+of unpaid employment for the library author. Rather than
+adding a bunch of special code to the library itself, this
+code can packaged as a "helper" or "mix-in" class. Then
+a new archive is derived from both the "base" archive class
+AND the "helper" class. This is how boost::shared_ptr
+has been implemented.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Overview
+
+
+Our goals for such a system are:
+
+
+
+Other implementations
+ Before getting started I searched around for current
+ implementations. I found several.
+
+
+
+
+
+ Its has lots of differences - and lots in common with this implementation.
+
+
+
+
+
+
+
+Library Status: serialization
+Run Date: 02:42:48 UTC, Tuesday 10 June 2008
+
+
+
+
+
diff --git a/deal.II/contrib/boost/libs/serialization/doc/pimpl.html b/deal.II/contrib/boost/libs/serialization/doc/pimpl.html
new file mode 100644
index 0000000000..4a8ca9b337
--- /dev/null
+++ b/deal.II/contrib/boost/libs/serialization/doc/pimpl.html
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+ Test Name
+gcc-3.4.4
+
+ profile
+
+peformance_array_binary_archive Pass Profile
+peformance_array_text_archive Pass Profile
+peformance_array_text_warchive Missing
+peformance_array_xml_archive Pass Profile
+peformance_array_xml_warchive Missing
+performance_iterators Pass Profile
+performance_iterators_base64 Pass Profile
+
+
+
+
+
+
+
+
+ Serialization
+ PIMPL
+
+PIMPL is a C++ programming idiom described by Herb Sutter [10]
+which stands for "Private Implementation". It is also referred to as
+the "Handle Body Idiom". Included in this library is a program called
+demo_pimpl.cpp
+which illustrates how this is used. The file
+demo_pimpl_A.hpp
+contains the declaration of the a class that hides its implementation
+by including a pointer to struct B that is only defined as a pointer.
+
+Serialization of A requires access to the definition of B in order so it
+is defined in the separately compiled module:
+demo_pimpl_A.cpp
+by:
+
+// class whose declaration is hidden by a pointer
+struct B;
+
+struct A {
+ // class a contains a pointer to a "hidden" declaration
+ B *pimpl;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int file_version);
+ A();
+};
+
+As described in [10] this brings the
+following advantages:
+
+#include "demo_pimpl_A.hpp"
+
+// "hidden" definition of class B
+struct B {
+ int b;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int file_version){
+ ar & b;
+ }
+};
+
+A::A() :
+ pimpl(new B)
+{}
+
+A::~A(){
+ delete pimpl;
+}
+
+// now we can define the serialization for class A
+template<class Archive>
+void A::serialize(Archive & ar, const unsigned int file_version){
+ ar & pimpl;
+}
+
+
+So, we compile the modules and everything is fine. However when we
+link, we get an error. Two symbols are undefined:
+
+The problem is that when compiling the above code,
+there is no instantiation of the
+void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
+void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
+
serialize
template.
+There can't be as its not "known" what types of archives
+the serialization is going to be used with. So these functions are "missing"
+when an attempt to link is made. The solution is to explicitly instantiate
+serialization code for those archives which are going to be used. In this
+example, including the the following code in any *.cpp file does just that:
+
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+
+template void A::serialize<boost::archive::text_iarchive>(
+ boost::archive::text_iarchive & ar,
+ const unsigned int file_version
+);
+template void A::serialize<boost::archive::text_oarchive>(
+ boost::archive::text_oarchive & ar,
+ const unsigned int file_version
+);
+
+The program should now link as well as compile.
+
+
+
+
+
+
+
+
+
+
+ Serialization
+ Rationale
+
+
+
+typeid
information is not included in archivesThe term "serialization" is preferred to "persistence"
+Archives are not streams
+
+
+Archive Members are Templates
+Rather than Virtual Functions
+The previous version of this library defined virtual functions for all
+primitive types. These were overridden by each archive class. There were
+two issues related to this:
+
+ long long
,
+ __int64
,
+ etc.) resulted in messy and fragile code. Replacing this with templates
+ and letting the compiler generate the code for the primitive types actually
+ used, resolved this problem. Of course, the ripple effects of this design
+ change were significant, but in the end led to smaller, faster, more
+ maintainable code.
+
+
+std::strings
are treated specially in text files
+
+std::string
+ and std::wstring
.
+ Presumably they optimize appropriately.
+ std::basic_string
are in fact handled
+ as vectors of the element type.
+
typeid
information is not included in archives
+I originally thought that I had to save the name of the class specified by std::type_of::name()
+in the archive. This created difficulties as std::type_of::name()
is not portable and
+not guaranteed to return the class name. This makes it almost useless for implementing
+archive portability. This topic is explained in much more detail in
+[7] page 206. It turned out that it was not necessary.
+As long as objects are loaded in the exact sequence as they were saved, the type
+is available when loading. The only exception to this is the case of polymorphic
+pointers never before loaded/saved. This is addressed with the register_type()
+and/or export
facilities described in the reference.
+In effect, export
generates a portable equivalent to
+typeid
information.
+
+
+
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/reference.html b/deal.II/contrib/boost/libs/serialization/doc/reference.html new file mode 100644 index 0000000000..b97cbe3a20 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/reference.html @@ -0,0 +1,42 @@ + + + + + + + +
+ + |
+
+ Serialization+Serializable Concept+ |
+
© Copyright Robert Ramey 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) +
+ + \ No newline at end of file diff --git a/deal.II/contrib/boost/libs/serialization/doc/release.html b/deal.II/contrib/boost/libs/serialization/doc/release.html new file mode 100644 index 0000000000..1559c94af5 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/release.html @@ -0,0 +1,242 @@ + + + + + + + +
+ ++ |
+
+ + Serialization++ Release Notes+ |
+
+ Changes have been made to archive classes included with the library. Users who + have used these a guide to making their own archive classes will find that + these will likely no longer compile. This can be remedied by making the + following changes in the code which instantiates these archive classes. +
+Old Code:
+...
+#include <boost/archive/impl/archive_pointer_iserializer.ipp>
+...
+template class detail::archive_pointer_iserializer<naked_text_iarchive> ;
+...
+template class detail::archive_pointer_iserializer<text_iarchive> ;
+
should be replaced with this new code:
+#include <boost/archive/impl/archive_serializer_map.ipp>
+...
+template class detail::archive_serializer_map<naked_text_iarchive> ;
+...
+template class detail::archive_serializer_map<text_iarchive> ;
+
+
+new/delete
+ operators. This functionaly is not available on some compilers.
+ std::streambuf
+ interface. This should result in noticeably faster execution in many cases.
+const
correctness for save/load operators. Note that this
+ may produce compile time errors in code which compiled without problem in
+ earlier boost releases. In most cases the fix is trivial. In other cases, code
+ should be scrutinized to be sure that it doesn't use the serialization system
+ in a way which may introduce subtle bugs in to the program. A fuller
+ explanation of this issue can be found
+ here.
+ shared_ptr<T>
.
+ This is compatible with public interface of shared_ptr<T>
+ so it should be more robust and not have to change in the future. The
+ implementation optionally includes code to load shared_ptr<T>
+ stored in archives created with boost 1.32. This code is stored in 'he header:
+ boost/serialization/shared_ptr_132.hpp
. If your application needs to
+ load archives created with boost 1.32 libraries, include the above header
+ before each inclusion of boost/serialization/shared_ptr.hpp
.
+ std::string
and
+ std::wstring
+ contain characters such as '\0' and -1 (EOF) which cannot be rendered in text
+ and XML archives without an escape mechanism. Currently there is no such escape
+ mechanism implemented.
+
+ std::map
is fixed in this version. Unfortunately, the fix breaks
+ serialization of std::map
+ for those compilers which do not support partial template specialization. Also,
+ types which contain pointers or tracked types might not work correctly.
++ Aside from the above, there are a number of issues related to specific + platforms. These are listed in Specific + Compiler/Library Issues. +
+ © Copyright Robert Ramey 2002-2009. + 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/serialization.html b/deal.II/contrib/boost/libs/serialization/doc/serialization.html new file mode 100644 index 0000000000..ec15eb123a --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/serialization.html @@ -0,0 +1,932 @@ + + + + + + + +
+ + |
+
+ Serialization+Serializable Concept+ |
+
const
Members
+ serialize
into
+ save/load
+ T
is Serializable
+if and only if one of the following is true:
+serialize
+ serialize
+
+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);
+}
+
+That is, the default definition of template serialize
+presumes the existence of a class member function template of the following
+signature:
+
+template<class Archive>
+void serialize(Archive &ar, const unsigned int version){
+ ...
+}
+
+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:
+
+friend class boost::serialization::access;
+
+in the class definition. This latter method should be preferred over the option
+of making 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.
+
+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 &
operator is
+defined as <<
+for output archives and as >>
input archives. The
+"polymorphic" behavior of the &
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.
+
+
my_class
, the
+override would be specified as:
+
+// namespace selection
+
+template<class Archive>
+inline void serialize(
+ Archive & ar,
+ my_class & t,
+ const unsigned int file_version
+){
+ ...
+}
+
+
+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 private
, 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.
+
+boost::serialization
. 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:
+boost::serialization
++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 furter will find more information in +serialization.hpp + +
operator &
to all the data members of the class.
+
+{
+ // save/load class member variables
+ ar & member1;
+ ar & member2;
+}
+
+
+
+template<class Base, class Derived>
+Base & base_object(Derived &d);
+
+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 Serializable type
+T
the base class state should be
+serialized like this:
+
+{
+ // 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;
+}
+
+Resist the temptation to just cast *this
to the base class.
+This might seem to work but may fail to invoke code necessary for
+proper serialization.
+
+Note that this is NOT the same as calling the serialize
+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 serialize
+member functions should be private
.
+
+
const
Membersconst
members to an archive
+requires no special considerations.
+Loading const
members can be addressed by using a
+const_cast
:
+
+ ar & const_cast<T &>(t);
+
+Note that this violates the spirit and intention of the const
+keyword. const
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 const
means in the context
+of serialization.
+
+boost::shared_ptr<T>
and for
+std::list<T>
. If I have defined serialization for my own
+class my_t
, then serialization for
+std::list< boost::shared_ptr< my_t> >
is already available
+for use.
+
+See for an example that shows how this idea might be implemented for your own
+class templates, see
+
+demo_auto_ptr.cpp.
+This shows how non-intrusive serialization
+for the template auto_ptr
from the standard library
+can be implemented.
+
+A somewhat trickier addition of serialization to a standard template +can be found in the example + +shared_ptr.hpp + + +
+In the specification of serialization for templates, its common
+to split serialize
+into a load/save
pair.
+Note that the convenience macro described
+above
+isn't helpful in these cases as the number and kind of
+template class arguments won't match those used when splitting
+serialize
for a simple class. Use the override
+syntax instead.
+
+
+{
+ // 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;
+}
+
+
+serialize
into Save/Load
+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);
+}
+
+This splits the serialization into two separate functions save
+and load
. Since the new serialize
template
+is always the same it can be generated by invoking the macro
+BOOST_SERIALIZATION_SPLIT_MEMBER() defined in the header file
+
+boost/serialization/split_member.hpp
+.
+So the entire serialize
function above can be replaced with:
+
+BOOST_SERIALIZATION_SPLIT_MEMBER()
+
+serialize
function template.
+
+
+To use save
and
+load
function templates rather than
+serialize
:
+
+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)
+{
+ ...
+}
+}}
+
+include the header file
+
+boost/serialization/split_free.hpp
+.
+and override the free serialize
function template:
+
+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);
+}
+}}
+
+To shorten typing, the above template can be replaced with
+the macro:
+
+BOOST_SERIALIZATION_SPLIT_FREE(my_class)
+
+
+Note that although the functionality to split the
+serialize
function into save/load
+has been provided, the usage of the serialize
+function with the corresponding &
operator
+is preferred. The key to the serialization implementation is that objects are saved
+and loaded in exactly the same sequence. Using the &
+operator and serialize
+function guarantees that this is always the case and will minimize the
+occurence of hard to find errors related to synchronization of
+save
and load
+functions.
+
+Also note that BOOST_SERIALIZATION_SPLIT_FREE
+must be used outside of any namespace.
+
+
+To properly save and restore an object through a pointer the +following situations must be addressed: +
Saving a pointer: +
<<
+and >>
operators
+
+// 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();
+}
+
+The default load_construct_data
invokes the
+default constructor "in-place" to initialize the memory.
+
+If there is no such default constructor, the function templates
+load_construct_data
and
+perhaps save_construct_data
+will have to be overridden. Here is a simple example:
+
+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)
+ {}
+};
+
+the overrides would be:
+
+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 ...
+
+In addition to the deserialization of pointers, these overrides are used
+in the deserialization of STL containers whose element type has no default
+constructor.
+
+
+class base {
+ ...
+};
+class derived_one : public base {
+ ...
+};
+class derived_two : public base {
+ ...
+};
+main(){
+ ...
+ base *b;
+ ...
+ ar & b;
+}
+
+When saving b
what kind of object should be saved?
+When loading b
what kind of object should be created?
+Should it be an object of class derived_one
,
+derived_two
, or maybe base
?
+
+It turns out that the kind of object serialized depends upon whether the base class
+(base
in this case) is polymophic or not.
+If base
is not polymorphic, that is if it has no
+virtual functions, then an object of the type base
+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.
+
+
+If the base class is polymorphic, an object of the most derived type
+(derived_one
+or derived_two
+in this case) will be serialized. The question of which type of object is to be
+serialized is (almost) automatically handled by the library.
+
+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". +
+Expanding our previous example: +
+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;
+}
+
+When b
is read it is
+preceded by a unique (to the archive) class identifier which
+has previously been related to class derived_one
or
+derived_two
.
+
+If a derived class has NOT been automatically "registered" as described
+above, an
+unregistered_class
exception
+will be thrown when serialization is invoked.
+
+This can be addressed by registering the derived class explicitly. All archives are +derived from a base class which implements the following template: +
+template<class T>
+register_type();
+
+So our problem could just as well be addressed by writing:
+
+main(){
+ ...
+ ar.template register_type<derived_one>();
+ ar.template register_type<derived_two>();
+ base *b;
+ ...
+ ar & b;
+}
+
+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.
+
++So we have another method: +
+#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;
+}
+
+The macro BOOST_CLASS_EXPORT_GUID
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 -
+Export Key.
++
template<class Archive, class T>
.
+This means that serialization code must be instantiated for each
+combination of archive and data type that is serialized in the program.
+
+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, BOOST_CLASS_EXPORT_GUID
explicitly
+instantiates the class serialization code for all archive classes used
+by the program.
+
+
track_selectively
.
+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
+export a class
+identifier by specifying BOOST_CLASS_EXPORT
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
+track_never
+in those programs.
+
+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, track_never
+can be used.
+
boost::serialization::base_object<Base>(Derived &)
+is to ensure that the base/derived pair is added to the table
+before the main
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 base_object
+and specify an empty function for the base class serialization.
+The alternative is to "register" the Base/Derived relationship
+explicitly by invoking the template
+void_cast_register<Derived, Base>();
.
+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:
+
+#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
+ 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;
+}
+
++ +In order for this template to be invoked in code compiled by non-conforming +compilers, the following syntax may be used: +
+boost::serialization::void_cast_register(
+ static_cast<Derived *>(NULL),
+ static_cast<Base *>(NULL)
+);
+
+For more information, see Template Invocation syntax
+
+
+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)
+ {}
+};
+
+the overrides would be:
+
+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 ...
+
+
+T
is a serializable type,
+then any native C++ array of type T is a serializable type.
+That is, if T
+is a serializable type, then the following
+is automatically available and will function as expected:
+
+T t[4];
+ar << t;
+ ...
+ar >> t;
+
+
+std::list
, use:
+
+#include <boost/serialization/list.hpp>
+
+rather than
+
+#include <list>
+
+Since the former includes the latter, this all that is necessary.
+The same holds true for all STL collections as well as templates
+required to support them (e.g. std::pair
).
++As of this writing, the library contains serialization of the following boost clases: +
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/shared_ptr.html b/deal.II/contrib/boost/libs/serialization/doc/shared_ptr.html new file mode 100644 index 0000000000..932ab59d2e --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/shared_ptr.html @@ -0,0 +1,233 @@ + + + + + + + +
+ + |
+
+ Serialization+Template serialization -
+ |
+
boost::serialization
namespace.
+
+shared_ptr<T>
is defined in
+shared_ptr.hpp.
+
+The general class outline for a shared_ptr<T>
is:
+
shared_ptr<T>
contains:
+ T *px;
+ shared_count pn;
which contains a pointer to:
+ sp_counted_base_impl<T, ...>
which is
+derived from the polymorphic abstract class
+ sp_counted_base
+
+The first cut at implementing serialization for shared_ptr
+just serializes the relevant members of shared_ptr
.
+It's almost trivial:
+
+template<class Archive, class T>
+inline void serialize(
+ Archive & ar,
+ shared_ptr<T> & t,
+ const unsigned int file_version,
+ int
+){
+ ar & t.px; // save the raw pointer
+ ar & t.pn; // save the shared reference count
+}
+
+So far so good. Now for the serialization of shared_count
:
+
+template<class Archive>
+inline void save(
+ Archive & ar,
+ const boost::detail::shared_count & t,
+ const unsigned int file_version
+){
+ ar << t.pi_;
+}
+
+template<class Archive>
+inline void load(
+ Archive & ar,
+ boost::detail::shared_count & t,
+ const unsigned int file_version
+){
+ ar >> t.pi_;
+}
+
+A key feature of this library is the ability to specify serialization
+of a class or template without changing the class or template declaration
+or definition. This is referred to as non-intrusive serialization.
+
+The pi_
member of shared count is a pointer to an
+instance of sp_counted_base_impl
. Since this class
+doesn't have a default constructor, serialization requires
+specification of the following overload:
+
+template<class Archive, class P, class D>
+inline void save_construct_data(
+ Archive & ar,
+ const boost::detail::sp_counted_base_impl * t,
+ const unsigned int file_version
+){
+ // variables used for construction
+ ar << t->ptr;
+ ar << *t;
+}
+
+template
+inline void load_construct_data(
+ Archive & ar,
+ boost::detail::sp_counted_base_impl * t,
+ const unsigned int file_version
+){
+ P ptr_;
+ ar >> ptr_;
+ // placement new
+ ::new(t)boost::detail::sp_counted_base_impl
(ptr_, D());
+ ar >>; *t;
+}
+
+The statement ar >> ptr_
is key. This deserializes
+the same pointer deserialzed above. Default object tracking will ensure
+that no more than one instance of the object is created and that the
+pointer returned by multiple deserializations are all the same. Hence,
+regardless of how many instances of shared_ptr/shared_count
+corresponding to a particular object are created, the will all point
+to the same object.
+
+Since sp_counted_base_impl<P, D>
is derived from
+sp_counted_base
, the following is needed:
+
+
+template<class Archive, class P, class D>
+inline void serialize(
+ Archive & ar,
+ boost::detail::sp_counted_base_impl<P, D> & t,
+ const unsigned int file_version,
+ int
+){
+ ar & boost::serialization::base_object<
+ boost::detail::sp_counted_base
+ >(*this);
+}
+
+which will in turn require serialization of its base class:
+
+inline void serialize(
+ Archive & ar,
+ boost::detail::sp_counted & t,
+ const unsigned int file_version,
+ int
+){
+}
+
+It would seem we're done, running the test program,
+
+demo_shared_ptr.cpp
+,
+with this code produces the following output.
+
+a = 0x003017A0 use count = 2
+a1 = 0x003017A0 use count = 2
+unique element count = 1
+a = 0x00000000 use count = 0
+a1 = 0x00000000 use count = 0
+unique element count = 0
+a = 0x00303060 use count = 1
+a1 = 0x00303060 use count = 1
+unique element count = 1
+
+This indicates that we're not quite done. Due to default object
+tracking, sp_counted_base_impl<P, D>
is only
+created once regardless of how many shared pointers point to the
+same object. Of course, it has to be this way. The reference
+count starts at 1 and is never incrememented. Code must be added
+to the serialization functions to maintain the proper reference
+count.
+
+The process of serialization of an empty base class -
+sp_counted_base
- seems like additional overhead.
+Examination of code in
+
+base_object.hpp
+
+reveals that base_object.hpp
provides two functions:
+
+// register the relationship between each derived class
+// its polymorphic base
+void_cast_register<
+ boost::detail::sp_counted_base_impl<P, D>
+ boost::detail::sp_counted_base,
+>();
+
+and we don't have to include a trival serializer for sp_counted_base
++Finally we need to specify name-value pair wrappers if we want to be able +to use this serialization with XML archives. +
+Actually, even this is really just a start. Among the issues not addressed in +this implementation are: +
weak_ptr
is not addressed. I haven't even looked into this.
+ shared_ptr
+ haven't been addressed at all. To be confident that the implementation is
+ complete and correct, all these should be addressed as well.
+
+BOOST_SHARED_POINTER_EXPORT(T)
+BOOST_SHARED_POINTER_EXPORT_GUID(T, K)
+
+These are specialize versions of the macros used for exporting classes serialized through raw pointers.
++Clearly, complete, correct and exception safe serialization of smart pointers is going to +be a challenge. I hope that this implementation provides a useful +starting point for such an effort. +
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/shared_ptr2.html b/deal.II/contrib/boost/libs/serialization/doc/shared_ptr2.html new file mode 100644 index 0000000000..0e831b798e --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/shared_ptr2.html @@ -0,0 +1,103 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
shared_ptr
+illustrates the straightforward way of serializing a moderately complicated class structure.
+Unfortunately, this way of doing it suffered from some undesirable features
+shared_ptr
.
+ The shared_ptr
interface has been included
+ in std::tr1
and may someday be included in the standard
+ C++ library. An implementation which depends only on the public interface can be guaranteed to
+ function with any other future implementation of shared_ptr
.
+
+template<class Archive, class T>
+inline void save(
+ Archive & ar,
+ const boost::shared_ptr<T> &t,
+ const unsigned int /* file_version */
+){
+ const T * t_ptr = t.get();
+ // just serialize the underlying raw pointer
+ ar <<: boost::serialization::make_nvp("px", t_ptr);
+}
+
+template<class Archive, class T>
+inline void load(
+ Archive & ar,
+ boost::shared_ptr<T> &t,
+ const unsigned int file_version
+){
+ T* r;
+ // recover the underlying raw pointer
+ ar >> boost::serialization::make_nvp("px", r);
+
+ // To Do - match up with other shared pointers which
+ // use this same raw pointer.
+ ...
+}
+
+
+In principle, this is very much simpler than the original implementation. Completion of
+this code requires:
+
+shared_ptr
instances.
+ weak_ptr
.
+boost::serialization::shared_ptr.hpp
+
++Note that if your code needs to read archives created under boost version 1.32, you will +have to include the following + +
+#include <boost/serialization/shared_ptr_132.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+
+rather than just
+
+#include <boost/serialization/shared_ptr.hpp>
+
+
+© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/simple_log.html b/deal.II/contrib/boost/libs/serialization/doc/simple_log.html new file mode 100644 index 0000000000..1a6281edc2 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/simple_log.html @@ -0,0 +1,95 @@ + + + + + + + +
+ + |
+
+ Serialization+A Simple Logging Archive Class+ |
+
simple_log_archive.hpp
implements a simple but useful
+archive class. This class can be used to send any serializable types
+on an output text stream in a readable format. Usage of this facility
+is trivially easy:
+
+
+#include "simple_log_archive.hpp"
+...
+// display the complete schedule
+simple_log_archive log(std::cout);
+log << schedule;
+
+
+and it produces the following output
+
+
+schedule
+ count 6
+ item
+ first
+ driver bob
+ hour 6
+ minute 24
+ second ->
+ stops
+ count 3
+ item ->
+ latitude
+ degrees 34
+ minutes 135
+ seconds 52.56
+ longitude
+ degrees 134
+ minutes 22
+ seconds 78.3
+...
+
+
+The complete example is
+demo_simple_log.cpp
. Look at
+Trivial Archive to get a
+better understanding of how this works.
+
+Also, note the following:
+© Copyright Robert Ramey 2002-2010. +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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/singleton.html b/deal.II/contrib/boost/libs/serialization/doc/singleton.html new file mode 100644 index 0000000000..80f71c8824 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/singleton.html @@ -0,0 +1,256 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
main
is called
+ regardless of where they might be referenced within the program.
+ In a multi-tasking system, this guarentees that there will be no
+ race conditions during the construction of any instance. No
+ thread locking is required to guarentee this.
+ const
+ instances are thread-safe during the whole program. Again, no
+ thread locking is required.
+ main
is called.
+ For a more general purpose usage, thread locking on this
+ singleton could easily be implemented. But as the serialization
+ library didn't require it, it wasn't implemented.
+
+namespace boost {
+namespace serialization {
+
+template
+class singleton : public boost::noncopyable
+{
+public:
+ static const T & get_const_instance();
+ static T & get_mutable_instance();
+ static bool is_destroyed();
+};
+
+} // namespace serialization
+} // namespace boost
+
+
+
+static const T & get_const_instance();
+
+static T & get_mutable_instance();
+
+static bool is_destroyed();
+
true
if the destructor on this singleton has been
+called. Otherwise, return false
.
+
+singleton<T>
+
+
+, the type T must be default constructable.
+It doesn't require static variables - though it may have them.
+Since the library guarentees that only one instance of
+
+
+singleton<T>
+
+
+and all accesss is through the above static interface
+functions, common member functions of T become
+the functional equivalent of
+static
functions.
+
+
+The first way is illustrated by and excerpt from the file
+extended_type_info.cpp
.
+which contains the following code:
+
+
+typedef std::set ktmap;
+...
+void
+extended_type_info::key_register(const char *key) {
+ ...
+ result = singleton::get_mutable_instance().insert(this);
+ ...
+}
+
+Just by referring to the singleton instance anywhere in the program
+will guarentee that one and only one instance for the specified
+type (ktmap
in this example)
+will exist throughout the program. There is no need for anyother
+declaration or definition.
+
+A second way is to use
+
+
+singleton<T>
+
+
+as one of the base classes of the type. This is illustrated by a simplified
+excerpt from
+
+
+extended_type_info_typeid.hpp
+
+
+
+
+template<class T>
+class extended_type_info_typeid :
+ public detail::extended_type_info_typeid_0,
+ public singleton<extended_type_info_typeid<const T> >
+{
+ friend class singleton<extended_type_info_typeid<const T> >;
+private:
+ // private constructor to inhibit any existence other than the
+ // static one. Note: not all compilers support this !!!
+ extended_type_info_typeid() :
+ detail::extended_type_info_typeid_0()
+ {
+ type_register(typeid(T));
+ }
+ ~extended_type_info_typeid(){}
+ ...
+};
+
+
+This usage will permit a more natural syntax to be used:
+
+extended_type_info_typeid<T>::get_const_instance()
+
+
+Again, including one or more of the above statements anywhere
+in the program will guarentee that one and only one instance
+is created and referred to.
+
++Do not call get_mutable_instance when more than one thread is running! +<'> +All singletons used in the serialization library follow this rule. +In order to help detect accidental violations of this rule there +exists an singleton lock/unlock functions. +
+void boost::serialization::singleton_module::lock();
+void boost::serialization::singleton_module::unlock();
+bool boost::serialization::singleton_module::is_locked();
+
+In a program compiled for debug, any invocation of
+get_mutable_instance()
+while the library is in a "locked" state will trap in an assertion.
+The singleton module lock state is initialized as "unlocked" to permit
+alteration of static variables before
+main
is called.
+The lock()
and
+unlock()
are "global"
+in they affect ALL the singletons defined by this template.
+All serialization tests invoke lock()
+at the start of the progam. For programs compiled in release
+mode these functions have no effect.
+
+© Copyright Robert Ramey 2007. +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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/smart_cast.html b/deal.II/contrib/boost/libs/serialization/doc/smart_cast.html new file mode 100644 index 0000000000..1d43e8ad06 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/smart_cast.html @@ -0,0 +1,155 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
static_cast<T *<>(U *)
static_cast<T &<>(U &)
+
dynamic_cast<T *<>(U *)
dynamic_cast<T &<>(U &)
+#include <boost/serialization/smart_cast.hpp>
+
+struct top {
+};
+
+struct base1 : public top {
+ bool is_storable() const {
+ return true;
+ }
+ virtual ~base1();
+};
+
+struct base2 {
+ virtual ~base2();
+};
+
+struct derived1 :
+ public base1
+{
+ derived1();
+};
+
+struct derived2 :
+ public base1,
+ public base2
+{
+ derived2();
+};
+
+template<class T>
+bool is_storable(T &t){
+ // what type of cast to use here?
+
+ // this fails at compiler time when T == base2
+ // return static_cast<base1 &>(t).is_storable();
+
+ // this fails at compiler time when T == top
+ // otherwise it works but cannot optimize inline function call
+ // return dynamic_cast<base1 &>(t).is_storable();
+
+ // this always works - and is guarenteed to generate the fastest code !
+ return (boost::smart_cast_reference<base1 &>(t)).is_storable();
+}
+
+int main(){
+ derived1 d1;
+ top & t1 = d1;
+ derived2 d2;
+ base2 & b2 = d2;
+
+ bool result;
+ result = is_storable(d1);
+ result = is_storable(d2);
+ result = is_storable(b2);
+ result = is_storable(b2);
+ result = is_storable(t1);
+ return 0;
+}
+
+The serialization library includes a mix of classes which use
+both static polymorphism (CRTP) and dynamic
+polymorphism via virtual functions. smart_cast
+was written to address the more problematic manifestations of the
+situation exmplified above.
+
+
+smart_cast<Target *, Source *>(Source * s);
+smart_cast<Target *>(Source * s);
+smart_cast<Target &, Source &>(Source & s);
+
+Note that the above syntax doesn't include
+
+smart_cast<Target & >(Source & s)
+
+but the same functionality is supported the the following special syntax
+
+smart_cast_reference<Target &>(Source & s)
+
+
+smart_cast
can be used only on compilers that support partial
+template specialization or on types for which have be specified with the
+macro
+BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(<type>)
+has been applied.
+
+© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/special.html b/deal.II/contrib/boost/libs/serialization/doc/special.html new file mode 100644 index 0000000000..ea95bf6d76 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/special.html @@ -0,0 +1,591 @@ + + + + + + + +
+ + |
+
+ Serialization+Special Considerations+ |
+
+This could cause problems in +progams where the copies of different objects are saved from the same address. +
+template<class Archive>
+void save(boost::basic_oarchive & ar, const unsigned int version) const
+{
+ for(int i = 0; i < 10; ++i){
+ A x = a[i];
+ ar << x;
+ }
+}
+
+In this case, the data to be saved exists on the stack. Each iteration
+of the loop updates the value on the stack. So although the data changes
+each iteration, the address of the data doesn't. If a[i] is an array of
+objects being tracked by memory address, the library will skip storing
+objects after the first as it will be assumed that objects at the same address
+are really the same object.
+
+To help detect such cases, output archive operators expect to be passed
+const
reference arguments.
+
+Given this, the above code will invoke a compile time assertion. +The obvious fix in this example is to use +
+template<class Archive>
+void save(boost::basic_oarchive & ar, const unsigned int version) const
+{
+ for(int i = 0; i < 10; ++i){
+ ar << a[i];
+ }
+}
+
+which will compile and run without problem.
+The usage of const
by the output archive operators
+will ensure that the process of serialization doesn't
+change the state of the objects being serialized. An attempt to do this
+would constitute augmentation of the concept of saving of state with
+some sort of non-obvious side effect. This would almost surely be a mistake
+and a likely source of very subtle bugs.
++Unfortunately, implementation issues currently prevent the detection of this kind of +error when the data item is wrapped as a name-value pair. +
+A similar problem can occur when different objects are loaded to and address +which is different from the final location: +
+template<class Archive>
+void load(boost::basic_oarchive & ar, const unsigned int version) const
+{
+ for(int i = 0; i < 10; ++i){
+ A x;
+ ar >> x;
+ std::m_set.insert(x);
+ }
+}
+
+In this case, the address of x
is the one that is tracked rather than
+the address of the new item added to the set. Left unaddressed
+this will break the features that depend on tracking such as loading object through a pointer.
+Subtle bugs will be introduced into the program. This can be
+addressed by altering the above code thusly:
+
+
+template<class Archive>
+void load(boost::basic_iarchive & ar, const unsigned int version) const
+{
+ for(int i = 0; i < 10; ++i){
+ A x;
+ ar >> x;
+ std::pair<std::set::const_iterator, bool> result;
+ result = std::m_set.insert(x);
+ ar.reset_object_address(& (*result.first), &x);
+ }
+}
+
+This will adjust the tracking information to reflect the final resting place of
+the moved variable and thereby rectify the above problem.
++If it is known a priori that no pointer +values are duplicated, overhead associated with object tracking can +be eliminated by setting the object tracking class serialization trait +appropriately. +
+By default, data types designated primitive by
+Implementation Level
+class serialization trait are never tracked. If it is desired to
+track a shared primitive object through a pointer (e.g. a
+long
used as a reference count), It should be wrapped
+in a class/struct so that it is an identifiable type.
+The alternative of changing the implementation level of a long
+would affect all long
s serialized in the whole
+program - probably not what one would intend.
+
+It is possible that we may want to track addresses even though
+the object is never serialized through a pointer. For example,
+a virtual base class need be saved/loaded only once. By setting
+this serialization trait to track_always
, we can suppress
+redundant save/load operations.
+
+BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
+
+
+boost::serialization::object_serializable
.
++Turning off tracking and class information serialization will result +in pure template inline code that in principle could be optimised down +to a simple stream write/read. Elimination of all serialization overhead +in this manner comes at a cost. Once archives are released to users, the +class serialization traits cannot be changed without invalidating the old +archives. Including the class information in the archive assures us +that they will be readable in the future even if the class definition +is revised. A light weight structure such as display pixel might be +declared in a header like this: + +
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/level.hpp>
+#include <boost/serialization/tracking.hpp>
+
+// a pixel is a light weight struct which is used in great numbers.
+struct pixel
+{
+ unsigned char red, green, blue;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int /* version */){
+ ar << red << green << blue;
+ }
+};
+
+// elminate serialization overhead at the cost of
+// never being able to increase the version.
+BOOST_CLASS_IMPLEMENTATION(pixel, boost::serialization::object_serializable);
+
+// eliminate object tracking (even if serialized through a pointer)
+// at the risk of a programming error creating duplicate objects.
+BOOST_CLASS_TRACKING(pixel, boost::serialization::track_never)
+
+
+wchar_t
while other compilers reserve only 2 bytes.
+So its possible that a value could be written that couldn't be represented by the loading program. This is a
+fairly obvious situation and easily handled by using the numeric types in
+<boost/cstdint.hpp>
+
+A special integral type is std::size_t
which is a typedef
+of an integral types guaranteed to be large enough
+to hold the size of any collection, but its actual size can differ depending
+on the platform. The
+collection_size_type
+wrapper exists to enable a portable serialization of collection sizes by an archive.
+Recommended choices for a portable serialization of collection sizes are to
+use either 64-bit or variable length integer representation.
+
+
+
+template<class T>
+struct my_wrapper {
+ template<class Archive>
+ Archive & serialize ...
+};
+
+...
+
+class my_class {
+ wchar_t a;
+ short unsigned b;
+ template<class Archive>
+ Archive & serialize(Archive & ar, unsigned int version){
+ ar & my_wrapper(a);
+ ar & my_wrapper(b);
+ }
+};
+
+If my_wrapper
uses default serialization
+traits there could be a problem. With the default traits, each time a new type is
+added to the archive, bookkeeping information is added. So in this example, the
+archive would include such bookkeeping information for
+my_wrapper<wchar_t>
and for
+my_wrapper<short_unsigned>
.
+Or would it? What about compilers that treat
+wchar_t
as a
+synonym for unsigned short
?
+In this case there is only one distinct type - not two. If archives are passed between
+programs with compilers that differ in their treatment
+of wchar_t
the load operation will fail
+in a catastrophic way.
+
+One remedy for this is to assign serialization traits to the template
+my_template
such that class
+information for instantiations of this template is never serialized. This
+process is described above and
+has been used for Name-Value Pairs.
+Wrappers would typically be assigned such traits.
+
+Another way to avoid this problem is to assign serialization traits
+to all specializations of the template my_wrapper
+for all primitive types so that class information is never saved. This is what has
+been done for our implementation of serializations for STL collections.
+
+
ios::binary
. If this is not done, the archive generated
+will be unreadable.
++Unfortunately, no way has been found to detect this error before loading the archive. Debug builds +will assert when this is detected so that may be helpful in catching this error. + +
BOOST_CLASS_EXPORT
.
+Export implies two things:
+
+BOOST_CLASS_EXPORT
in the same
+source module that includes any of the archive class headers will
+instantiate code required to serialize polymorphic pointers of
+the indicated type to the all those archive classes. If no
+archive class headers are included, then no code will be instantiated.
+
+
+Note that the implemenation of this functionality requires
+that the BOOST_CLASS_EXPORT
+macro appear after and the inclusion of any archive
+class headers for which code is to be instantiated.
+So, code that uses BOOST_CLASS_EXPORT
+will look like the following:
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+... // other archives
+
+#include "a.hpp" // header declaration for class a
+BOOST_CLASS_EXPORT(a)
+... // other class headers and exports
+
+This will be true regardless of whether the is part
+of a stand alone executable, a static library or
+a dyanmic or shared library.
+
+Including
+BOOST_CLASS_EXPORT
+in the "a.hpp" header itself as one would do with
+other serialization traits will make it difficult
+or impossible to follow the rule above regarding
+inclusion of archive headers before
+BOOST_CLASS_EXPORT
+is invoked. This can best be addressed by using
+BOOST_CLASS_EXPORT_KEY
+in the header declarations and
+BOOST_CLASS_EXPORT_IMPLEMENT
+in the class definition file.
+
+
+This system has certain implications for placing code in static or shared
+libraries. Placing BOOST_CLASS_EXPORT
+in library code will have no effect unless archive class headers are
+also included. So when building a library, one should include all headers
+for all the archive classes which he anticipates using. Alternatively,
+one can include headers for just the
+Polymoprhic Archives.
+
+
+Strictly speaking, export should not be necessary if all pointer serialization +occurs through the most derived class. However, in order to detect +what would be catastophic error, the library traps ALL serializations through +a pointer to a polymorphic which are not exported or otherwise registered. +So, in practice, be prepared to register or export all classes with one +or more virtual functions which are serialized through a pointer. + +
+Note that the implementation of this functionality depends upon vendor +specific extensions to the C++ language. So, there is no guarenteed portability +of programs which use this facility. However, all C++ compilers which +are tested with boost provide the required extensions. The library +includes the extra declarations required by each of these compilers. +It's reasonable to expect that future C++ compilers will support +these extensions or something equivalent. + +
BOOST_CLASS_EXPORT_KEY
+in headers.
+BOOST_CLASS_EXPORT_IMPLEMENT
+in definitions compiled in the library. For any particular type,
+there should be only one file which contains
+BOOST_CLASS_EXPORT_IMPLEMENT
+for that type. This ensures that only one copy
+of serialization code will exist within the program. It avoids
+wasted space and the possibility of having different
+versions of the serialization code in the same program.
+Including
+BOOST_CLASS_EXPORT_IMPLEMENT
+in multiple files could result in a failure
+to link due to duplicated symbols or the throwing
+of a runtime exception.
+demo_pimpl.cpp
+,
+
+demo_pimpl_A.cpp
+
+and
+
+demo_pimpl_A.hpp
+
+where implementation of serializaton is in a static library
+completely separate from the main program.
+
+
+
+
+test_dll_simple
+,
+and
+
+dll_a.cpp
+
+where implementation of serializaton is also completely separate
+from the main program but the code is loaded at runtime. In this
+example, this code is loaded automatically when the program which
+uses it starts up, but it could just as well be loaded and unloaded
+with an OS dependent API call.
+
+Also included are
+
+test_dll_exported.cpp
+,
+and
+
+polymorphic_derived2.cpp
+
+which are similar to the above but include tests of the export
+and no_rtti facilities in the context of DLLS.
+
+For best results, write your code to conform to the following +guidelines: +
inline
code in classes used in DLLS.
+This will generate duplicate code in the DLLS and mainline. This
+needlessly duplicates code. Worse, it makes is possible for
+different versions of the same code exist simultaneously. This
+type of error turns out to be excruciatingly difficult to debug.
+Finally, it opens the possibility that module being referred to
+might be explictly unloaded which would (hopefully) result in
+a runtime error. This is another bug that is not always
+reproducible or easy to find. For class member templates use something like
+
+
+template<class Archive>
+void serialize(Archive & ar, const unsigned int version);
+
+in the header, and
+
+
+template<class Archive>
+void myclass::serialize(Archive & ar, const unsigned int version){
+ ...
+}
+
+BOOST_EXPORT_CLASS_IMPLEMENT(my_class)
+
+#include <boost/archive/text_oarchive>
+#include <boost/archive/text_iarchive<
+template myclass::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
+template myclass::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
+... // repeat for each archive class to be used.
+
+in the implementation file. This will result in generation of all code
+required in only one place. The library does not detect this type of error for you.
+ dlopen
in *nix or
+LoadLibrary
in Windows). Try to arrange that they are unloaded in the reverse
+sequence. This should guarentee that problems are avoided even if the
+above guidline hasn't been followed.
+
+extended_type_info
+for associating classes with external identifying strings (GUID)
+and void_cast
+for casting between pointers of related types.
+
+To complete the functionality of
+extended_type_info
+the ability to construct and destroy corresponding types has been
+added. In order to use this functionality, one must specify
+how each type is created. This should be done at the time
+a class is exported. So, a more complete example of the code above would be:
+
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+... // other archives
+
+#include "a.hpp" // header declaration for class a
+
+// this class has a default constructor
+BOOST_SERIALIZATION_FACTORY_0(a)
+// as well as one that takes one integer argument
+BOOST_SERIALIZATION_FACTORY_1(a, int)
+
+// specify the GUID for this class
+BOOST_CLASS_EXPORT(a)
+... // other class headers and exports
+
+
+With this in place, one can construct, serialize and destroy
+about which only is know the GUID and a base class.
+
+
+
+However, Writing/Reading different archives simultaneously
+in different tasks is permitted as each archive instance is (almost)
+completely independent from any other archive instance. The only shared
+information are some type tables which have been implemented using a
+lock-free thread-safe
+
+singleton
+
+described elsewhere in this documentation.
+
+This singleton implementation guarentees that all of this shared +information is initialized when the code module which contains +them is loaded. The serialization library takes care to +ensure that these data structures are not subsequently +modified. The only time there could be a problem would +be if code is loaded/unloaded while another task is +serializing data. This could only occur for types whose +serialization is implemented in a dynamically loaded/unload DLL +or shared library. So if the following is avoided: +
array
+wrapper.
+
+Serialization functions for data types containing contiguous arrays of homogeneous
+types, such as for std::vector
, std::valarray
or
+boost::multiarray
should serialize them using an
+array
wrapper to make use of
+these optimizations.
+
+Archive types that can provide optimized serialization for contiguous arrays of
+homogeneous types should implement these by overloading the serialization of
+the array
wrapper, as is done
+for the binary archives.
+
+
+© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/state_saver.html b/deal.II/contrib/boost/libs/serialization/doc/state_saver.html new file mode 100644 index 0000000000..1fc1bd507b --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/state_saver.html @@ -0,0 +1,82 @@ + + + + + + + +state_saver
+ + |
+
+ Serialization+
|
+
+Sometimes a certain value has to change only for a limited scope. +This class wrapper saves a copy of the current state of some object, +and resets the object's state at destruction time, undoing any change the object +may have gone through. Here is the interface: + +
+template
+// T requirements:
+// - POD or object semantic (cannot be reference, function, ...)
+// - copy constructor
+// - operator = (no-throw one preferred)
+class state_saver : private boost::noncopyable
+{
+private:
+ ... // implementation
+
+public:
+ state_saver(T & object);
+ ~state_saver();
+};
+
+
+The complete implementation can be found
+here
+
+The following illustrates how this is expected to be used.
+
+
+#include <boost/state_saver.hpp>
+
+void func(A & a)
+ boost::state_saver<A> s(a);
+ ... // alter state of a by calling non-const functions
+ ... // call other functions
+ // original state of a automatically restored on exit
+}
+
+
++Robert Ramey made an initial version for the serialization library. +
+Pavel Vozenilek made several non-obvious refinements to make it more +secure and boost friendly + +
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/static_warning.html b/deal.II/contrib/boost/libs/serialization/doc/static_warning.html new file mode 100644 index 0000000000..050f1542fc --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/static_warning.html @@ -0,0 +1,53 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
<boost/serialization/static_warning.hpp>
supplies a single macro
+BOOST_STATIC_WARNING(x)
, which generates a compile time warning message if
+the integral-constant-expression x is not true.
++Note that if the condition is true, then the macro will generate neither +code nor data - and the macro can also be used at either namespace, +class or function scope. When used in a template, the expression x +will be evaluated at the time the template is instantiated; this is +particularly useful for validating template parameters. +
+It is intended that the functioning of BOOST_STATIC_WARNING(x)
+be identical to that of BOOST_STATIC_ASSERT(x)
+except that rather than resulting in a compilation error, it will result in
+a compiler warning. In all other respects it should be the same. So
+for more information on using BOOST_STATIC_WARNING(x)
+consult the documentation for BOOST_STATIC_ASSERT(x)
+here.
+
+
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/strong_typedef.html b/deal.II/contrib/boost/libs/serialization/doc/strong_typedef.html new file mode 100644 index 0000000000..bc8f25d806 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/strong_typedef.html @@ -0,0 +1,91 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
typedef
creates an alias for an existing type. It does not create
+a new type that can be used for matching either function or template parameters.
+This can be shown by trying to compile the following example.
++typedef int a; +void f(int x); // (1) function to handle simple integers +void f(a x); // (2) special function to handle integers of type a +int main(){ + int x = 1; + a y; + y = x; // other operations permitted as a is converted as necessary + f(x); // chooses (1) + f(y); // chooses (2) +} ++Since typedef doesn't create a new type, this program can't compile to code +that implements its obvious intention. +
+Usage of BOOST_STRONG_TYPEDEF +addresses this. +
+ +#include <boost/serialization/strong_typedef.hpp> + + +BOOST_STRONG_TYPEDEF(int, a) +void f(int x); // (1) function to handle simple integers +void f(a x); // (2) special function to handle integers of type a +int main(){ + int x = 1; + a y; + y = x; // other operations permitted as a is converted as necessary + f(x); // chooses (1) + f(y); // chooses (2) +} ++The program will now compile and run as expected. + +
BOOST_STRONG_TYPEDEF
+has been designed to be similar to the standard
+typedef
. So
+
+
+BOOST_STRONG_TYPEDEF(primitive type, name)
+
+
+will create a new type "name" which will be substitutable for the original
+type but still of distinct type.
+
+BOOST_STRONG_TYPEDEF
is a macro
+which generates a class named "name" wraps and instance of its
+primitive type and provides appropriate conversion operators in order
+to make the new type substitutable for the one that it wraps.
+
+© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/style.css b/deal.II/contrib/boost/libs/serialization/doc/style.css new file mode 100644 index 0000000000..de95898abd --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/style.css @@ -0,0 +1,15 @@ +pre{ + BORDER-RIGHT: gray 1pt solid; + BORDER-TOP: gray 1pt solid; + BORDER-LEFT: gray 1pt solid; + BORDER-BOTTOM: gray 1pt solid; + MARGIN-LEFT: 0pt; + background-color: #EEEEEE; +} + +/* +(C) Copyright 2008 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) +*/ \ No newline at end of file diff --git a/deal.II/contrib/boost/libs/serialization/doc/todo.html b/deal.II/contrib/boost/libs/serialization/doc/todo.html new file mode 100644 index 0000000000..873feb45d0 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/todo.html @@ -0,0 +1,113 @@ + + + + + + + +
+ + |
+
+ Serialization+To Do+ |
+
+Its missing the following: +
+The first thing I did was include some of the serialization library tests. +It became immediatly apparent that these tests were totally unsuitable +for performance testing and that new tests needed to be written for this +purpose. These tests would highlight the location of any performance +bottlenecks in the serialization library. Whenever I've subjected my +code in the past to this type of analysis, I've always been suprised +to find bottlenecks in totally unanticipated places and fixing those +has always lead to large improvements in performance. I expect that +this project would have a huge impact on the utility of the serialization +library. + +
extended_typeinfo
+implemenation which presumes that all classes names have been exported.
+So, to make this library compatible for platforms without RTTI,
+a set of tests, examples and new manual section would have to be created
+
+Revised 1 November, 2008 +
© Copyright Robert Ramey 2002-2008. +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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/traits.html b/deal.II/contrib/boost/libs/serialization/doc/traits.html new file mode 100644 index 0000000000..64d6c53e2c --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/traits.html @@ -0,0 +1,807 @@ + + + + + + + +
+ + |
+
+ Serialization+Class Serialization Traits+ |
+
int
, it wouldn't make sense to save
+a version number in the archive. Likewise, for a data type that is never
+serialized through a pointer, it would (almost) never make sense to track
+the address of objects saved to/loaded from the archive as it will never
+be saved/loaded more than once in any case. Details of
+serialization for a particular data type will vary depending on the
+type, the way it is used and specifications of the programmer.
++One can alter the manner in which a particular data type is serialized +by specifying one or more class serialization traits. +It is not generally necessary for the programmer to explictly assign +traits to his classes as there are default values for all traits. +If the default values are not appropriate they can be assigned by the programmer. +A template is used to associate a typename with a constant. For example +see +version.hpp. +
+namespace boost {
+namespace serialization {
+template<class T>
+struct version
+{
+ BOOST_STATIC_CONSTANT(unsigned int, value = 0);
+};
+} // namespace serialization
+} // namespace boost
+
+
+For any class T
, The default definition
+of boost::serialization::version<T>::value
is 0.
+If we want to assign a value of 2 as the version for class my_class
+we specialize the version template:
+
+namespace boost {
+namespace serialization {
+struct version<my_class>
+{
+ BOOST_STATIC_CONSTANT(unsigned int, value = 2);
+};
+} // namespace serialization
+} // namespace boost
+
+Now whenever the version number for class my_class
is required,
+the value 2 will be returned rather than the default value of 0.
++To diminish typing and enhance readability, a macro is defined +so that instead of the above, we could write: +
+BOOST_CLASS_VERSION(my_class, 2)
+
+which expands to the code above.
+
+
+// names for each level
+enum level_type
+{
+ // Don't serialize this type. An attempt to do so should
+ // invoke a compile time assertion.
+ not_serializable = 0,
+ // write/read this type directly to the archive. In this case
+ // serialization code won't be called. This is the default
+ // case for fundamental types. It presumes a member function or
+ // template in the archive class that can handle this type.
+ // there is no runtime overhead associated reading/writing
+ // instances of this level
+ primitive_type = 1,
+ // Serialize the objects of this type using the objects "serialize"
+ // function or template. This permits values to be written/read
+ // to/from archives but includes no class or version information.
+ object_serializable = 2,
+ ///////////////////////////////////////////////////////////////////
+ // once an object is serialized at one of the above levels, the
+ // corresponding archives cannot be read if the implementation level
+ // for the archive object is changed.
+ ///////////////////////////////////////////////////////////////////
+ // Add class information to the archive. Class information includes
+ // implementation level, class version and class name if available.
+ object_class_info = 3,
+};
+
+Using a macro defined in level.hpp
we can specify
+that my_class
should be serialized along with its version number:
+
+BOOST_CLASS_IMPLEMENTATION(my_class, boost::serialization::object_class_info)
+
+If implementation level is not explicitly assigned, the system uses
+a default according to the following rules.
+volatile
+assign not_serializable
+ primitive_type
+ object_class_info
+object_serializable
+to override the default setting of object_class_info
.
+For example,
+this has been done for the
+
+binary_object wrapper
+
+
+// names for each tracking level
+enum tracking_type
+{
+ // never track this type
+ track_never = 0,
+ // track objects of this type if the object is serialized through a
+ // pointer.
+ track_selectively = 1,
+ // always track this type
+ track_always = 2
+};
+
+A corresponding macro is defined so that we can use:
+
+BOOST_CLASS_TRACKING(my_class, boost::serialization::track_never)
+
+Default tracking traits are:
+track_never
.
+ track_never
.
+ That is, addresses of addresses are not tracked by default.
+ boost::serialization::nvp
,
+ track_never
.
+ track_selectively
.
+ That is addresses of serialized objects are tracked if and only if
+ one or more of the following is true:
+ +The default behavior is almost always the most convenient one. However, +there a few cases where it would be desirable to override the +default. One case is that of a virtual base class. In a diamond +heritance structure with a virtual base class, object tracking +will prevent redundant save/load invocations. So here is one +case where it might be convenient to override the default tracking +trait. (Note: in a future version the default will be reimplemented +to automatically track classes used as virtual bases). This +situation is demonstrated by +test_diamond.cpp +included with the library. + +
+This is addressed by invoking
+BOOST_CLASS_EXPORT_IMPLEMENT(T)
+in the file which defines (implements) the class T.
+This ensures that code for the derived class T will
+be explicity instantiated.
+
typeid()
which can be
+used to return a unique string for the class. This is not entirely
+statisfactory for our purposes for the following reasons:
+
+So in the serialization library, this is addressed by invoking
+BOOST_CLASS_EXPORT_KEY2(my_class, "my_class_external_identifier")
+in the header file which declares he class.
+In a large majority of applications, the class name works just fine
+for the external identifier string so the following short cut is
+defined -
+BOOST_CLASS_EXPORT_KEY(my_class)
.
+
BOOST_CLASS_EXPORT(my_class)
+or
+BOOST_CLASS_EXPORT_GUID(my_class, "my_class_external_identifier")
+in either he declaration header or definition. These macros
+expand to invocation of the of both of the macros described above.
+(GUID stands for Globally Unique IDentfier.)
++(Elsewhere +in this manual, the serialization of derived classes is addressed in detail.) +
+The header file +export.hpp +contains all macro definitions described here. +The library will throw a runtime exception if +
BOOST_IS_ABSTRACT(T)
+to do this. Not all compilers support this type trait and corresponding
+macro. To address this, the macro
+BOOST_SERIALIZATION_ASSUME_ABSTRACT(T)
has been
+implemented to permit one to explicitly indicate that a specified
+type is in fact abstract. This will guarentee that
+BOOST_IS_ABSTRACT
+will return the correct value for all compilers.
+
+typeid(...)
which is available
+in systems which support RTTI (Run Time
+Type Information).
+This will be satisfactory in almost all cases and most users of this
+library will lose nothing in skipping this section of the manual.
+
+However, there are some cases where the default type determination
+system is not convenient. Some platforms might not support
+RTTI or it may have been disabled in order to speed execution
+or for some other reason. Some applications, E.G. runtime linking
+of plug-in modules, can't depend on C++ RTTI to determine the
+true derived class. RTTI only returns the correct type for polymorphic
+classes - classes with at least one virtual function. If any of these
+situations applies, one may substitute his own implementation of
+extended_type_info
+
+The interface to facilities required to implement serialization is defined in
+extended_type_info.hpp.
+
+Default implementation of these facilities based on typeid(...)
+is defined in
+
+extended_type_info_typeid.hpp.
+
+An alternative implementation based on exported class identifiers
+is defined in
+extended_type_info_no_rtti.hpp.
+
+By invoking the macro: +
+BOOST_CLASS_TYPE_INFO(
+ my_class,
+ extended_type_info_no_rtti<my_class>
+)
+
+we can assign the type information implementation to each class on a case by
+case basis. There is no requirement that all classes in a program use the same
+implementation of extended_type_info
. This supports the concept
+that serialization of each class is specified "once and for all" in a header
+file that can be included in any project without change.
++This is illustrated by the test program +test_no_rtti.cpp. +Other implementations are possible and might be necessary for +certain special cases. + +version.hpp. +
+namespace boost {
+namespace serialization {
+template<class T>
+struct is_wrapper
+ : public mpl::false_
+{};
+} // namespace serialization
+} // namespace boost
+
+
+For any class T
, The default definition
+of boost::serialization::is_wrapper<T>::value
is thus false.
+
+If we want to declare that a class my_class
+is a wrapper we specialize the version template:
+
+namespace boost {
+namespace serialization {
+struct is_wrapper<my_class>
+ : mpl::true_
+{};
+} // namespace serialization
+} // namespace boost
+
++To diminish typing and enhance readability, a macro is defined +so that instead of the above, we could write: +
+BOOST_CLASS_IS_WRAPPER(my_class)
+
+which expands to the code above.
+
+
+namespace boost { namespace serialization {
+ template
+ struct is_bitwise_serializable
+ : public is_arithmetic
+ {};
+} }
+
+is used, and can be specialized for other classes. The specialization
+is made easy by the corresponding macro:
+
+BOOST_IS_BITWISE_SERIALIZABLE(my_class)
+
+
+
+template<class T>
+struct nvp : public std::pair<const char *, T *>
+{
+ ...
+};
+
+used by XML archives to associate a name with a data variable of type T.
+These data types are never tracked and never versioned. So one might
+want to specify:
+
+BOOST_CLASS_IMPLEMENTATION(nvp<T>, boost::serialization::level_type::object_serializable)
+BOOST_CLASS_TRACKING(nvp<T>, boost::serialization::track_never)
+
+Examination of the definition of these macros reveals that they won't expand
+to sensible code when used with a template argument. So rather than using the
+convenience macros, use the original definitions
+
+template<class T>
+struct implementation_level<nvp<T> >
+{
+ typedef mpl::integral_c_tag tag;
+ typedef mpl::int_<object_serializable> type;
+ BOOST_STATIC_CONSTANT(
+ int,
+ value = implementation_level::type::value
+ );
+};
+
+// nvp objects are generally created on the stack and are never tracked
+template<class T>
+struct tracking_level<nvp<T> >
+{
+ typedef mpl::integral_c_tag tag;
+ typedef mpl::int_<track_never> type;
+ BOOST_STATIC_CONSTANT(
+ int,
+ value = tracking_level::type::value
+ );
+};
+
+to assign serialization traits to all classes generated by the template
+nvp<T>
++ +Note that it is only possible to use the above method to assign traits to +templates when using compilers which correctly support Partial Template Specialization. + +One's first impulse might be to do something like: + +
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template<class T>
+struct implementation_level<nvp<T> >
+{
+ ... // see above
+};
+
+// nvp objects are generally created on the stack and are never tracked
+template<class T>
+struct tracking_level<nvp<T> >
+{
+ ... // see above
+};
+#endif
+
+This can be problematic when one wants to make his code and archives
+portable to other platforms. It means the she objects will be serialized differently
+depending on the platform used. This implies that objects saved from one platform
+won't be loaded properly on another. In other words, archives won't be portable.
++This problem is addressed by creating another method of assigning serialization traits +to user classes. This is illustrated by the serialization for a +name-value pair. +
+Specifically, this entails deriving the template from a special class
+
+boost::serialization::traits
which is specialized for a specific
+combination of serialization traits.
+When looking up the serialization traits, the library first checks to see if this class has been
+used as a base class. If so, the corresponding traits are used. Otherwise, the standard defaults
+are used. By deriving from a serialization traits class rather than relying upon Partial Template
+Specializaton, one can a apply serialization traits to a template and those traits will be
+the same across all known platforms.
+
+The signature for the traits template is: +
+template<
+ class T,
+ int Level,
+ int Tracking,
+ unsigned int Version = 0,
+ class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T),
+ class IsWrapper = mpl::false_
+>
+struct traits
+
+and template parameters should be assigned according to the following table:
++
parameter | description | permitted values | default value |
---|---|---|---|
T | target class | class name | none |
Level | implementation level | not_serializable | none |
Tracking | tracking level | track_never | none |
Version | class version | unsigned integer | 0 |
ETTI | type_info implementation | extended_type_info_typeid | default type_info implementation |
IsWrapper | is the type a wrapper? | mpl::false_ | mpl::false_ |
+T t;
+ar << t;
+
+
+unless the tracking_level serialization trait is set to "track_never". The following
+will compile without problem:
+
+
+const T t
+ar << t;
+
+
+Likewise, the following code will trap at compile time:
+
+
+T * t;
+ar >> t;
+
+
+if the tracking_level serialization trait is set to "track_never".
+
+
+The following case illustrates the function of this message.
+It was originally used as an example in the
+mailing list by Peter Dimov.
+
+
+
+Suppose that the above message is not displayed and the code is used as is.
+
+class construct_from
+{
+ ...
+};
+
+void main(){
+ ...
+ Y y;
+ construct_from x(y);
+ ar << x;
+}
+
+void main(){
+ ...
+ Y y;
+ construct_from x(y);
+ ar << x;
+ ...
+ x.f(); // change x in some way
+ ...
+ ar << x
+}
+
+ + Again no problem. He gets two different of copies in the archive, each one is different. + That is he gets exactly what he expects and is naturally delighted. +
+
+class K {
+ shared_ptr <construct_from> z;
+ template <class Archive>
+ void serialize(Archive & ar, const unsigned version){
+ ar << z;
+ }
+};
+
+
+ + He builds and runs the program and tests his new functionality. It works + great and he's delighted. +
+
+
+BOOST_CLASS_TRACKING(construct_from, track_never)
+
+ +
shared_ptr<construct_from>
+is not going to have a single raw pointer shared amongst the instances. Each loaded
+shared_ptr<construct_from>
is going to
+have its own distinct raw pointer. This will break
+shared_ptr
and cause a memory leak. Again,
+The cause of this problem is very far removed from the point of discovery. It could
+well be that the problem is not even discovered until after the archives are loaded.
+Now we not only have difficult to find and fix program bug, but we have a bunch of
+invalid archives and lost data.
+Now consider what happens when the message is displayed: + +
+
+ar << x;
+
+ +
const_cast
+ - because it looks bad. So he'll just make the following change an move on.
+
+Y y;
+const construct_from x(y);
+ar << x;
+
+ + Things work fine and he moves on. +
+
+Y y;
+const construct_from x(y);
+...
+x.f(); // change x in some way ; compile error f() is not const
+...
+ar << x
+
+ + He's mildly annoyed now he tries the following: +
+
const
+ from const construct_from
above - damn now he
+ gets the trap. If he looks at the comment code where the
+ BOOST_STATIC_ASSERT
+ occurs, he'll do one of two things
+ +
const_cast
+ and fire off a complaint to the list and mabe they will fix it.
+ In this case, the story branches off to the previous scenario.
+ +
+BOOST_CLASS_TRACKING(construct_from, track_never)
+
+ +
construct_from
trait has been set to
+ "track_never" so he should always get copies and the log should be what we expect.
+ +
BOOST_CLASS_TRACKING
that
+ was inserted. Now the second trap is avoided, But damn - the first trap is
+ popping up again. Eventually, after some code restructuring, the differing
+ requirements of serializating construct_from
+ are reconciled.
++A problem arises when a program which reads an archive +includes the operation ar >> T * so that tracking information +will be included in the archive. When a program which +creates the archive doesn't include ar << T it is presumed +that the archive doesn't include tracking information and +the archive will fail to load. Also the reverse situation could +trigger a similar problem. +
+Though this situation is unlikely for several reasones, +it is possible - hence this warning. +
© Copyright Robert Ramey 2002-2004 and Matthias Troyer 2006. +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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/tutorial.html b/deal.II/contrib/boost/libs/serialization/doc/tutorial.html new file mode 100644 index 0000000000..8154611fea --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/tutorial.html @@ -0,0 +1,584 @@ + + + + + + + +
+ + |
+
+ Serialization+Tutorial+ |
+
serialize
into save/load
+
+ar << data;
+ar & data;
+
+An input archive is similar to an input datastream. Data can be loaded from the archive
+with either the >> or the & operator.
+
+ar >> data;
+ar & data;
+
+
+When these operators are invoked for primitive data types, the data is simply saved/loaded
+to/from the archive. When invoked for class data types, the class
+serialize
function is invoked. Each
+serialize
function is uses the above operators
+to save/load its data members. This process will continue in a recursive manner until
+all the data contained in the class is saved/loaded.
+
+
serialize
+function to save and load class data members.
++Included in this library is a program called +demo.cpp which illustrates how +to use this system. Below we excerpt code from this program to +illustrate with the simplest possible case how this library is +intended to be used. +
+
+#include <fstream>
+
+// include headers that implement a archive in simple text format
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+/////////////////////////////////////////////////////////////
+// gps coordinate
+//
+// illustrates serialization for a simple type
+//
+class gps_position
+{
+private:
+ friend class boost::serialization::access;
+ // When the class Archive corresponds to an output archive, the
+ // & operator is defined similar to <<. Likewise, when the class Archive
+ // is a type of input archive the & operator is defined similar to >>.
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & degrees;
+ ar & minutes;
+ ar & seconds;
+ }
+ int degrees;
+ int minutes;
+ float seconds;
+public:
+ gps_position(){};
+ gps_position(int d, int m, float s) :
+ degrees(d), minutes(m), seconds(s)
+ {}
+};
+
+int main() {
+ // create and open a character archive for output
+ std::ofstream ofs("filename");
+
+ // create class instance
+ const gps_position g(35, 59, 24.567f);
+
+ // save data to archive
+ {
+ boost::archive::text_oarchive oa(ofs);
+ // write class instance to archive
+ oa << g;
+ // archive and stream closed when destructors are called
+ }
+
+ // ... some time later restore the class instance to its orginal state
+ gps_position newg;
+ {
+ // create and open an archive for input
+ std::ifstream ifs("filename");
+ boost::archive::text_iarchive ia(ifs);
+ // read class state from archive
+ ia >> newg;
+ // archive and stream closed when destructors are called
+ }
+ return 0;
+}
+
+
+For each class to be saved via serialization, there must exist a function to
+save all the class members which define the state of the class.
+For each class to be loaded via serialization, there must exist a function to
+load theese class members in the same sequence as they were saved.
+In the above example, these functions are generated by the
+template member function serialize
.
+
+
The above formulation is intrusive. That is, it requires +that classes whose instances are to be serialized be +altered. This can be inconvenient in some cases. +An equivalent alternative formulation permitted by the +system would be: +
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+class gps_position
+{
+public:
+ int degrees;
+ int minutes;
+ float seconds;
+ gps_position(){};
+ gps_position(int d, int m, float s) :
+ degrees(d), minutes(m), seconds(s)
+ {}
+};
+
+namespace boost {
+namespace serialization {
+
+template<class Archive>
+void serialize(Archive & ar, gps_position & g, const unsigned int version)
+{
+ ar & g.degrees;
+ ar & g.minutes;
+ ar & g.seconds;
+}
+
+} // namespace serialization
+} // namespace boost
+
+
+In this case the generated serialize functions are not members of the
+gps_position
class. The two formulations function
+in exactly the same way.
+
+The main application of non-intrusive serialization is to permit serialization
+to be implemented for classes without changing the class definition.
+In order for this to be possible, the class must expose enough information
+to reconstruct the class state. In this example, we presumed that the
+class had public
members - not a common occurence. Only
+classes which expose enough information to save and restore the class
+state will be serializable without changing the class definition.
+
+A serializable class with serializable members would look like this: +
+class bus_stop
+{
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & latitude;
+ ar & longitude;
+ }
+ gps_position latitude;
+ gps_position longitude;
+protected:
+ bus_stop(const gps_position & lat_, const gps_position & long_) :
+ latitude(lat_), longitude(long_)
+ {}
+public:
+ bus_stop(){}
+ // See item # 14 in Effective C++ by Scott Meyers.
+ // re non-virtual destructors in base classes.
+ virtual ~bus_stop(){}
+};
+
+That is, members of class type are serialized just as +members of primitive types are. +
+Note that saving an instance of the class bus_stop
+with one of the archive operators will invoke the
+serialize
function which saves
+latitude
and
+longitude
. Each of these in turn will be saved by invoking
+serialize
in the definition of
+gps_position
. In this manner the whole
+data structure is saved by the application of an archive operator to
+just its root item.
+
+
+
Derived classes should include serializations of their base classes. +
+#include <boost/serialization/base_object.hpp>
+
+class bus_stop_corner : public bus_stop
+{
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ // serialize base class information
+ ar & boost::serialization::base_object<bus_stop>(*this);
+ ar & street1;
+ ar & street2;
+ }
+ std::string street1;
+ std::string street2;
+ virtual std::string description() const
+ {
+ return street1 + " and " + street2;
+ }
+public:
+ bus_stop_corner(){}
+ bus_stop_corner(const gps_position & lat_, const gps_position & long_,
+ const std::string & s1_, const std::string & s2_
+ ) :
+ bus_stop(lat_, long_), street1(s1_), street2(s2_)
+ {}
+};
+
+
+
+Note the serialization of the base classes from the derived
+class. Do NOT directly call the base class serialize
+functions. Doing so might seem to work but will bypass the code
+that tracks instances written to storage to eliminate redundancies.
+It will also bypass the writing of class version information into
+the archive. For this reason, it is advisable to always make member
+serialize
functions private. The declaration
+friend boost::serialization::access
will grant to the
+serialization library access to private member variables and functions.
+
+
bus_stop
.
+
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ bus_stop * stops[10];
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ int i;
+ for(i = 0; i < 10; ++i)
+ ar & stops[i];
+ }
+public:
+ bus_route(){}
+};
+
+
+Each member of the array stops
will be serialized.
+But remember each member is a pointer - so what can this really
+mean? The whole object of this serialization is to permit
+reconstruction of the original data structures at another place
+and time. In order to accomplish this with a pointer, it is
+not sufficient to save the value of the pointer, rather the
+object it points to must be saved. When the member is later
+loaded, a new object has to be created and a new pointer has
+to be loaded into the class member.
++If the same pointer is serialized more than once, only one instance +is be added to the archive. When read back, no data is read back in. +The only operation that occurs is for the second pointer is set equal to the first +
+Note that, in this example, the array consists of polymorphic pointers. +That is, each array element point to one of several possible +kinds of bus stops. So when the pointer is saved, some sort of class +identifier must be saved. When the pointer is loaded, the class +identifier must be read and and instance of the corresponding class +must be constructed. Finally the data can be loaded to newly created +instance of the correct type. + +As can be seen in +demo.cpp, +serialization of pointers to derived classes through a base +clas pointer may require explicit enumeration of the derived +classes to be serialized. This is referred to as "registration" or "export" +of derived classes. This requirement and the methods of +satisfying it are explained in detail +here +
+All this is accomplished automatically by the serialization +library. The above code is all that is necessary to accomplish +the saving and loading of objects accessed through pointers. +
+
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ bus_stop * stops[10];
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & stops;
+ }
+public:
+ bus_route(){}
+};
+
+
+
+
+#include <boost/serialization/list.hpp>
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ std::list<bus_stop *> stops;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & stops;
+ }
+public:
+ bus_route(){}
+};
+
+
+
+Suppose we're satisfied with our bus_route
class, build a program
+that uses it and ship the product. Some time later, it's decided
+that the program needs enhancement and the bus_route
class is
+altered to include the name of the driver of the route. So the
+new version looks like:
+
+
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ std::list<bus_stop *> stops;
+ std::string driver_name;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & driver_name;
+ ar & stops;
+ }
+public:
+ bus_route(){}
+};
+
+
+Great, we're all done. Except... what about people using our application
+who now have a bunch of files created under the previous program.
+How can these be used with our new program version?
++In general, the serialization library stores a version number in the +archive for each class serialized. By default this version number is 0. +When the archive is loaded, the version number under which it was saved +is read. The above code can be altered to exploit this +
+
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/version.hpp>
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ std::list<bus_stop *> stops;
+ std::string driver_name;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ // only save/load driver_name for newer archives
+ if(version > 0)
+ ar & driver_name;
+ ar & stops;
+ }
+public:
+ bus_route(){}
+};
+
+BOOST_CLASS_VERSION(bus_route, 1)
+
+
+By application of versioning to each class, there is no need to
+try to maintain a versioning of files. That is, a file version
+is the combination of the versions of all its constituent classes.
+
+This system permits programs to be always compatible with archives
+created by all previous versions of a program with no more
+effort than required by this example.
+
+serialize
+into save/load
serialize
function is simple, concise, and guarantees
+that class members are saved and loaded in the same sequence
+- the key to the serialization system. However, there are cases
+where the load and save operations are not as similar as the examples
+used here. For example, this could occur with a class that has evolved through
+multiple versions. The above class can be reformulated as:
+
+
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/split_member.hpp>
+
+class bus_route
+{
+ friend class boost::serialization::access;
+ std::list<bus_stop *> stops;
+ std::string driver_name;
+ template<class Archive>
+ void save(Archive & ar, const unsigned int version) const
+ {
+ // note, version is always the latest when saving
+ ar & driver_name;
+ ar & stops;
+ }
+ template<class Archive>
+ void load(Archive & ar, const unsigned int version)
+ {
+ if(version > 0)
+ ar & driver_name;
+ ar & stops;
+ }
+ BOOST_SERIALIZATION_SPLIT_MEMBER()
+public:
+ bus_route(){}
+};
+
+BOOST_CLASS_VERSION(bus_route, 1)
+
+
+The macro BOOST_SERIALIZATION_SPLIT_MEMBER()
generates
+code which invokes the save
+or load
+depending on whether the archive is used for saving or loading.
+
+In this tutorial, we have used a particular
+archive class - text_oarchive
for saving and
+text_iarchive
for loading.
+text archives render data as text and are portable across platforms. In addition
+to text archives, the library includes archive class for native binary data
+and xml formatted data. Interfaces to all archive classes are all identical.
+Once serialization has been defined for a class, that class can be serialized to
+any type of archive.
+
+If the current set of archive classes doesn't provide the +attributes, format, or behavior needed for a particular application, +one can either make a new archive class or derive from an existing one. +This is described later in the manual. + +
+The astute reader might notice that these examples contain a subtle but important flaw.
+They leak memory. The bus stops are created in the
+main
function. The bus schedules may refer to these bus stops
+any number of times. At the end of the main function after the bus schedules are destroyed,
+the bus stops are destroyed. This seems fine. But what about the structure
+new_schedule
data item created by the
+process of loading from an archive? This contains its own separate set of bus stops
+that are not referenced outside of the bus schedule. These won't be destroyed
+anywhere in the program - a memory leak.
+
+There are couple of ways of fixing this. One way is to explicitly manage the bus stops.
+However, a more robust and transparent is to use
+shared_ptr
rather than raw pointers. Along
+with serialization implemenations for the Standard Library, the serialization library
+includes implementation of serialization for
+boost::shared ptr
. Given this, it should be
+easy to alter any of these examples to eliminate the memory leak. This is left
+as an excercise for the reader.
+
+
© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/void_cast.html b/deal.II/contrib/boost/libs/serialization/doc/void_cast.html new file mode 100644 index 0000000000..51c0bae309 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/void_cast.html @@ -0,0 +1,104 @@ + + + + + + + +
+ + |
+
+ Serialization+
+ |
+
dynamic_cast<T>(U * u)
+for casting a pointer at runtime between two related types. However, this can only be
+used for polymorphic classes. That is, it can only be used with related classes which have at least one virtual function.
+Limiting the serializaton of pointers to only such class would diminish the applicability
+of the library.
+
+boost::serialization
.
+
+
+template<class Derived, class Base>
+const void_cast_detail::void_caster &
+void_cast_register(
+ Derived const * derived = NULL,
+ Base * const base = NULL
+)
+
Derived
is immediately derived from
+Base
in a global table.
+
+ void_cast_register<A, B>();
+ void_cast_register<B, C>();
+
+ automatically derives the fact that A can be upcast to C and vice-versa.
+
+void *
+void_upcast(
+ extended_type_info const & derived_type,
+ extended_type_info const & base_type,
+ void * const t
+);
+
+void *
+void_downcast(
+ extended_type_info const & derived_type,
+ extended_type_info const & base_type,
+ void * const t
+);
+
+extended_type_info
+records. An attempt to cast between types not "registered" with
+void_cast_register
+will throw a
+boost::archive::archive_exception
+with value equal to
+unregistered_cast
+© Copyright Robert Ramey 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) +
+ + diff --git a/deal.II/contrib/boost/libs/serialization/doc/wrappers.html b/deal.II/contrib/boost/libs/serialization/doc/wrappers.html new file mode 100644 index 0000000000..79107ac4a4 --- /dev/null +++ b/deal.II/contrib/boost/libs/serialization/doc/wrappers.html @@ -0,0 +1,213 @@ + + + + + + + +
+ + |
+
+ Serialization+Serialization Wrappers+ |
+
BOOST_STRONG_TYPEDEF
+
+Wrappers need to be treated in a special way by some archives, and hence
+the is_wrapper
trait for
+these wrapper classes is set to true.
+
+
+boost::serialization::binary_object(void * t, size_t size);
+boost::serialization::make_binary_object(void * t, size_t size);
+
+which will construct a temporary binary object that can be serialized just like any other object.
+Its default serialization is to use archive class primitives
+save_binary
and load_binary
.
+Note that it doesn't allocated any storage or create any objects.
+Its sole purpose is to pass the data size and address as pair to the archive class.
+
+
+boost::array<T>
or a std::vector<T>
.
+The purpose of this wrapper is to support archive types (such as binary
+archives) that provide optimized serialization for contiguous sequences of
+objects of the same type.
+
+The header file
+
+array.hpp
+
+includes the function
+
+template <T>
+boost::serialization::make_array(T* t, std::size_t size);
+
+which will construct a temporary array
object
+
+template
+class array
+{
+public:
+ typedef T value_type;
+ array(value_type* t, std::size_t s);
+ value_type* address() const;
+ std::size_t count() const;
+};
+
+that can be serialized just like any other object.
+Its default serialization is to use serialize each array element.
+Note that it doesn't allocated any storage or create any objects.
+Its sole purpose is to pass the data type, size and address to the archive class.
+
+Archive types that can provide optimized implementations for contiguous
+arrays of homogeneous data types should overload the serialization of
+array
.
+
+
+BOOST_STRONG_TYPEDEF
BOOST_STRONG_TYPEDEF
template.
+The serialization libraries uses these to pass particular kinds of integers such
+as object_id, version, etc. to an archive class. Given that these integers
+are now distinguishable according to their type, XML archives can apply
+special handling to these types. For example, a version number is rendered
+as an XML attribute in the form "version=12". In the absence of any specific override,
+these types are automatically converted to the underlying integer type so the
+special overrides used for XML archives aren't needed for other archives.
+
+
+
+collection_size_type
in the
+header file
+
+collection_size_type.hpp
+. This type should be used for serializaing the size of a C++ collection, so
+that the archive can pick the best integral representation for the serialization
+of collection sizes. This is necessary since, although std::size_t
+is guaranteed to be an integral type large enough to represent the size of
+a collection on a specific platform, the archive might want to serialize
+the size differently than this type. For example, the collection_size_type
+might be serialized as a variable length integer in a portable binary archive.
+
+
+
+
+
+
+
+Our solution is to wrap class members to be serialized in a
+name-value-pair. This structure is defined in
+nvp.hpp.
+It is just a reference to the data member coupled with a pointer to
+to a const char *
which
+corresponds to the XML name. It implements the default
+serialization functions for a name-value pair. This default
+action is to just ignore the item name and serialize the
+data value in the normal manner. For archive classes that
+don't make any special provision for name-value pairs, this
+is the action which will be invoked when the name-value pair
+is serialized. Hence, wrapping a data value into a name-value
+pair will have no effect when used with archives which
+make no special provision for this wrapper.
+
+The xml archive classes contain code similar to: +
+// special treatment for name-value pairs.
+template<class T>
+xml_oarchive & operator&(const boost::serialization::nvp & t)
+{
+ // write an xml start tag
+ start_tag(t.name());
+
+ // serialize the data as usual
+ *this & t.value();
+
+ // write an xml end tag
+ end_tag(t.name());
+}
+
+The most obvious and convient name to assign to as the XML data item name
+is - surpise! - the name of the C++ class data member. So our serialization
+code will look like:
+
+ar & make_nvp("my_variable", my_variable);
+
+To simplify typing and enhance readability a macro is defined so we can write:
+
+ar & BOOST_SERIALIZATION_NVP(my_variable);
+
+Similarly there exists a macro definition that permits us to write:
+
+BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class)
+
+
+Note that these macros must be used in the namespace of the class,
+and without qualifying the namespace in the argument.
+
++demo_gps.hpp +includes NVP wrappers or all data members. +demo_xml.cpp +saves and loads data to an XML archive. +Here +is example of the XML Archive corresponding to our tutorial example. + +
+ar & make_nvp("named_binary_object", make_binary_object(address, size));
+
+
+© Copyright Robert Ramey 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) +
+ +