Compare commits

...

85 Commits

Author SHA1 Message Date
nobody d4a5c4810f This commit was manufactured by cvs2svn to create tag
'Version_1_33_1_beta'.

[SVN r31604]
2005-11-08 23:18:41 +00:00
Rene Rivera f976f993ae Fix save-load dependency problems when building with more than one toolset.
[SVN r31498]
2005-10-27 15:31:25 +00:00
Robert Ramey b724041a6e small modification to accomodate QNX
[SVN r31489]
2005-10-27 07:25:44 +00:00
Victor A. Wagner Jr. 43892a0b2b Changed - the table of legal characters for an XML tag
- the problem was found by Benjamin Higgins, bhiggins@gmail.com and
          was an obvious typo.


[SVN r31488]
2005-10-27 06:40:01 +00:00
Robert Ramey afb4250f38 remove force:include from como linker arguments
[SVN r31465]
2005-10-25 18:21:52 +00:00
Douglas Gregor a54da565ef Add BOOST_DEDUCED_TYPENAME for Metrowerks CodeWarrior
[SVN r31461]
2005-10-25 13:49:23 +00:00
Douglas Gregor bd84d08b40 Fixes for shared_ptr serialization on Borland compilers, from John Maddock
[SVN r31445]
2005-10-24 15:31:26 +00:00
Douglas Gregor 9dbb735f0e Fix dependency problems with tests, from Troy D. Straszheim
[SVN r31444]
2005-10-24 15:14:47 +00:00
Robert Ramey a5549c8daa addition to accomodate browsers with javascript turned off
[SVN r31438]
2005-10-23 21:35:09 +00:00
Robert Ramey b6f3b37c86 replace _ with -
[SVN r31434]
2005-10-23 16:51:41 +00:00
Robert Ramey e89dc7cec6 document compiler warning messages
[SVN r31433]
2005-10-23 16:35:01 +00:00
Robert Ramey ed3a89bc7a suppress irrelevant warnings
[SVN r31432]
2005-10-23 16:33:43 +00:00
Douglas Gregor 0ca9f4f7a6 Fix broken uses of NULL
[SVN r31349]
2005-10-16 17:04:58 +00:00
Robert Ramey a9a8d219ca correct error which shows up in test_no_rtti
[SVN r31340]
2005-10-15 20:14:31 +00:00
Robert Ramey b067cfc518 workaround ICE on old plaforms
[SVN r31337]
2005-10-15 14:20:11 +00:00
Robert Ramey 5ac1d1156e include commented out includes to fix bjam dependencies
[SVN r31304]
2005-10-12 16:47:52 +00:00
Robert Ramey 2f11734b5f add mention that derived pointers must be polymorphic
[SVN r31287]
2005-10-11 15:12:58 +00:00
Robert Ramey 23b8fb8785 back out reset_object_address template
[SVN r31286]
2005-10-11 15:10:23 +00:00
Robert Ramey 1749bf9c03 correct very first illustration
[SVN r31260]
2005-10-10 03:26:49 +00:00
Robert Ramey 2f119f0694 remove unnecessary serialization_map declaration
[SVN r31259]
2005-10-10 03:23:49 +00:00
Robert Ramey a3f6ecee7f reformat
[SVN r31258]
2005-10-10 03:22:44 +00:00
Robert Ramey e553bbfb0d remove const from reset_object_address declaration
[SVN r31257]
2005-10-10 03:20:28 +00:00
Robert Ramey c0a5309e93 update for 1.33.1
[SVN r31171]
2005-10-02 06:25:42 +00:00
Robert Ramey c852736757 fix xml test
[SVN r31170]
2005-10-02 06:04:17 +00:00
Robert Ramey 6a1209e115 reset_object_address is now a template
[SVN r31169]
2005-10-02 06:02:06 +00:00
Robert Ramey 24b596bcf4 make sure no destructors call any virtual functions
[SVN r31168]
2005-10-02 06:01:14 +00:00
Robert Ramey ca999aaa88 make sure destruct doesnt call any virtual functions
[SVN r31167]
2005-10-02 05:59:38 +00:00
Robert Ramey 903da1f79a reset object address now a template
[SVN r31166]
2005-10-02 05:58:37 +00:00
Robert Ramey 51be585b61 fix tab
[SVN r31165]
2005-10-02 05:57:24 +00:00
Robert Ramey 814429125c minor code refactor
[SVN r31164]
2005-10-02 05:52:42 +00:00
Robert Ramey 9a1a43dd68 change reset_object_address to use template
[SVN r31163]
2005-10-02 05:51:40 +00:00
Robert Ramey 0d4712f1cb fix errorneous call into virtual function from destructor
[SVN r31162]
2005-10-02 05:50:13 +00:00
Robert Ramey 2afb64b2e6 improved archive concept
[SVN r31086]
2005-09-23 06:13:57 +00:00
Robert Ramey 142db7e716 correct tests to help passing
[SVN r31057]
2005-09-20 16:17:32 +00:00
Robert Ramey 33750658a3 BOOST_NO_EXCEPTION fixup
[SVN r31041]
2005-09-19 17:18:34 +00:00
Robert Ramey 10c0efac47 add info about map
[SVN r31031]
2005-09-19 03:16:56 +00:00
Robert Ramey 66685340a0 change to accomodate map serialization
[SVN r31030]
2005-09-19 03:14:59 +00:00
Robert Ramey 65a3901e68 correct for BOOST_NO_EXCEPTION
[SVN r31026]
2005-09-19 01:52:02 +00:00
Robert Ramey 81402ffadc amend and reformat archive concepts
[SVN r31013]
2005-09-16 20:06:57 +00:00
Robert Ramey 4cce79fffc misc document refinements and corrections
[SVN r31003]
2005-09-15 20:12:37 +00:00
Rene Rivera fb8b2f0825 MinGW runtime 3.8 now supports wide char functions, but only the C99 set. MinGW specific patch to use std::wcrtomb instead of std::wctomb.
[SVN r31001]
2005-09-15 16:36:10 +00:00
Rene Rivera 67cda7157c Fix the condition for STLport-5 so that it works when there is no stlport-version property.
[SVN r30999]
2005-09-15 16:19:10 +00:00
Rene Rivera f055298bcf MinGW-3.4.2 + STLport-5 can support wide char operations.
[SVN r30960]
2005-09-13 19:12:47 +00:00
Robert Ramey 181abc0c76 add test for nested invocations
[SVN r30939]
2005-09-13 04:33:30 +00:00
Robert Ramey 8d8f08e9c7 suppress error messages
[SVN r30938]
2005-09-13 04:32:16 +00:00
Robert Ramey d45be5d5cc enhance comments
[SVN r30937]
2005-09-13 04:28:26 +00:00
Robert Ramey 2dd7478b0d update data member name
[SVN r30936]
2005-09-13 04:26:51 +00:00
Robert Ramey fc4f873b14 add guard for unknown deletion
[SVN r30935]
2005-09-13 04:25:49 +00:00
Robert Ramey e7cf216b41 add erase call
[SVN r30934]
2005-09-13 04:23:04 +00:00
Robert Ramey f622a85d1d formating improvement
[SVN r30933]
2005-09-13 04:22:02 +00:00
Robert Ramey 4e506b8b20 add erase member function
[SVN r30932]
2005-09-13 04:20:27 +00:00
Robert Ramey 99e810a2ad make destructor non-virtual
[SVN r30931]
2005-09-13 04:18:13 +00:00
Robert Ramey d3399abe7d cosmetic formating improvement
[SVN r30930]
2005-09-13 04:17:30 +00:00
Robert Ramey d1ddaf6d40 remove virtual from destructor
[SVN r30928]
2005-09-13 03:54:10 +00:00
Robert Ramey 5e92b44ac0 correction for reset_object_address
[SVN r30814]
2005-09-05 14:48:41 +00:00
Robert Ramey 35e5022b1d small adjustment in derived pointer example
[SVN r30804]
2005-09-04 20:05:49 +00:00
Robert Ramey 43b1e020f6 add test for map::value_type
[SVN r30803]
2005-09-04 20:02:48 +00:00
Robert Ramey 157b54fbb0 factor out common module
[SVN r30802]
2005-09-04 20:00:15 +00:00
Robert Ramey 4a997c5ee3 correct subtle error in map serialization
[SVN r30801]
2005-09-04 19:58:48 +00:00
Robert Ramey c5d7d99379 update template traits information
[SVN r30797]
2005-09-03 18:34:15 +00:00
Robert Ramey 76f2cb91ea correct header sequence explanation
[SVN r30796]
2005-09-03 18:33:17 +00:00
Robert Ramey 87685cc870 correction to reset_object_address
[SVN r30788]
2005-09-03 04:45:27 +00:00
Robert Ramey 24d628a70e new header file
[SVN r30766]
2005-09-01 07:16:07 +00:00
Robert Ramey 5d989c4d98 augment test
[SVN r30765]
2005-09-01 07:13:34 +00:00
Robert Ramey 52a0ddee21 remove header sequence requirment
[SVN r30764]
2005-09-01 07:12:32 +00:00
Robert Ramey 34d7b41249 correct reset_object_address
[SVN r30763]
2005-09-01 07:06:09 +00:00
Robert Ramey 6a45041ca8 remove header sequence requirment
[SVN r30762]
2005-09-01 07:02:34 +00:00
Robert Ramey 31eb724fd0 remove header sequence requirement
[SVN r30761]
2005-09-01 06:56:46 +00:00
Robert Ramey c0b4cf938b remove header sequence requirement and bug fixes
[SVN r30760]
2005-09-01 06:55:24 +00:00
Douglas Gregor 34c29757e4 kFreeBSD support from Domenico Andreoli
[SVN r30687]
2005-08-26 15:00:14 +00:00
Robert Ramey 04a833252c fix typos
[SVN r30642]
2005-08-23 23:44:52 +00:00
Robert Ramey 8fd0680eff tweak to help code instantiation
[SVN r30519]
2005-08-10 05:35:31 +00:00
Robert Ramey a3922971b4 permit non-default constructors
[SVN r30518]
2005-08-10 05:34:42 +00:00
Robert Ramey f606820031 fix indent
[SVN r30517]
2005-08-10 05:31:46 +00:00
Robert Ramey d3ed1792fc move is_abstract to serialization namespace
[SVN r30516]
2005-08-10 05:30:55 +00:00
Robert Ramey 094071d25e add missing entry points
[SVN r30515]
2005-08-10 05:28:57 +00:00
Robert Ramey b85d43ac2b change type to typex to accomodate BCB
[SVN r30514]
2005-08-09 15:43:31 +00:00
Rene Rivera 72db2ac39b Fix fallout of changes to collection_load_imp.hpp of moving the stl sub-namespace scope.
[SVN r30486]
2005-08-05 14:27:58 +00:00
Robert Ramey 0606fd8027 remove superfluous header
[SVN r30474]
2005-08-04 21:09:04 +00:00
Robert Ramey ef8745cf48 include is_pointer.hpp
[SVN r30466]
2005-08-04 17:42:30 +00:00
Jonathan Turkanis 25b0ed093c fixed broken links
[SVN r30431]
2005-08-03 21:42:39 +00:00
Jonathan Turkanis 01adcfc182 fixed broken links
[SVN r30423]
2005-08-03 20:11:21 +00:00
Douglas Gregor 3d715fa6ad Remove broken link
[SVN r30349]
2005-07-31 19:07:09 +00:00
Douglas Gregor e1176c244c Rename test project to under 32 characters
[SVN r30347]
2005-07-31 18:46:20 +00:00
nobody d15db6d4c4 This commit was manufactured by cvs2svn to create branch 'RC_1_33_0'.
[SVN r30300]
2005-07-28 18:22:24 +00:00
84 changed files with 1946 additions and 1011 deletions
+3 -2
View File
@@ -43,6 +43,7 @@ SOURCES =
WSOURCES =
codecvt_null
utf8_codecvt_facet
basic_text_wiprimitive
basic_text_woprimitive
binary_wiarchive
@@ -52,7 +53,6 @@ WSOURCES =
xml_wgrammar
xml_wiarchive
xml_woarchive
utf8_codecvt_facet
;
template boost_serialization_base
@@ -60,13 +60,14 @@ template boost_serialization_base
: ## requirements ##
std::locale-support
toolset::require-boost-spirit-support
toolset::suppress-warnings
toolset::optimizations
# the common names rule ensures that the library will
# be named according to the rules used by the install
# and auto-link features:
common-variant-tag
<sysinclude>$(BOOST_ROOT)
<stlport-iostream>on
<borland*><*><cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-8001 -w-0018 -w-8066"
<msvc><*><cxxflags>-Gy
<vc*><*><cxxflags>-Gy
<define>BOOST_LIB_DIAGNOSTIC=1
+38 -2
View File
@@ -51,8 +51,11 @@ rule toolset::require-wide-char-io-support ( toolset variant : subvariant-path p
echo **** wide char i/o not supported by libcomo standard library **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "mingw*" :
echo **** wide char i/o not supported by the mingw standard library **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
if ! [ MATCH "^([5][.][0])$" : [ get-values <stlport-version> : $(properties) ] ]
{
echo **** wide char i/o not supported by the mingw standard library **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
}
}
return $(subvariant-path) $(properties) ;
}
@@ -80,3 +83,36 @@ rule toolset::require-shared-libraries-support ( toolset variant : subvariant-pa
}
return $(subvariant-path) $(properties) ;
}
# certain tool sets display warnings which are not applicable to the serialization library
rule toolset::suppress-warnings ( toolset variant : subvariant-path properties * )
{
switch $(toolset) {
case "vc-8*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-wd4996" ] ;
case "*cygwin*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
case "gcc*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
case "mingw*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
case "borland*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066" ] ;
}
return $(subvariant-path) $(properties) ;
}
# set optimization switches for certain toolsets. We do it here rather than in the
# Jamfile requirements because here we can use a regex for the compiler name.
rule toolset::optimizations ( toolset variant : subvariant-path properties * )
{
switch $(toolset) {
case "vc*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
case "msvc" :
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
}
return $(subvariant-path) $(properties) ;
}
+186 -266
View File
@@ -14,273 +14,194 @@
</td>
<td valign="top">
<h1 align="center">Serialization</h1>
<h2 align="center">Archive Concept</h2>
<h2 align="center">Archive Concepts</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#saving_interface">Saving</a>
<dt><a href="#loading_interface">Loading</a>
<dt><a href="#saving_interface">Saving Archive Concept</a>
<dt><a href="#loading_interface">Loading Archive Concept</a>
<dt><a href="#archive_models">Models</a>
<dt><a href="#exceptions">Exceptions</a>
<dt><a href="#charactersets">Character Sets</a>
</dl>
An <strong>Archive</strong> contains a sequence of bytes created from
an arbitrary nested set of C++ data structures.
<h4><a name="saving_interface">Saving</a></h4>
An object that saves data to an archive implements the following interface.
<pre><code>
class oarchive : ...
{
...
public:
// called to save objects
template&lt;class T&gt;
oarchive & operator&lt;&lt;(const T & t);
template&lt;class T&gt;
oarchive & operator&(T & t){
return *this &lt;&lt; t;
}
void save_binary(const void *address, std::size_t count);
template&lt;class T&gt;
register_type(T * t = NULL);
unsigned int library_version() const;
struct is_saving {
typedef mpl::bool_&lt;true&gt; type;
BOOST_STATIC_CONSTANT(bool, value=true);
};
struct is_loading {
typedef mpl::bool_&lt;false&gt; type;
BOOST_STATIC_CONSTANT(bool, value=false);
};
...
};
</code></pre>
The template parameter <code>T</code> must correspond to a type which
models the <a href="serialization.html"><strong>Serializable</strong></a> concept.
<dl>
<dt><h4><code>
template&lt;class T&gt;
oarchive & operator&lt;&lt;(const T & t);
template&lt;class T&gt;
oarchive & operator&(T & t);
</code></h4></dt>
<dd>
<p>
Appends an object of type T to the archive. The object may be
<h4>Notation</h4>
In the following descriptions
<ul>
<li>A primitive data type such as int, char, float, etc.
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
function has been defined.
<li>A pointer to a serializable object.
<li><code>SA</code> is an type modeling the <a href="#loading_interface">Saving Archive Concept</a>
<li><code>sa</code> is an instance of type SA.
<li><code>LA</code> is an type modeling the <a href="#loading_interface">Loading Archive Concept</a>
<li><code>la</code> is an instance of type LA.
<li><code>T</code> is an <a href="serialization.html"><strong>Serializable</strong></a> Type
<li><code>x</code> is an instance of type T Type</li>.
<li><code>u,v</code> is a pointer to a an instance of type T
<li><code>count</code> is an instance of a type that can be converted to <code>std::size_t</code>.
</ul>
</dd>
<dt><h4><code>
void save_binary(const void *address, std::size_t count);
</code></h4></dt>
<dd>
Appends to the archive <code style="white-space: normal">count</code> bytes found at
<code style="white-space: normal">address</code>.
</dd>
<dt><h4><code>
template&lt;class T&gt;
register_type(T * t = NULL);
</code></h4></dt>
<dd>
Appends a sequential integer to the archive. This integer becomes the "key" used
to look up the class type when the archive is later loaded. This process is
referred to as "class registration". It is only necessary to invoke this function for
objects of derived classes which are serialized through a base class pointer. This
is explained in detail in
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
</dd>
<dt><h4><code>
unsigned int library_version() const;
</code></h4></dt>
<dd>
Returns the version number of the serialization library that created the archive.
This number will be incremented each time the library is altered in such a way
that serialization could be altered for some type. For example, suppose the type
used for a count of collection members is changed. The code that loads collections
might be conditioned on the library version to make sure that libraries created by
previous versions of the library can still be read.
</dd>
<dt><h4><code>
is_saving::type = mpl::bool&lt;true&gt;;
is_saving::value= true;
is_loading::type = mpl::bool&lt;false&gt;;
is_loading::value= false;
</code></h4></dt>
<dd>
These integral constants permit archive attributes to be queried at compiler
or execution time. They can used to generate code with boost
<a href="../../mpl/doc/index.html">mpl</a>
. For and example
showing how these can beused, see the implementation of
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
</dd>
<h4><a name="saving_interface">Saving Archive Concept</a></h4>
<h4>Associated Types</h4>
Intuitively, a type modeling this concept will generate a sequence of bytes
correpsonding to an arbitrary set of C++ data structures. Each type modeling the
Saving Archive concept (SA) may be associated with another type modeling the
<a href="#loading_interface">Loading Archive Concept</a>(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 the is equivalent to the original.
The notion of equivalence is defined by the implementations of the pair of archives and the
way the data is are rendered <a href="serialization.html">serializable</a>.
<p>
<h4>Valid Expressions</h4>
<dl>
<dt><h4><code>
SA::is_saving
</code></h4></dt>
<dd>
Returns the Boost MPL Integral Constant type boost::mpl::bool_&lt;true&gt;
</dd>
<dt><h4><code>
SA::is_loading
</code></h4></dt>
<dd>
Returns the Boost MPL Integral Constant type boost::mpl::bool_&lt;false&gt;
</dd>
<dt><h4><code>
sa &lt;&lt; x
<br>
sa &amp; x
</code></h4></dt>
<dd>
These expressions must perform exactly the same function. They append the
value of <code style="white-space: normal">x</code> along with other information to <code>sa</code>.
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 <code>x</code>.
<p>
Returns a reference to <code>sa</code>.
</dd>
<dt><h4><code>
sa.save_binary(u, count)
</code></h4></dt>
<dd>
Appends to the archive <code style="white-space: normal">size_t(count)</code> bytes found at
<code style="white-space: normal">u</code>.
</dd>
<dt><h4><code>
sa.register_type&lt;T&gt;()
<br>
sa.register_type(u)
</code></h4></dt>
<dd>
Appends information about class T to the archive. This information is used to
construct the correct class when a derived pointer is loaded by a corresponding
Loading Archive type.
Invocation of this member function is referred to as "class registration".
This is explained in detail in
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
The second syntax is included to permit this function to be called on non-conforming
compilers when <code style="white-space: normal">sa</code> is a template argument.
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
</dd>
<dt><h4><code>
sa.library_version()
</code></h4></dt>
<dd>
Returns an unsigned integer containing the current version number of the serialization
library. This number will be incremented each time the library is altered in such a
way that serialization could be altered for some type. For example, suppose the type
used for a count of collection members is changed. The code that loads collections
might be conditioned on the library version to make sure that libraries created by
previous versions of the library can still be read.
</dd>
</dl>
<h4><a name="loading_interface">Loading</a></h4>
An object that saves data to an archive implements the following interface.
<pre><code>
class iarchive : ...
{
...
public:
// called to load objects
template&lt;class T&gt;
iarchive & operator&gt;&gt;(T & t);
template&lt;class T&gt;
iarchive & operator&(T & t){
return *this &gt;&gt; t;
}
void delete_created_pointers();
void load_binary(void *address, std::size_t count);
template&lt;class T&gt;
register_type(T * t = NULL);
reset_object_address(void * old_address, void * new_address);
unsigned int library_version() const;
struct is_saving {
typedef mpl::bool_&lt;false&gt; type;
BOOST_STATIC_CONSTANT(bool, value=false);
};
struct is_loading {
typedef mpl::bool_&lt;true&gt; type;
BOOST_STATIC_CONSTANT(bool, value=true);
};
...
};
} //namespace archive
) //namespace boost
</code></pre>
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
<h4>Associated Types</h4>
Each model of this concept presumes the
existence of a corresponding type modeling the
<a href="#saving_interface">Saving Archive Concept</a>.
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.
<h4>Valid Expressions</h4>
<dl>
The template parameter <code>T</code> must correspond to a type which
models the <a href="serialization.html"><strong>Serializable</strong></a> concept.
<dt><h4><code>
template&lt;class T&gt;
iarchive & operator&gt;&gt;(T & t);
template&lt;class T&gt;
iarchive & operator&(T & t);
</code></h4></dt>
<dd>
<p>
Retrieves an object of type T from the archive. The object may be
<ul>
<li>A primitive data type such as int, char, float, etc.
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
function has been defined.
<li>A pointer to a serializable object.
</ul>
</dd>
<dt><h4><code>
void load_binary(void *address, std::size_t count);
</code></h4></dt>
<dd>
Retrieves from the archive <code style="white-space: normal">count</code> bytes and stores
them in memory starting at <code style="white-space: normal">address</code>.
</dd>
<dt><h4><code>
void delete_created_pointers();
</code></h4></dt>
<dd>
Deletes all objects created by the loading of pointers. This can be used to
avoid memory leaks that might otherwise occur if pointers are being loaded
and the archive load encounters an exception.
</dd>
<dt><h4><code>
template&lt;class T&gt;
register_type(T * t = NULL);
</code></h4></dt>
<dd>
Retrieves the next integer from the archive and adds an entry to a table which
relates the integer to the type T. When pointers are loaded, this integer is
used to indicate which object type should be created. This process is
referred to as "class registration". It is only necessary to invoke this function for
objects of derived classes which are serialized through a base class pointer. If this
function is called during the saving of data to the archive, it should be called during the
loading of the data from the archive at the same point in the serialization process.
This is explained in detail in
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>
</dd>
<dt><h4><code>
void reset_object_address(void * new_address, void * old_address);
</code></h4></dt>
<dd>
In order to facilitate loading of objects through a pointer
and to elminate redundant loading of objects, this system implements object address tracking.
Normally this is done automatically with no action required on the part of the user. However,
there are cases when an object must be de-serialized to a temporary location then
moved to its final destination. This is common in loading collections.
<p>
In such cases, reset_object_address should be invoked to communicate the final address
of the last item loaded. This permits the internal tables to be correctly maintained
in these special case.
</dd>
<dt><h4><code>
unsigned int library_version() const;
</code></h4></dt>
<dd>
Returns the version number of the serialization library that created the archive.
This number will be incremented each time the library is altered in such a way
that serialization could be altered for some type. For example, suppose the type
used for a count of collection members is changed. The code that loads collections
might be conditioned on the library version to make sure that libraries created by
previous versions of the library can still be read.
</dd>
<dt><h4><code>
is_saving::type = mpl::bool&lt;false&gt;;
is_saving::value= false;
is_loading::type = mpl::bool&lt;true&gt;;
is_loading::value= true;
</code></h4></dt>
<dd>
These integral constants permit archive attributes to be queried at compiler
or execution time. They can used to generate code with boost
<a href="../../mpl/doc/index.html">mpl</a>
. For and example
showing how these can beused, see the implementation of
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
</dd>
<dt><h4><code>
LA::is_saving
</code></h4></dt>
<dd>
Returns the Boost MPL Integral Constant type boost::mpl::bool_&lt;false&gt;
</dd>
<dt><h4><code>
LA::is_loading
</code></h4></dt>
<dd>
Returns the Boost MPL Integral Constant type boost::mpl::bool_&lt;true&gt;
</dd>
<dt><h4><code>
la &gt;&gt; x
<br>
la &amp; x
</code></h4></dt>
<dd>
These expressions must perform exactly the same function.
Sets <code>x</code> to a value retrieved from <code>la</code>.
<p>
Returns a reference to <code>la</code>.
</dd>
<dt><h4><code>
la.load_binary(u, count)
</code></h4></dt>
<dd>
Retrieves from <code style="white-space: normal">la</code> <code style="white-space: normal">size_t(count)</code> bytes and stores
them in memory starting at <code style="white-space: normal">u</code>.
</dd>
<dt>
<dt><h4><code>
la.register_type&lt;T&gt;()
<br>
la.register_type(u)
</code></h4></dt>
<dd>
Retrieves information about class T from the archive. This information is used to
construct the correct class when loading a pointer to a derived class not
otherwise referred to in the program by name.
Invocation of this member function is referred to as "class registration".
This is explained in detail in
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
The second syntax is included to permit this function to be called on non-conforming
compilers when <code style="white-space: normal">la</code> is a template argument.
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
</dd>
<dt><h4><code>
la.library_version()
</code></h4></dt>
<dd>
Returns an unsigned integer containing the version number of the serialization
library that created the archive. This number will be incremented each time the
library is altered in such a way that serialization could be altered for some type.
For example, suppose the type used for a count of collection members is changed.
The code that loads collections might be conditioned on the library version to make
sure that libraries created by previous versions of the library can still be read.
</dd>
<dt><h4><code>
la.reset_object_address(v, u)
</code></h4></dt>
<dd>
Communicates to the archive that the object originally at address u has been
moved to address v.
<p>
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 is permits the
the archive to properly implement object tracking. Object tracking is required in order
to correctly implement serialization of pointers to instances of derived classes.
</dd>
<dt><h4><code>
la.delete_created_pointers()
</code></h4></dt>
<dd>
Deletes all objects created by the loading of pointers. This can be used to
avoid memory leaks that might otherwise occur if pointers are being loaded
and the archive load encounters an exception.
</dd>
</dl>
There are archives based on text, binary and XML file
@@ -308,7 +229,6 @@ This library includes a various implementation 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.
@@ -319,28 +239,28 @@ these archives, one or more of the following header files must be
included in the code module containing the serialization code.
<pre><code>
// a portable text archive</a>
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive(ostream &s)</a> // saving
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive(istream &s)</a> // loading
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive</a> // saving
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive</a> // loading
// a portable text archive using a wide character stream</a>
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive(wostream &s)</a> // saving
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive(wistream &s)</a> // loading
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive</a> // saving
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive</a> // loading
// a non-portable native binary archive</a>
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive(ostream &s)</a> // saving
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive(istream &s)</a> // loading
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive</a> // saving
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive</a> // loading
<!--
// a non-portable native binary archive which use wide character streams
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive(wostream &s)</a> // saving
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive(wistream &s)</a> // loading
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive</a> // saving
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive</a> // loading
-->
// a portable XML archive</a>
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive(ostream &s)</a> // saving
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive(istream &s)</a> // loading
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive</a> // saving
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive</a> // loading
// a portable XML archive which uses wide characters - use for utf-8 output</a>
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive(wostream &s)</a> // saving
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive(wistream &s)</a> // loading
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive</a> // saving
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive</a> // loading
</code></pre>
All of these archives implement the same inteface. Hence, it should suffice to describe only one
+21 -21
View File
@@ -1,4 +1,4 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
@@ -111,12 +111,12 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#examples">List of Examples</a>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="archives.html">Reference</a></dt>
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="reference.html">Reference</a></dt>
<dd><div id="reference_detail"><dl class="page-index">
<dt><img style="display:none" src="plus.gif" id="archive_concept"><a target="detail" href="archives.html">Archive Concept</a>
<dt><img style="display:none" src="plus.gif" id="archive_concept"><a target="detail" href="archives.html">Archive Concepts</a>
<dd><div id="archive_concept_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#saving_interface">Saving</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#loading_interface">Loading</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#saving_interface">Saving Archive Concept</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#loading_interface">Loading Archive Concept</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#archive_models">Archive Models</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#exceptions">Exceptions</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#charactersets">Character Sets</a>
@@ -159,7 +159,7 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#composition">Composition</a>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="traits"><a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
<dt><img style="display:none" src="plus.gif" id="traits"><a target="detail" href="traits.html">Class Serialization Traits</a>
<dd><div id="traits_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#version">Version</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#level">Implementation Level</a>
@@ -173,8 +173,8 @@ function initialize() {
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="special"><a target="detail" href="special.html">Special Considerations</a>
<dd><div id="special_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#headersequence">Header Inclusion Sequence</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#objecttracking">Object Tracking</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#export">Exporting Class Serialization</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#classinfo">Class Information</a>
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
<dd><div id="portability_detail"><dl class="page-index">
@@ -194,19 +194,19 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#stream_error"><code>stream_error</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_class_name"><code>invalid_class_name</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_cast"><code>unregistered_cast</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parse_error"><code>xml_archive_parse_error</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parsing_error"><code>xml_archive_parsing_error</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_mismatch"><code>xml_archive_tag_mismatch</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_name_error"><code>xml_archive_tag_name_error</code></a>
</dl></div></dd>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exception_safety.html">Exception Safety</a>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
<dd><div id="archive_reference_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">Implementation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#usage">Usage</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#testing">Testing</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#polymorphic">Polymorphic Archives</a>
</dl></div></dd>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
<dd><div id="archive_reference_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">Implementation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#usage">Usage</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#testing">Testing</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#polymorphic">Polymorphic Archives</a>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="implementation"><a target="detail" href="implementation.html">Implementation Notes</a>
<dd><div id="implementation_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#functiontemplateordering">Partial Function Template Ordering</a>
@@ -215,9 +215,10 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#partialtemplatespecialization">Partial Template Specialization</a>
<dt><img style="display:none" src="plus.gif" id="othercompilerissues"><a target="detail" href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>
<div id="othercompilerissues_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.x</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.X,4.X</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc295">GCC 2.95</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#intel80">Intel 8.0</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc80">Visual C++ 8.0</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc71">Visual C++ 7.1</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc70">Visual C++ 7.0</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc6">Visual C++ 6.0</a>
@@ -261,7 +262,7 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#runtime">Runtime Interface</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#requirements">Requirements</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
</dl>
</dl></div></dd>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="void_cast.html"><code>void_cast</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html">utf-8 code_cvt</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
@@ -269,7 +270,7 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
</dl></div></dd>
</dl></div></dd>
<!--
<dt><img style="display:none" src="dot.gif"><a target="detail" href="configuration.html">Configuration Information</a></dt>
-->
@@ -279,7 +280,7 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#archives">Archives are not streams</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#trap">Compile time trap when saving a non-const value</a></dt>
</dl>
</dl></div></dd>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="history.html">History</a>
<!--
<dt><img style="display:none" src="dot.gif"><a target="detail" href="definitions.html">Definitions</a></dt>
@@ -287,7 +288,6 @@ function initialize() {
-->
<dt><img style="display:none" src="dot.gif"><a target="detail" href="bibliography.html">Bibliography</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="acknowledgments.html">Acknowledgments</a></dt>
</dl></div>
</small>
</body>
+1 -1
View File
@@ -200,7 +200,7 @@ 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 <a href="special.html#runtimecasting">Runtime Casting</a>.
is described in <a href="serialization.html#runtimecasting">Runtime Casting</a>.
This exception is thrown if an attempt is made to convert between two pointers
whose relationship has not been registered,
+42 -13
View File
@@ -32,9 +32,10 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#partialtemplatespecialization">Partial Template Specialization</a>
<dt><a href="#othercompilerissues">Specific Compiler/Library Issues</a>
<dl class="page-index">
<dt><a href="#gcc3x">GCC 3.X, 4.x</a>
<dt><a href="#gcc3x">GCC 3.X, 4.X</a>
<dt><a href="#gcc295">GCC 2.95</a>
<dt><a href="#intel80">Intel 8.0</a>
<dt><a href="#vc80">Visual C++ 8.0</a>
<dt><a href="#vc71">Visual C++ 7.1</a>
<dt><a href="#vc70">Visual C++ 7.0</a>
<dt><a href="#vc6">Visual C++ 6.0</a>
@@ -199,11 +200,26 @@ the syntax described above.
</ul>
<h3><a name="othercompilerissues">Specific Compiler/Library Issues</a></h3>
<h4><a name="gcc3x">GCC 3.X, 4.x</a></h4>
GCC versions for Cygwin and MinGW fail to support wide character I/O.
So all tests using wide char I/O fail. Note that if wide character I/O support
is added with STLPort, all tests complete successfully.
<h4><a name="gcc3x">GCC 3.X, 4.X</a></h4>
<ul>
<li>GCC versions for Cygwin and MinGW fail to support wide character I/O.
So all tests using wide char I/O fail. Note that if wide character I/O support
is added with STLPort, all tests complete successfully.
<li>This compiler generates long warning messages related to the usage of
non virtual destructors in polymorphic classes. These warnings have been
carfully considered and the code that generates these warning has been
unchanged. In this case the warning should should be ignored as in certain
usages of the library, making the destructors virtual could lead to problems.
As an alternative, base class destructors have been make "protected" to
address the concerns that motivate these warning messages. When building
the serialization library and tests with bjam, these warnings are suppressed.
When building one's own applications, these warnings can be suppressed by
adding the following to the compiler command line:
<pre><code>
-Wno-non-virtual-dtor
-Wno-ctor-dtor-privacy
</code></pre>
</ul>
<h4><a name="gcc295">GCC 2.95</a></h4>
All of the above plus:<br>
<ul>
@@ -212,11 +228,21 @@ All of the above plus:<br>
<li>Polymorphic archive tests fail.
<li>XML serialization only works with version 1.6x of spirit. In order to build
and use this library with this compiler, one must use version 1.6x rather than the
latest version shipped with boost. See Release Notes.
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
</ul>
<h4><a name="Intel80">Intel C++ 8.0</a></h4>
No known issues. All tests compile and run in debug and release modes.
<h4><a name="vc80">Visual C++ 8.0</a></h4>
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:
<pre><code>
/wd4996
</code></pre>
<h4><a name="vc71">Visual C++ 7.1</a></h4>
Derivation from an archive class defined in a DLL as described in ... will not work.
This is due to the way that VC++ handles templeted code with __decl(dllexport) and
@@ -280,15 +306,19 @@ decided to use these configurations.
<li>The "pimpl" demo fails to link. Cause and workaround for this is unknown
<li>XML serialization only works with version 1.6x of spirit. In order to build and use this
library with this compiler, one must use version 1.6x rather than the latest version
shipped with boost. See <a href="release.html#Installation">Release Notes</a>.
shipped with boost. See <a href="release.html">Release Notes</a>.
<li>This compiler does not support partial template specialization.
The implementation of the new <code>shared_ptr</code> serialization depends upon
compiler support for partial template specialization. This compiler doesn't implement this
feature. In order to serialize <code style="white-space: normal">shared_ptr&lt;A&gt;</code>,
invoke the macro <code style="white-space: normal">BOOST_SERIALIZATION_SHARED_PTR(A)</code>
in the header code.
<li>Lack of support for partial template specialization also creates problems for
serialization of <code style="white-space: normal">std::map</code>. 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.
</ul>
<h4><a name="vc6">Visual C++ 6.0</a></h4>
<h4><a name="vc6">Visual C++ 6.5</a></h4>
all the above issues for Visual C++ 7.0 plus:
<ul>
<li>Out of line template definitions are not recognized and fail with a confusing
@@ -326,7 +356,6 @@ all the above issues for Visual C++ 7.0 plus:
<li>Code modules exceeding some undetermined size that use the library will fail with
<i>fatal error C1204: compiler limit : internal structure overflow</i>. This can be addressed
by dividing the module into smaller ones.
<li>The library cannot be built as a DLL with this compiler.
</ul>
<h4><a name="borland">Borland 5.64 and 5.51</a></h4>
<ul>
@@ -341,7 +370,7 @@ all the above issues for Visual C++ 7.0 plus:
with this compiler.
<li>XML serialization only works with version 1.6x of spirit. In order to build
and use this library with this compiler, one must use version 1.6x rather than the
latest version shipped with boost. See Release Notes.
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
</ul>
<h4><a name="comeau">Comeau 4.3.3</a></h4>
<ul>
@@ -375,8 +404,8 @@ These platforms have several issues:
<li>The dinkumware library shipped with this compiler does not change the locale facet
of an i/o stream unless the <code style="white-space: normal">imbue</code> 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 local that archives implement. The
stream local must be set explicitly on the stream before an archive is opened on it. The
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 <code style="white-space: normal">no_codecvt</code> flag. Note this problem will
occur on all compilers shipped with this library.
<li>Other issues have been worked around in the file.
+1 -1
View File
@@ -36,7 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
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
this context, this might used implement object persistence, remote
the context, this might used implement object persistence, remote
parameter passing or other facility. In this system we use the term
<strong>"archive"</strong> to refer to a specific rendering of this
stream of bytes. This could be a file of binary data, text data,
+42
View File
@@ -0,0 +1,42 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Serialization - Serialization of Classes</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Serialization</h1>
<h2 align="center">Serializable Concept</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="archives.html">Archive Concepts</a>
<dt><a href="serialization.html">Serializable Concept</a>
<dt><a href="special.html">Special Considerations</a>
<dt><a href="archive_reference.html">Archive Class Reference</a>
<dt><a href="implementation.html">Implementation Notes</a>
</dl>
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+4 -1
View File
@@ -90,13 +90,16 @@ at the front of the list of include paths.
and <code style="white-space: normal">std::wstring</code> contain characters such as
'\0' which cannot be rendered in XML without an escape mechanism. Currently there is
no such escape mechanism implemented.
<li>A subtle error in the implementation of serialiaton of <code style="white-space: normal">std::map</code>
is fixed in this version. Unfortunately, the fix breaks serialization of
<code style="white-space: normal">std::map</code> for those compilers which do not support
partial template specialization.
</ul>
<p>
Aside from the above, there are a number of issus related to specific platforms.
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
Distributed under the Boost Software License, Version 1.0. (See
+39 -20
View File
@@ -1,4 +1,4 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
@@ -77,8 +77,7 @@ if and only if one of the following is true:
<a target="detail" href="traits.html#Traits">serialization traits</a>,
any user type can also be designated as "primitive"
so that it is handled in this way.
<li>it is a class type one of the following is true for all archive classes:
it is a class type and for all <strong>Archive</strong> classes, one of the following
<li>It is a class type and for all <strong>Archive</strong> classes, one of the following
has been declared:
<ul>
<li>a class member function <code style="white-space: normal">serialize</code>
@@ -194,6 +193,12 @@ templates can be in any of the following namespaces:
<li>namespace of the archive class
<li>namespace of the type being serialized
</ul>
<p>
Note that, at first glance, this suggestion may seem to be wrong for compilers which implement
two phase lookup. In fact, the serialization library used a perhaps overly clever
method to support this rule even for such compilers. Those with an interest in studying
this furter will find more information in
<a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
<h3><a name="classmembers">Serialization of Class Members</a></h3>
Regardless of which of the above methods is used, the body of the serialize function must
@@ -207,7 +212,6 @@ specify the data to be saved/loaded by sequential application of the archive
}
</code></pre>
<h4><a name="base">Base Classes</a></h4>
The header file
<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
@@ -285,8 +289,7 @@ shared_ptr.hpp
</a>
<!--
Only the most minimal change to
<a href="../../../boost/serialization/shared_count.hpp" target="shared_count_hpp">
shared_count.hpp</a>
<code>shared_count.hpp</code>
(to gain access to some private members) was necessary to achieve this.
This should demonstrate how easy it is to non-intrusively
implement serialization to any data type or template.
@@ -585,19 +588,28 @@ class derived_two : public base {
main(){
...
base *b;
...
ar &amp; b;
}
</code></pre>
When saving <code style="white-space: normal">b</code> what kind of object should be saved?
When loading <code style="white-space: normal">b</code> what kind of object should be created?
An object of class <code style="white-space: normal">derived_one</code>,
Should it be an object of class <code style="white-space: normal">derived_one</code>,
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
<p>
If this situation is not addressed by one of the methods described below,
an <a target="detail" href="exceptions.html#unregistered_class">
<code style="white-space: normal">unregistered_class</code></a> exception will be thrown when serialization is
invoked.
<p>Many times this situation is resolved automatically by the serialization
library.
It turns out that the kind of object serialized depends upon whether the base class
(<code style="white-space: normal">base</code> in this case) is polymophic or not.
If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
virtual functions, then an object of the type <code style="white-space: normal">base</code>
will be serialized. Information in any derived classes will be lost. If this is what is desired
(it usually isn't) then no other effort is required.
<p>
If the base class is polymorphic, an object of the most derived type
(<code style="white-space: normal">derived_one</code>
or <code style="white-space: normal">derived_two</code>
in this case) will be serialized. The question of which type of object is to be
serialized is (almost) automatically handled by the library.
<p>
The system "registers" each class in an archive the first time an object of that
class it is serialized and assigns a sequential number to it. Next time an
@@ -608,31 +620,36 @@ 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"
the same sequence. This includes "registration".
<p>
In many situations the problem never comes up. Consider:
Expanding our previous example:
<pre><code>
main(){
derived_one d1;
derived_two d2:
...
ar &gt;&gt; d1;
ar &gt;&gt; d2;
ar &amp; d1;
ar &amp; 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 &amp; b;
}
</code></pre>
Here, the problem doesn't present itself. When <code style="white-space: normal">b</code> is read it is
When <code style="white-space: normal">b</code> is read it is
preceded by a unique (to the archive) class identifier which
has previously been related to class <code style="white-space: normal">derived_one</code> or
<code style="white-space: normal">derived_two</code>.
<p>
If a derived class hasn't been automatically "registered" as described
above, we have the option of registering it explicitly. All archives are
If a derived class has NOT been automatically "registered" as described
above, an <a target="detail" href="exceptions.html#unregistered_class">
<code style="white-space: normal">unregistered_class</code></a> exception
will be thrown when serialization is invoked.
<p>
This can be addressed by registering the derived class explicitly. All archives are
derived from a base class which implements the following template:
<pre><code>
template&lt;class T&gt;
@@ -645,6 +662,7 @@ main(){
ar.template register_type&lt;derived_one&gt;();
ar.template register_type&lt;derived_two&gt;();
base *b;
...
ar &amp; b;
}
</code></pre>
@@ -668,6 +686,7 @@ BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
main(){
...
base *b;
...
ar &amp; b;
}
</code></pre>
+101 -14
View File
@@ -26,8 +26,8 @@ http://www.boost.org/LICENSE_1_0.txt)
</table>
<hr>
<dl class="page-index">
<dt><a href="#headersequence">Header Inclusion Sequence</a>
<dt><a href="#objecttracking">Object Tracking</a>
<dt><a href="#export">Exporting Class Serialization</a>
<dt><a href="#classinfo">Class Information</a>
<dt><a href="#portability">Archive Portability</a>
<dl class="page-index">
@@ -40,17 +40,6 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="exception_safety.html">Exception Safety</a>
</dl>
<h3><a name="headersequence">Header Inclusion Sequence</a></h3>
This library is includes a large number of headers that can be included
in user code modules. The section
<a href="headers.html">Code Structure</a>
contains a summary of these headers.
<strong>
This library requires that all headers that implement archives be included
before any headers that implement class serialization.
</strong>
Violations of this rule will result in cryptic compile time errors.
<h3><a name="objecttracking">Object Tracking</a></h3>
Depending on how the class is used and other factors, serialized objects
may be tracked by memory address. This prevents the same object from being
@@ -152,8 +141,6 @@ The alternative of changing the implementation level of a <code style="white-spa
would affect all <code style="white-space: normal">long</code>s serialized in the whole
program - probably not what one would intend.
<p>
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
@@ -162,6 +149,106 @@ redundant save/load operations.
<pre><code>
BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
</code></pre>
<h3><a name="export">Exporting Class Serialization</a></h3>
<a target="detail" href="traits.html#export">Elsewhere</a> in this manual, we have described
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>. This is used to make the serialization library aware
that code should be instantiated for serialization of a given class even though the
class hasn't been otherwise referred to by the program.
<p>
There are several ways <code style="white-space: normal">BOOST_CLASS_EXPORT</code> could have been
implemented.
<p>
One approach would be to instantiate serialization code for all archive classes included in the library.
This would add to each executable a large amount of code that is most likely never called.
Also it would needlessly slow down compilations of any program that uses the library. Finally,
the list of archives would be "built-in" to the library which would compilicate the addition of
new or custom archive classes.
<p>
Another approach would be for the library user to somehow explicitly instantiate which archive classes
code should be instantiated for each class to be serialized. Users would have to include
header files corresponding the archive classes to be instantiated.
The list of instantiated archive classes would have to be manually kept in sync with the
archive class headers actually included. This was considered burdensome and error prone.
<p>
This implementation of <code style="white-space: normal">BOOST_CLASS_EXPORT</code> works in the
following way:
<ul>
<li>All header modules of the form &lt;boost/archive/*archive.hpp&gt; are required to precede
the header module <a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>.
<li>The header <a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
builds a list of archive classes whose header modules have been previously included.
It does this by checking to see which inclusion guard constants have been defined.
<li><code style="white-space: normal">BOOST_CLASS_EXPORT(my_class)</code> explicitly instantiates
serialization code for <code style="white-space: normal">my_class</code> for each archive in the list.
</ul>
Serialization code will be instantiated for a given archive class
if and only if the module that defines that archive class has been included in the program.
Given this, our program will contain all necessary code instantiations and no other.
<p>
For many styles of code organization this header sequencing requirement presents little problem.
Serialization code organized by class headers that are designed to be independent of archive
implementations will look something like the following:
<code><pre>
// A.hpp
// Note:to preserve independence from any particular archive implementation,
// no headers from &lt;boost/archive/...&gt; are included.
// Headers can be included in any order.
#include &lt;boost/serialization/...&gt;
#include &lt;boost/serialization/export.hpp&gt;
... // include other headers that A depends upon
class A {
...
};
BOOST_CLASS_EXPORT(A) // note: the export name of this class
</pre></code>
This style:
<ul>
<li>permits the header to include all aspects of the serialization implementation.
<li>permits the header to be included anywhere else as part of some other class declaration.
<li>reflects the concept of headers as a "library of types" which
can be used independently in other programs or other parts of the same program.
<li>reflects a fundamental principle of the serialization library design in that the
specification of serialization of any class is independent of any archive implementation.
</ul>
However, it might not always be possible or convenient to conform to the above style. Something
like the following might be required or preferred:
<code><pre>
// A.hpp
// headers can be included in any order
#include &lt;boost/archive/text_oarchive.hpp&gt;
#include &lt;boost/archive/text_iarchive.hpp&gt;
...
#include &lt;boost/serialization/...&gt;
...
// can't do the following because then A.hpp couldn't be included somewhere else
// #include &lt;boost/serialization/export.hpp&gt;
class A {
...
};
// can't do the following because export.hpp is not included !!
//BOOST_CLASS_EXPORT(A) // note: the export name of this class
</pre></code>
As noted in the comments, this would work. But
<code style="white-space: normal">#include &lt;.../export.hpp&gt;</code> can't be used
without conflicting with other modules which use
<code style="white-space: normal">#include &lt;.../*archive.hpp&gt;</code>. In this
case we can move the export to an implementation file:
<code><pre>
// A.cpp
#include "A.hpp"
...
// export.hpp header should be last;
#include &lt;boost/serialization/export.hpp&gt;
...
BOOST_CLASS_EXPORT(A)
...
</pre></code>
<h3><a name="classinfo">Class Information</a></h3>
By default, for each class serialized, class information is written to the archive.
This information includes version number, implementation level and tracking
+7 -5
View File
@@ -336,10 +336,11 @@ convenience macros, use the original definitions
template&lt;class T&gt;
struct implementation_level&lt;nvp&lt;T&gt; &gt;
{
typedef mpl::int_&lt;object_serializable&gt; type; \
typedef mpl::integral_c_tag tag;
typedef mpl::int_&lt;object_serializable&gt; type;
BOOST_STATIC_CONSTANT(
enum level_type,
value = static_cast&lt;enum level_type&gt;(type::value)
int,
value = implementation_level::type::value
);
};
@@ -347,10 +348,11 @@ struct implementation_level&lt;nvp&lt;T&gt; &gt;
template&lt;class T&gt;
struct tracking_level&lt;nvp&lt;T&gt; &gt;
{
typedef mpl::integral_c_tag tag;
typedef mpl::int_&lt;track_never&gt; type;
BOOST_STATIC_CONSTANT(
enum tracking_type,
value = static_cast&lt;enum tracking_type&gt;(type::value)
int,
value = tracking_level::type::value
);
};
</code></pre>
+39 -14
View File
@@ -107,24 +107,28 @@ public:
int main() {
// create and open a character archive for output
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
// create class instance
const gps_position g(35, 59, 24.567f);
// write class instance to archive
oa &lt;&lt; g;
// close archive
ofs.close();
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa &lt;&lt; g;
// archive and stream closed when destructors are called
}
// ... some time later restore the class instance to its orginal state
// create and open an archive for input
std::ifstream ifs("filename", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
// read class state from archive
gps_position newg;
ia &gt;&gt; newg;
// close archive
ifs.close();
{
// create and open an archive for input
std::ifstream ifs("filename", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia &gt;&gt; newg;
// archive and stream closed when destructors are called
}
return 0;
}
</code>
@@ -295,7 +299,7 @@ public:
</code>
</pre>
Each member of the array <code style="white-space: normal">stops</code> will be serialized.
But, remember each member is a pointer - so what can this really
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
@@ -304,6 +308,27 @@ 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.
<p>
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
<p>
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
<a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>,
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
<a href="serialization.html#derivedpointers">here</a>
<p>
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.
@@ -515,7 +540,7 @@ This is described later in the manual.
<dt><a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp</a>
<dd>This is a variation the original demo which supports xml archives in addition
to the others. The extra wrapping macros are needed to associate a data
item name with the correspoding xml tag. For more information see
item name with the corresponding xml tag. For more information see
<a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>.
<a href="../example/demo_save.xml" target="demo_save_xml">Here</a>
is what an xml archive looks like.
+2 -5
View File
@@ -16,10 +16,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#include <cassert>
namespace boost {
@@ -28,7 +25,8 @@ namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by archives
//
class archive_exception : public virtual std::exception
class archive_exception :
public virtual std::exception
{
public:
typedef enum {
@@ -114,5 +112,4 @@ protected:
}// namespace archive
}// namespace boost
#endif //BOOST_NO_EXCEPTIONS
#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
-6
View File
@@ -16,11 +16,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#if defined(BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP) \
|| defined(BOOST_SERIALIZATION_TRAITS_HPP)
#error "no serialization headers my precede any archive headers"
#endif
#include <boost/config.hpp>
#include <boost/strong_typedef.hpp>
#include <boost/noncopyable.hpp>
@@ -132,5 +127,4 @@ BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type)
#error "export.hpp must not be included before any archive header"
#endif
#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP
@@ -124,6 +124,10 @@ public:
os << std::setprecision(std::numeric_limits<double>::digits10 + 2);
os << t;
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_text_oprimitive(OStream & os, bool no_codecvt);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~basic_text_oprimitive();
public:
// unformatted append of one character
void put(int c){
@@ -131,7 +135,6 @@ public:
boost::throw_exception(archive_exception(archive_exception::stream_error));
os.put(c);
}
// unformatted append of null terminated string
void put(const char * s){
if(os.fail())
@@ -139,12 +142,6 @@ public:
while('\0' != *s)
os.put(*s++);
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_text_oprimitive(OStream & os, bool no_codecvt);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~basic_text_oprimitive();
public:
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
save_binary(const void *address, std::size_t count);
};
+2
View File
@@ -24,6 +24,8 @@
namespace std{
#if defined(__LIBCOMO__)
using ::mbstate_t;
#elif defined(_QNXNTO_)
using std::mbstate_t;
#elif defined(BOOST_DINKUMWARE_STDLIB)
using ::mbstate_t;
#elif defined(__SGI_STL_PORT)
@@ -42,6 +42,8 @@ protected:
archive_pointer_iserializer(
const boost::serialization::extended_type_info & eti
);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~archive_pointer_iserializer();
public:
virtual const basic_iserializer & get_basic_serializer() const
// mscvc 6.0 requires template functions to be implemented. For this
@@ -75,8 +77,6 @@ public:
find(
const boost::serialization::extended_type_info & eti
);
virtual ~archive_pointer_iserializer(){}
};
} // namespace detail
@@ -39,6 +39,8 @@ protected:
archive_pointer_oserializer(
const boost::serialization::extended_type_info & eti
);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~archive_pointer_oserializer();
public:
// return the type_extended save pointer corresponding to a give
// type_info. returns NULL, if there is no such instance. This
@@ -49,7 +51,6 @@ public:
find(
const boost::serialization::extended_type_info & eti
);
virtual ~archive_pointer_oserializer(){}
};
} // namespace detail
@@ -56,7 +56,7 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive
virtual void vload(tracking_type &t) = 0;
protected:
basic_iarchive(unsigned int flags);
virtual ~basic_iarchive();
~basic_iarchive();
public:
// note: NOT part of the public API.
void next_object_pointer(void *t);
@@ -45,7 +45,7 @@ protected:
explicit basic_iserializer(
const boost::serialization::extended_type_info & type_
);
virtual ~basic_iserializer();
~basic_iserializer();
public:
bool serialized_as_pointer() const {
return bpis != NULL;
@@ -56,15 +56,6 @@ public:
const basic_pointer_iserializer * get_bpis_ptr() const {
return bpis;
}
#if 0
virtual void load_object_data(
basic_iarchive & ar,
void *x,
const unsigned int file_version
) const {
assert(false);
};
#endif
virtual void load_object_data(
basic_iarchive & ar,
void *x,
@@ -63,7 +63,7 @@ class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive
virtual void vsave(const tracking_type t) = 0;
protected:
basic_oarchive(unsigned int flags);
virtual ~basic_oarchive();
~basic_oarchive();
public:
// note: NOT part of the public interface
void register_basic_serializer(const basic_oserializer & bos);
@@ -44,7 +44,7 @@ protected:
explicit basic_oserializer(
const boost::serialization::extended_type_info & type_
);
virtual ~basic_oserializer();
~basic_oserializer();
public:
bool serialized_as_pointer() const {
return bpos != NULL;
@@ -41,7 +41,7 @@ protected:
explicit basic_pointer_iserializer(
const boost::serialization::extended_type_info & type_
);
virtual ~basic_pointer_iserializer();
~basic_pointer_iserializer();
public:
virtual const basic_iserializer & get_basic_serializer() const = 0;
virtual void load_object_ptr(
@@ -40,7 +40,7 @@ protected:
explicit basic_pointer_oserializer(
const boost::serialization::extended_type_info & type_
);
virtual ~basic_pointer_oserializer();
~basic_pointer_oserializer();
public:
virtual const basic_oserializer & get_basic_serializer() const = 0;
virtual void save_object_ptr(
@@ -16,11 +16,13 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <boost/noncopyable.hpp>
#include <boost/config.hpp>
#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace boost {
namespace archive {
namespace detail {
@@ -38,7 +40,7 @@ public:
return m_eti;
}
bool operator<(const basic_serializer & rhs) const {
return m_eti < rhs.get_eti();
return & m_eti < & rhs.get_eti();
}
};
@@ -33,22 +33,26 @@ namespace detail {
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer;
struct type_info_pointer_compare
struct BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) type_info_pointer_compare
{
bool operator()(
const basic_serializer * lhs, const basic_serializer * rhs
) const ;
};
struct BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer_map
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer_map
{
typedef std::set<const basic_serializer *, type_info_pointer_compare> map_type;
map_type map;
map_type m_map;
bool & m_deleted;
public:
bool insert(const basic_serializer * bs);
const basic_serializer * tfind(
const boost::serialization::extended_type_info & type_
) const;
basic_serializer_map();
void erase(basic_serializer * bs);
basic_serializer_map(bool & deleted);
~basic_serializer_map();
};
} // namespace detail
@@ -18,7 +18,6 @@
#include <string>
#include <boost/cstdint.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -41,14 +40,8 @@ protected:
public:
/////////////////////////////////////////////////////////
// archive public interface
struct is_loading {
typedef mpl::bool_<true> type;
BOOST_STATIC_CONSTANT(bool, value=true);
};
struct is_saving {
typedef mpl::bool_<false> type;
BOOST_STATIC_CONSTANT(bool, value=false);
};
typedef mpl::bool_<true> is_loading;
typedef mpl::bool_<false> is_saving;
// return a pointer to the most derived class
Archive * This(){
@@ -56,7 +49,7 @@ public:
}
template<class T>
const basic_pointer_iserializer * register_type(T * t = NULL){
const basic_pointer_iserializer * register_type(T * = NULL){
const basic_pointer_iserializer & bpis =
archive::detail::instantiate_pointer_iserializer(
static_cast<Archive *>(NULL),
@@ -65,19 +58,18 @@ public:
this->This()->register_basic_serializer(bpis.get_basic_serializer());
return & bpis;
}
void lookup_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
boost::shared_ptr<void> & sph
){
this->This()->basic_iarchive::lookup_basic_helper(eti, sph);
this->This()->lookup_basic_helper(eti, sph);
}
void insert_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
this->This()->basic_iarchive::insert_basic_helper(eti, sph);
this->This()->insert_basic_helper(eti, sph);
}
template<class T>
Archive & operator>>(T & t){
@@ -41,15 +41,8 @@ protected:
public:
/////////////////////////////////////////////////////////
// archive public interface
struct is_loading {
typedef mpl::bool_<false> type;
BOOST_STATIC_CONSTANT(bool, value=false);
};
struct is_saving {
typedef mpl::bool_<true> type;
BOOST_STATIC_CONSTANT(bool, value=true);
};
typedef mpl::bool_<false> is_loading;
typedef mpl::bool_<true> is_saving;
// return a pointer to the most derived class
Archive * This(){
@@ -57,7 +50,7 @@ public:
}
template<class T>
const basic_pointer_oserializer * register_type(const T * t = NULL){
const basic_pointer_oserializer * register_type(const T * = NULL){
const basic_pointer_oserializer & bpos =
instantiate_pointer_oserializer(
static_cast<Archive *>(NULL),
@@ -69,16 +62,16 @@ public:
void lookup_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
boost::shared_ptr<void> & sph
){
this->This()->basic_oarchive::lookup_basic_helper(eti, sph);
this->This()->lookup_basic_helper(eti, sph);
}
void insert_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
this->This()->basic_oarchive::insert_basic_helper(eti, sph);
this->This()->insert_basic_helper(eti, sph);
}
template<class T>
Archive & operator<<(T & t){
+9 -8
View File
@@ -76,6 +76,7 @@ namespace std{
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/void_cast.hpp>
namespace boost {
@@ -122,8 +123,8 @@ public:
>= boost::serialization::object_class_info;
}
virtual bool tracking(const unsigned int flags) const {
if(0 != (flags & no_tracking))
return false;
// if(0 != (flags & no_tracking))
// return false;
return boost::serialization::tracking_level<T>::value
== boost::serialization::track_always
|| boost::serialization::tracking_level<T>::value
@@ -354,11 +355,11 @@ struct load_non_pointer_type {
// and serialization level to the archive
struct load_standard {
static void invoke(Archive &ar, T &t){
//BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
// borland - for some reason T is const here - even though
// its not called that way - so fix it her
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
void * x = & const_cast<typex &>(t);
//BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
// borland - for some reason T is const here - even though
// its not called that way - so fix it her
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
void * x = & const_cast<typex &>(t);
ar.load_object(x, iserializer<Archive, T>::instantiate());
}
};
@@ -445,7 +446,7 @@ struct load_pointer_type {
// virtual serialize functions used for plug-ins
typedef BOOST_DEDUCED_TYPENAME
mpl::eval_if<
is_abstract<T>,
serialization::is_abstract<T>,
mpl::identity<abstract<T> >,
mpl::identity<non_abstract<T> >
>::type typex;
+7 -6
View File
@@ -66,6 +66,7 @@
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/void_cast.hpp>
#include <boost/archive/archive_exception.hpp>
@@ -115,8 +116,8 @@ public:
>= boost::serialization::object_class_info;
}
virtual bool tracking(const unsigned int flags) const {
if(0 != (flags & no_tracking))
return false;
// if(0 != (flags & no_tracking))
// return false;
return boost::serialization::tracking_level<T>::value == boost::serialization::track_always
|| boost::serialization::tracking_level<T>::value == boost::serialization::track_selectivly
&& serialized_as_pointer();
@@ -328,10 +329,10 @@ struct save_pointer_type {
struct abstract
{
static const basic_pointer_oserializer * register_type(Archive & /* ar */){
typedef BOOST_DEDUCED_TYPENAME
boost::serialization::type_info_implementation<T>::type::is_polymorphic typex;
// it has? to be polymorphic
BOOST_STATIC_ASSERT(typex::value);
BOOST_STATIC_ASSERT(
boost::serialization::type_info_implementation<T>::type::is_polymorphic::value
);
return static_cast<const basic_pointer_oserializer *>(NULL);
}
};
@@ -352,7 +353,7 @@ struct save_pointer_type {
// virtual serialize functions used for plug-ins
typedef
BOOST_DEDUCED_TYPENAME mpl::eval_if<
is_abstract<T>,
serialization::is_abstract<T>,
mpl::identity<abstract<T> >,
mpl::identity<non_abstract<T> >
>::type typex;
@@ -33,6 +33,11 @@ namespace std{
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
template<class T>
class shared_ptr;
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
@@ -64,8 +69,8 @@ private:
){
return ArchiveImplementation::load_pointer(t, bpis_ptr, finder);
}
virtual void delete_created_pointers(){
ArchiveImplementation::delete_created_pointers();
virtual void set_library_version(unsigned int archive_library_version){
ArchiveImplementation::set_library_version(archive_library_version);
}
virtual unsigned int get_library_version() const{
return ArchiveImplementation::get_library_version();
@@ -73,6 +78,9 @@ private:
virtual unsigned int get_flags() const {
return ArchiveImplementation::get_flags();
}
virtual void delete_created_pointers(){
ArchiveImplementation::delete_created_pointers();
}
virtual void load_binary(void * t, std::size_t size){
ArchiveImplementation::load_binary(t, size);
}
@@ -147,6 +155,18 @@ private:
virtual void register_basic_serializer(const basic_iserializer & bis){
ArchiveImplementation::register_basic_serializer(bis);
}
virtual void lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
){
ArchiveImplementation::lookup_basic_helper(eti, sph);
}
virtual void insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
){
ArchiveImplementation::insert_basic_helper(eti, sph);
}
public:
// the >> operator
template<class T>
@@ -33,6 +33,11 @@ namespace std{
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
template<class T>
class shared_ptr;
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
@@ -146,6 +151,18 @@ private:
virtual void register_basic_serializer(const detail::basic_oserializer & bos){
ArchiveImplementation::register_basic_serializer(bos);
}
virtual void lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
ArchiveImplementation::lookup_basic_helper(eti, sph);
}
virtual void insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
ArchiveImplementation::insert_basic_helper(eti, sph);
}
public:
// the << operator
template<class T>
@@ -8,6 +8,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <boost/archive/detail/basic_serializer_map.hpp>
@@ -18,9 +20,11 @@ namespace archive {
namespace detail {
template<class Archive>
basic_serializer_map & iserializer_map(){
static basic_serializer_map map;
return map;
basic_serializer_map *
iserializer_map(){
static bool deleted = false;
static basic_serializer_map map(deleted);
return deleted ? NULL : & map;
}
template<class Archive>
@@ -30,7 +34,9 @@ archive_pointer_iserializer<Archive>::archive_pointer_iserializer(
) :
basic_pointer_iserializer(eti)
{
iserializer_map<Archive>().insert(this);
basic_serializer_map *mp = iserializer_map<Archive>();
assert(NULL != mp);
mp->insert(this);
}
template<class Archive>
@@ -38,9 +44,20 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *)
archive_pointer_iserializer<Archive>::find(
const boost::serialization::extended_type_info & eti
){
return static_cast<const basic_pointer_iserializer *>(
iserializer_map<Archive>().tfind(eti)
);
basic_serializer_map *mp = iserializer_map<Archive>();
assert(NULL != mp);
return static_cast<const basic_pointer_iserializer *>(mp->tfind(eti));
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
archive_pointer_iserializer<Archive>::~archive_pointer_iserializer(){
// note: we need to check that the map still exists as we can't depend
// on static variables being constructed in a specific sequence
basic_serializer_map *mp = iserializer_map<Archive>();
if(NULL == mp)
return;
mp->erase(this);
}
} // namespace detail
@@ -18,10 +18,11 @@ namespace archive {
namespace detail {
template<class Archive>
basic_serializer_map &
basic_serializer_map *
oserializer_map(){
static basic_serializer_map map;
return map;
static bool deleted = false;
static basic_serializer_map map(deleted);
return deleted ? NULL : & map;
}
template<class Archive>
@@ -29,9 +30,11 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
archive_pointer_oserializer<Archive>::archive_pointer_oserializer(
const boost::serialization::extended_type_info & eti
) :
basic_pointer_oserializer(eti)
basic_pointer_oserializer(eti)
{
oserializer_map<Archive>().insert(this);
basic_serializer_map *mp = oserializer_map<Archive>();
assert(NULL != mp);
mp->insert(this);
}
template<class Archive>
@@ -39,9 +42,20 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *)
archive_pointer_oserializer<Archive>::find(
const boost::serialization::extended_type_info & eti
){
return static_cast<const basic_pointer_oserializer *>(
oserializer_map<Archive>().tfind(eti)
);
basic_serializer_map *mp = oserializer_map<Archive>();
assert(NULL != mp);
return static_cast<const basic_pointer_oserializer *>(mp->tfind(eti));
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
archive_pointer_oserializer<Archive>::~archive_pointer_oserializer(){
// note: we need to check that the map still exists as we can't depend
// on static variables being constructed in a specific sequence
basic_serializer_map *mp = oserializer_map<Archive>();
if(NULL == mp)
return;
mp->erase(this);
}
} // namespace detail
@@ -22,7 +22,7 @@ namespace std{
#include <boost/detail/workaround.hpp>
#include <boost/archive/basic_binary_iarchive.hpp>
#include <boost/serialization/extended_type_info.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -22,7 +22,7 @@ namespace std{
#include <boost/detail/workaround.hpp>
#include <boost/archive/basic_text_iarchive.hpp>
#include <boost/serialization/extended_type_info.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -15,7 +15,7 @@
#include <boost/archive/basic_xml_iarchive.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/extended_type_info.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -11,8 +11,8 @@
#include <algorithm>
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__)
namespace std{
using ::strlen;
namespace std{
using ::strlen;
} // namespace std
#endif
@@ -26,12 +26,11 @@ namespace archive {
namespace detail {
template<class CharType>
struct XML_name {
typedef bool result_type;
void operator()(CharType t) const{
unsigned char lookup_table[] = {
const unsigned char lookup_table[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0, // -.
0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -.
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A-
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _
@@ -59,7 +58,7 @@ struct XML_name {
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::write_attribute(
const char *attribute_name,
const char *attribute_name,
int t,
const char *conjunction
){
@@ -69,11 +68,11 @@ basic_xml_oarchive<Archive>::write_attribute(
this->This()->save(t);
this->This()->put('"');
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::write_attribute(
const char *attribute_name,
const char *attribute_name,
const char *key
){
this->This()->put(' ');
@@ -82,7 +81,7 @@ basic_xml_oarchive<Archive>::write_attribute(
this->This()->put(key);
this->This()->put('"');
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::indent(){
@@ -97,7 +96,7 @@ basic_xml_oarchive<Archive>::save_start(const char *name)
{
if(NULL == name)
return;
// be sure name has no invalid characters
std::for_each(name, name + std::strlen(name), detail::XML_name<const char>());
@@ -119,7 +118,7 @@ basic_xml_oarchive<Archive>::save_end(const char *name)
{
if(NULL == name)
return;
// be sure name has no invalid characters
std::for_each(name, name + std::strlen(name), detail::XML_name<const char>());
@@ -151,7 +150,7 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
{
int i = t.t; // extra .t is for borland
write_attribute(OBJECT_ID(), i, "=\"_");
write_attribute(OBJECT_ID(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -160,20 +159,20 @@ basic_xml_oarchive<Archive>::save_override(
int
){
int i = t.t; // extra .t is for borland
write_attribute(OBJECT_REFERENCE(), i, "=\"_");
write_attribute(OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
{
int i = t.t; // extra .t is for borland
write_attribute(VERSION(), i);
write_attribute(VERSION(), i);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const class_id_type & t, int)
{
write_attribute(CLASS_ID(), t);
write_attribute(CLASS_ID(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -181,7 +180,7 @@ basic_xml_oarchive<Archive>::save_override(
const class_id_reference_type & t,
int
){
write_attribute(CLASS_ID_REFERENCE(), t);
write_attribute(CLASS_ID_REFERENCE(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -189,7 +188,7 @@ basic_xml_oarchive<Archive>::save_override(
const class_id_optional_type & t,
int
){
write_attribute(CLASS_ID(), t);
write_attribute(CLASS_ID(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -198,13 +197,13 @@ basic_xml_oarchive<Archive>::save_override(const class_name_type & t, int)
const char * key = t;
if(NULL == key)
return;
write_attribute(CLASS_NAME(), key);
write_attribute(CLASS_NAME(), key);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const tracking_type & t, int)
{
write_attribute(TRACKING(), t.t); // extra .t is for borland
write_attribute(TRACKING(), t.t); // extra .t is for borland
}
template<class Archive>
@@ -215,12 +214,12 @@ basic_xml_oarchive<Archive>::init(){
this->This()->put("<!DOCTYPE boost_serialization>\n");
// xml document wrapper - outer root
this->This()->put("<boost_serialization");
write_attribute("signature", ARCHIVE_SIGNATURE());
write_attribute("version", ARCHIVE_VERSION());
write_attribute("signature", ARCHIVE_SIGNATURE());
write_attribute("version", ARCHIVE_VERSION());
this->This()->put(">\n");
}
template<class Archive>
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) :
detail::common_oarchive<Archive>(flags),
@@ -230,16 +229,16 @@ basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) :
{
}
template<class Archive>
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_oarchive<Archive>::~basic_xml_oarchive(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
this->This()->put("</boost_serialization>\n");
}
BOOST_CATCH(...){}
BOOST_CATCH_END
this->This()->put("</boost_serialization>\n");
}
BOOST_CATCH(...){}
BOOST_CATCH_END
}
}
} // namespace archive
@@ -91,6 +91,18 @@ text_iarchive_impl<Archive>::load(std::wstring &ws)
#endif // BOOST_NO_STD_WSTRING
#endif // BOOST_NO_CWCHAR
template<class Archive>
BOOST_ARCHIVE_DECL(void)
text_iarchive_impl<Archive>::load_override(class_name_type & t, int){
basic_text_iarchive<Archive>::load_override(t, 0);
}
template<class Archive>
BOOST_ARCHIVE_DECL(void)
text_iarchive_impl<Archive>::init(){
basic_text_iarchive<Archive>::init();
}
template<class Archive>
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
text_iarchive_impl<Archive>::text_iarchive_impl(
@@ -168,20 +168,30 @@ xml_iarchive_impl<Archive>::xml_iarchive_impl(
basic_xml_iarchive<Archive>(flags),
gimpl(new xml_grammar())
{
if(0 == (flags & no_header))
init();
if(0 == (flags & no_header)){
BOOST_TRY{
init();
}
BOOST_CATCH(...){
delete gimpl;
#ifndef BOOST_NO_EXCEPTIONS
throw; // re-throw
#endif
}
BOOST_CATCH_END
}
}
template<class Archive>
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
xml_iarchive_impl<Archive>::~xml_iarchive_impl(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
gimpl->windup(is);
}
BOOST_CATCH(...){}
BOOST_CATCH_END
BOOST_TRY{
gimpl->windup(is);
}
BOOST_CATCH(...){}
BOOST_CATCH_END
}
delete gimpl;
}
} // namespace archive
@@ -168,20 +168,30 @@ xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
);
is.imbue(* archive_locale);
}
if(0 == (flags & no_header))
this->init();
if(0 == (flags & no_header)){
BOOST_TRY{
this->init();
}
BOOST_CATCH(...){
delete gimpl;
#ifndef BOOST_NO_EXCEPTIONS
throw; // re-throw
#endif
}
BOOST_CATCH_END
}
}
template<class Archive>
BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
xml_wiarchive_impl<Archive>::~xml_wiarchive_impl(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
gimpl->windup(is);
}
BOOST_CATCH(...){}
BOOST_CATCH_END
BOOST_TRY{
gimpl->windup(is);
}
BOOST_CATCH(...){}
BOOST_CATCH_END
}
delete gimpl;
}
@@ -84,7 +84,11 @@ class mb_from_wchar
void fill(){
wchar_t value = * this->base_reference();
#if (defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 3) || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION >= 8))))
m_bend = std::wcrtomb(m_buffer, value, 0);
#else
m_bend = std::wctomb(m_buffer, value);
#endif
assert(-1 != m_bend);
assert((std::size_t)m_bend <= sizeof(m_buffer));
assert(m_bend > 0);
+16 -3
View File
@@ -42,7 +42,12 @@ namespace std{
# define BOOST_NO_INTRINSIC_INT64_T
#endif
namespace boost {
namespace boost {
template<class T>
class shared_ptr;
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail {
class basic_iarchive;
@@ -93,8 +98,14 @@ public:
virtual void load_start(const char * name) = 0;
virtual void load_end(const char * name) = 0;
virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0;
virtual void delete_created_pointers() = 0;
virtual void lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
) = 0;
virtual void insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
) = 0;
// msvc and borland won't automatically pass these to the base class so
// make it explicit here
@@ -118,8 +129,10 @@ public:
}
public:
// utility function implemented by all legal archives
virtual void set_library_version(unsigned int archive_library_version) = 0;
virtual unsigned int get_library_version() const = 0;
virtual unsigned int get_flags() const = 0;
virtual void delete_created_pointers() = 0;
virtual void load_binary(void * t, std::size_t size) = 0;
@@ -42,6 +42,11 @@ namespace std{
#endif
namespace boost {
template<class T>
class shared_ptr;
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail {
class basic_oarchive;
@@ -92,6 +97,14 @@ public:
virtual void save_start(const char * name) = 0;
virtual void save_end(const char * name) = 0;
virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0;
virtual void lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
) = 0;
virtual void insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
) = 0;
virtual unsigned int get_library_version() const = 0;
virtual void end_preamble() = 0;
+4
View File
@@ -63,6 +63,10 @@ protected:
void load_override(T & t, BOOST_PFTO int){
basic_text_iarchive<Archive>::load_override(t, 0);
}
BOOST_ARCHIVE_DECL(void)
load_override(class_name_type & t, int);
BOOST_ARCHIVE_DECL(void)
init();
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
text_iarchive_impl(std::istream & is, unsigned int flags);
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
-1
View File
@@ -65,7 +65,6 @@ protected:
BOOST_ARCHIVE_DECL(void)
save(const std::wstring &ws);
#endif
protected:
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
text_oarchive_impl(std::ostream & os, unsigned int flags);
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+3 -23
View File
@@ -31,28 +31,8 @@
#include <boost/static_assert.hpp>
#include <boost/serialization/type_info_implementation.hpp>
// if no archive headers have been included
// skip inclusion of void_cast.hpp . This is to avoid auto-link when
// a module doesn't doesn't actually invoke serializaton but rather
// just declares it.
#if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP)
namespace boost {
namespace serialization {
namespace void_cast_detail{
class void_caster;
} // namespace void_cast_detail
template<class Derived, class Base>
const void_cast_detail::void_caster & void_cast_register(
const Derived * /* dnull = NULL */,
const Base * /* bnull = NULL */
);
} // namespace serialization
} // namespace boost
#else
#include <boost/serialization/void_cast.hpp>
#endif
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/void_cast_fwd.hpp>
namespace boost {
namespace serialization {
@@ -126,7 +106,7 @@ namespace detail {
static_cast<const Base *>(NULL)
);
}
} m_reg;
};
static void invoke(){
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
BOOST_DEDUCED_TYPENAME type_info_implementation<Base>::type::is_polymorphic,
@@ -25,13 +25,13 @@
#include <cassert>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
namespace boost{
namespace serialization {
@@ -41,50 +41,13 @@ namespace stl {
// implementation of serialization for STL containers
//
// reserve space on stack for an object of type T without actually
// construction such an object
template<typename T >
struct stack_allocate
{
T * address() {
return static_cast<T*>(storage_.address());
}
T & reference() {
return * address();
}
private:
typedef BOOST_DEDUCED_TYPENAME boost::aligned_storage<
sizeof(T),
#if BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x560))
8
#else
boost::alignment_of<T>::value
#endif
> type;
type storage_;
};
// construct element on the stack
template<class Archive, class T>
struct stack_construct : public stack_allocate<T>
{
stack_construct(Archive & ar){
// note borland emits a no-op without the explicit namespace
boost::serialization::load_construct_data_adl(ar, this->address(), 0U);
}
~stack_construct(){
this->address()->~T(); // undo load_construct_data above
}
};
// sequential container input
template<class Archive, class Container>
struct archive_input_seq
{
inline void operator()(Archive &ar, Container &s)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
stack_construct<Archive, type> t(ar);
detail::stack_construct<Archive, BOOST_DEDUCED_TYPENAME Container::value_type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
s.push_back(t.reference());
@@ -98,24 +61,13 @@ struct archive_input_map
{
inline void operator()(Archive &ar, Container &s)
{
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
typedef BOOST_DEDUCED_TYPENAME std::pair<
BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::referent_type
> type;
#else
typedef BOOST_DEDUCED_TYPENAME std::pair<
BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::mapped_type
> type;
#endif
stack_construct<Archive, type> t(ar);
detail::stack_construct<Archive, BOOST_DEDUCED_TYPENAME Container::value_type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
std::pair<BOOST_DEDUCED_TYPENAME Container::const_iterator, bool> result =
s.insert(t.reference());
assert(result.second); // make sure we inserted a new element
ar.reset_object_address(& (* result.first), & t);
ar.reset_object_address(& (* result.first), & t.reference());
}
};
@@ -126,13 +78,13 @@ struct archive_input_set
inline void operator()(Archive &ar, Container &s)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
stack_construct<Archive, type> t(ar);
detail::stack_construct<Archive, type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
std::pair<BOOST_DEDUCED_TYPENAME Container::const_iterator, bool> result =
s.insert(t.reference());
assert(result.second); // make sure we inserted a new element
ar.reset_object_address(& (* result.first), & t);
ar.reset_object_address(& (* result.first), & t.reference());
}
};
@@ -142,23 +94,12 @@ struct archive_input_multimap
{
inline void operator()(Archive &ar, Container &s)
{
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
typedef BOOST_DEDUCED_TYPENAME std::pair<
BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::referent_type
> type;
#else
typedef BOOST_DEDUCED_TYPENAME std::pair<
BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::mapped_type
> type;
#endif
stack_construct<Archive, type> t(ar);
detail::stack_construct<Archive, BOOST_DEDUCED_TYPENAME Container::value_type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
BOOST_DEDUCED_TYPENAME Container::const_iterator result
= s.insert(t.reference());
ar.reset_object_address(& (* result), & t);
ar.reset_object_address(& (* result), & t.reference());
}
};
@@ -169,12 +110,12 @@ struct archive_input_multiset
inline void operator()(Archive &ar, Container &s)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
stack_construct<Archive, type> t(ar);
detail::stack_construct<Archive, type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
BOOST_DEDUCED_TYPENAME Container::const_iterator result
= s.insert(t.reference());
ar.reset_object_address(& (* result), & t);
ar.reset_object_address(& (* result), & t.reference());
}
};
@@ -18,8 +18,6 @@
// helper function templates for serialization of collections
#include <boost/archive/basic_archive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/serialization.hpp>
@@ -0,0 +1,69 @@
#ifndef BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP
#define BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(_MSC_VER) && (_MSC_VER <= 1020)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// collections_load_imp.hpp: serialization for loading stl collections
// (C) Copyright 2002 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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/aligned_storage.hpp>
namespace boost{
namespace serialization {
namespace detail {
// reserve space on stack for an object of type T without actually
// construction such an object
template<typename T >
struct stack_allocate
{
T * address() {
return static_cast<T*>(storage_.address());
}
T & reference() {
return * address();
}
private:
typedef BOOST_DEDUCED_TYPENAME boost::aligned_storage<
sizeof(T),
#if BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x560))
8
#else
boost::alignment_of<T>::value
#endif
> type;
type storage_;
};
// construct element on the stack
template<class Archive, class T>
struct stack_construct : public stack_allocate<T>
{
stack_construct(Archive & ar){
// note borland emits a no-op without the explicit namespace
boost::serialization::load_construct_data_adl(ar, this->address(), 0U);
}
~stack_construct(){
this->address()->~T(); // undo load_construct_data above
}
};
} // detail
} // serializaition
} // boost
#endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP
+56 -49
View File
@@ -9,7 +9,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// export.hpp: set traits of classes to be serialized
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// (C) Copyright 2002 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)
@@ -25,7 +25,7 @@
#include <boost/config.hpp>
// if no archive headers have been included this is a no op
// this is to permit BOOST_EXPORT etc to be included in a
// this is to permit BOOST_EXPORT etc to be included in a
// file declaration header
#if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP)
#define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)
@@ -44,7 +44,7 @@
#include <boost/archive/detail/known_archive_types.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/serialization/is_abstract.hpp>
namespace boost {
@@ -62,7 +62,6 @@ template<class Archive, class T>
BOOST_DLLEXPORT const basic_pointer_oserializer &
instantiate_pointer_oserializer(Archive * ar, T *) BOOST_USED;
namespace export_impl
{
struct nothing{
@@ -136,7 +135,7 @@ struct export_generator {
};
template<class T, class ASeq>
const export_generator<T, ASeq>
const export_generator<T, ASeq>
export_generator<T, ASeq>::instance;
// instantiation of this template creates a static object.
@@ -147,12 +146,12 @@ struct guid_initializer {
eti_type::export_register(key);
}
static const guid_initializer instance;
guid_initializer(const char *key = NULL) BOOST_USED ;
guid_initializer(const char *key = 0) BOOST_USED ;
};
template<class T>
guid_initializer<T>::guid_initializer(const char *key){
if(NULL != key)
if(0 != key)
export_register(key);
}
@@ -167,56 +166,63 @@ const guid_initializer<T> guid_initializer<T>::instance;
template<class T, class ASeq>
struct export_instance {
struct abstract {
static const void *
static const export_generator<T, ASeq> *
invoke(){
return NULL;
return 0;
}
};
struct not_abstract {
static const void *
static const export_generator<T, ASeq> *
invoke(){
return & export_generator<T, ASeq>::instance;
}
};
static BOOST_DLLEXPORT std::pair<const void *, const void *>
#if ! (defined(BOOST_MSVC) && (_MSC_VER <= 1300))
invoke() BOOST_USED;
#else
invoke() {
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
is_abstract<T>,
mpl::identity<abstract>,
mpl::identity<not_abstract>
>::type typex;
return std::pair<const void *, const void *>(
typex::invoke(),
& guid_initializer<T>::instance
);
}
#endif
};
#if ! (defined(BOOST_MSVC) && (_MSC_VER <= 1300))
template<class T, class ASeq>
BOOST_DLLEXPORT
std::pair<const void *, const void *>
export_instance<T, ASeq>::invoke() {
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
is_abstract<T>,
mpl::identity<abstract>,
mpl::identity<not_abstract>
>::type type;
return std::pair<const void *, const void *>(
type::invoke(),
& guid_initializer<T>::instance
);
}
#endif
template<class T, class ASeq>
BOOST_DLLEXPORT
std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
export_instance_invoke() {
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
serialization::is_abstract<T>,
mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::abstract>,
mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::not_abstract>
>::type typex;
return std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>(
typex::invoke(),
& guid_initializer<T>::instance
);
}
template<class T, class ASeq>
std::pair<const void *, const void *>
export_instantiate(T &, ASeq &){
return export_instance<T, ASeq>::invoke();
struct export_archives {
struct empty_archive_list {
static BOOST_DLLEXPORT
std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
invoke(){
return std::pair<const export_generator<T, ASeq> *,
const guid_initializer<T> *>(0, 0);
}
};
struct non_empty_archive_list {
static BOOST_DLLEXPORT
std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
invoke(){
return export_instance_invoke<T, ASeq>();
}
};
};
template<class T, class ASeq>
BOOST_DLLEXPORT
std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
export_archives_invoke(T &, ASeq &){
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
mpl::empty<ASeq>,
mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::empty_archive_list>,
mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::non_empty_archive_list>
>::type typex;
return typex::invoke();
}
} // namespace detail
@@ -231,14 +237,15 @@ export_instantiate(T &, ASeq &){
const guid_initializer< T > \
guid_initializer< T >::instance(K); \
template \
BOOST_DLLEXPORT std::pair<const void *, const void *> \
export_instantiate(T &, ASEQ &); \
BOOST_DLLEXPORT \
std::pair<const export_generator<T, ASEQ> *, const guid_initializer<T> *> \
export_archives_invoke<T, ASEQ>(T &, ASEQ &); \
} } } \
/**/
#endif
// check for unnecessary export. T isn't polymorphic so there is no
// check for unnecessary export. T isn't polymorphic so there is no
// need to export it.
#define BOOST_CLASS_EXPORT_CHECK(T) \
BOOST_STATIC_WARNING( \
@@ -257,7 +264,7 @@ export_instantiate(T &, ASeq &){
/**/
// the default exportable class identifier is the class name
#define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ) \
#define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ) \
BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, BOOST_PP_STRINGIZE(T), A)
// the default exportable class identifier is the class name
@@ -38,18 +38,31 @@ class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info :
private:
virtual bool
less_than(const extended_type_info &rhs) const = 0;
int type_info_key_cmp(const extended_type_info & rhs) const;
// used to uniquely identify the type of class derived from this one
// so that different derivations of this class can be simultaneously
// included in implementation of sets and maps.
const char * type_info_key;
int type_info_key_cmp(const extended_type_info & rhs) const;
const char * m_type_info_key;
// flag to indicate wheter its been registered by type;
bool m_self_registered;
// flag to indicate wheter its been registered by type;
bool m_key_registered;
// flag indicating that no virtual function should be called here
// this is necessary since it seems that at least one compiler (borland
// and one version of gcc call less_than above when erasing even
// when given an iterator argument.
bool m_is_destructing;
protected:
const char * key;
extended_type_info(const char * type_info_key_);
virtual ~extended_type_info() = 0;
const char * m_key;
extended_type_info(const char * type_info_key);
~extended_type_info();
public:
void self_register();
void key_register(const char *key);
bool is_destructing() const {
return m_is_destructing;
}
bool operator<(const extended_type_info &rhs) const;
bool operator==(const extended_type_info &rhs) const {
return this == & rhs;
@@ -58,7 +71,7 @@ public:
return this != & rhs;
}
const char * get_key() const {
return key;
return m_key;
}
static const extended_type_info * find(const char *key);
static const extended_type_info * find(const extended_type_info * t);
@@ -42,9 +42,9 @@ namespace detail {
class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_no_rtti_0 :
public extended_type_info
{
protected:
virtual bool
less_than(const boost::serialization::extended_type_info &rhs) const ;
protected:
extended_type_info_no_rtti_0();
~extended_type_info_no_rtti_0();
public:
@@ -59,11 +59,11 @@ template<class T>
class extended_type_info_no_rtti_1 :
public extended_type_info_no_rtti_0
{
private:
// private constructor to inhibit any existence other than the
// static one
protected:
extended_type_info_no_rtti_1(){}
public:
// note borland complains at making this destructor protected
~extended_type_info_no_rtti_1(){};
static const boost::serialization::extended_type_info *
get_derived_extended_type_info(const T & t){
// find the type that corresponds to the most derived type.
@@ -93,7 +93,12 @@ public:
template<class T>
class extended_type_info_no_rtti :
public detail::extended_type_info_no_rtti_1<const T>
{};
{
// private constructor to inhibit any existence other than the
// static one
extended_type_info_no_rtti(){}
~extended_type_info_no_rtti(){};
};
} // namespace serialization
} // namespace boost
+16 -12
View File
@@ -18,31 +18,35 @@
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_abstract.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
#include <boost/type_traits/is_abstract.hpp>
#else
// default to false if not supported
// supplant boost/type_traits/is_abstract.hpp
# define BOOST_TT_IS_ABSTRACT_CLASS_HPP
namespace boost {
namespace boost {
namespace serialization {
template<class T>
struct is_abstract {
typedef mpl::bool_<false> type;
BOOST_STATIC_CONSTANT(bool, value = false);
// default to false if not supported
#ifdef BOOST_NO_IS_ABSTRACT
typedef BOOST_DEDUCED_TYPENAME mpl::bool_<false> type;
BOOST_STATIC_CONSTANT(bool, value = false);
#else
typedef BOOST_DEDUCED_TYPENAME boost::is_abstract<T>::type type;
BOOST_STATIC_CONSTANT(bool, value = type::value);
#endif
};
} // namespace boost
#endif
} // namespace serialization
} // namespace boost
// define a macro to make explicit designation of this more transparent
#define BOOST_IS_ABSTRACT(T) \
namespace boost { \
namespace serialization { \
template<> \
struct is_abstract< T > { \
typedef mpl::bool_<true> type; \
BOOST_STATIC_CONSTANT(bool, value = true); \
}; \
} // namespace boost
} \
} \
/**/
#endif //BOOST_SERIALIZATION_IS_ABSTRACT_CLASS_HPP
+1 -1
View File
@@ -28,7 +28,7 @@
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/integral_c_tag.hpp>
#include <boost/serialization/traits.hpp>
//#include <boost/serialization/traits.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/split_member.hpp>
+65 -67
View File
@@ -16,88 +16,86 @@
#include <boost/config.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/integral_c_tag.hpp>
#include <boost/optional.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/assert.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
// function specializations must be defined in the appropriate
// namespace - boost::serialization
namespace boost {
namespace serialization {
template<class Archive, class T>
void save(
Archive & ar,
const boost::optional<T> & t,
const unsigned int /*version*/
){
const bool tflag = t;
ar << boost::serialization::make_nvp("initialized", tflag);
if (tflag)
ar << boost::serialization::make_nvp("value", *t);
namespace serialization {
template<class Archive, class T>
void save(
Archive & ar,
const boost::optional<T> & t,
const unsigned int /*version*/
){
const bool tflag = t;
ar << boost::serialization::make_nvp("initialized", tflag);
if (tflag)
ar << boost::serialization::make_nvp("value", *t);
}
template<class Archive, class T>
void load(
Archive & ar,
boost::optional<T> & t,
const unsigned int /*version*/
){
bool tflag;
ar >> boost::serialization::make_nvp("initialized", tflag);
if (tflag){
detail::stack_construct<Archive, T> aux(ar);
ar >> boost::serialization::make_nvp("value", aux.reference());
t.reset(aux.reference());
}
template<class Archive, class T>
void load(
Archive & ar,
boost::optional<T> & t,
const unsigned int /*version*/
){
bool tflag;
ar >> boost::serialization::make_nvp("initialized", tflag);
if (tflag){
T aux;
ar >> boost::serialization::make_nvp("value", aux);
t.reset(aux);
}
else {
t.reset();
}
else {
t.reset();
}
}
template<class Archive, class T>
void serialize(
Archive & ar,
boost::optional<T> & t,
const unsigned int version
){
boost::serialization::split_free(ar, t, version);
}
template<class Archive, class T>
void serialize(
Archive & ar,
boost::optional<T> & t,
const unsigned int version
){
boost::serialization::split_free(ar, t, version);
}
// the following would be slightly more efficient. But it
// would mean that archives created with programs that support
// TPS wouldn't be readable by programs that don't support TPS.
// Hence we decline to support this otherwise convenient optimization.
//#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if 0
// the following would be slightly more efficient. But it
// would mean that archives created with programs that support
// TPS wouldn't be readable by programs that don't support TPS.
// Hence we decline to support this otherwise convenient optimization.
//#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if 0
template <class T>
struct implementation_level<optional<T> >
{
typedef mpl::integral_c_tag tag;
typedef mpl::int_<boost::serialization::object_serializable> type;
BOOST_STATIC_CONSTANT(
int ,
value = boost::serialization::implementation_level::type::value
);
};
template <class T>
struct implementation_level<optional<T> >
{
typedef mpl::integral_c_tag tag;
typedef mpl::int_<boost::serialization::object_serializable> type;
BOOST_STATIC_CONSTANT(
int ,
value = boost::serialization::implementation_level::type::value
);
};
template<class T>
struct tracking_level<optional<T> >
{
typedef mpl::integral_c_tag tag;
typedef mpl::int_<boost::serialization::track_never> type;
BOOST_STATIC_CONSTANT(
int ,
value = boost::serialization::tracking_level::type::value
);
};
template<class T>
struct tracking_level<optional<T> >
{
typedef mpl::integral_c_tag tag;
typedef mpl::int_<boost::serialization::track_never> type;
BOOST_STATIC_CONSTANT(
int ,
value = boost::serialization::tracking_level::type::value
);
};
#endif
#endif
} // serialization
} // namespace boost
+34 -26
View File
@@ -28,15 +28,18 @@
#include <boost/archive/archive_exception.hpp>
// no extended type info system has been selected, use the typeid based one
#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
#include <boost/serialization/extended_type_info_typeid.hpp>
#endif
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/static_assert.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/void_cast_fwd.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// shared_ptr serialization traits
@@ -47,17 +50,33 @@
namespace boost {
namespace serialization{
template<class T>
struct version< ::boost::shared_ptr<T> > { \
struct version< ::boost::shared_ptr<T> > {
typedef mpl::integral_c_tag tag;
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
typedef BOOST_DEDUCED_TYPENAME mpl::int_<1> type;
#else
typedef mpl::int_<1> type;
#endif
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
BOOST_STATIC_CONSTANT(unsigned int, value = 1);
#else
BOOST_STATIC_CONSTANT(unsigned int, value = type::value);
#endif
};
// don't track shared pointers
template<class T>
struct tracking_level< ::boost::shared_ptr<T> > {
typedef mpl::integral_c_tag tag;
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
typedef BOOST_DEDUCED_TYPENAME mpl::int_< ::boost::serialization::track_never> type;
#else
typedef mpl::int_< ::boost::serialization::track_never> type;
#endif
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
BOOST_STATIC_CONSTANT(int, value = ::boost::serialization::track_never);
#else
BOOST_STATIC_CONSTANT(int, value = type::value);
#endif
};
}}
#define BOOST_SERIALIZATION_SHARED_PTR(T)
@@ -77,6 +96,9 @@
namespace boost {
namespace serialization{
class extended_type_info;
namespace detail {
struct null_deleter {
@@ -141,32 +163,18 @@ public:
// utility function for creating/getting a helper - could be useful in general
// but shared_ptr is the only class (so far that needs it) and I don't have a
// convenient header to place it into.
template<class Archive, class T>
T &
get_helper(Archive & ar){
extended_type_info * eti = type_info_implementation<T>::type::get_instance();
shared_ptr<void> sph;
ar.lookup_helper(eti, sph);
if(NULL == sph.get()){
sph = shared_ptr<T>(new T);
ar.insert_helper(eti, sph);
}
return * static_cast<T *>(sph.get());
}
#if 0
template<class Archive, class H>
H &
get_helper(Archive & ar){
shared_ptr<H> sph;
ar.lookup_helper(sph);
extended_type_info * eti = type_info_implementation<H>::type::get_instance();
shared_ptr<void> sph;
ar.lookup_helper(eti, sph);
if(NULL == sph.get()){
sph = shared_ptr<H>(new H);
ar.insert_helper(sph);
ar.insert_helper(eti, sph);
}
return * static_cast<T *>(sph.get());
return * static_cast<H *>(sph.get());
}
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// serialization for shared_ptr
@@ -182,7 +190,7 @@ inline void save(
// is never tracked by default. Wrap int in a trackable type
BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
const T * t_ptr = t.get();
ar << boost::serialization::make_nvp("px", t_ptr);
ar << boost::serialization::make_nvp("px", t_ptr);
}
template<class Archive, class T>
@@ -195,7 +203,7 @@ inline void load(
// something like shared_ptr<int>. This occurs because int
// is never tracked by default. Wrap int in a trackable type
BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
T* r;
T* r;
#ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
if(file_version < 1){
ar.register_type(static_cast<
@@ -211,7 +219,7 @@ inline void load(
else
#endif
{
ar >> boost::serialization::make_nvp("px", r);
ar >> boost::serialization::make_nvp("px", r);
}
get_helper<Archive, detail::shared_ptr_helper >(ar).reset(t,r);
}
+3 -3
View File
@@ -60,16 +60,16 @@ inline void load(
if(0 == count)
return;
boost::serialization::stl::stack_construct<Archive, U> u(ar);
boost::serialization::detail::stack_construct<Archive, U> u(ar);
ar >> boost::serialization::make_nvp("item", u.reference());
t.push_front(u.reference());
BOOST_DEDUCED_TYPENAME BOOST_STD_EXTENSION_NAMESPACE::slist<U, Allocator>::iterator last;
last = t.begin();
while(--count > 0){
boost::serialization::stl::stack_construct<Archive, U> u(ar);
boost::serialization::detail::stack_construct<Archive, U> u(ar);
ar >> boost::serialization::make_nvp("item", u.reference());
last = t.insert_after(last, u.reference());
ar.reset_object_address(& (*last), & u);
ar.reset_object_address(& (*last), & u.reference());
}
}
+1
View File
@@ -26,6 +26,7 @@
#include <boost/mpl/integral_c_tag.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/serialization/traits.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking_enum.hpp>
@@ -20,10 +20,6 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
///////////////////////////////////////////////////////////////////////////////
// If no other implementation has been designated as default,
// use extended_type_info_typeid.hpp
namespace boost {
namespace serialization {
template<class T>
+6 -1
View File
@@ -20,6 +20,7 @@
#include <utility>
#include <boost/config.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/serialization/nvp.hpp>
// function specializations must be defined in the appropriate
@@ -40,7 +41,11 @@ inline void serialize(
STD::pair<F, S> & p,
const unsigned int /* file_version */
){
ar & boost::serialization::make_nvp("first", p.first);
// note: we remove any const-ness on the first argument. The reason is that
// for stl maps, the type saved is pair<const key, T). We remove
// the const-ness in order to be able to load it.
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<F>::type typef;
ar & boost::serialization::make_nvp("first", const_cast<typef &>(p.first));
ar & boost::serialization::make_nvp("second", p.second);
}
+3 -2
View File
@@ -98,10 +98,11 @@ struct variant_impl {
// necessary has to copy the value. This wouldn't be necessary
// with an implementation that de-serialized to the address of the
// aligned storage included in the variant.
BOOST_DEDUCED_TYPENAME mpl::front<S>::type value;
typedef BOOST_DEDUCED_TYPENAME mpl::front<S>::type head_type;
head_type value;
ar >> BOOST_SERIALIZATION_NVP(value);
v = value;
ar.reset_object_address(& v, & value);
ar.reset_object_address(& boost::get<head_type>(v), & value);
return;
}
typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<S>::type type;
@@ -0,0 +1,34 @@
#ifndef BOOST_SERIALIZATION_VOID_CAST_FWD_HPP
#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// void_cast_fwd.hpp: interface for run-time casting of void pointers.
// (C) Copyright 2005 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)
// gennadiy.rozental@tfn.com
// See http://www.boost.org for updates, documentation, and revision history.
namespace boost {
namespace serialization {
namespace void_cast_detail{
class void_caster;
} // namespace void_cast_detail
template<class Derived, class Base>
BOOST_DLLEXPORT
inline const void_cast_detail::void_caster & void_cast_register(
const Derived * /* dnull = NULL */,
const Base * /* bnull = NULL */
) BOOST_USED;
} // namespace serialization
} // namespace boost
#endif // BOOST_SERIALIZATION_VOID_CAST_HPP
+72 -51
View File
@@ -80,8 +80,9 @@ class basic_iarchive_impl :
// list of objects which might be moved. We use a vector for implemenation
// in the hope the the truncation operation will be faster than either
// with a list or stack adaptor
std::vector<std::size_t> moveable_object_stack;
std::size_t moveable_object_position;
object_id_type moveable_objects_start;
object_id_type moveable_objects_end;
object_id_type moveable_objects_recent;
void reset_object_address(
const void * new_address,
@@ -95,7 +96,7 @@ class basic_iarchive_impl :
const basic_iserializer * bis;
const class_id_type class_id;
cobject_type(
std::size_t class_id_,
class_id_type class_id_,
const basic_iserializer & bis_
) :
bis(& bis_),
@@ -196,7 +197,8 @@ class basic_iarchive_impl :
basic_iarchive_impl(unsigned int flags) :
m_archive_library_version(ARCHIVE_VERSION()),
m_flags(flags),
moveable_object_position(0),
moveable_objects_start(0),
moveable_objects_end(0),
pending_object(NULL),
pending_bis(NULL),
pending_version(0)
@@ -254,24 +256,44 @@ basic_iarchive_impl::reset_object_address(
const void * new_address,
const void *old_address
){
// if the this object wasn't tracked
std::size_t i = moveable_object_position;
if(i >= moveable_object_stack.size())
return;
if(old_address != object_id_vector[i].address)
// skip to any lower level ones
++i;
while(i < moveable_object_stack.size()){
object_id_type i;
// this code handles a couple of situations.
// a) where reset_object_address is applied to an untracked object.
// In such a case the call is really superfluous and its really an
// an error. But we don't have access to the types here so we can't
// know that. However, this code will effectively turn this situation
// into a no-op and every thing will work fine - albeat with a small
// execution time penalty.
// b) where the call to reset_object_address doesn't immediatly follow
// the << operator to which it corresponds. This would be a bad idea
// but the code may work anyway. Naturally, a bad practice on the part
// of the programmer but we can't detect it - as above. So maybe we
// can save a few more people from themselves as above.
for(i = moveable_objects_recent; i < moveable_objects_end; ++i){
if(old_address == object_id_vector[i].address)
break;
}
for(; i < moveable_objects_end; ++i){
// calculate displacement from this level
assert(object_id_vector[i].address >= old_address);
// warning - pointer arithmetic on void * is in herently non-portable
// but expected to work on all platforms in current usage
std::size_t member_displacement
= reinterpret_cast<std::size_t>(object_id_vector[i].address)
- reinterpret_cast<std::size_t>(old_address);
object_id_vector[i].address = reinterpret_cast<void *>(
reinterpret_cast<std::size_t>(new_address) + member_displacement
);
if(object_id_vector[i].address > old_address){
std::size_t member_displacement
= reinterpret_cast<std::size_t>(object_id_vector[i].address)
- reinterpret_cast<std::size_t>(old_address);
object_id_vector[i].address = reinterpret_cast<void *>(
reinterpret_cast<std::size_t>(new_address) + member_displacement
);
}
else{
std::size_t member_displacement
= reinterpret_cast<std::size_t>(old_address)
- reinterpret_cast<std::size_t>(object_id_vector[i].address);
object_id_vector[i].address = reinterpret_cast<void *>(
reinterpret_cast<std::size_t>(new_address) - member_displacement
);
}
++i;
}
}
@@ -297,7 +319,8 @@ inline class_id_type
basic_iarchive_impl::register_type(
const basic_iserializer & bis
){
cobject_type co(cobject_info_set.size(), bis);
class_id_type id(static_cast<int>(cobject_info_set.size()));
cobject_type co(id, bis);
std::pair<cobject_info_set_type::const_iterator, bool>
result = cobject_info_set.insert(co);
@@ -305,10 +328,12 @@ basic_iarchive_impl::register_type(
cobject_id_vector.push_back(cobject_id(bis));
assert(cobject_info_set.size() == cobject_id_vector.size());
}
const int id = result.first->class_id;
cobject_id & coid = cobject_id_vector[id];
id = result.first->class_id;
// borland complains without this minor hack
const int tid = id;
cobject_id & coid = cobject_id_vector[tid];
coid.bpis_ptr = bis.get_bpis_ptr();
return result.first->class_id;
return id;
}
void
@@ -370,34 +395,31 @@ basic_iarchive_impl::load_object(
cobject_id & co = cobject_id_vector[id];
load_preamble(ar, co);
// save the current move stack position in case we want to truncate it
boost::state_saver<object_id_type> w(moveable_objects_start);
// note: extra line used to evade borland issue
const bool tracking = co.tracking_level;
// if we didn't track this object when the archive was saved
if(! tracking){
// all we need to do is read the data
(bis.load_object_data)(ar, t, co.file_version);
return;
object_id_type this_id;
moveable_objects_start =
this_id = object_id_vector.size();
// if we tracked this object when the archive was saved
if(tracking){
// if it was already read
if(!track(ar, t))
// we're done
return;
// add a new enty into the tracking list
object_id_vector.push_back(aobject(t, cid));
// and add an entry for this object
moveable_objects_end = object_id_vector.size();
}
// we're tracking the object
// if it was already read
if(! track(ar, t))
// we're done
return;
std::size_t tracking_list_position = object_id_vector.size();
// add a new enty into the tracking list
object_id_vector.push_back(aobject(t, cid));
// save the current move stack position in case we want to truncate it
std::size_t next_moveable_object_position = moveable_object_stack.size();
// and add an entry for this object
moveable_object_stack.push_back(tracking_list_position);
// read data
(bis.load_object_data)(ar, t, co.file_version);
// last object created
moveable_object_position = next_moveable_object_position;
moveable_objects_recent = this_id;
}
inline const basic_pointer_iserializer *
@@ -457,8 +479,7 @@ basic_iarchive_impl::load_pointer(
return bpis_ptr;
// save state
std::size_t original_moveable_stack_size(moveable_object_stack.size());
state_saver<std::size_t> w(moveable_object_position);
state_saver<object_id_type> w(moveable_objects_start);
if(! tracking){
bpis_ptr->load_object_ptr(ar, t, co.file_version);
@@ -474,11 +495,14 @@ basic_iarchive_impl::load_pointer(
// predict next object id to be created
const unsigned int ui = object_id_vector.size();
state_saver<object_id_type> w(moveable_objects_end);
// because the following operation could move the items
// don't use co after this
// add to list of serialized objects so that we can properly handle
// cyclic strucures
object_id_vector.push_back(aobject(t, cid));
bpis_ptr->load_object_ptr(
ar,
object_id_vector[ui].address,
@@ -490,9 +514,6 @@ basic_iarchive_impl::load_pointer(
// and add to list of created pointers
created_pointers.push_back(created_pointer_type(cid, t));
}
// anything pointed to is never moved
// so truncate the stack of moveable objects
moveable_object_stack.resize(original_moveable_stack_size);
return bpis_ptr;
}
+1 -1
View File
@@ -17,7 +17,7 @@ namespace detail {
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_iserializer::basic_iserializer(
const boost::serialization::extended_type_info & eti
const boost::serialization::extended_type_info & eti
) :
basic_serializer(eti),
bpis(NULL)
+20 -6
View File
@@ -25,19 +25,33 @@ namespace boost {
namespace archive {
namespace detail {
bool type_info_pointer_compare::operator()(
BOOST_ARCHIVE_DECL(bool)
type_info_pointer_compare::operator()(
const basic_serializer * lhs, const basic_serializer * rhs
) const {
) const {
return *lhs < *rhs;
}
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_serializer_map::basic_serializer_map(){
basic_serializer_map::basic_serializer_map(bool & deleted) :
m_deleted(deleted)
{
m_deleted = false;
}
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_serializer_map::~basic_serializer_map(){
m_deleted = true;
}
BOOST_ARCHIVE_DECL(bool)
basic_serializer_map::insert(const basic_serializer * bs){
return map.insert(bs).second;
return m_map.insert(bs).second;
}
BOOST_ARCHIVE_DECL(void)
basic_serializer_map::erase(basic_serializer * bs){
m_map.erase(bs);
}
class basic_serializer_arg : public basic_serializer {
@@ -53,8 +67,8 @@ basic_serializer_map::tfind(
) const {
const basic_serializer_arg bs(eti);
map_type::const_iterator it;
it = map.find(& bs);
if(it == map.end())
it = m_map.find(& bs);
if(it == m_map.end())
return NULL;
return *it;
}
+95 -42
View File
@@ -43,13 +43,20 @@ class tkmap {
bool
operator()(const extended_type_info * lhs, const extended_type_info * rhs) const
{
assert(! lhs->is_destructing());
assert(! rhs->is_destructing());
return *lhs < *rhs;
}
};
typedef std::multiset<const extended_type_info *, type_info_compare> type;
tkmap(){}
// typedef std::multiset<const extended_type_info *, type_info_compare> type;
typedef std::set<const extended_type_info *, type_info_compare> type;
type m_map;
static tkmap * m_self;
tkmap(){}
static tkmap::type::iterator
lookup(const extended_type_info * eti){
return m_self->m_map.find(eti);
}
public:
~tkmap(){
m_self = NULL;
@@ -60,14 +67,16 @@ public:
static tkmap instance;
m_self = & instance;
}
// make sure that attempt at registration is done only once
assert(lookup(eti) == m_self->m_map.end());
m_self->m_map.insert(eti);
}
static const extended_type_info *
find(const extended_type_info * t){
find(const extended_type_info * eti){
if(NULL == m_self)
return NULL;
tkmap::type::const_iterator it;
it = m_self->m_map.find(t);
it = m_self->m_map.find(eti);
if(it == m_self->m_map.end())
return NULL;
return *it;
@@ -76,6 +85,19 @@ public:
purge(const extended_type_info * eti){
if(NULL == m_self)
return;
// note: the following can't be used as this function
// is called from a destructor of extended_type_info.
// This will generate an error on some machines - which
// makes sense be cause by this time the derived class data
// might be gone. Leave this in as a reminder not to do this
#if 0
tkmap::type::iterator it;
it = lookup(eti);
// it should be in there
assert(it != m_self->m_map.end());
m_self->m_map.erase(it);
#endif
tkmap::type::iterator i = m_self->m_map.begin();
tkmap::type::iterator k = m_self->m_map.end();
while(i != k){
@@ -106,10 +128,32 @@ class ktmap {
return std::strcmp(lhs->get_key(), rhs->get_key()) < 0;
}
};
typedef std::multiset<const extended_type_info *, key_compare> type;
// typedef std::multiset<const extended_type_info *, key_compare> type;
typedef std::set<const extended_type_info *, key_compare> type;
type m_map;
static ktmap * m_self;
ktmap(){}
class extended_type_info_arg : public extended_type_info
{
public:
extended_type_info_arg(const char * key) :
extended_type_info(NULL)
{
m_key = key;
}
virtual bool
less_than(const extended_type_info &rhs) const
{
assert(false);
return false; // to prevent a syntax error
}
};
static ktmap::type::iterator
lookup(const char *key){
extended_type_info_arg arg(key);
return m_self->m_map.find(&arg);
}
public:
~ktmap(){
m_self = NULL;
@@ -120,36 +164,10 @@ public:
static ktmap instance;
m_self = & instance;
}
// make sure that all GUIDs are unique
assert(lookup(eti->get_key()) == m_self->m_map.end());
m_self->m_map.insert(eti);
}
static void
purge(const extended_type_info * eti){
if(NULL == m_self)
return;
ktmap::type::iterator i = m_self->m_map.begin();
ktmap::type::iterator k = m_self->m_map.end();
while(i == k){
// note that the erase might invalidate i so save it here
ktmap::type::iterator j = i++;
if(*j == eti)
m_self->m_map.erase(j);
}
}
class extended_type_info_arg : public extended_type_info
{
public:
extended_type_info_arg(const char * search_key_)
: extended_type_info(NULL)
{
key = search_key_;
}
virtual bool
less_than(const extended_type_info &rhs) const
{
assert(false);
return false; // to prevent a syntax error
}
};
static const extended_type_info *
find(const char *key)
{
@@ -162,7 +180,32 @@ public:
return NULL;
return *it;
}
static void
purge(const extended_type_info * eti){
if(NULL == m_self)
return;
// note: the following can't be used as this function
// is called from a destructor of extended_type_info.
// This will generate an error on some machines - which
// makes sense be cause by this time the derived class data
// might be gone. Leave this in as a reminder not to do this
#if 0
ktmap::type::iterator it;
it = lookup(eti->get_key());
// expect it to be in there !
assert(it != m_self->m_map.end());
m_self->m_map.erase(it);
#endif
ktmap::type::iterator i = m_self->m_map.begin();
ktmap::type::iterator k = m_self->m_map.end();
while(i != k){
// note that the erase might invalidate i so save it here
ktmap::type::iterator j = i++;
if(*j == eti)
m_self->m_map.erase(j);
}
}
};
ktmap * ktmap::m_self = NULL;
@@ -179,43 +222,51 @@ BOOST_SERIALIZATION_DECL(void)
extended_type_info::self_register()
{
detail::tkmap::insert(this);
m_self_registered = true;
}
BOOST_SERIALIZATION_DECL(void)
extended_type_info::key_register(const char *key_) {
if(NULL == key_)
return;
key = key_;
m_key = key_;
detail::ktmap::insert(this);
m_key_registered = true;
}
BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
extended_type_info::extended_type_info(const char * type_info_key_) :
type_info_key(type_info_key_),
key(NULL)
extended_type_info::extended_type_info(
const char * type_info_key
) :
m_type_info_key(type_info_key),
m_self_registered(false),
m_key_registered(false),
m_is_destructing(false)
{}
BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
extended_type_info::~extended_type_info(){
// remove entries in maps which correspond to this type
m_is_destructing = true;
BOOST_TRY{
detail::tkmap::purge(this);
detail::ktmap::purge(this);
if(m_self_registered)
detail::tkmap::purge(this);
if(m_key_registered)
detail::ktmap::purge(this);
unregister_void_casts(this);
}
BOOST_CATCH(...){}
BOOST_CATCH_END
}
BOOST_SERIALIZATION_DECL(int)
extended_type_info::type_info_key_cmp(const extended_type_info & rhs) const {
if(type_info_key == rhs.type_info_key)
if(m_type_info_key == rhs.m_type_info_key)
return 0;
//return strcmp(lhs.type_info_key, rhs.type_info_key);
// all we require is that the type_info_key be unique
// so just compare the addresses
return type_info_key < rhs.type_info_key ? -1 : 1;
return m_type_info_key < rhs.m_type_info_key ? -1 : 1;
}
BOOST_SERIALIZATION_DECL(const extended_type_info *)
@@ -231,6 +282,8 @@ extended_type_info::operator<(const extended_type_info &rhs) const {
return true;
if(i > 0)
return false;
assert(! is_destructing());
assert(! rhs.is_destructing());
return less_than(rhs);
}
+1 -1
View File
@@ -26,7 +26,7 @@ BOOST_SERIALIZATION_DECL(bool)
extended_type_info_no_rtti_0::less_than(
const boost::serialization::extended_type_info &rhs) const
{
return std::strcmp(key, rhs.get_key()) < 0;
return std::strcmp(m_key, rhs.get_key()) < 0;
}
BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
+2
View File
@@ -111,6 +111,8 @@ void_caster_registry * void_caster_registry::m_self = NULL;
void
void_caster_registry::purge(const extended_type_info * eti){
if(NULL == m_self)
return;
if(! empty()){
iterator i = m_self->m_set.begin();
while(i != m_self->m_set.end()){
+17 -17
View File
@@ -5,7 +5,6 @@
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# See http://www.boost.org/libs/test for the library home page.
subproject libs/serialization/test ;
@@ -46,7 +45,8 @@ rule run-template ( test-name : sources * : requirements * ) {
: # requirements
std::locale-support
toolset::require-boost-spirit-support
<borland*><*><cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066"
toolset::suppress-warnings
toolset::optimizations
$(requirements)
: # test name
$(test-name)
@@ -69,7 +69,6 @@ rule run-invoke ( test-name : sources * : defns * )
# msvc stlport 4.5.3 only works with static lib
<msvc-stlport><*><runtime-link>static
<vc-6_5-stlport><*><runtime-link>static
<como><*><linkflags>"-force:multiple"
<define>$(defns)
<define>BOOST_LIB_DIAGNOSTIC=1
] ;
@@ -245,19 +244,6 @@ test-suite "serialization" :
[ test-bsl-run_polymorphic_archive test_polymorphic : test_polymorphic_A ]
;
# This last DEPENDS makes the directory for the part 2 depend on the
# completion of part 1. You may ask why the directory and not the test
# itself? Strangely it's because to properly chain the tests you need to
# make the earliest step of the second test depend on the latest part of
# the next test. And directories are the only sure thing that you can know
# a test needs first.
DEPENDS test_class_info_load_text_archive.run : test_class_info_save_text_archive.run ;
DEPENDS test_class_info_load_text_warchive.run : test_class_info_save_text_warchive.run ;
DEPENDS test_class_info_load_xml_archive.run : test_class_info_save_xml_archive.run ;
DEPENDS test_class_info_load_xml_archive.run : test_class_info_save_xml_warchive.run ;
DEPENDS test_class_info_load_binary_archive.run : test_class_info_save_binary_archive.run ;
if $(BOOST_SERIALIZATION_TEST) {
test-suite "serialization" :
[ test-bsl-run-no-lib test_iterators ]
@@ -307,7 +293,21 @@ if $(BOOST_SERIALIZATION_TEST) {
[ compile test_const_pass.cpp : std::locale-support ]
;
DEPENDS test_demo_xml_load.run : test_demo_xml_save.run ;
}
saving-tests = [ test-bsl-run_files test_class_info_save ]
[ test-bsl-run test_demo_xml_save ] ;
loading-tests = [ test-bsl-run_files test_class_info_load ]
[ test-bsl-run test_demo_xml_load ] ;
## This makes each individual load test depend on the run of the
## corresponding save test. It is important to do this one at a
## time because $(saving-tests) and $(loading-tests) can contain
## the targets for multiple toolsets.
for local save-test-i in $(saving-tests)
{
DEPENDS $(loading-tests[1]:S=.run) : $(save-test-i:S=.run) ;
loading-tests = $(loading-tests[2-]) ;
}
}
+5
View File
@@ -4,6 +4,10 @@
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <boost/archive/polymorphic_text_woarchive.hpp>
typedef boost::archive::polymorphic_text_woarchive test_oarchive;
typedef std::wofstream test_ostream;
@@ -11,3 +15,4 @@ typedef std::wofstream test_ostream;
typedef boost::archive::polymorphic_text_wiarchive test_iarchive;
typedef std::wifstream test_istream;
#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
#endif
+1 -1
View File
@@ -10,4 +10,4 @@
#define main test_main
#include "../example/demo.cpp"
#include "../example/demo_xml_load.cpp"
+1 -1
View File
@@ -10,4 +10,4 @@
#define main test_main
#include "../example/demo.cpp"
#include "../example/demo_xml_save.cpp"
+5 -5
View File
@@ -186,19 +186,19 @@ test_main( int /* argc */, char* /* argv */[] )
{
test_ostream ofs(testfile);
test_oarchive oa(ofs);
oa << boost::serialization::make_nvp("bp", bp);
oa << BOOST_SERIALIZATION_NVP(bp);
}
base* bp2;
{
test_istream ifs(testfile);
test_iarchive ia(ifs);
ia >> boost::serialization::make_nvp("bp2", bp2);
ia >> BOOST_SERIALIZATION_NVP(bp2);
}
BOOST_ASSERT(1 == save_count);
BOOST_ASSERT(1 == load_count);
BOOST_ASSERT(*bp2 == *bp);
BOOST_CHECK(1 == save_count);
BOOST_CHECK(1 == load_count);
BOOST_CHECK(*bp2 == *bp);
std::remove(testfile);
return EXIT_SUCCESS;
+71 -5
View File
@@ -61,6 +61,8 @@ struct random_key {
}
};
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(random_key)
#if defined(__LIBCOMO__) || (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
namespace std {
@@ -83,8 +85,8 @@ namespace BOOST_STD_EXTENSION_NAMESPACE {
#endif
int test_main( int /* argc */, char* /* argv */[] )
{
void
test_map(){
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
@@ -105,6 +107,45 @@ int test_main( int /* argc */, char* /* argv */[] )
ia >> boost::serialization::make_nvp("amap", amap1);
}
BOOST_CHECK(amap == amap1);
std::remove(testfile);
}
void
test_map_2(){
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
BOOST_CHECKPOINT("map_2");
std::pair<int, int> a(11, 22);
std::map<int, int> b;
b[0] = 0;
b[-1] = -1;
b[1] = 1;
{
test_ostream os(testfile, TEST_STREAM_FLAGS);
std::pair<int, int> * const pa = &a;
std::map<int, int> * const pb = &b;
test_oarchive oa(os);
oa << BOOST_SERIALIZATION_NVP(pb);
oa << BOOST_SERIALIZATION_NVP(pa);
}
{
test_istream is(testfile, TEST_STREAM_FLAGS);
std::pair<int, int> *pa = 0;
std::map<int, int> *pb = 0;
test_iarchive ia(is);
ia >> BOOST_SERIALIZATION_NVP(pb);
ia >> BOOST_SERIALIZATION_NVP(pa);
delete pa;
delete pb;
}
std::remove(testfile);
}
void
test_multimap(){
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
BOOST_CHECKPOINT("multimap");
std::multimap<random_key, A> amultimap;
@@ -122,8 +163,15 @@ int test_main( int /* argc */, char* /* argv */[] )
ia >> boost::serialization::make_nvp("amultimap", amultimap1);
}
BOOST_CHECK(amultimap == amultimap1);
std::remove(testfile);
}
void
test_hash_map(){
#ifdef BOOST_HAS_HASH
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
BOOST_CHECKPOINT("hash_map");
// test hash_map of objects
BOOST_STD_EXTENSION_NAMESPACE::hash_map<random_key, A> ahash_map;
@@ -150,7 +198,16 @@ int test_main( int /* argc */, char* /* argv */[] )
std::copy(ahash_map1.begin(), ahash_map1.end(), std::back_inserter(tvec1));
std::sort(tvec1.begin(), tvec1.end());
BOOST_CHECK(tvec == tvec1);
std::remove(testfile);
#endif
}
void
test_hash_multimap(){
#ifdef BOOST_HAS_HASH
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
BOOST_CHECKPOINT("hash_multimap");
BOOST_STD_EXTENSION_NAMESPACE::hash_multimap<random_key, A> ahash_multimap;
ahash_multimap.insert(std::make_pair(random_key(), A()));
@@ -170,6 +227,7 @@ int test_main( int /* argc */, char* /* argv */[] )
// to implement the == operator for hash collections - but goes ahead
// does it anyway even though it doesn't seem to work. So sort into
// vectors and then compare.
std::vector< std::pair<random_key, A> > tvec, tvec1;
tvec.clear();
tvec1.clear();
std::copy(ahash_multimap.begin(), ahash_multimap.end(), std::back_inserter(tvec));
@@ -177,8 +235,16 @@ int test_main( int /* argc */, char* /* argv */[] )
std::copy(ahash_multimap1.begin(), ahash_multimap1.end(), std::back_inserter(tvec1));
std::sort(tvec1.begin(), tvec1.end());
BOOST_CHECK(tvec == tvec1);
#endif
std::remove(testfile);
#endif
}
int test_main( int /* argc */, char* /* argv */[] )
{
test_map();
test_map_2();
test_multimap();
test_hash_map();
test_hash_multimap();
return EXIT_SUCCESS;
}
+146 -2
View File
@@ -25,7 +25,7 @@ namespace std{
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/split_member.hpp>
// Someday, maybe all tests will be converted to the unit test framework.
// but for now use the text execution monitor to be consistent with all
@@ -161,7 +161,7 @@ public:
};
BOOST_TEST_DONT_PRINT_LOG_VALUE( E )
// check that moves don't move stuff pointed too
// check that moves don't move stuff pointed to
class F {
friend class boost::serialization::access;
E * m_eptr;
@@ -208,11 +208,155 @@ void test4(){
BOOST_CHECK_EQUAL(f, f1);
}
// check that multiple moves keep track of the correct target
class G {
friend class boost::serialization::access;
A m_a1;
A m_a2;
A *m_pa2;
template<class Archive>
void save(Archive &ar, const unsigned int file_version) const {
ar << m_a1;
ar << m_a2;
ar << m_pa2;
}
template<class Archive>
void load(Archive &ar, const unsigned int file_version){
A a; // temporary A
ar >> a;
m_a1 = a;
ar.reset_object_address(& m_a1, & a);
ar >> a;
m_a2 = a;
ar.reset_object_address(& m_a2, & a);
ar & m_pa2;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
public:
bool operator==(const G &rhs) const {
return
m_a1 == rhs.m_a1
&& m_a2 == rhs.m_a2
&& *m_pa2 == *rhs.m_pa2;
}
G & operator=(const G & rhs) {
m_a1 = rhs.m_a1;
m_a2 = rhs.m_a2;
m_pa2 = & m_a2;
return *this;
}
G(){
m_pa2 = & m_a2;
}
G(const G & rhs){
*this = rhs;
}
~G(){}
};
BOOST_TEST_DONT_PRINT_LOG_VALUE( G )
void test5(){
std::stringstream ss;
const G g;
{
boost::archive::text_oarchive oa(ss);
oa << g;
}
G g1;
{
boost::archive::text_iarchive ia(ss);
ia >> g1;
}
BOOST_CHECK_EQUAL(g, g1);
}
// joaquin's test - this tests the case where rest_object_address
// is applied to an item which in fact is not tracked so that
// the call is in fact superfluous.
struct foo
{
int x;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &,const unsigned int)
{
}
};
struct bar
{
foo f[2];
foo* pf[2];
private:
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
template<class Archive>
void save(Archive& ar,const unsigned int)const
{
for(int i=0;i<2;++i){
ar<<f[i].x;
ar<<f[i];
}
for(int j=0;j<2;++j){
ar<<pf[j];
}
}
template<class Archive>
void load(Archive& ar,const unsigned int)
{
for(int i=0;i<2;++i){
int x;
ar>>x;
f[i].x=x;
ar.reset_object_address(&f[i].x,&x);
ar>>f[i];
}
for(int j=0;j<2;++j){
ar>>pf[j];
}
}
};
int test6()
{
bar b;
b.f[0].x=0;
b.f[1].x=1;
b.pf[0]=&b.f[0];
b.pf[1]=&b.f[1];
std::ostringstream oss;
{
boost::archive::text_oarchive oa(oss);
oa<<const_cast<const bar&>(b);
}
bar b1;
b1.pf[0]=0;
b1.pf[1]=0;
std::istringstream iss(oss.str());
boost::archive::text_iarchive ia(iss);
ia>>b1;
BOOST_CHECK(b1.pf[0]==&b1.f[0]&&b1.pf[1]==&b1.f[1]);
return 0;
}
int test_main(int /* argc */, char * /* argv */[])
{
test1();
test2();
test3();
test4();
test5();
test6();
return EXIT_SUCCESS;
}
+5 -4
View File
@@ -19,13 +19,14 @@ namespace std{
#endif
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include "test_tools.hpp"
#include <boost/preprocessor/stringize.hpp>
#include BOOST_PP_STRINGIZE(BOOST_ARCHIVE_TEST)
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
// This is a simple class. It contains a counter of the number
@@ -48,7 +49,7 @@ public:
virtual ~A(){--count;} // default destructor
};
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(A)
//BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(A)
BOOST_SERIALIZATION_SHARED_PTR(A)
// B is a subclass of A
+1 -1
View File
@@ -82,8 +82,8 @@ public:
};
// B needs to be exported because its serialized via a base class pointer
//BOOST_CLASS_EXPORT(B)
BOOST_SHARED_POINTER_EXPORT(B)
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(B)
BOOST_SERIALIZATION_SHARED_PTR(B)
int A::count = 0;
+10
View File
@@ -91,4 +91,14 @@ namespace archive {
#include <boost/test/test_tools.hpp>
// the following is to ensure that when one of the libraries changes
// BJAM rebuilds and relinks the test.
/*
#include "text_archive.hpp"
#include "text_warchive.hpp"
#include "binary_archive.hpp"
#include "xml_archive.hpp"
#include "xml_warchive.hpp"
*/
#endif // BOOST_SERIALIZATION_TEST_TOOLS_HPP
File diff suppressed because it is too large Load Diff
+12 -6
View File
@@ -43,7 +43,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization-vc71-mt-gd-1_33.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-mt-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -96,7 +96,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-mt-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -147,7 +147,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-s-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -198,7 +198,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-mt-s-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -251,7 +251,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-s-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -304,7 +304,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_serialization.lib"/>
OutputFile="$(OutDir)/libboost_serialization-vc71-mt-s-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -446,6 +446,9 @@
<File
RelativePath="..\..\..\boost\serialization\detail\shared_ptr_132.hpp">
</File>
<File
RelativePath="..\..\..\boost\serialization\detail\stack_constructor.hpp">
</File>
</Filter>
</Filter>
<Filter
@@ -615,6 +618,9 @@
<File
RelativePath="..\..\..\boost\serialization\void_cast.hpp">
</File>
<File
RelativePath="..\..\..\boost\serialization\void_cast_fwd.hpp">
</File>
<File
RelativePath="..\..\..\boost\archive\wcslen.hpp">
</File>
+6 -6
View File
@@ -43,7 +43,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization-vc71-mt-gd-1_32.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-mt-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -96,7 +96,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-mt-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -147,7 +147,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-mt-s-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -199,7 +199,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-s-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -252,7 +252,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-mt-s-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -303,7 +303,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libboost_wserialization.lib"/>
OutputFile="$(OutDir)/libboost_wserialization-vc71-s-gd-1_33_1.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool