Compare commits

..

1 Commits

Author SHA1 Message Date
Ronald Garcia 96fe06322f Created a branch from trunk
[SVN r38959]
2007-08-26 05:34:35 +00:00
501 changed files with 19577 additions and 36569 deletions
+3
View File
@@ -0,0 +1,3 @@
This file is used by the project manager only and should be treated like the project file
+147
View File
@@ -0,0 +1,147 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.06.00"/>
<PROJECT value="test_simple_class.exe"/>
<OBJFILES value="..\test\test_simple_class.obj"/>
<RESFILES value="test_simple_class.res"/>
<IDLFILES value=""/>
<IDLGENFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value="..\..\..\bin\boost\libs\serialization\build\libboost_serialization.lib\borland\debug\runtime-link-static\libboost_serialization.lib
..\..\..\bin\boost\libs\serialization\build\libboost_wserialization.lib\borland\debug\runtime-link-static\libboost_wserialization.lib
..\..\..\bin\boost\libs\test\build\libboost_test_exec_monitor.lib\borland\debug\runtime-link-static\libboost_test_exec_monitor.lib"/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="vcl.bpi rtl.bpi dbrtl.bpi adortl.bpi vcldb.bpi vclx.bpi bdertl.bpi
vcldbx.bpi ibxpress.bpi dsnap.bpi cds.bpi bdecds.bpi qrpt.bpi teeui.bpi
teedb.bpi tee.bpi dss.bpi teeqr.bpi visualclx.bpi visualdbclx.bpi
dsnapcrba.bpi dsnapcon.bpi bcbsmp.bpi vclie.bpi xmlrtl.bpi inet.bpi
inetdbbde.bpi inetdbxpress.bpi inetdb.bpi nmfast.bpi webdsnap.bpi
bcbie.bpi websnap.bpi soaprtl.bpi dclocx.bpi dbexpress.bpi dbxcds.bpi
indy.bpi bcb2kaxserver.bpi"/>
<PATHCPP value=".;..\test"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="ilink32"/>
<USERDEFINES value="_DEBUG;BOOST_ARCHIVE_TEST=xml_warchive.hpp"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;USEPACKAGES"/>
<MAINSOURCE value="test_simple_class.bpf"/>
<INCLUDEPATH value="..\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="..\test;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
<OTHERFILES value=""/>
</MACROS>
<OPTIONS>
<IDLCFLAGS value="-I..\test -IC:\boost_1_31_0 -I$(BCB)\include -I$(BCB)\include\vcl
-src_suffix cpp -D_DEBUG -DBOOST_ARCHIVE_TEST=xml_warchive.hpp -boa"/>
<CFLAG1 value="-Od -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi- -tWC -tWM -c"/>
<PFLAGS value="-$YD -$W -$O- -$A8 -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-D&quot;&quot; -ap -Tpe -x -Gn -v"/>
<OTHERFILES value=""/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mt.lib"/>
<OTHERFILES value=""/>
</LINKER>
<FILELIST>
<FILE FILENAME="test_simple_class.res" FORMNAME="" UNITNAME="test_simple_class.res" CONTAINERID="ResTool" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="test_simple_class.bpf" FORMNAME="" UNITNAME="test_simple_class" CONTAINERID="BPF" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="..\test\test_simple_class.cpp" FORMNAME="" UNITNAME="test_simple_class" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="..\..\..\bin\boost\libs\serialization\build\libboost_serialization.lib\borland\debug\runtime-link-static\libboost_serialization.lib" FORMNAME="" UNITNAME="libboost_serialization.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="..\..\..\bin\boost\libs\serialization\build\libboost_wserialization.lib\borland\debug\runtime-link-static\libboost_wserialization.lib" FORMNAME="" UNITNAME="libboost_wserialization.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="..\..\..\bin\boost\libs\test\build\libboost_test_exec_monitor.lib\borland\debug\runtime-link-static\libboost_test_exec_monitor.lib" FORMNAME="" UNITNAME="libboost_test_exec_monitor.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
</FILELIST>
<BUILDTOOLS>
</BUILDTOOLS>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1033
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlIncludePath]
Count=5
Item0=..\test;C:\boost_1_31_0\libs\serialization\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl
Item1=C:\boost_1_31_0\libs\serialization\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl
Item2=C:\boost_1_31_0\libs;C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
Item3=C:\boost_1_31_0\libs\;C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
Item4=C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
[HistoryLists\hlLibraryPath]
Count=2
Item0=..\test;C:\boost_1_31_0\libs\serialization\test;$(BCB)\lib\obj;$(BCB)\lib
Item1=C:\boost_1_31_0\libs\serialization\test;$(BCB)\lib\obj;$(BCB)\lib
[HistoryLists\hlDebugSourcePath]
Count=1
Item0=$(BCB)\source\vcl
[HistoryLists\hlConditionals]
Count=2
Item0=_DEBUG;BOOST_ARCHIVE_TEST=xml_warchive.hpp
Item1=_DEBUG
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
Launcher=
UseLauncher=0
DebugCWD=
HostApplication=
RemoteHost=
RemotePath=
RemoteLauncher=
RemoteCWD=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=1
LinkCGLIB=0
[CORBA]
AddServerUnit=1
AddClientUnit=1
PrecompiledHeaders=1
[Language]
ActiveLang=
ProjectLang=
RootDir=
</IDEOPTIONS>
</PROJECT>
Binary file not shown.
+28 -48
View File
@@ -8,46 +8,28 @@
project boost/serialization
: source-location ../src
: requirements <dependency>../../config/test/all//BOOST_NO_STD_LOCALE
<conditional>@include-spirit
;
;
SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
rule include-spirit ( properties * )
{
local old-compiler ;
if <toolset>borland in $(properties)
{
old-compiler = true ;
}
else if <toolset>msvc in $(properties)
{
if <toolset-msvc:version>6.5 in $(properties)
|| <toolset-msvc:version>7.0 in $(properties)
{
old-compiler = true ;
}
}
local result ;
if $(old-compiler)
{
if $(SPIRIT_ROOT)
{
# note - we can't use <include>$(SPIRIT_ROOT) because
# it puts -I$(SPIRIT_ROOT) AFTER the "../../.." in the command line.
# so use these instead
result = <cxxflags>-I$(SPIRIT_ROOT) ;
local SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
for local tset in borland { # vc iw
if ( <toolset>$(tset) in $(properties) ) {
if ( $(SPIRIT_ROOT) ) {
result = <cxxflags>-I$(SPIRIT_ROOT) ;
}
else {
echo **** spirit 1.6x required to build library with this compiler **** ;
result = <build>no ;
}
}
else
{
echo **** spirit 1.6x required to build library with this compiler **** ;
result = <build>no ;
}
}
}
return $(result) ;
}
SOURCES =
basic_archive
basic_iarchive
@@ -62,9 +44,10 @@ SOURCES =
basic_xml_archive
binary_iarchive
binary_oarchive
codecvt_null
extended_type_info
extended_type_info_typeid
extended_type_info_no_rtti
extended_type_info_typeid
polymorphic_iarchive
polymorphic_oarchive
stl_port
@@ -79,29 +62,26 @@ SOURCES =
WSOURCES =
basic_text_wiprimitive
basic_text_woprimitive
binary_wiarchive
binary_woarchive
text_wiarchive
text_woarchive
utf8_codecvt_facet
xml_wgrammar
xml_wiarchive
xml_woarchive
codecvt_null
;
lib boost_serialization
: $(SOURCES).cpp
:
<toolset>msvc:<cxxflags>/Gy
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
: $(SOURCES).cpp
: <toolset>msvc:<cxxflags>/Gy
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
<conditional>@include-spirit
;
lib boost_wserialization
: $(WSOURCES).cpp boost_serialization
:
<toolset>msvc:<cxxflags>/Gy
<dependency>../../config/test/all//BOOST_NO_STD_WSTREAMBUF
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
boost-install boost_serialization boost_wserialization ;
: $(WSOURCES).cpp boost_serialization
: <toolset>msvc:<cxxflags>/Gy
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
<conditional>@include-spirit
;
+126
View File
@@ -0,0 +1,126 @@
# Boost serialization Library Build Jamfile
# (C) Copyright Robert Ramey 2002-2004.
# Use, modification, and distribution are 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/libs/serialization for the library home page.
# building this library needs a working version of spirit
rule toolset::require-boost-spirit-support ( toolset variant : subvariant-path properties * )
{
local requires-spirit = false ;
switch $(toolset) {
case "borland*" :
requires-spirit = true ;
case "msvc*" :
requires-spirit = true ;
case "iw*" :
requires-spirit = true ;
case "vc-6*" :
requires-spirit = true ;
case "vc7*" :
requires-spirit = true ;
case "vc-7_0*" :
requires-spirit = true ;
case "gcc-2*" :
requires-spirit = true ;
}
if $(requires-spirit) = true {
if $(SPIRIT_ROOT) # && ( exist $(SPIRIT_ROOT) )
{
properties += <include>$(SPIRIT_ROOT) ;
}
else {
echo **** spirit 1.6x required to build library with this compiler **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
}
}
return $(subvariant-path) $(properties) ;
}
# certain tool sets are known apriori not to support wide char i/o
rule toolset::require-wide-char-io-support ( toolset variant : subvariant-path properties * )
{
switch $(toolset) {
case "*cygwin" :
echo **** wide char i/o not supported by cygwin gcc library **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "como*" :
echo **** wide char i/o not supported by libcomo standard library **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "mingw*" :
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) ;
}
# certain tool sets are known apriori not to support creation of DLLS
rule toolset::require-shared-libraries-support ( toolset variant : subvariant-path properties * )
{
switch $(toolset) {
case "como*" :
echo **** DLLs cannot be built with this compiler **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "msvc-stlport*" :
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "vc-6_5-stlport*" :
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
case "cw*" :
local runtime-link = [ get-values <runtime-link> : $(properties) ] ;
if static in $(runtime-link) {
echo **** DLLS cannot be built with static runtime linking **** ;
properties = [ impose-requirements $(properties) : <build>no ] ;
}
}
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" ] ;
case "gcc*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
case "qcc*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
case "QCC*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
case "mingw*" :
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
}
return $(subvariant-path) $(properties) ;
}
+7 -7
View File
@@ -30,27 +30,27 @@ http://www.boost.org/LICENSE_1_0.txt)
<li>David Abrahams improved implementation of "export" functionality. This not
only eliminated an annoying header sequencing requirement, but also the need to maintain
a list of "known archives".
<li>Mattias Troyer enhanced the implementation of native binary archives. This includes
<li>Mattias Troyer ehnanced the implementation of native binary archives. This includes
enhancement and generalization of the library itself including generalization of
the wrapper concept.
<li>Markus Sch&ouml;pflin tracked down issues with TRU64 compiler resulting in 100% passing.
<li>Markus Schöpflin tracked down issues with TRU64 compiler resulting in 100% passing.
<li><a href="mailto::troy@resophonic.com"> Troy D. Straszheim</a> made the initial version of variant serialization.
<li>Tonko Juricic helped refine and complete project files for VC 7.1 ide
<li><a href="http://www.boost.org/people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
<li><a href="../../../people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
Code Warrior, toolset configuration and bjam and much else.
<li>Martin Ecker detected (and fixed!) a number of sublte errors regarding cyclic
pointers, shared pointers. He also built the library as a DLL and raised some issues
<li>Pavel Vozenilek invested much effort in review of code and documentation
resulting in many improvements. In addition he help a lot with porting to other
platforms including VC 6.0, Intel, and especially Borland.
<li><a href="http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a> and
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> who got the boost
<li><a href="../../../people/jens_maurer.htm">Jens Maurer</a> and
<a href="../../../people/beman_dawes.html">Beman Dawes</a> who got the boost
serialization ball rolling. It was one or both of these two that invented
the much beloved <code>&amp;</code> syntax used to implement both save and
load in one fuction specification.
<li><a href="http://www.boost.org/people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
<li><a href="../../../people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
early draft and contributing the diamond inheritance example.
<li><a href="http://www.boost.org/people/william_kempf.htm">William E. Kempf</a>
<li><a href="../../../people/william_kempf.htm">William E. Kempf</a>
who made the templates for this and other boost manuals. This relieved
me of much aggravation.
<li><a href="mailto:vahan@unicad.am">Vahan Margaryan</a> and
+28 -37
View File
@@ -34,41 +34,30 @@ http://www.boost.org/LICENSE_1_0.txt)
<h3><a name="implementation">Implementation</a></h3>
The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
class must implement to in order to be used to serialize
<a href="serialization.html"><strong>Serializable</strong></a> types.
<a href="serialization.html"><strong>Serializable</strong></a> types.
The library implements a family of archives appropriate for different purposes.
This section describes how they have been implemented and one way one
can implement his own archive class.
This section describes how they have been implemented and how one can implement his own archive class.
Our discussion will focus on archives used for loading as the hierarchy is exactly analogous
for archives used for saving data.
<p>
Our archives have been factored in to a tree of classes in order to minimize
repetition of code. This is shown in the accompanying
<a target="class_diagram" href="class_diagram.html">class diagram</a>.
Any class which fullfills the following requirements will function as
a loading archive.
<h4>Minimum Requirments</h4>
The archive class is derived from:
All input archives should be derived from the following template:
<pre><code>
template&lt;class Archive&gt;
detail::common_iarchive;
</code></pre>
<h4>Minimum Requirments</h4>
An instance of the this template handles all the "bookkeeping" associated
with serialization. In order to be a functional only the following additional
functions <strong>must</strong> be declared:
functions <strong>must</strong> be defined:
<dl>
<dt><h4><code>void load(T &t);</code></h4></dt>
<dd>
This function must be implemented for all primitive data types. This can be
accomplished through the use of a member template or explicit declarations
for all primitive types.
accomplished through the use of a member template or explict declarations
for all prmititive types.
</dd>
<dt><h4><code>void load_binary(void *address, std::size_t size);</code></h4></dt>
@@ -92,12 +81,13 @@ So, the most trivial implementation of an input archive would look like this:
<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
#include &lt;boost/archive/detail/common_iarchive.hpp&gt;
</a>
/////////////////////////////////////////////////////////////////////////
// class trivial_iarchive - read serialized objects from a input text stream
class trivial_iarchive :
public boost::archive::detail::common_iarchive&lt;trivial_iarchive&gt;
{
// permit serialization system privileged access to permit
// permit serialization system priviledged access to permit
// implementation of inline templates for maximum speed.
friend class boost::archive::load_access;
@@ -153,7 +143,7 @@ by XML archive to inject "&lt;/name&gt;" after data.
<dd>
<strong>Default</strong>:Does nothing.<br>
<strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
It's not called when archive book keeping data is saved. This is used by XML archives
Its not called when archive book keeping data is saved. This is used by XML archives
to determine when to inject a "&gt;" character at end of XML header. XML output archives
keep their own internal flag indicating that data being written is header data. This
internal flag is reset when an object start tag is written. When
@@ -236,9 +226,7 @@ One or more of the following issues may need to be addressed:
all data objects.
<li>Addressing any of the above may generate more issues to be addressed.
<li>The archives included with library are all templates which use a
<code style="white-space: normal">stream</code> or
<code style="white-space: normal">streambuf</code>
as a template parameter rather than simple classes.
<code style="white-space: normal">stream</code> as a template parameter rather than simple classes.
Combined with the above, even more issues arise with non-conforming compilers.
</ul>
The attached <a target="class_diagram" href="class_diagram.html">class diagram</a>
@@ -253,15 +241,17 @@ EXCEPT for one special case.
<ul>
<li>Instances of a derived class are serialized through a base class pointer.
<li>Such instances are not "registered" neither implicitly nor explicitly. That
is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used
to instantiate the serialization code for the included archives.
is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used to instantiate the serialization
code for the included archives.
</ul>
To make this work, the following should be included after the archive
class definition.
The problem here is that BOOT_CLASS_EXPORT only generates code for those archives
included with the library - not those added subsequently. To generate code for
newly created archive classes, the following should be used.
<pre><code>
#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES trivial_oarchive
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES trivial_iarchive
</code></pre>
before <code style="white-space: normal">BOOST_CLASS_EXPORT</code> is invoked for any serializable class.
Failure to do this will not inhibit the program from compiling, linking
and executing properly - except in one case. If an instance of a derived
class is serialized through a pointer to its base class, the program
@@ -269,7 +259,8 @@ will throw an
<a href="exceptions.html#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
exception.
<p>
Only one of the above statements is permitted, However, any number of new archive
classes can be specified as list separated by commas.
<h4><a name="testing">Testing</h4>
Exhaustive testing of the library requires testing the different aspects of object
@@ -311,16 +302,16 @@ typedef std::ifstream test_istream;
#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
</code></pre>
To test a new archive, for example, portable binary archives, with the gcc compiler,
make a header file <code style="white-space: normal">portable_binary_archive.hpp</code>
To test a new archive, for example, portable binary archives, make a
header file <code style="white-space: normal">portable_binary_archive.hpp</code>
and invoke <code style="white-space: normal">bjam</code> with
<pre><code>
-sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
</code></pre>
This process in encapsulated in the shell or cmd script
<code style="white-space: normal">library_test</code> whose command line is
This process in encapsulated in the shell script
<code style="white-space: normal">run_archive_test</code> whose command line is
<pre><code>
library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
run_archive_test &lt;test header file&gt; &lt;toolset&gt; [&lt;boost root&gt;] [&lt;target directory&gt;]
</code></pre>
<h3><a name="polymorphic">Polymorphic Archives</a></h3>
@@ -376,9 +367,9 @@ As can be seen in the
and the header files, this implementation is just a composition of the polymorphic
interface and the standard template driven implementation. This composition is
accomplished by the templates
<a target=polymorphic_iarchive_route_hpp href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp"><code style="white-space: normal">polymorphic_iarchive_route.hpp</code></a>
<a target=polymorphic_iarchive_dispatch_hpp href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_iarchive_dispatch.hpp</code></a>
and
<a target=polymorphic_oarchive_route_hpp href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp"><code style="white-space: normal">polymorphic_oarchive_route.hpp</code></a>.
<a target=polymorphic_oarchive_dispatch_hpp href="../../../boost/archive/detail/polymorphic_oarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_oarchive_dispatch.hpp</code></a>.
As these contain no code specific to the particular implementation archive, they can be used to create
a polymorphic archive implementation from any functioning templated archive implementation.
<p>
+11 -11
View File
@@ -41,14 +41,14 @@ In the following descriptions
<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
corresponding to an arbitrary set of C++ data structures. Each type modeling the
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 that is equivalent to the original.
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 are rendered <a href="serialization.html">serializable</a>.
way the data is are rendered <a href="serialization.html">serializable</a>.
<p>
<h4>Valid Expressions</h4>
<dl>
@@ -190,8 +190,8 @@ equivalent to the original.
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 permits the
archive to properly implement object tracking. Object tracking is required in order
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>
@@ -215,7 +215,7 @@ archives is discussed in
<p>
The existence of the <code style="white-space: normal">&lt;&lt;</code>
and <code style="white-space: normal">&gt;&gt;</code> suggests
and <code style="white-space: normal">&gt;&gt;</code> suggest
a relationship between archives and C++ i/o streams. <strong>Archives are not
C++ i/o streams</strong>. All the archives included with this system take a stream
as an argument in the constructor and that stream is used for output or input.
@@ -224,7 +224,7 @@ archive interface. It just turns out that the archives written so far have
found it useful to base their implementation on streams.
<h3><a name="archive_models">Archive Models</a></h3>
This library includes various implementations of the Archive concept.
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.
@@ -307,7 +307,7 @@ public:
text_oarchive(std::ostream & os, unsigned int flags = 0);
</code></h4></dt>
<dd>
Constructs an archive given an open <code style="white-space: normal">stream</code> as
Contructs an archive given an open <code style="white-space: normal">stream</code> as
an argument and optional flags. For most applications there will be no need to use flags.
Flags are defined by <code style="white-space: normal">enum archive_flags</code> enumerator.
Multiple flags can be combined with the <code style="white-space: normal">|</code> operator.
@@ -339,7 +339,7 @@ tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
<dd>
Destructor for an archive. This should be called before the stream is
closed. It restores any altered stream facets to their state before the
archive was opened.
the archive was opened.
</dd>
</dl>
@@ -402,12 +402,12 @@ binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
<h3><a name="exceptions">Exceptions</h3>
All of the archive classes included may throw exceptions. The list of exceptions that might
be thrown can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
be throw can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
of this documentation.
<h3><a name="charactersets">Character Sets</h3>
This library includes two archive classes for XML. The wide character
version (<code style="white-space: normal">xml_w?archive</code>) renders its output as UTF-8 which can
version (<code style="white-space: normal">xml_w?archive</code>) renders it output as UTF-8 which can
handle any wide character without loss of information.
<code style="white-space: normal">std::string</code> data is converted from multi-byte format to wide
character format using the current <code style="white-space: normal">
+7 -7
View File
@@ -52,14 +52,14 @@ common_iarchive&lt;text_iarchive&gt; <a href="../../../boost/archive/detail/comm
| / |
| / |
| / |
<font color="blue">text_iarchive_impl&lt;text_iarchive&gt;</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_impl <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
<font color="blue">text_iarchive_impl&lt;text_iarchive&gt;</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
| \ |
| \ |
| \_____________________________________ <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
| \_____________________________________ |
| \ /
| \ /
| \ /
<font color="red">text_iarchive</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt; <a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">-></a>
<font color="red">text_iarchive</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_dispatch&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt; <a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">-></a>
|
|
|
@@ -68,7 +68,7 @@ common_iarchive&lt;text_iarchive&gt; <a href="../../../boost/archive/detail/comm
</code></pre>
This diagram shows the relationship between the various classes that implement loading (input
serialization) for text files. The hierachy and organization is similar for saving and for
serialization) for text files. The hierachy and organization is identical for saving and for
other types of archives as well. In the diagram, classes written in <font color="blue">blue</font>
implement loading for a given archive type. (in this case its text archives).
Users include classes in <font color="red">red</font> to load their data from a partcular
@@ -146,11 +146,11 @@ never change. They are in <code>namespace boost::archive::detail</code>
for all archives present and future.
<p><dt><code>
<a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</a>
<a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">polymorphic_iarchive_dispatch&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</a>
</code></dt>
<dd><p>
This class implements the <code style="white-space: normal">polymorphic_iarchive</code> in terms of a specific
concrete class. Virtual function calls are routed to the implementing class. In this example,
concrete class. Virtual function calls are forwarded to the implementing class. In this example,
that implementing class would be text_iarchive_impl.
<p><dt><code>
@@ -158,7 +158,7 @@ never change. They are in <code>namespace boost::archive::detail</code>
</code></dt>
<dd>
this is just a typedef so we can write polymorphic_text_archive rather than
<code style="white-space: normal">polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</code>
<code style="white-space: normal">polymorphic_iarchive_dispatch&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</code>
</dl>
<hr>
+1 -1
View File
@@ -28,7 +28,7 @@ width="277" height="86"> <br clear="all">
<a name="sec:utf8-codecvt-facet-class"></a>
<h1><code>utf8_codecvt_facet</code></h1>
<h1>UTF-8 Codecvt Facet</h1>
<pre>
+6 -35
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 .
@@ -87,10 +87,9 @@ function initialize() {
<dt><img style="display:none" src="plus.gif" id="release_notes"><a target="detail" href="release.html">Release Notes</a></dt>
<dd><div id="release_notes_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#requirements">Requirements</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_35">Differences from version 1.35</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_34">Differences from version 1.34</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_32">Differences from version 1.32</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_33">Differences from version 1.33</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_34">Differences from version 1.34</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#todo">Pending Issues</a></dt>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="overview"><a target="detail" href="overview.html">Overview</a></dt>
@@ -149,7 +148,6 @@ function initialize() {
<dt><img style="display:none" src="plus.gif" id="derivedpointers"><a target="detail" href="serialization.html#derivedpointers">Pointers to Objects of Derived Classes</a>
<dd><div id="derivedpointers_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#registration">Registration</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#export">Export</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#instantiation">Instantiation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#selectivetracking">Selective Tracking</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#runtimecasting">Runtime Casting</a>
@@ -181,6 +179,7 @@ function initialize() {
<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#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">
@@ -189,9 +188,7 @@ function initialize() {
</dl></div></dd>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#binary_archives">Binary Archives</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#xml_archives">XML Archives</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#dlls">DLLS - Serialization and Runtime Linking</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#plugins">Plugins</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#multi_threading">Multi-Threading</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#optimizations">Optimzations</a>
<dt><img style="display:none" src="plus.gif" id="exceptions"><a target="detail" href="exceptions.html">Archive Exceptions</a>
@@ -265,8 +262,8 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="pimpl.html">PIMPL</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="otherclasses">Other Classes
<dd><div id="otherclasses_detail"><dl class="page-index">
<dt><img style="display:none" src="plus.gif" id="miscellaneous">Miscellaneous
<dd><div id="miscellaneous_detail"><dl class="page-index">
<dt><img style="display:none" src="plus.gif" id="extended_type_info"><a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
<dd><div id="extended_type_info_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#motivation">Motivation</a>
@@ -275,21 +272,12 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
</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"><code>utf8_codecvt_facet</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>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
<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>
<dt><img style="display:none" src="plus.gif" id="singleton"><a target="detail" href="singleton.html"><code>singleton</code></a>
<dd><div id="singleton_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#motivation">Motivation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#features">Features</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#classinterface">Class Interface</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#requirements">Requirements</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#examples">Examples</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#multithreading">Multi-Threading</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>
@@ -301,23 +289,6 @@ function initialize() {
<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></div></dd>
<dt><img style="display:none" src="plus.gif" id="todo"><a target="detail" href="todo.html">To Do</a></dt>
<dd><div id="todo_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#portablebinaryarchive">Portable Binary Archive</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#performancetesting">Performance Testing and Profiling</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#backversioning">Back Versioning</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#nortti">Environments without RTTI</a></dt>
<dt><img style="display:none" src="plus.gif" id="newcasestudies"><a target="detail" href="new_case_studies.html">Proposed Case Studies</a></dt>
<dd><div id="newcasestudies_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#functionobject">Serializing a Function Object</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archiveadaptor">Archive Adaptors</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archivehelper">Archive Helpers</a></dt>
</dl></div></dd>
</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>
+2 -3
View File
@@ -43,9 +43,8 @@ http://www.boost.org/LICENSE_1_0.txt)
Archive operators can throw a <code style="white-space: normal">boost::archive_exception</code>
object which can be caught by an application program. These exceptions are defined
in the files <a target="archive_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
archive_exception.hpp</a>
and <a target="basic_xml_archive_hpp" href="../../../boost/archive/basic_xml_archive.hpp">
basic_xml_archive.hpp</a>.
boost/archive/archive_exception.hpp</a> and <a target="archive_xml_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
boost/archive/archive_xml_exception.hpp</a>.
<pre><code>
namespace boost {
namespace archive {
+125 -120
View File
@@ -33,6 +33,7 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#example">Example</a>
</dl>
<h3><a name="motivation">Motivation</a></h3>
The serialization library needs a system like
<code style="white-space: normal">type_info/typeid()</code> to perform
@@ -61,6 +62,11 @@ the following functions
different applications. In fact, including different headers in different
name spaces is an accepted method used to avoid name space conflicts.
Thus the namespace::class_name can't be used as a key.
<li>
We may want the ability to serialize objects through a base class even though
they have no <code style="white-space: normal">virtual</code> function. That
is, objects of classes which are not polymorphic in the strict C++ sense. This
is not supported by the standard system.
<li>
There exists the possibility that different classes use different type id
mechanism. The class header might include this information. If we want to
@@ -68,86 +74,97 @@ the following functions
mechanism support inter-operability accross different type id systems.
</ul>
<h3>Features</h3>
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
extended_type_info</a></code> is an implementation
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> is an implementation
of <code style="white-space: normal">std::type_info</code> functionality with the
following features:
<ul>
<li>
Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
<code style="white-space: normal">extended_type_info</a></code> records - one for each type
serialized.
Maintains a global table of <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> records - one for each type known
to the program.
<li>
permits association of an arbitrary string key with a type. Often this key would
permits association of an arbitrary key with a type. Often this key would
be the class name - but it doesn't have to be. This key is referred to as
a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe.
Typically this GUID would be in header files and be used to match type accross
applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string
key with any known type. We'll refer to these types as "exported types"
applications.
<li>
permits the "mixing" of type info systems. For example, one class might use
<code style="white-space: normal">typeid()</code> to find the external identifier
of a class while another might not.
</ul>
Exported types are maintained in a global table so that given a string key, the
corresponding type can be found. This facility is used by the serialization library
in order to construct types serialized through a base class pointer.
The serialization system maintains two global tables.
<ul>
<li>The first is a global type table. it has an entry for each type used.
Each entry is an instance of a class derived from
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>. This table is used
to retrieve the unique <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
information for any given type.
<li>The second is global key table. It has an entry for each type which has been assigned a GUID string key.
This table is used to retrieve the unique
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> given its GUID.
</ul>
This library includes two different type id systems:
<ul>
<li>
<code style="white-space: normal"><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">extended_type_info_typeid</a></code>
which is implemented in terms of the standard
<code style="white-space: normal">typeid()</code>.
<li>
<code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">extended_type_info_no_rtti</a></code>
which is implemented in a way that doesn't rely on the existence
RTTI. However, it does require that all classes for which type id is to be used
be explictly assigned an external key - which otherwise would be optional.
</ul>
<h3><a name="runtime">Runtime Interface</a></h3>
<pre><code">
namespace boost {
namespace serialization {
class extended_type_info
class BOOST_SERIALIZATION_DECL extended_type_info :
private boost::noncopyable
{
protected:
// this class can't be used as is. It's just the
// common functionality for all type_info replacement
// systems. Hence, make these protected
const char * m_key;
extended_type_info(const unsigned int type_info_key);
~extended_type_info();
extended_type_info(const char * type_info_key);
public:
void self_register();
void key_register(const char *key);
const char * get_key() const {
return m_key;
}
const char * get_key() const;
bool operator<(const extended_type_info &rhs) const;
bool operator==(const extended_type_info &rhs) const;
bool operator!=(const extended_type_info &rhs) const {
return !(operator==(rhs));
}
// for plugins
virtual void * construct(unsigned int count = 0, ...) const;
virtual void destroy(void const * const p) const;
bool operator!=(const extended_type_info &rhs) const;
static const extended_type_info * find(const char *key);
static const extended_type_info * find(const extended_type_info * t);
};
} // namespace serialization
} // namespace boost
</code></pre>
<p>
Generally, there will be one and only one
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
instance created for each type. However, this is enforced only at the executable
module level. That is, if a program includes some shared libraries or DLLS,
there may be more than one instance of this class correponding to a particular type.
For this reason the comparison functions below can't just compare the addresses of
this instance but rather must be programmed to compare the the actual information
the instances contain.
There must be one and only one <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
instance created for each type. For this reason, this class is marked is derived from
<code style="white-space: normal">boost::noncopyable</code>.
<dl>
<dt><h4><pre><code>
extended_type_info(unsigned int type_info_key);
extended_type_info(const char * type_info_key);</code></pre></h4></dt>
<dd>
This constructor should be called by all derived classes. It should be passed
a pointer to a const string which identifies the type id system being used. This
type id is used to distinguish among the various type id system that might be used
and allow them to interoperate.
</dd>
<dt><h4><pre><code>
void self_register();
</code></pre></h4></dt>
<dd>
This constructor should be called by all derived classes.
The argument should be the particular implementation. For
this default implementation base on typeid(), this is the
value 1. Each system must have its own integer. This value
is used to permit the inter-operability of different typeinfo
systems.
This function adds entry for an entry to the global type table. It would usually be
called from the constructor of the derived class which implements the
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> functionality.
</dd>
<dt><h4><pre><code>
@@ -163,8 +180,6 @@ For this purpose, it must be the same in all program instances which
refer to the same type.
<p>
It may sometimes be referred to as a GUID - a <b>G</b>lobal <b>U</b>nique <b>ID</b>entifier.
</dd>
<dt><h4><pre><code>
const char *get_key() const;
</code></pre></h4></dt>
@@ -174,93 +189,58 @@ instance. If no key has been associated with the instance, then a NULL is retur
</dd>
<dt><h4><pre><code>
bool operator<(const extended_type_info & rhs) const;
bool operator==(const extended_type_info & rhs) const;
bool operator!=(const extended_type_info & rhs) const;
bool operator&lt;(const extended_type_info &rhs) const;
bool operator==(const extended_type_info &rhs) const;
bool operator!=(const extended_type_info &rhs) const;
</code></pre></h4></dt>
<dd>
These functions are used to compare two
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
<code style="white-space: normal">
extended_type_info
</code>
</a>
objects. They a strict total ordering on all instances of this class.
</dd>
<dt><h4><pre><code>
virtual void * construct(unsigned int count = 0, ...) const;
</code></pre></h4></dt>
<dd>
Construct a new instance of the type to which this
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
<code style="white-space: normal">
extended_type_info
</code>
</a>
record corresponds. This function takes variable list of up to 4 arguments
of any type. These arguments are passed to the type's constructor
at runtime. In order to use the facility,
one must declare a type sequence for the constructor arguments.
Arguments for this function must match in number and type
with those specified when the type was exported.
This function permits one to create instances of
any exported type given only the exported <strong>GUID</strong> assigned
with BOOST_CLASS_EXPORT.
If these types are defined in DLLS or shared libraries. When these modules
are loaded at runtime, these constructor can be called until the module
is unloaded. These modules are referred to as <b>plugin</b>.
</code>
</dd>
<dt><h4><pre><code>
virtual void destroy(void const * const p) const;
</code></pre></h4></dt>
<dd>
Destroy an instance created by the above constructor.
</dd>
These functions are used to compare two <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> objects.
Among other things, these are used for lookup in the tables.
<dt><h4><pre><code>
static const extended_type_info * find(const char *key);
</code></pre></h4></dt>
<dd>
Given a character string key or <strong>GUID</strong>, return the address of a
corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
Given a character string key or <strong>GUID</strong>, return the address of the
unique corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
object.
<dt><h4><pre><code>
static const extended_type_info * find(const extended_type_info * t);
</code></pre></h4></dt>
<dd>
Given a pointer to an
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>,
return the address of the instance of the same type in the main table.
That is the argument t is used as a search argment to find the main
table entry for a given type. It would be used like this:
<code><pre>
// return the global type entry for our type T
return find(some_extended_type_info_implementation&lt;T&gt;())
</pre></code>
</dl>
<h3><a name="requirements">Requirements</a></h3>
In order to be used by the serialization library, an implementation of
<code style="white-space: normal">extended_type_info</code>,
(referred to as ETI here), must be derived from
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
<code style="white-space: normal">
extended_type_info
</code>
</a>
and also implement the following:
(referred to as ETI here), must implement the following:
<dl>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
static extended_type_info &
ETI::get_mutable_instance();
static const extended_type_info &
ETI::get_const:instance();
virtual bool
ETI::less_than(const extended_type_info &rhs) const;
</pre></code></h4></dt>
<dd>
Return a pointer to the instance of
<code style="white-space: normal">extended_type_info</code>
which corresponds to type T. Normally these instances are static objects so
this just amounts to returning the address of this static object.
Impose a strict total ordering on all instances of the class ETI.
</dd>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
const extended_type_info *
ETI::get_derived_extended_type_info(const T & t) const;
static const extended_type_info *
ETI::get_derived_extended_type_info(const T & t);
</pre></code></h4></dt>
<dd>
Return a pointer to the
@@ -270,16 +250,45 @@ the "true type" of the type T. The "true type" is the lowest type in the
hierarchy of classes. The type T can always be cast to the "true type" with
a static cast. Implemention of this function will vary among type id systems
and sometimes will make presumptions about the type T than can be identified
with a particular <code style="white-space: normal">extended_type_info</code> implementation.
with a particular <code style="white-space: normal">extended_type_info implementation</code>.
</dd>
<dt><h4><code style="white-space: normal"><pre>
bool ETI::less_than(const extended_type_info &rhs) const;
template&lt;class ETI&gt;
static extended_type_info *
ETI::get_instance();
</pre></code></h4></dt>
<dd>
Compare this instance to another one using the same
<code style="white-space: normal">extended_type_info</code> implementation.
Return a pointer to the instance of
<code style="white-space: normal">extended_type_info</code>
which corresponds to type T. Normally these instances are static objects so
this just amounts to returning the address of this static object.
</dd>
<dt><h4><code style="white-space: normal"><pre>
static void
template&lt;class ETI&gt;
ETI::export_register(const char * key);
</pre></code></h4></dt>
<dd>
The main function is to invoke key_register to add the GUID to the
global table. Depending on the type id system being used, it might
perform other initializaition functions as well.
</dd>
</dl>
It must define the following
<a href="../../mpl/doc/refmanual/integral-constant.html">
Itegral Constant</a>
of type
<a href="../../mpl/doc/refmanual/bool.html">bool</a>:
<dl>
<dt><h4><code style="white-space: normal"><pre>
ETI::is_polymorphic
</pre></code></h4></dt>
<dd>
</dd>
</dl>
<h3><a name="models">Models</a></h3>
@@ -293,11 +302,9 @@ by the compiler.
<p>
<code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
extended_type_info_no_rtti</a></h4></code>
is implemented in a way that doesn't rely on the existence RTTI.
However, if the export facility is to be used to serialize types
through base class pointers, those types are required to implement
a virtual function with the signature:
is implemented in a way that doesn't rely on the existence RTTI.
However, it does require that all classes for which type id is to be used implement
a virtual function of the signiture:
<code><pre>
virtual const char * get_key();
</pre></code>
@@ -309,9 +316,7 @@ as described above.
The test program <code style="white-space: normal"><a target="test_no_rtti" href="../test/test_no_rtti.cpp">test_no_rtti</a></code>
implements this function in terms of the <code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
extended_type_info</a></code> API above to return the export key associated with the class.
This requires that non-abstract types be exported. It also demostrates the
inter-operability with between two different implementations of
<code style="white-space: normal">extended_type_info</code>.
This requires that non-abstract types be exported.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
+7 -8
View File
@@ -161,14 +161,13 @@ boost/serialization/export.hpp
</a>
<dd>For serialization of pointers to derived classes via key export.</dd>
<dt><a target="assume_abstract" href="../../../boost/serialization/assume_abstract.hpp">
boost/serialization/assume_abstract.hpp
<dt><a target="is_abstract" href="../../../boost/serialization/is_abstract.hpp">
boost/serialization/is_abstract.hpp
</a>
<dd>This is just a thin wrapper which permits one to explicitly specify that a
particular type is an abstract base class. It is necessary to use this
for compilers which don't support the boost type traits implementation of
is_abstact.
</dd>
<dd>For serialization of pointers to abstract base classes. A generic implementation
of this is functional only on the most modern compilers. This one is just
a thin wrapper which permits one to specify "by hand" whether or not a base class
is abstract or not.</dd>
</dl>
@@ -329,7 +328,7 @@ boost/archive/detail/common_iarchive.hpp
boost/archive/detail/common_oarchive.hpp
</a>
<dd>
All archive implementations are derived from these header files. They provide
All archive implmentations are derived from these header files. They provide
the interface to the internal implementation details of the library.
</dd>
+12 -12
View File
@@ -207,10 +207,10 @@ the syntax described above.
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
carefully considered and the code that generates these warning has 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 made "protected" to
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
@@ -223,8 +223,7 @@ the syntax described above.
<h4><a name="gcc295">GCC 2.95</a></h4>
All of the above plus:<br>
<ul>
<li>The serialization library depends on the templated stream
implementation to function properly.
<li>The serialization library depends on the templeted stream implemention
to function properly. So STLPort must be used to build the library.
<li>Polymorphic archive tests fail.
<li>XML serialization only works with version 1.6x of spirit. In order to build
@@ -246,7 +245,7 @@ line by including the following switch:
<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 templated code with __decl(dllexport) and
This is due to the way that VC++ handles templeted code with __decl(dllexport) and
__decl(dllimport) specifications. Basically, this compiler requires that all the
instantiations have the same specification - even though they have different
template arguments. The example <code style="white-space: normal">
@@ -256,14 +255,15 @@ similar to the pre-defined archives in order to function.
This compiler does not have RTTI or exception handling turned on by default. Although
they are not strictly necessary to use the serialization package, the example and test
program presume that they are enabled. So be sure your command line or IDE settings
enable these features if you want to build and run these programs.
enable these features if you want
these switches are enabled if you want to build and run these programs.
<p>
This compiler can treat <code style="white-space: normal">wchar_t</code> as either
a short integer or an intrinsic type.
If <code style="white-space: normal">/Zc:wchar_t</code> is specified on the
compile command line, <code style="white-space: normal">wchar_t</code> will be
considered an intrinsic type - otherwise
it will be treated as a synonym for a 16 bit integer. The library can be used
it will be treated as a synonym for a 16 bit integer. The libary can be used
either way - <strong>BUT</strong> - both the libray <strong>AND</strong> the application
must be compiled with the same switch settings. Note that <code style="white-space: normal">BJAM</code>
includes this switch by default. So if want to use the libraries that
@@ -356,11 +356,11 @@ all the above issues for Visual C++ 7.0 plus:
without a base class.)
</ul>
Working around this in the implementation of the library for this compiler
entailed a ridiculous amount of effort. Even so, the effort wasn't entirely successful.
entailed a ridiculous amount of effort. Even so, the effort wasn't entirely succesful.
With this compiler, this message will still appear under the following conditions:
<ul>
<li>When serializing a class with multiple base classes. This problem causes two
failure in the test suite. I have been unable to devise a way to work around this.
failure in the test suite. I have been unable to divise a way to work around this.
<li>Using more than one kind of archive in the same code module. This should be easy
to work around in practice.
</ul>
@@ -372,11 +372,11 @@ all the above issues for Visual C++ 7.0 plus:
<ul>
<li><code style="white-space: normal">enum</code> data members cannot be serialized.
Conversion to/from integers will work around the problem.
<li>If class serialize functions are not accessible either by making them public or by
<li>If class serialize functions are not accessable either by making them public or by
including <code style="white-space: normal">friend</code> declarations as described in
<a href="serialization.html#member">Class Serialization - Member Function</a>, the
will compile but fail at runtime.
<li>Tests using custom extended type which doesn't use RTTI fails. (5.64 only !).
<li>Tests using custom extended type which doesn't use rtti fails. (5.64 only !).
<li>Tests built in release mode fail. This seems to be an issue with the boost test system
with this compiler.
<li>XML serialization only works with version 1.6x of spirit. In order to build
@@ -428,7 +428,7 @@ These platforms have several issues:
<li>when built to use dynamic linking versions of C++ runtime code (<runtime-link>dynamic)
all tests fail to link. This is due to a missing symbol in the stlport library related
to custom codecvt facets.
<li>the test_set fails to run correctly. It seems the hashed set iterator doesn't
<li>the test_set fails to run correctly. It seems the hashed set interator doesn't
implement the ++ operator correctly. This causes the test to fail by consuming all available
memory. Given this, this test is commented out.
</ul>
-91
View File
@@ -1,91 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Serialization - Proposed Case Studies</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">Proposed Case Studies</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#functionobject">Serializing a Function Object</a></dt>
<dt><a href="#archiveadaptor">Archive Adaptors</a></dt>
<dt><a href="#archivehelper">Archive Helpers</a></dt>
</dl>
These are not part of the library itself, but rather
techiques on how to use the library to address specific situations.
<h2><a name="functionobject"></a>Serializing a Function Object</h2>
An example on how to serialize a function object. I believe this
could be done by serializing pointer to the object in question. Since
the Serialization library resurrects pointer of the correct type
this should be easily implementable.
<p>
If a group of function objects were all derived from the
same polymorphic base class - perhaps via multiple inheritance,
the the function object effectively becomes a "variable" which
encapsulates code.
<p>
This case study would show how to do this.
<h2><a name="archiveadaptor"></a>Archive Adaptors</h2>
Often users want to add their own special functionality to an
existing archive. Examples of this are performance enhancements
for specific types, Adjustment of output syntax for xml archives,
and logging/debug output as archives are written and/or read.
If this functionalty is implemented as an "adaptor" template
which takes the base class as a template argument, such functionality
appended to any archive for which that funtionality makes sense.
For example, an adaptor for generating an xml schema could be
appended to both wide narrow character versions of xml archives.
<p>
This case study would show how to make a useful archive adaptor.
<h2><a name="archivehelper"></a>Archive Helpers</h2>
Some types are not serializable as they stand. That is - they
do not fullfill the requirements of the "Serializable Concept".
The iconic example of this is boost::shared_ptr. Sometimes
these types could be made serializable by adding code inside
the library. Of course, doing that would create a lifetime
of unpaid employment for the library author. Rather than
adding a bunch of special code to the library itself, this
code can packaged as a "helper" or "mix-in" class. Then
a new archive is derived from both the "base" archive class
AND the "helper" class. This is how boost::shared_ptr
has been implemented.
<p>
It would also be possible to make a "generic runtime helper"
which would effectively extend the API of the library. Previously
the library included such a helper class. It was removed
in favor of the current implementation. But this functionality
should be added back in with another adaptor which would
become part of the library.
<hr>
<p>Revised 1 November, 2008
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
-30
View File
@@ -1,30 +0,0 @@
<html>
<head>
<title>Boost Library Status Automatic Test</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<table border="0">
<tr>
<td><img border="0" src="../../../boost.png" width="277" height="86"></td>
<td>
<h1>Library Status: serialization</h1>
<b>Run Date:</b> 02:42:48 UTC, Tuesday 10 June 2008
</td>
</table>
<br>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<td rowspan="2">Test Name</td>
<td align="center" >gcc-3.4.4</td>
</tr><tr>
<td align="center" >profile</td>
</tr><tr><td>peformance_array_binary_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
<tr><td>peformance_array_text_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
<tr><td>peformance_array_text_warchive</a></td><td align="right"><i>Missing</i></td></tr>
<tr><td>peformance_array_xml_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
<tr><td>peformance_array_xml_warchive</a></td><td align="right"><i>Missing</i></td></tr>
<tr><td>performance_iterators</a></td><td align="right">Pass <a href="profile2.txt"><i>Profile</i></a></td></tr>
<tr><td>performance_iterators_base64</a></td><td align="right">Pass <a href="profile3.txt"><i>Profile</i></a></td></tr>
</table>
</body>
</html>
-149
View File
@@ -1,149 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 200 0.00 0.00 void accumulate<unsigned long>(unsigned int&, unsigned long const&)
0.00 0.00 0.00 150 0.00 0.00 _pei386_runtime_relocator
0.00 0.00 0.00 1 0.00 0.00 std::ostream::operator<<(void const*)
0.00 0.00 0.00 1 0.00 0.00 __divdi3
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 200/200 setvbuf [1286]
[4] 0.0 0.00 0.00 200 void accumulate<unsigned long>(unsigned int&, unsigned long const&) [4]
-----------------------------------------------
0.00 0.00 150/150 _cygwin_crt0_common@8 [1230]
[5] 0.0 0.00 0.00 150 _pei386_runtime_relocator [5]
-----------------------------------------------
0.00 0.00 1/1 _lseek64 [1234]
[6] 0.0 0.00 0.00 1 std::ostream::operator<<(void const*) [6]
-----------------------------------------------
0.00 0.00 1/1 __tcf_1 [1221]
[7] 0.0 0.00 0.00 1 __divdi3 [7]
-----------------------------------------------
2 main [1263]
[1263] 0.0 0.00 0.00 0+2 main [1263]
2 main [1263]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[4] void accumulate<unsigned long>(unsigned int&, unsigned long const&) [7] __divdi3
[6] std::ostream::operator<<(void const*) [5] _pei386_runtime_relocator
-203
View File
@@ -1,203 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
100.00 0.01 0.01 __gnu_cxx::__atomic_add(int volatile*, int)
0.00 0.01 0.00 51 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
0.00 0.01 0.00 36 0.00 0.00 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill()
0.00 0.01 0.00 30 0.00 0.00 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
0.00 0.01 0.00 11 0.00 0.00 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&)
0.00 0.01 0.00 9 0.00 0.00 void test_transform_width<6, 8>(unsigned int)
0.00 0.01 0.00 9 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain()
0.00 0.01 0.00 5 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*)
0.00 0.01 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
0.00 0.01 0.00 1 0.00 0.00 void test_xml_escape<char const>(char const*, char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 void test_xml_unescape<char const>(char const*, char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 void test_stream_iterators<char>(char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 test_main(int, char**)
0.00 0.01 0.00 1 0.00 0.00 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
0.00 0.01 0.00 1 0.00 0.00 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) for 100.00% of 0.01 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.01 0.00 __gnu_cxx::__atomic_add(int volatile*, int) [1]
-----------------------------------------------
0.00 0.00 51/51 void test_transform_width<6, 8>(unsigned int) [9]
[5] 0.0 0.00 0.00 51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
-----------------------------------------------
0.00 0.00 36/36 void test_transform_width<6, 8>(unsigned int) [9]
[6] 0.0 0.00 0.00 36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
-----------------------------------------------
0.00 0.00 30/30 void test_transform_width<6, 8>(unsigned int) [9]
[7] 0.0 0.00 0.00 30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
-----------------------------------------------
0.00 0.00 11/11 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
[8] 0.0 0.00 0.00 11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
-----------------------------------------------
0.00 0.00 9/9 test_main(int, char**) [16]
[9] 0.0 0.00 0.00 9 void test_transform_width<6, 8>(unsigned int) [9]
0.00 0.00 51/51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
0.00 0.00 36/36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
0.00 0.00 30/30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
-----------------------------------------------
0.00 0.00 9/9 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
[10] 0.0 0.00 0.00 9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
-----------------------------------------------
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
[11] 0.0 0.00 0.00 5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
-----------------------------------------------
0.00 0.00 1/2 global constructors keyed to main [38]
0.00 0.00 1/2 global destructors keyed to main [35]
[12] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [12]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[13] 0.0 0.00 0.00 1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
0.00 0.00 11/11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[14] 0.0 0.00 0.00 1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
0.00 0.00 9/9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[15] 0.0 0.00 0.00 1 void test_stream_iterators<char>(char const*, unsigned int) [15]
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
-----------------------------------------------
0.00 0.00 1/1 main [1211]
[16] 0.0 0.00 0.00 1 test_main(int, char**) [16]
0.00 0.00 9/9 void test_transform_width<6, 8>(unsigned int) [9]
0.00 0.00 1/1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
0.00 0.00 1/1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
-----------------------------------------------
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
[17] 0.0 0.00 0.00 1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
-----------------------------------------------
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
[18] 0.0 0.00 0.00 1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
0.00 0.00 1/1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[13] void test_xml_escape<char const>(char const*, char const*, unsigned int) [16] test_main(int, char**) [5] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
[14] void test_xml_unescape<char const>(char const*, char const*, unsigned int) [8] boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [1] __gnu_cxx::__atomic_add(int volatile*, int)
[9] void test_transform_width<6, 8>(unsigned int) [11] boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [17] char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
[15] void test_stream_iterators<char>(char const*, unsigned int) [10] boost::archive::iterators::xml_unescape<char const*>::drain() [18] std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
[12] __static_initialization_and_destruction_0(int, int) (performance_iterators.cpp) [6] boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [7] std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
-153
View File
@@ -1,153 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 200 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
0.00 0.00 0.00 150 0.00 0.00 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill()
0.00 0.00 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
0.00 0.00 0.00 1 0.00 0.00 void test_base64<char>()
0.00 0.00 0.00 1 0.00 0.00 std::_List_base<char, std::allocator<char> >::_M_clear()
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 200/200 void test_base64<char>() [7]
[4] 0.0 0.00 0.00 200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
-----------------------------------------------
0.00 0.00 150/150 void test_base64<char>() [7]
[5] 0.0 0.00 0.00 150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
-----------------------------------------------
0.00 0.00 1/2 global constructors keyed to main [27]
0.00 0.00 1/2 global destructors keyed to main [24]
[6] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [6]
-----------------------------------------------
0.00 0.00 1/1 main [1156]
[7] 0.0 0.00 0.00 1 void test_base64<char>() [7]
0.00 0.00 200/200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
0.00 0.00 150/150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
0.00 0.00 1/1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
-----------------------------------------------
0.00 0.00 1/1 void test_base64<char>() [7]
[8] 0.0 0.00 0.00 1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[7] void test_base64<char>() [5] boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [8] std::_List_base<char, std::allocator<char> >::_M_clear()
[6] __static_initialization_and_destruction_0(int, int) (performance_iterators_base64.cpp) [4] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
+3 -3
View File
@@ -228,7 +228,7 @@ its discovered
After a lot of investigation, it's discovered what the source of the problem
and class construct_from is marked "track_never" by including:
<code style="white-space: normal"><pre>
BOOST_CLASS_TRACKING(construct_from, track_never)
BOOST_SERIALIZATION_TRACKING(construct_from, track_never)
</pre></code>
<li>Now everything works again. Or - so it seems.
<p>
@@ -298,7 +298,7 @@ ar &lt;&lt; x
might not even be written yet). OK, I'll add the following to my
construct_from.hpp to solve the problem.
<code style="white-space: normal"><pre>
BOOST_CLASS_TRACKING(construct_from, track_never)
BOOST_SERIALIZATION_TRACKING(construct_from, track_never)
</pre></code>
</ol>
</ul>
@@ -311,7 +311,7 @@ BOOST_CLASS_TRACKING(construct_from, track_never)
<li>But now he gets another trap - trying to save an object of a
class marked "track_never" through a pointer. So he goes back to
construct_from.hpp and comments out the
<code style="white-space: normal">BOOST_CLASS_TRACKING</code> that
<code style="white-space: normal">BOOST_SERIALIZATION_TRACKING</code> that
was inserted. Now the second trap is avoided, But damn - the first trap is
popping up again. Eventually, after some code restructuring, the differing
requirements of serializating <code style="white-space: normal">construct_from</code>
+33 -52
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 .
@@ -27,22 +27,20 @@ http://www.boost.org/LICENSE_1_0.txt)
<hr>
<dl class="index">
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#differences_1_35">Differences from version 1.35</a></dt>
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
<dt><a href="#differences_1_32">Differences from version 1.32</a></dt>
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
<dt><a href="#todo">Pending Issues</a></dt>
</dl>
As of this is written, there are no known bugs. However, due to compiler/library quirks and or
This is the Boost 1.33 Serialization Library.
There are currently no known bugs. However, due to compiler/library quirks and or
bugs, some tests fail with some combinations of compilers and libraries.
<h2><a name="requirements"></a>Requirements</h2>
This library has been tested on Boost version 1.34 and 1.35.
<!--
This library requires Boost version 1.33 or later.
<p>
The serialization library uses the boost spirit package to load XML archives.
We have found that all tests pass using spirit 1.6x. Spirit 1.8 and higher does not work with
older compilers - specifically MSVC 6, Borland and GCC < 3.0.
older compilers - specificallly MSVC 6, Borland and GCC < 3.0.
If you are using one of these compilers, you may download a version
of spirit 1.6 <a href="http://spirit.sourceforge.net/index.php?doc=download/index.html">here</a>.
To use this downloaded version rather than the one included with boost,
@@ -54,46 +52,11 @@ set SPIRIT_ROOT=c:/spirit16
If you're not using bjam and the Jamfile to build the library, be sure that
the directory which contains the version of spirit you plan to use is placed
at the front of the list of include paths.
-->
<h2><a name="differences_1_35"></a>Differences from Boost 1.35</h2>
<ul>
<li>The library is now thread safe. That is, multiple archives can be open
in different threads. This has been implmented with a lock-free algorithm
to avoid any performance bottlenecks.
<li>Serialization of types defined in shared libraries is now supported.
shared libraries (DLLS) can be loaded/unloaded dynamically at runtime.
This includes the serialization of instances of abstract base classes so that
a program can be written so as to be compatible with as yet undefined
and un-implemented code.
<li>The extended type info system has been enhanced to in order to implement
the above. It is now a general purpose system for creating and casting of
types about which is only known a string ID and an abstract base class.
<li>All bug reports filed as TRAK tickets have been addressed.
<li>As of this writing, the library will fail build on older compilers such
as MSVC before version 7.1 and older versions of Borland compilers. This
might or might not change in the future.
</ul>
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</h2>
<ul>
<li>Enhanced support for fast serialization for native binary archives. By Mattias Troyer.
<li>Improved implementation of "export" functionality. Removes header ordering
requirement and eliminates the maintenance of a pre-determined list of "known archives"
By David Abrahams.
<li>Improved support for STLPort.
</ul>
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
<ul>
<li>Native Binary archives use the <code style="white-space: normal">std::streambuf</code> interface.
This should result in noticeably faster execution in many cases.
</ul>
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
<ul>
<li>Dynamic Linking Library (DLLs and shared libraries) for platforms which support them. See
<a href="../../../more/getting_started/windows.html#auto-linking">Automatic Linking on Windows</a>.
<a href="../../../more/getting_started.html#auto-link">Automatic Linking on Windows</a>.
<li>Implementation of auto-link for compilers which can support this.
<li>Better support for <em>Argument Dependent Lookup</em> and two-phase lookup.
This results in simpler rules regarding the placing of serialization specializations
@@ -103,7 +66,7 @@ at the front of the list of include paths.
<li>Improved <code>const</code> correctness for save/load operators. Note that this may
produce compile time errors in code which compiled without problem in earlier boost releases.
In most cases the fix is trivial. In other cases, code should be scrutinized to be
sure that it doesn't use the serialization system in a way which may introduce subtle bugs in
sure that it doesn't use the serializaton system in a way which may introduce subtle bugs in
to the program. A fuller explanation of this issue can be found
<a target="detail" href="traits.html#tracking">here</a>.
<li>A new implementation of serialization for <code style="white-space: normal">shared_ptr&lt;T&gt;</code>. This
@@ -115,24 +78,42 @@ at the front of the list of include paths.
needs to load archives created with boost 1.32 libraries, include the above header
before each inclusion of <code style="white-space: normal">boost/serialization/shared_ptr.hpp</code>.
<li>More compilers tested and supported.
<li>Miscellaneous bug fixes.
<li>Miscelleanous bug fixes.
</ul>
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
<ul>
<li>Native Binary archives use the <code style="white-space: normal">std::streambuf</code> interface.
This should result in noticibly faster execution in many cases.
</ul>
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</h2>
<ul>
<li>Ehanced support for fast serialiation for native binary archives. By Mattias Troyer.
<li>Improved implementation of "export" functionality. Removes header ordering
requirement and eliminates the maintainence of a pre-determined list of "known archives"
By David Abrahams.
<li>Improved support for STLPort.
</ul>
<h2><a name="todo"></a>Pending issues</h2>
<ul>
<li>Compile, and test on more platforms
<li>implement <code>is_virtual_base&lt;T&gt;</code> to automatically
eliminate redundancy in virtual base class serialization.
<li>currently can't serialize through a pointer an object a of class
that implements its own <code style="white-space: normal">new/delete</code> operators.
<li>Its possible that <code style="white-space: normal">std::string</code>
and <code style="white-space: normal">std::wstring</code> contain characters such as
'\0' and -1 (EOF) which cannot be rendered in text and XML archives without an escape mechanism.
Currently there is no such escape mechanism implemented.
<li>A subtle error in the implementation of serializaton of <code style="white-space: normal">std::map</code>
'\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>
<li>Floating point values which are number cannot be serialized to text base archives.
</ul>
<p>
Aside from the above, there are a number of issues related to specific platforms.
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>
+8 -11
View File
@@ -48,13 +48,12 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#splittingfreefunctions">Free Functions</a>
</dl>
</dl>
<dt><a href="#pointeroperators">Pointers</a>
<dt><a href="#pointers">Pointers</a>
<dl class="page-index">
<dt><a href="#constructors">Non-Default Constructors</a>
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
<dl class="page-index">
<dt><a href="#registration">Registration</a>
<dt><a href="#export">Export</a>
<dt><a href="#instantiation">Instantiation</a>
<dt><a href="#selectivetracking">Selective Tracking</a>
<dt><a href="#runtimecasting">Runtime Casting</a>
@@ -78,15 +77,14 @@ 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 and one of the following has been declared according
to the prototypes detailed below:
<li>It is a class type and one of the following has been declared:
<ul>
<li>a class member function <code style="white-space: normal">serialize</code>
<li>a global function <code style="white-space: normal">serialize</code>
</ul>
<li>it is a pointer to a <strong>Serializable</strong> type.
<li>it is a reference to a <strong>Serializable</strong> type.
<li>it is a native C++ Array of <strong>Serializable</strong> type.
<li>it is an native C++ Array of <strong>Serializable</strong> type.
</ul>
<h2><a name="primitiveoperators">Primitive Types</a></h2>
@@ -677,9 +675,8 @@ main(){
Note that if the serialization function is split between save and load, both
functions must include the registration. This is required to keep the save
and corresponding load in syncronization.
<h4><a name="export">Export</a></h4>
The above will work but may be inconvenient. We don't always know which derived
<p>
This will work but may be inconvenient. We don't always know which derived
classes we are going to serialize when we write the code to serialize through
a base class pointer. Every time a new derived class is written we have to
go back to all the places where the base class is serialized and update the
@@ -794,8 +791,8 @@ class derived : public base {
boost::serialization::base_object&lt;base&gt;(*this);
// method 2 : explicitly register base/derived relationship
boost::serialization::void_cast_register&lt;derived, base&gt;(
static_cast&lt;derived *&gt;(NULL),
static_cast&lt;base *&gt;(NULL)
static_cast&lt;base *&gt;(NULL),
static_cast&lt;derived *&gt;(NULL)
)
}
};
@@ -922,7 +919,7 @@ As of this writing, the library contains serialization of the following boost cl
<li>auto_ptr (demo)
</ul>
Others are being added to the list so check the boost files section and headers for
new implementations!
new implmentations!
<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
+6 -6
View File
@@ -20,7 +20,7 @@ http://www.boost.org/LICENSE_1_0.txt)
</td>
<td valign="top">
<h1 align="center">Serialization</h1>
<h2 align="center"><code style="white-space: normal">shared_ptr&lt;class T&gt;</code> Revisited</h2>
<h2 align="center"><code style="white-space: normal">shared_ptr&lt;class T&gt;</code> Revisted</h2>
</td>
</tr>
</table>
@@ -32,7 +32,7 @@ Unfortunately, this way of doing it suffered from some undesirable features
<li>It was dependent on the Boost implementation of <code style="white-space: normal">shared_ptr</code>.
The <code style="white-space: normal">shared_ptr</code> interface has been included
in <code style="white-space: normal">std::tr1</code> and may someday be included in the standard
C++ library. An implementation which depends only on the public interface can be guaranteed to
C++ library. An implementation which depends only on the public interface can be guarenteed to
function with any other future implementation of <code style="white-space: normal">shared_ptr</code>.
<li>It required extra macros for export.
</ul>
@@ -45,7 +45,7 @@ inline void save(
const unsigned int /* file_version */
){
const T * t_ptr = t.get();
// just serialize the underlying raw pointer
// just seriailize the underlying raw pointer
ar &lt;&lt: boost::serialization::make_nvp("px", t_ptr);
}
@@ -56,7 +56,7 @@ inline void load(
const unsigned int file_version
){
T* r;
// recover the underlying raw pointer
// recover the underlying raw poiter
ar >> boost::serialization::make_nvp("px", r);
// To Do - match up with other shared pointers which
@@ -65,13 +65,13 @@ inline void load(
}
</code></pre>
In principle, this is very much simpler than the original implementation. Completion of
In priniciple this is very much simpler than the original implementation. Completion of
this code requires:
<ol>
<li>Filling in the "To Do". This required making an extra map for
<code style="white-space: normal">shared_ptr</code> instances.
<li>A method for identifying pointers to the same objects from pointers to their base classes.
<li>A method for identifing pointers to the same objects from pointers to their base classes.
<li>Backward compatibility with pointers serialized by the previous method. This exploits
the serialization class versioning.
<li>Proper handling of <code style="white-space: normal">weak_ptr</code>.
-241
View File
@@ -1,241 +0,0 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Serialization - singleton</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"><code style="white-space: normal">singleton</code></h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt><a href="#motivation">Motivation</a>
<dt><a href="#features">Features</a>
<dt><a href="#classinterface">Class Interface</a>
<dt><a href="#requirements">Requirements</a>
<dt><a href="#example">Examples</a>
<dt><a href="#multithreading">Multi-Threading</a>
</dl>
<h3><a name="motivation">Motivation</a></h3>
The serialization library relies on the existence of a number
of static variables and tables to store information related
to runtime types. Examples are tables which relate exported
names to types and tables which relate base classes to derived
classes. Construction, destruction and usage of these variables
requires consideration of the following issues:
<ul>
<li>Some static data variables and constants entries refer to others.
The sequence of initialization cannot be arbitrary but must be in proper
sequence.</li>
<li>A number of static variables aren't referred explicitly and, without
special precautions, will be stripped by most code optimizers</li>
<li>Many of these variables are created by templates and special care must
be taken to be sure that they are instantiated</li>
<li>In a multi-threading system, its possible that these static variables
will be accessed concurrently by separate threads. This would create a
race condition with unpredictabe behavior</li>
</ul>
This singleton class addresses all of the above issues.
<h3><a name="features">Features</a></h3>
This singleton implementation has the following features:
<ul>
<li>
Any instance will be constructed before any attempt is made to access it.</li>
<li>
Any instance created with a template is guarenteed to be instantiated.
<li>
Regardless of whether or not an instance has been explicitly
referred to, it will not be stripped by the optimizer when the
executable is built in release mode.
<li>
All instances are constructed before
<code style="white-space: normal">main</code> is called
regardless of where they might be referenced within the program.
In a multi-tasking system, this guarentees that there will be no
race conditions during the construction of any instance. No
thread locking is required to guarentee this.
<li>
The above implies that any <code style="white-space: normal">const</code>
instances are thread-safe during the whole program. Again, no
thread locking is required.
<li>
If a mutable instance is created, and such an instance is modified
after main is called in a mult-threading system, there exists
the possibility that a race condition will occur. The serialization
library takes care that in the few places where a mutable
singleton is required, it is not altered after
<code style="white-space: normal">main</code> is called.
For a more general purpose usage, thread locking on this
singleton could easily be implemented. But as the serialization
library didn't require it, it wasn't implemented.
</ul>
<h3><a name="classinterface">Class Interface</a></h3>
<pre><code>
namespace boost {
namespace serialization {
template <class T>
class singleton : public boost::noncopyable
{
public:
static const T & get_const_instance();
static T & get_mutable_instance();
};
} // namespace serialization
} // namespace boost
</code></pre>
<dl>
<dt><h4><pre><code>
static const T & get_const_instance();</code></pre></h4></dt>
<dd>
Retrieve a constant reference to the singleton for this type.
</dd>
<dt><h4><pre><code>
static T & get_mutable_instance();</code></pre></h4></dt>
<dd>
Retrieve a mutable reference to the singleton for this type.
</dd>
</dl>
<h3><a name="requirements">Requirements</a></h3>
In order to be used as
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
<code style="white-space: normal">
singleton&lt;T&gt;
</code>
</a>
, the type T must be default constructable.
It doesn't require static variables - though it may have them.
Since the library guarentees that only one instance of
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
<code style="white-space: normal">
singleton&lt;T&gt;
</code>
</a>
and all accesss is through the above static interface
functions, common member functions of T become
the functional equivalent of
<code style="white-space: normal">static</code> functions.
<h3><a name="example">Examples</a></h3>
There are at least two different ways to use this class template.
Both are used in the serialization library.
<p>
The first way is illustrated by and excerpt from the file
<code style="white-space: normal"><a target="extended_type_info" href="../src/extended_type_info.cpp">extended_type_info.cpp</a></code>.
which contains the following code:
<pre><code>
typedef std::set<const extended_type_info *, key_compare> ktmap;
...
void
extended_type_info::key_register(const char *key) {
...
result = singleton<ktmap>::get_mutable_instance().insert(this);
...
}
</code></pre>
Just by referring to the singleton instance anywhere in the program
will guarentee that one and only one instance for the specified
type (<code style="white-space: normal">ktmap</code> in this example)
will exist throughout the program. There is no need for anyother
declaration or definition.
<p>
A second way is to use
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
<code style="white-space: normal">
singleton&lt;T&gt;
</code>
</a>
as one of the base classes of the type. This is illustrated by a simplified
excerpt from
<a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
<code style="white-space: normal">
extended_type_info_typeid.hpp
</code>
</a>
<pre><code>
template&lt;class T&gt;
class extended_type_info_typeid :
public detail::extended_type_info_typeid_0,
public singleton&lt;extended_type_info_typeid&lt;const T&gt; &gt;
{
friend class singleton&lt;extended_type_info_typeid&lt;const T&gt; &gt;;
private:
// private constructor to inhibit any existence other than the
// static one. Note: not all compilers support this !!!
extended_type_info_typeid() :
detail::extended_type_info_typeid_0()
{
type_register(typeid(T));
}
~extended_type_info_typeid(){}
...
};
</code></pre>
This usage will permit a more natural syntax to be used:
<pre><code>
extended_type_info_typeid&lt;T&gt;::get_const_instance()
</code></pre>
Again, including one or more of the above statements anywhere
in the program will guarentee that one and only one instance
is created and referred to.
<h3><a name="multithreading">Multi-Threading</a></h3>
This singleton CAN be safely used in multi-threading applications if one
is careful follow a simple rule:
<p>
<b>Do not call get_mutable_instance when more than one thread is running!</b>
<p>
All singletons used in the serialization library follow this rule.
In order to help detect accidental violations of this rule there
exists an singleton lock/unlock functions.
<pre><code>
boost::serialization::global_lock::get_mutable_instance().lock();
boost::serialization::global_lock::get_mutable_instance().unlock();
</code></pre>
In a program compiled for debug, any invocation of
<code style="white-space: normal">get_mutable_instance()</code>
while the library is in a "locked" state will trap in an assertion.
The global_lock state is initialized as "unlocked" to permit
alteration of static variables before
<code style="white-space: normal">main</code> is called. All
serialization tests invoke <code style="white-space: normal">lock()</code>
at the start of the progam. For programs compiled in release
mode these functions have no effect.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+98 -181
View File
@@ -27,6 +27,7 @@ http://www.boost.org/LICENSE_1_0.txt)
<hr>
<dl class="page-index">
<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">
@@ -35,9 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
</dl>
<dt><a href="#binary_archives">Binary Archives</a>
<dt><a href="#xml_archives">XML Archives</a>
<dt><a href="#export">Exporting Class Serialization</a>
<dt><a href="#dlls">DLLS - Serialization and Runtime Linking</a>
<dt><a href="#plugins">Plugins</a>
<dt><a href="#multi_threading">Multi-Threading</a>
<dt><a href="#optimizations">Optimizations</a>
<dt><a href="exceptions.html">Archive Exceptions</a>
@@ -154,6 +153,55 @@ redundant save/load operations.
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. This functionality
is necessary to implement serialization of pointers through a virtual base
class pointer. That is, a polymorphic pointer.
<p>
This macro specifies a "<b>G</b>lobally <b>U</b>nique <b>ID</b>entifier".
This is an string which identifies the class to be created when data is loaded.
Generally a text representation of the class name is sufficient for this purpose,
but in certain cases it maybe necessary to specify a different string by using
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code>
rather than a simple
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>.
<p>
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> would usually
be specified in the same header file as the class declaration to which it
corresponds. That is, <code style="white-space: normal">BOOST_CLASS_EXPORT(T)</code>
is a "trait" of the class T. So a program using this class will look
something like:
<pre><code>
#include &lt;boost/archive/xml_oarchive.hpp&gt;
.... // any other archive classes
#include "my_class.hpp" // which contains BOOST_CLASS_EXPORT(my_class)
</code></pre>
These headers can be in any order. (In boost versions 1.34
and earlier, the archive headers had to go before any headers which
contain <code style="white-space: normal">BOOST_CLASS_EXPORT</code>.)
Any code required to serialize types specified
by <code style="white-space: normal">BOOST_CLASS_EXPORT</code> will be
instantiated for each archive whose header is included. (note that the code
is instantiated regardless of whether or not it is actually invoked.)
If no archive headers are included - no code should be instantiated.
This will permit <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
to be a permanent part of the <code style="white-space: normal">my_class.hpp</code> .
<p>
Note that the implementation of this functionality depends upon vendor
specific extensions to the C++ language. So, there is no guarenteed portability
of programs which use this facility. However, all C++ compilers which
are tested with boost provide the required extensions. The library
includes the extra declarations required by each of these compilers.
It's reasonable to expect that future C++ compilers will support
these extensions or something equivalent.
<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
@@ -238,7 +286,7 @@ struct my_wrapper {
class my_class {
wchar_t a;
short unsigned b;
template&lt;class Archive&gt;
template<&lt;class Archive&gt;
Archive & serialize(Archive & ar, unsigned int version){
ar & my_wrapper(a);
ar & my_wrapper(b);
@@ -297,105 +345,13 @@ just the value portion of the data is serialized. The name portion is discarded
So by always using <a target="detail" href="wrappers.html#nvp">name-value pairs</a>, it will
be guarenteed that all data can be serialized to all archive classes with maximum efficiency.
<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>.
Export implies two things:
<ul>
<li>Instantiates code which is not otherwise referred to.
<li>Associates an external identifier with the class to be serialized.
The fact that the class isn't explicitly referred to implies this
requirement.
</ul>
In C++, usage of code not explicitly referred to is implemented via
virtual functions. Hence, the need for export is implied by the
usage of a derived class that is manipulated via a pointer or
reference to it's base class.
<p>
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the same
source module that includes any of the archive class headers will
instantiate code required to serialize polymorphic pointers of
the indicated type to the all those archive classes. If no
archive class headers are included, then no code will be instantiated.
<p>
Note that the implemenation of this functionality requires
that the <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
macro appear <b>after</b> and the inclusion of any archive
class headers for which code is to be instantiated.
So, code that uses <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
will look like the following:
<pre><code>
#include &lt;boost/archive/text_oarchive.hpp&gt;
#include &lt;boost/archive/text_oarchive.hpp&gt;
... // other archives
#include "a.hpp" // header declaration for class a
BOOST_CLASS_EXPORT(a)
... // other class headers and exports
</code></pre>
This will be true regardless of whether the is part
of a stand alone executable, a static library or
a dyanmic or shared library.
<p>
Note that including
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
in the "a.hpp" header itself as one would do with
other serialization traits will make it difficult
or impossible to follow the rule above regarding
inclusion of archive headers before
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
is invoked. This is different than other serialization
traits which would normally be included in same file
as the class declaration.
<p>
This system has certain implications for placing code in static or shared
libraries. Placing <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
in library code will have no effect unless archive class headers are
also included. So when building a library, one should include all headers
for all the archive classes which he anticipates using. Alternatively,
one can include headers for just the
<a href="archive_reference.html#polymorphic">Polymoprhic Archives</a>.
Also, when making shared libraries, there is currently a restriction
that only one such library can use <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
for any given type. All this will most likely make it inconvenient
to include <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
as part of the header of the class to be serialized. So, <b>the
best way to use <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
is to include it in the same module which implements the class</b>.
<p>
Strictly speaking, export should not be necessary if all pointer serialization
occurs through the most derived class. However, in order to detect
what would be catastophic error, the library traps ALL serializations through
a pointer to a polymorphic which are not exported or otherwise registered.
So, in practice, be prepared to register or export all classes with one
or more virtual functions which are serialized through a pointer.
<p>
Note that the implementation of this functionality depends upon vendor
specific extensions to the C++ language. So, there is no guarenteed portability
of programs which use this facility. However, all C++ compilers which
are tested with boost provide the required extensions. The library
includes the extra declarations required by each of these compilers.
It's reasonable to expect that future C++ compilers will support
these extensions or something equivalent.
<h3><a name="dlls">DLLS - Serialization and Runtime Linking</a></h3>
Serialization code can be placed in libraries to be linked at runtime. That is,
code can be placed in DLLS(Windows) Shared Libraries(*nix), or static libraries
as well as the main executable. As long as
<a target="detail" href="serialization.html#export">
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
</a>
is not used, The serialization library imposes no special requirements
that need be taken into account when distributing code among various modules.
<p>
For static libraries, this is illustrated by
code can be placed in DLLS(Windows) or Shared Libraries(*nix).
Along with the "export" facility, this
permits a program to written without knowledge of the actual types to be serialized.
This package doesn't include an example of this technique - but coding would be
very similar to the example
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
<code style="white-space: normal">demo_pimpl.cpp</code>
</a>,
@@ -406,91 +362,52 @@ and
<a href = "../example/demo_pimpl_A.hpp" target="demo_pimpl">
<code style="white-space: normal">demo_pimpl_A.hpp</code>
</a>
where implementation of serializaton is in a static library
completely separate from the main program.
<p>
For runtime linked libraries this is illustrated by one of the tests:
<a href = "../test/test_dll_simple.cpp" target="test_dll_simple">
<code style="white-space: normal">test_dll_simple</code>
</a>,
and
<a href = "../test/dll_a.cpp" target="dll_a">
<code style="white-space: normal">dll_a.cpp</code>
</a>
where implementation of serializaton is also completely separate
from the main program but the code is loaded at runtime. In this
example, this code is loaded automatically when the program which
uses it starts up, but it could just as well be loaded and unloaded
with an OS dependent API call.
<h3><a name="plugins">Plugins</a></h3>
In order to implement the library, various facilities for runtime
manipulation of types are runtime were required. These
are <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
for associating classes with external identifying strings (<b>GUID</b>)
and <a target="detail" href="void_cast.html"><code>void_cast</code></a>
for casting between pointers of related types.
To complete the functionality of
<a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
the ability to construct and destroy corresponding types has been
added. In order to use this functionality, one must specify
how each type is created. This should be done at the time
a class is exported. So, a more complete example of the code above would be:
<pre><code>
#include &lt;boost/archive/text_oarchive.hpp&gt;
#include &lt;boost/archive/text_oarchive.hpp&gt;
... // other archives
#include "a.hpp" // header declaration for class a
// this class has a default constructor
BOOST_SERIALIZATION_FACTORY_0(a)
// as well as one that takes one integer argument
BOOST_SERIALIZATION_FACTORY_1(a, int)
// specify the GUID for this class
BOOST_CLASS_EXPORT(a)
... // other class headers and exports
</code></pre>
With this in place, one can construct, serialize and destroy
about which only is know the <b>GUID</b> and a base class.
where implementation of serializaton is completely separate
from the main program.
<h3><a name="multi_threading">Multi-Threading</a></h3>
The fundamental purpose of serialization would conflict with multiple
thread concurrently writing/reading from/to a single open archive instance.
The library implementation presumes that the application avoids such an situtation.
The nature of serialization would conflict with multiple thread concurrently
writing/reading from/to a single open archive. Since each archive is
independent from ever other one, there should be no problem
in having multiple open archives from one or more threads.
<p>
However, Writing/Reading different archives simultaneously
in different tasks is permitted as each archive instance is (almost)
completely independent from any other archive instance. The only shared
information are some type tables which have been implemented using a
lock-free thread-safe
<a target="detail" href="singleton.html">
<code style="white-space: normal">singleton</code>
</a>
described elsewhere in this documentation.
Well, not quite.
<p>
This singleton implementation guarentees that all of this shared
information is initialized when the code module which contains
them is loaded. The serialization library takes care to
ensure that these data structures are not subsequently
modified. The only time there could be a problem would
be if code is loaded/unloaded while another task is
serializing data. This could only occur for types whose
serialization is implemented in a dynamically loaded/unload DLL
or shared library. So if the following is avoided:
<ul>
<li>Accessing the same archive instance from different tasks.
<li>Loading/Unloading DLLS or shared libraries while any archive
instances are open.
</ul>
The library should be thread safe.
There are a couple of global data structures for holding
information of serializable types. These structures are
used to dispatch to correct code to handle each pair
of serializable types and archive types. Since this
information is shared among all archives, there is
potential for problems. This has been addressed
carefully implementing the library so that these
structures are all initialized before
<code style="white-space: normal">main(...)</code>
is called. From then on they are never altered. So
there SHOULD be no problem having mulitple archives
open simultaneously - be it from the same or different
threads.
<p>
Well, almost.
<p>
With dynamically loaded code - DLLS or Shared Libraries,
these global data structures can be altered when a library
is loaded or unloaded. That is, in this case, these
globa data structures can be altered after
<code style="white-space: normal">main(...)</code>
is called. So if a thread is dynamically loading/unloading
modules which contain serialization code while an
archive is open there could be problems. Also, if
such loading/unloading is happening concurrently
in different threads, there could also be problems.
<p>
It might not be easy to control this. Is possible that
some systems may not actually load modules until they
are actually needed. So even though we think that
there is not dynamic loading/unloading of such code
it could be occurring as "help" to manage resources.
On such systems, access to archive code would have
to be syncronized with some multi-threading construct
in order to be functional.
<h3><a name="optimizations">Optimizations</a></h3>
In performance critical applications that serialize large sets of contiguous data of homogeneous
+1 -19
View File
@@ -25,25 +25,7 @@ http://www.boost.org/LICENSE_1_0.txt)
</tr>
</table>
<hr>
The header <code>&lt;boost/static_warning.hpp&gt;</code> supplies a single macro
<code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>, which generates a compile time warning message if
the integral-constant-expression x is not true.
<p>
Note that if the condition is true, then the macro will generate neither
code nor data - and the macro can also be used at either namespace,
class or function scope. When used in a template, the expression x
will be evaluated at the time the template is instantiated; this is
particularly useful for validating template parameters.
<p>
It is intended that the functioning of <code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>
be identical to that of <code style="white-space: normal">BOOST_STATIC_ASSERT(x)</code>
except that rather than resulting in a compilation error, it will result in
a compiler warning. In all other respects it should be the same. So
for more information on using <code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>
consult the documentation for <code style="white-space: normal">BOOST_STATIC_ASSERT(x)</code>
<a href="../../../doc/html/boost_staticassert.html">here</a>.
To do.
<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
-7
View File
@@ -6,10 +6,3 @@ pre{
MARGIN-LEFT: 0pt;
background-color: #EEEEEE;
}
/*
(C) Copyright 2008 Robert Ramey - http://www.rrsd.com .
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
-113
View File
@@ -1,113 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Serialization - To Do</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">To Do</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#portablebinaryarchives">Portable Binary Archives</a></dt>
<dt><a href="#performancetesting">Performance Testing and Profiling</a></dt>
<dt><a href="#backversioning">Back Versioning</a></dt>
<dt><a href="#nortti">Testing for Environments with No RTTI</a></dt>
<dt><a href="new_case_studies.html">Additional Case Studies</a></dt>
</dl>
These are enhancements that the serialization library needs but have not been done.
Some of these projects, though tricky, are not huge and would be suitable
for someone who has a limited time to spend on them. In particular, they
might be of interest as student projects such as the Google Summer of Code.
<h2><a name="portablebinaryarchives"></a>Portable Binary Archives</h2>
Currently there is a portable binary archive in the examples directory.
It is not regularly submitted to the exhaustive boost testing regimen
but it is tested occasionally and has been used in production code.
<p>
Its missing the following:
<ul>
<li>Addition of portable floating point types. This is not trivial. In addition to
handling floating point types of varying sizes, It requires
handling invalid floating point numbers (NaNs) in a portable manner.
<li>Some way to test archive portability within the Boost testing regimen.
<li>Integration into the Boost testing similar to the other archive classes.
</ul>
<h2><a name="performancetesting"></a>Performance Testing and Profiling</h2>
I've managed to setup performance profiling using the following:
<ul>
<li>current (as I write this) Boost.Build tools.
<li>the gcc compiler.
<li>and a shell script - profile.sh
<li>library_status program from the tools/regression/src directory
</ul>
Invoking profile script produces a
<a href=performance_status.html">table</a>
which shows the results of each test and links to the actual
profile.
<p>
The first thing I did was include some of the serialization library tests.
It became immediatly apparent that these tests were totally unsuitable
for performance testing and that new tests needed to be written for this
purpose. These tests would highlight the location of any performance
bottlenecks in the serialization library. Whenever I've subjected my
code in the past to this type of analysis, I've always been suprised
to find bottlenecks in totally unanticipated places and fixing those
has always lead to large improvements in performance. I expect that
this project would have a huge impact on the utility of the serialization
library.
<h2><a name="backversioning"></a>Back Versioning</h2>
It has been suggested that a useful feature of the library would be
the ability to create "older versions" of archives. Currently,
the library permits one make programs that are guarenteed
the ability to load archives with classes of a previous version.
But there is not way to save classes in accordance with a
previous version. At first I dismissed this a a huge project
with small demand. A cursory examination of the code revealed
that this would not be very difficult. It would require some
small changes in code and some additional tests. Also it
would require special treatment in the documentation - perhaps
a case study.
<h2><a name="nortti"></a>Environments without RTTI</h2>
I note that some have commented that this library requires RTTI.
This is not strictly true. The examples and almost all the
tests presume the existence of RTTI. But it should be possible
to use the library without it. The example used for testing is an
<code style="white-space: normal">extended_typeinfo</code>
implemenation which presumes that all classes names have been exported.
So, to make this library compatible for platforms without RTTI,
a set of tests, examples and new manual section would have to be created
<hr>
<p>Revised 1 November, 2008
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+17 -69
View File
@@ -179,7 +179,7 @@ Default tracking traits are:
That is, addresses of addresses are not tracked by default.
<li>All current serialization wrappers such as <code style="white-space: normal">boost::serialization::nvp</code>,
<code style="white-space: normal">track_never</code>.
<li>For all other types, <code style="white-space: normal">track_selectively</code>.
<li>For all other types, <code style="white-space: normal">track_selectivly</code>.
That is addresses of serialized objects are tracked if and only if
one or more of the following is true:
<ul>
@@ -242,20 +242,23 @@ BOOST_CLASS_EXPORT_GUID(my_class, "my_class")
</code></pre>
If the an external name is required somewhere in the program and none
has been assigned, a static assertion will be invoked.
<h3><a name="abstract">Abstract</a></h3>
When serializing an object through a pointer to its base class,
the library needs to determine whether or not the bas is abstract
(i.e. has at least one virtual function). The library uses the
type trait macro <code style="white-space: normal">BOOST_IS_ABSTRACT(T)</code>
to do this. Not all compilers support this type trait and corresponding
macro. To address this, the macro <code style="white-space: normal">
BOOST_SERIALIZATION_ASSUME_ABSTRACT(T)</code> has been
implemented to permit one to explicitly indicate that a specified
type is in fact abstract. This will guarentee that
<code style="white-space: normal">BOOST_IS_ABSTRACT</code>
will return the correct value for all compilers.
When serializing an object through a pointer to its base class
and that base class is abstract (i.e. has at least one virtual function
assigned a value of 0), A compile error will be emitted. This is
addressable in one over several ways:
<ul>
<li>remove the =0 in the base classes so that the base class is no
longer abstract.
<li>implement is_abstract for your compiler. (code written according to
the C++ standard is included with this library. But it is known to fail
on several compilers.
<li>use the macro <code style="white-space: normal">BOOST_IS_ABSTRACT(my_class)</code> to indicate
that the class is an abstract base class. This will cause the compiler
to avoid generating code that causes this error.
This macro must be used in the global namespace, with full namespace
qualification of the argument class.
</ul>
<h3><a name="typeinfo">Type Information Implementation</a></h3>
This last trait is also related to the serialization of objects
through a base class pointer. The implementation of this facility
@@ -468,61 +471,6 @@ and template parameters should be assigned according to the following table:
<tr><td><code>IsWrapper</code></td><td><code></code>is the type a wrapper?</td><td><code>mpl::false_<br>mpl::true_</code></td><td><code>mpl::false_</code></td></tr>
</table>
<<<<<<< .working
<h3><a name="tracking">Bitwise serialization</a></h3>
Some simple classes could be serialized just by directly copying all bits
of the class. This is, in particular, the case for POD data types containing
no pointer members, and which are neither versioned nor tracked. Some archives,
such as non-portable binary archives can make us of this information to
substantially speed up serialization.
To indicate the possibility of bitwise serialization the type trait defined
in the header
file <a href="../../../boost/serialization/is_bitwise_serializable.hpp" target="is_bitwise_serializable">is_bitwise_serializable.hpp</a>
is used:
<pre><code>
namespace boost { namespace serialization {
template<class T>
struct is_bitwise_serializable
: public is_arithmetic<T>
{};
} }
</code></pre>
is used, and can be specialized for other classes. The specialization
is made easy by the corresponding macro:
<pre><code>
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
</code></pre>
=======
<h3><a name="tracking">Bitwise serialization</a></h3>
Some simple classes could be serialized just by directly copying all bits
of the class. This is, in particular, the case for POD data types containing
no pointer members, and which are neither versioned nor tracked. Some archives,
such as non-portable binary archives can make us of this information to
substantially speed up Serialization.
To indicate the possibility of bitwise serialization the type trait defined
in the header
file <a href="../../../boost/serialization/is_bitwise_serializable.hpp" target="is_bitwise_serializable">is_bitwise_serializable.hpp</a>
is used:
<pre><code>
namespace boost { namespace serialization {
template<class T>
struct is_bitwise_serializable
: public is_arithmetic<T>
{};
} }
</code></pre>
is used, and can be specialized for other classes. The specialization
is made easy by the corresponding macro:
<pre><code>
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
</code></pre>
>>>>>>> .merge-right.r41077
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004 and Matthias Troyer 2006.
Distributed under the Boost Software License, Version 1.0. (See
+1 -1
View File
@@ -123,7 +123,7 @@ int main() {
gps_position newg;
{
// create and open an archive for input
std::ifstream ifs("filename");
std::ifstream ifs("filename", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia &gt;&gt; newg;
+2 -2
View File
@@ -44,8 +44,8 @@ They are declared in the namespace
template&lt;class Derived, class Base&gt;
const void_cast_detail::void_caster &
void_cast_register(
Derived const * derived = NULL,
Base * const base = NULL
const Derived * derived = NULL,
const Base * base = NULL
)
</code></pre></h4></dt>
<dd>
-55
View File
@@ -1,55 +0,0 @@
# Boost serialization Library Build Jamfile
# (C) Copyright Robert Ramey 2002-2004.
# Use, modification, and distribution are 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/libs/serialization for the library home page.
project libs/serialization/example
: id serialization_test
: requirements <library>../build//boost_serialization
;
rule demo_bsl_run ( demo-name : othersources * : requirements * )
{
return [ run
# sources
$(demo-name).cpp
$(othersources).cpp
: # command
: # input files
: # requirements
# toolset suppress-warnings
<toolset>gcc:<cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy"
<toolset>msvc-8.0:<cxxflags>"-wd4996"
<toolset>borland:<cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066"
# toolset optimizations
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
<toolset>msvc:<cxxflags>"-Gy"
# toolset shared library support
<toolset>como,<runtime-link>shared:<build>no
<toolset>msvc,<stdlib>stlport,<runtime-link>shared:<build>no
<toolset>cw,<runtime-link>static:<build>no
$(requirements)
: # test name
$(demo-name)
]
;
}
test-suite "demo-suite" :
# demos
[ demo_bsl_run demo ]
[ demo_bsl_run demo_auto_ptr ]
[ demo_bsl_run demo_exception ]
[ demo_bsl_run demo_fast_archive ]
[ demo_bsl_run demo_pimpl : demo_pimpl_A ]
[ demo_bsl_run demo_polymorphic : demo_polymorphic_A ]
[ demo_bsl_run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
[ demo_bsl_run demo_shared_ptr ]
[ demo_bsl_run demo_xml ]
[ demo_bsl_run demo_xml_save ]
[ demo_bsl_run demo_xml_load : : <dependency>demo_xml_save ]
;
+2 -3
View File
@@ -7,7 +7,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <cstddef> // NULL
#include <iomanip>
#include <iostream>
#include <fstream>
@@ -21,7 +20,7 @@
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/is_abstract.hpp>
/////////////////////////////////////////////////////////////
// The intent of this program is to serve as a tutorial for
@@ -94,7 +93,7 @@ public:
virtual ~bus_stop(){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
BOOST_IS_ABSTRACT(bus_stop)
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
-50
View File
@@ -1,50 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_derived_class.cpp
// (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)
// should pass compilation and execution
#include <cstddef> // NULL
#include <fstream>
#include <cstdio> // remove
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif
#include "test_tools.hpp"
#include "B.hpp"
#include "A.ipp"
int test_main( int argc, char* argv[] )
{
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
B b, b1;
{
test_ostream os(testfile, TEST_STREAM_FLAGS);
test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
oa << boost::serialization::make_nvp("b", b);
}
{
test_istream is(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
ia >> boost::serialization::make_nvp("b1", b1);
}
BOOST_CHECK(b == b1);
std::remove(testfile);
return EXIT_SUCCESS;
}
// EOF
-321
View File
@@ -1,321 +0,0 @@
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
#define BOOST_SERIALIZATION_TEST_A_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
// A.hpp simple class test
// (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 <cassert>
#include <cstdlib> // for rand()
#include <cmath> // for fabs()
#include <cstddef> // size_t
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::rand;
using ::fabs;
using ::size_t;
}
#endif
//#include <boost/test/test_exec_monitor.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
#include <boost/archive/dinkumware.hpp>
#endif
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/access.hpp>
class A
{
private:
friend class boost::serialization::access;
// note: from an aesthetic perspective, I would much prefer to have this
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
// compiler. So hold our nose and put it her to permit running of tests.
template<class Archive>
void serialize(
Archive &ar,
const unsigned int /* file_version */
){
ar & BOOST_SERIALIZATION_NVP(b);
#ifndef BOOST_NO_INT64_T
ar & BOOST_SERIALIZATION_NVP(f);
ar & BOOST_SERIALIZATION_NVP(g);
#endif
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 )
int i;
if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){
i = l;
ar & BOOST_SERIALIZATION_NVP(i);
}
else{
ar & BOOST_SERIALIZATION_NVP(i);
l = i;
}
#else
ar & BOOST_SERIALIZATION_NVP(l);
#endif
ar & BOOST_SERIALIZATION_NVP(m);
ar & BOOST_SERIALIZATION_NVP(n);
ar & BOOST_SERIALIZATION_NVP(o);
ar & BOOST_SERIALIZATION_NVP(p);
ar & BOOST_SERIALIZATION_NVP(q);
#ifndef BOOST_NO_CWCHAR
ar & BOOST_SERIALIZATION_NVP(r);
#endif
ar & BOOST_SERIALIZATION_NVP(c);
ar & BOOST_SERIALIZATION_NVP(s);
ar & BOOST_SERIALIZATION_NVP(t);
ar & BOOST_SERIALIZATION_NVP(u);
ar & BOOST_SERIALIZATION_NVP(v);
ar & BOOST_SERIALIZATION_NVP(w);
ar & BOOST_SERIALIZATION_NVP(x);
ar & BOOST_SERIALIZATION_NVP(y);
#ifndef BOOST_NO_STD_WSTRING
ar & BOOST_SERIALIZATION_NVP(z);
#endif
}
bool b;
#ifndef BOOST_NO_INT64_T
boost::int64_t f;
boost::uint64_t g;
#endif
enum h {
i = 0,
j,
k
} l;
std::size_t m;
signed long n;
unsigned long o;
signed short p;
unsigned short q;
#ifndef BOOST_NO_CWCHAR
wchar_t r;
#endif
char c;
signed char s;
unsigned char t;
signed int u;
unsigned int v;
float w;
double x;
std::string y;
#ifndef BOOST_NO_STD_WSTRING
std::wstring z;
#endif
public:
A();
bool operator==(const A &rhs) const;
bool operator!=(const A &rhs) const;
bool operator<(const A &rhs) const; // used by less
// hash function for class A
operator std::size_t () const;
friend std::ostream & operator<<(std::ostream & os, A const & a);
friend std::istream & operator>>(std::istream & is, A & a);
};
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
template<class S>
void randomize(S &x)
{
assert(0 == x.size());
for(;;){
unsigned int i = std::rand() % 27;
if(0 == i)
break;
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
}
}
template<class T>
void accumulate(std::size_t & s, const T & t){
const char * tptr = (const char *)(& t);
unsigned int count = sizeof(t);
while(count-- > 0){
s += *tptr++;
}
}
A::operator std::size_t () const {
std::size_t retval = 0;
accumulate(retval, b);
#ifndef BOOST_NO_INT64_T
accumulate(retval, f);
accumulate(retval, g);
#endif
accumulate(retval, l);
accumulate(retval, m);
accumulate(retval, n);
accumulate(retval, o);
accumulate(retval, p);
accumulate(retval, q);
#ifndef BOOST_NO_CWCHAR
accumulate(retval, r);
#endif
accumulate(retval, c);
accumulate(retval, s);
accumulate(retval, t);
accumulate(retval, u);
accumulate(retval, v);
return retval;
}
inline A::A() :
b(true),
#ifndef BOOST_NO_INT64_T
f(std::rand() * std::rand()),
g(std::rand() * std::rand()),
#endif
l(static_cast<enum h>(std::rand() % 3)),
m(std::rand()),
n(std::rand()),
o(std::rand()),
p(std::rand()),
q(std::rand()),
#ifndef BOOST_NO_CWCHAR
r(std::rand()),
#endif
c(std::rand()),
s(std::rand()),
t(std::rand()),
u(std::rand()),
v(std::rand()),
w((float)std::rand()),
x((double)std::rand())
{
randomize(y);
#ifndef BOOST_NO_STD_WSTRING
randomize(z);
#endif
}
inline bool A::operator==(const A &rhs) const
{
if(b != rhs.b)
return false;
if(l != rhs.l)
return false;
#ifndef BOOST_NO_INT64_T
if(f != rhs.f)
return false;
if(g != rhs.g)
return false;
#endif
if(m != rhs.m)
return false;
if(n != rhs.n)
return false;
if(o != rhs.o)
return false;
if(p != rhs.p)
return false;
if(q != rhs.q)
return false;
#ifndef BOOST_NO_CWCHAR
if(r != rhs.r)
return false;
#endif
if(c != rhs.c)
return false;
if(s != rhs.s)
return false;
if(t != rhs.t)
return false;
if(u != rhs.u)
return false;
if(v != rhs.v)
return false;
if(w == 0 && std::fabs(rhs.w) > std::numeric_limits<float>::epsilon())
return false;
if(std::fabs(rhs.w/w - 1.0) > std::numeric_limits<float>::epsilon())
return false;
if(x == 0 && std::fabs(rhs.x - x) > std::numeric_limits<float>::epsilon())
return false;
if(std::fabs(rhs.x/x - 1.0) > std::numeric_limits<float>::epsilon())
return false;
if(0 != y.compare(rhs.y))
return false;
#ifndef BOOST_NO_STD_WSTRING
if(0 != z.compare(rhs.z))
return false;
#endif
return true;
}
inline bool A::operator!=(const A &rhs) const
{
return ! (*this == rhs);
}
inline bool A::operator<(const A &rhs) const
{
if(b != rhs.b)
return b < rhs.b;
#ifndef BOOST_NO_INT64_T
if(f != rhs.f)
return f < rhs.f;
if(g != rhs.g)
return g < rhs.g;
#endif
if(l != rhs.l )
return l < rhs.l;
if(m != rhs.m )
return m < rhs.m;
if(n != rhs.n )
return n < rhs.n;
if(o != rhs.o )
return o < rhs.o;
if(p != rhs.p )
return p < rhs.p;
if(q != rhs.q )
return q < rhs.q;
#ifndef BOOST_NO_CWCHAR
if(r != rhs.r )
return r < rhs.r;
#endif
if(c != rhs.c )
return c < rhs.c;
if(s != rhs.s )
return s < rhs.s;
if(t != rhs.t )
return t < rhs.t;
if(u != rhs.u )
return u < rhs.u;
if(v != rhs.v )
return v < rhs.v;
if(w != rhs.w )
return w < rhs.w;
if(x != rhs.x )
return x < rhs.x;
int i = y.compare(rhs.y);
if(i != 0 )
return i < 0;
#ifndef BOOST_NO_STD_WSTRING
int j = z.compare(rhs.z);
if(j != 0 )
return j < 0;
#endif
return false;
}
#endif // BOOST_SERIALIZATION_TEST_A_HPP
-321
View File
@@ -1,321 +0,0 @@
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
#define BOOST_SERIALIZATION_TEST_A_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
// A.hpp simple class test
// (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 <cassert>
#include <cstdlib> // for rand()
#include <cmath> // for fabs()
#include <cstddef> // size_t
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::rand;
using ::fabs;
using ::size_t;
}
#endif
//#include <boost/test/test_exec_monitor.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
#include <boost/archive/dinkumware.hpp>
#endif
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/access.hpp>
class A
{
private:
friend class boost::serialization::access;
// note: from an aesthetic perspective, I would much prefer to have this
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
// compiler. So hold our nose and put it her to permit running of tests.
template<class Archive>
void serialize(
Archive &ar,
const unsigned int /* file_version */
){
ar & BOOST_SERIALIZATION_NVP(b);
#ifndef BOOST_NO_INT64_T
ar & BOOST_SERIALIZATION_NVP(f);
ar & BOOST_SERIALIZATION_NVP(g);
#endif
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 )
int i;
if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){
i = l;
ar & BOOST_SERIALIZATION_NVP(i);
}
else{
ar & BOOST_SERIALIZATION_NVP(i);
l = i;
}
#else
ar & BOOST_SERIALIZATION_NVP(l);
#endif
ar & BOOST_SERIALIZATION_NVP(m);
ar & BOOST_SERIALIZATION_NVP(n);
ar & BOOST_SERIALIZATION_NVP(o);
ar & BOOST_SERIALIZATION_NVP(p);
ar & BOOST_SERIALIZATION_NVP(q);
#ifndef BOOST_NO_CWCHAR
ar & BOOST_SERIALIZATION_NVP(r);
#endif
ar & BOOST_SERIALIZATION_NVP(c);
ar & BOOST_SERIALIZATION_NVP(s);
ar & BOOST_SERIALIZATION_NVP(t);
ar & BOOST_SERIALIZATION_NVP(u);
ar & BOOST_SERIALIZATION_NVP(v);
ar & BOOST_SERIALIZATION_NVP(w);
ar & BOOST_SERIALIZATION_NVP(x);
ar & BOOST_SERIALIZATION_NVP(y);
#ifndef BOOST_NO_STD_WSTRING
ar & BOOST_SERIALIZATION_NVP(z);
#endif
}
bool b;
#ifndef BOOST_NO_INT64_T
boost::int64_t f;
boost::uint64_t g;
#endif
enum h {
i = 0,
j,
k
} l;
std::size_t m;
signed long n;
unsigned long o;
signed short p;
unsigned short q;
#ifndef BOOST_NO_CWCHAR
wchar_t r;
#endif
char c;
signed char s;
unsigned char t;
signed int u;
unsigned int v;
float w;
double x;
std::string y;
#ifndef BOOST_NO_STD_WSTRING
std::wstring z;
#endif
public:
A();
bool operator==(const A &rhs) const;
bool operator!=(const A &rhs) const;
bool operator<(const A &rhs) const; // used by less
// hash function for class A
operator std::size_t () const;
friend std::ostream & operator<<(std::ostream & os, A const & a);
friend std::istream & operator>>(std::istream & is, A & a);
};
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
template<class S>
void randomize(S &x)
{
assert(0 == x.size());
for(;;){
unsigned int i = std::rand() % 27;
if(0 == i)
break;
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
}
}
template<class T>
void accumulate(std::size_t & s, const T & t){
const char * tptr = (const char *)(& t);
unsigned int count = sizeof(t);
while(count-- > 0){
s += *tptr++;
}
}
A::operator std::size_t () const {
std::size_t retval = 0;
accumulate(retval, b);
#ifndef BOOST_NO_INT64_T
accumulate(retval, f);
accumulate(retval, g);
#endif
accumulate(retval, l);
accumulate(retval, m);
accumulate(retval, n);
accumulate(retval, o);
accumulate(retval, p);
accumulate(retval, q);
#ifndef BOOST_NO_CWCHAR
accumulate(retval, r);
#endif
accumulate(retval, c);
accumulate(retval, s);
accumulate(retval, t);
accumulate(retval, u);
accumulate(retval, v);
return retval;
}
inline A::A() :
b(true),
#ifndef BOOST_NO_INT64_T
f(std::rand() * std::rand()),
g(std::rand() * std::rand()),
#endif
l(static_cast<enum h>(std::rand() % 3)),
m(std::rand()),
n(std::rand()),
o(std::rand()),
p(std::rand()),
q(std::rand()),
#ifndef BOOST_NO_CWCHAR
r(std::rand()),
#endif
c(std::rand()),
s(std::rand()),
t(std::rand()),
u(std::rand()),
v(std::rand()),
w((float)std::rand()),
x((double)std::rand())
{
randomize(y);
#ifndef BOOST_NO_STD_WSTRING
randomize(z);
#endif
}
inline bool A::operator==(const A &rhs) const
{
if(b != rhs.b)
return false;
if(l != rhs.l)
return false;
#ifndef BOOST_NO_INT64_T
if(f != rhs.f)
return false;
if(g != rhs.g)
return false;
#endif
if(m != rhs.m)
return false;
if(n != rhs.n)
return false;
if(o != rhs.o)
return false;
if(p != rhs.p)
return false;
if(q != rhs.q)
return false;
#ifndef BOOST_NO_CWCHAR
if(r != rhs.r)
return false;
#endif
if(c != rhs.c)
return false;
if(s != rhs.s)
return false;
if(t != rhs.t)
return false;
if(u != rhs.u)
return false;
if(v != rhs.v)
return false;
if(w == 0 && std::fabs(rhs.w) > std::numeric_limits<float>::epsilon())
return false;
if(std::fabs(rhs.w/w - 1.0) > std::numeric_limits<float>::epsilon())
return false;
if(x == 0 && std::fabs(rhs.x - x) > std::numeric_limits<float>::epsilon())
return false;
if(std::fabs(rhs.x/x - 1.0) > std::numeric_limits<float>::epsilon())
return false;
if(0 != y.compare(rhs.y))
return false;
#ifndef BOOST_NO_STD_WSTRING
if(0 != z.compare(rhs.z))
return false;
#endif
return true;
}
inline bool A::operator!=(const A &rhs) const
{
return ! (*this == rhs);
}
inline bool A::operator<(const A &rhs) const
{
if(b != rhs.b)
return b < rhs.b;
#ifndef BOOST_NO_INT64_T
if(f != rhs.f)
return f < rhs.f;
if(g != rhs.g)
return g < rhs.g;
#endif
if(l != rhs.l )
return l < rhs.l;
if(m != rhs.m )
return m < rhs.m;
if(n != rhs.n )
return n < rhs.n;
if(o != rhs.o )
return o < rhs.o;
if(p != rhs.p )
return p < rhs.p;
if(q != rhs.q )
return q < rhs.q;
#ifndef BOOST_NO_CWCHAR
if(r != rhs.r )
return r < rhs.r;
#endif
if(c != rhs.c )
return c < rhs.c;
if(s != rhs.s )
return s < rhs.s;
if(t != rhs.t )
return t < rhs.t;
if(u != rhs.u )
return u < rhs.u;
if(v != rhs.v )
return v < rhs.v;
if(w != rhs.w )
return w < rhs.w;
if(x != rhs.x )
return x < rhs.x;
int i = y.compare(rhs.y);
if(i != 0 )
return i < 0;
#ifndef BOOST_NO_STD_WSTRING
int j = z.compare(rhs.z);
if(j != 0 )
return j < 0;
#endif
return false;
}
#endif // BOOST_SERIALIZATION_TEST_A_HPP
-112
View File
@@ -1,112 +0,0 @@
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
#define BOOST_SERIALIZATION_TEST_B_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
// B.hpp
// (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 <cstdlib> // for rand()
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::rand;
}
#endif
#include <boost/serialization/version.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/base_object.hpp>
#include "A.hpp"
///////////////////////////////////////////////////////
// Derived class test
class B : public A
{
private:
friend class boost::serialization::access;
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
// write any base class info to the archive
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
// write out members
ar << BOOST_SERIALIZATION_NVP(s);
ar << BOOST_SERIALIZATION_NVP(t);
ar << BOOST_SERIALIZATION_NVP(u);
ar << BOOST_SERIALIZATION_NVP(v);
ar << BOOST_SERIALIZATION_NVP(w);
ar << BOOST_SERIALIZATION_NVP(x);
}
template<class Archive>
void load(Archive & ar, const unsigned int file_version)
{
// read any base class info to the archive
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
switch(file_version){
case 1:
case 2:
ar >> BOOST_SERIALIZATION_NVP(s);
ar >> BOOST_SERIALIZATION_NVP(t);
ar >> BOOST_SERIALIZATION_NVP(u);
ar >> BOOST_SERIALIZATION_NVP(v);
ar >> BOOST_SERIALIZATION_NVP(w);
ar >> BOOST_SERIALIZATION_NVP(x);
default:
break;
}
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
signed char s;
unsigned char t;
signed int u;
unsigned int v;
float w;
double x;
public:
B();
virtual ~B(){};
bool operator==(const B &rhs) const;
};
B::B() :
s(std::rand()),
t(std::rand()),
u(std::rand()),
v(std::rand()),
w((float)std::rand() / std::rand()),
x((double)std::rand() / std::rand())
{
}
BOOST_CLASS_VERSION(B, 2)
inline bool B::operator==(const B &rhs) const
{
return
A::operator==(rhs)
&& s == rhs.s
&& t == rhs.t
&& u == rhs.u
&& v == rhs.v
&& std::fabs(w - rhs.w) <= std::numeric_limits<float>::round_error()
&& std::fabs(x - rhs.x) <= std::numeric_limits<float>::round_error()
;
}
#endif // BOOST_SERIALIZATION_TEST_B_HPP
-112
View File
@@ -1,112 +0,0 @@
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
#define BOOST_SERIALIZATION_TEST_B_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
// B.hpp
// (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 <cstdlib> // for rand()
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::rand;
}
#endif
#include <boost/serialization/version.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/base_object.hpp>
#include "A.hpp"
///////////////////////////////////////////////////////
// Derived class test
class B : public A
{
private:
friend class boost::serialization::access;
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
// write any base class info to the archive
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
// write out members
ar << BOOST_SERIALIZATION_NVP(s);
ar << BOOST_SERIALIZATION_NVP(t);
ar << BOOST_SERIALIZATION_NVP(u);
ar << BOOST_SERIALIZATION_NVP(v);
ar << BOOST_SERIALIZATION_NVP(w);
ar << BOOST_SERIALIZATION_NVP(x);
}
template<class Archive>
void load(Archive & ar, const unsigned int file_version)
{
// read any base class info to the archive
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
switch(file_version){
case 1:
case 2:
ar >> BOOST_SERIALIZATION_NVP(s);
ar >> BOOST_SERIALIZATION_NVP(t);
ar >> BOOST_SERIALIZATION_NVP(u);
ar >> BOOST_SERIALIZATION_NVP(v);
ar >> BOOST_SERIALIZATION_NVP(w);
ar >> BOOST_SERIALIZATION_NVP(x);
default:
break;
}
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
signed char s;
unsigned char t;
signed int u;
unsigned int v;
float w;
double x;
public:
B();
virtual ~B(){};
bool operator==(const B &rhs) const;
};
B::B() :
s(std::rand()),
t(std::rand()),
u(std::rand()),
v(std::rand()),
w((float)std::rand() / std::rand()),
x((double)std::rand() / std::rand())
{
}
BOOST_CLASS_VERSION(B, 2)
inline bool B::operator==(const B &rhs) const
{
return
A::operator==(rhs)
&& s == rhs.s
&& t == rhs.t
&& u == rhs.u
&& v == rhs.v
&& std::fabs(w - rhs.w) <= std::numeric_limits<float>::round_error()
&& std::fabs(x - rhs.x) <= std::numeric_limits<float>::round_error()
;
}
#endif // BOOST_SERIALIZATION_TEST_B_HPP
-1
View File
@@ -19,7 +19,6 @@
#include <algorithm>
#include <iostream>
#include <cstddef> // NULL
#include <fstream>
#include <string>
+1 -1
View File
@@ -11,7 +11,7 @@
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#define BOOST_ARCHIVE_SOURCE
#include <boost/archive/binary_oarchive_impl.hpp>
+1 -1
View File
@@ -91,7 +91,7 @@ public:
virtual ~bus_stop(){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
BOOST_IS_ABSTRACT(bus_stop)
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
+7 -37
View File
@@ -10,6 +10,7 @@
// should pass compilation and execution
#include <sstream>
#define BOOST_ARCHIVE_SOURCE
#include "portable_binary_oarchive.hpp"
#include "portable_binary_iarchive.hpp"
@@ -19,36 +20,30 @@
namespace std{ using ::rand; }
#endif
// the following is required to be sure the "EXPORT" works if it is used
#define CUSTOM_ARCHIVE_TYPES portable_binary_oarchive,portable_binary_iarchive
class A
{
friend class boost::serialization::access;
char c;
int i;
int i2; // special tricky case to check sign extension
unsigned int ui;
long l;
unsigned long ul;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* version */){
ar & c & i & i2 & ui & l & ul ;
ar & i & ui & l & ul ;
}
public:
bool operator==(const A & rhs) const {
return
c == rhs.c
&& i == rhs.i
&& i2 == rhs.i2
&& ui == rhs.ui
&& l == rhs.l
&& ul == rhs.ul
i == rhs.i && ui == rhs.ui && l == rhs.l && ul == rhs.ul
;
}
A() :
c(std::rand()),
i(std::rand()),
i2(0x80),
ui(std::rand()),
l(std::rand() * std::rand()),
l(std::rand()),
ul(std::rand())
{}
};
@@ -67,31 +62,6 @@ int main( int /* argc */, char* /* argv */[] )
portable_binary_iarchive pbia(ss);
pbia >> a1;
}
if(! (a == a1))
return 1;
ss.clear();
{
portable_binary_oarchive pboa(ss, endian_big);
pboa << a;
}
{
portable_binary_iarchive pbia(ss, endian_big);
pbia >> a1;
}
if(! (a == a1))
return 1;
ss.clear();
{
portable_binary_oarchive pboa(ss, endian_big);
pboa << a;
}
{
portable_binary_iarchive pbia(ss, endian_big);
pbia >> a1;
}
return !(a == a1);
}
+5 -6
View File
@@ -11,7 +11,6 @@
#include <iomanip>
#include <iostream>
#include <cstddef> // NULL
#include <fstream>
#include <string>
@@ -42,8 +41,8 @@ private:
}
public:
static int count;
A(){++count;} // default constructor
virtual ~A(){--count;} // default destructor
A::A(){++count;} // default constructor
virtual A::~A(){--count;} // default destructor
};
BOOST_SERIALIZATION_SHARED_PTR(A)
@@ -61,8 +60,8 @@ private:
}
public:
static int count;
B() : A() {};
virtual ~B() {};
B::B() : A() {};
virtual B::~B() {};
};
BOOST_SERIALIZATION_SHARED_PTR(B)
@@ -82,7 +81,7 @@ void display(boost::shared_ptr<A> &spa, boost::shared_ptr<A> &spa1)
std::cout << "unique element count = " << A::count << std::endl;
}
int main(int /* argc */, char /* *argv[] */)
int main(int argc, char *argv[])
{
std::string filename(boost::archive::tmpdir());
filename += "/testfile";
-284
View File
@@ -1,284 +0,0 @@
#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_xml.hpp
//
// (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)
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/version.hpp>
// This illustration models the bus system of a small city.
// This includes, multiple bus stops, bus routes and schedules.
// There are different kinds of stops. Bus stops in general will
// will appear on multiple routes. A schedule will include
// muliple trips on the same route.
/////////////////////////////////////////////////////////////
// gps coordinate
//
// llustrates serialization for a simple type
//
class gps_position
{
friend class boost::serialization::access;
friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
int degrees;
int minutes;
float seconds;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
ar & BOOST_SERIALIZATION_NVP(degrees)
& BOOST_SERIALIZATION_NVP(minutes)
& BOOST_SERIALIZATION_NVP(seconds);
}
public:
// every serializable class needs a constructor
gps_position(){};
gps_position(int _d, int _m, float _s) :
degrees(_d), minutes(_m), seconds(_s)
{}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}
/////////////////////////////////////////////////////////////
// One bus stop
//
// illustrates serialization of serializable members
//
class bus_stop
{
friend class boost::serialization::access;
virtual std::string description() const = 0;
gps_position latitude;
gps_position longitude;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(latitude);
ar & BOOST_SERIALIZATION_NVP(longitude);
}
protected:
bus_stop(const gps_position & _lat, const gps_position & _long) :
latitude(_lat), longitude(_long)
{}
public:
bus_stop(){}
friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
virtual ~bus_stop(){}
};
BOOST_IS_ABSTRACT(bus_stop)
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
return os << bs.latitude << bs.longitude << ' ' << bs.description();
}
/////////////////////////////////////////////////////////////
// Several kinds of bus stops
//
// illustrates serialization of derived types
//
class bus_stop_corner : public bus_stop
{
friend class boost::serialization::access;
std::string street1;
std::string street2;
virtual std::string description() const
{
return street1 + " and " + street2;
}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
// save/load base class information
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
ar & BOOST_SERIALIZATION_NVP(street1);
ar & BOOST_SERIALIZATION_NVP(street2);
}
public:
bus_stop_corner(){}
bus_stop_corner(const gps_position & _lat, const gps_position & _long,
const std::string & _s1, const std::string & _s2
) :
bus_stop(_lat, _long), street1(_s1), street2(_s2)
{
}
};
class bus_stop_destination : public bus_stop
{
friend class boost::serialization::access;
std::string name;
virtual std::string description() const
{
return name;
}
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
& BOOST_SERIALIZATION_NVP(name);
}
public:
bus_stop_destination(){}
bus_stop_destination(
const gps_position & _lat, const gps_position & _long, const std::string & _name
) :
bus_stop(_lat, _long), name(_name)
{
}
};
/////////////////////////////////////////////////////////////
// a bus route is a collection of bus stops
//
// illustrates serialization of STL collection templates.
//
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient. That is objects pointed to by more than one
// pointer are stored only once. In such cases only one such
// object is restored and pointers are restored to point to it
//
class bus_route
{
friend class boost::serialization::access;
friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
typedef bus_stop * bus_stop_pointer;
std::list<bus_stop_pointer> stops;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
// in this program, these classes are never serialized directly but rather
// through a pointer to the base class bus_stop. So we need a way to be
// sure that the archive contains information about these derived classes.
//ar.template register_type<bus_stop_corner>();
ar.register_type(static_cast<bus_stop_corner *>(NULL));
//ar.template register_type<bus_stop_destination>();
ar.register_type(static_cast<bus_stop_destination *>(NULL));
// serialization of stl collections is already defined
// in the header
ar & BOOST_SERIALIZATION_NVP(stops);
}
public:
bus_route(){}
void append(bus_stop *_bs)
{
stops.insert(stops.end(), _bs);
}
};
std::ostream & operator<<(std::ostream &os, const bus_route &br)
{
std::list<bus_stop *>::const_iterator it;
// note: we're displaying the pointer to permit verification
// that duplicated pointers are properly restored.
for(it = br.stops.begin(); it != br.stops.end(); it++){
os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
}
return os;
}
/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
//
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
// See definition of operator<< <pair<F, S> >(ar, pair)
//
// illustrates nesting of serializable classes
//
// illustrates use of version number to automatically grandfather older
// versions of the same class.
class bus_schedule
{
friend class boost::serialization::access;
friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(schedule);
}
// note: this structure was made public. because the friend declarations
// didn't seem to work as expected.
public:
struct trip_info
{
template<class Archive>
void serialize(Archive &ar, const unsigned int file_version)
{
// in versions 2 or later
if(file_version >= 2)
// read the drivers name
ar & BOOST_SERIALIZATION_NVP(driver);
// all versions have the follwing info
ar & BOOST_SERIALIZATION_NVP(hour)
& BOOST_SERIALIZATION_NVP(minute);
}
// starting time
int hour;
int minute;
// only after system shipped was the driver's name added to the class
std::string driver;
trip_info(){}
trip_info(int _h, int _m, const std::string &_d) :
hour(_h), minute(_m), driver(_d)
{}
~trip_info(){
}
};
// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
private:
std::list<std::pair<trip_info, bus_route *> > schedule;
public:
void append(const std::string &_d, int _h, int _m, bus_route *_br)
{
schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
}
bus_schedule(){}
};
BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
BOOST_CLASS_VERSION(bus_schedule, 2)
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
{
return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
}
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
{
std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
os << it->first << *(it->second);
}
return os;
}
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
@@ -1,34 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_portable_binary_iarchive.cpp
// (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 <istream>
#define BOOST_ARCHIVE_SOURCE
#include "polymorphic_portable_binary_iarchive.hpp"
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_iarchive.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class binary_iarchive_impl<
polymorphic_portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>;
template class detail::archive_pointer_iserializer<
polymorphic_portable_binary_iarchive
> ;
} // namespace archive
} // namespace boost
@@ -1,35 +0,0 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_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
// polymorphic_portable_binary_iarchive.hpp
// (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/archive/detail/polymorphic_iarchive_dispatch.hpp>
#include "portable_binary_iarchive.hpp"
typedef boost::archive::detail::polymorphic_iarchive_dispatch<
portable_binary_iarchive
> polymorphic_portable_binary_iarchive;
#include <boost/version.hpp>
#if BOOST_VERSION > 103401
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
polymorphic_portable_binary_iarchive
)
#endif
#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
@@ -1,35 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_portable_binary_oarchive.cpp
// (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 <ostream>
#define BOOST_ARCHIVE_SOURCE
#include "polymorphic_portable_binary_oarchive.hpp"
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_oarchive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of binary stream
template class binary_oarchive_impl<
polymorphic_portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>;
template class detail::archive_pointer_oserializer<
polymorphic_portable_binary_oarchive
> ;
} // namespace archive
} // namespace boost
@@ -1,34 +0,0 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_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
// polymorphic_portable_binary_oarchive.hpp
// (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/archive/detail/polymorphic_oarchive_dispatch.hpp>
#include "portable_binary_oarchive.hpp"
typedef boost::archive::detail::polymorphic_oarchive_dispatch<
portable_binary_oarchive
> polymorphic_portable_binary_oarchive;
#include <boost/version.hpp>
#if BOOST_VERSION > 103401
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
polymorphic_portable_binary_oarchive
)
#endif
#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
-47
View File
@@ -1,47 +0,0 @@
#ifndef PORTABLE_BINARY_ARCHIVE_HPP
#define PORTABLE_BINARY_ARCHIVE_HPP
// (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)
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/static_assert.hpp>
#include <climits>
#if CHAR_BIT != 8
#error This code assumes an eight-bit byte.
#endif
#include <boost/archive/basic_archive.hpp>
#include <boost/detail/endian.hpp>
enum portable_binary_archive_flags {
endian_big = 0x4000,
endian_little = 0x8000
};
//#if ( endian_big <= boost::archive::flags_last )
//#error archive flags conflict
//#endif
inline void
reverse_bytes(char size, char *address){
char * first = address;
char * last = first + size - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
}
#endif // PORTABLE_BINARY_ARCHIVE_HPP
-130
View File
@@ -1,130 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.cpp
// (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 <istream>
#include <string>
//#include <cstring> // memcpy
#include <boost/detail/endian.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/archive_exception.hpp>
#include "portable_binary_iarchive.hpp"
void
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
char size;
l = 0;
this->primitive_base_t::load(size);
if(0 == size){
return;
}
bool negative = (size < 0);
if(negative)
size = -size;
if(size > maxsize)
boost::serialization::throw_exception(
portable_binary_iarchive_exception()
);
char * cptr = reinterpret_cast<char *>(& l);
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
#endif
this->primitive_base_t::load_binary(cptr, size);
#ifdef BOOST_BIG_ENDIAN
if(m_flags & endian_little)
#else
if(m_flags & endian_big)
#endif
reverse_bytes(size, cptr);
if(negative)
l = -l;
}
void
portable_binary_iarchive::load_override(
boost::archive::class_name_type & t, int
){
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
load_override(cn, 0);
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_class_name)
);
std::memcpy(t, cn.data(), cn.size());
// borland tweak
t.t[cn.size()] = '\0';
}
void
portable_binary_iarchive::init(unsigned int flags){
if(0 == (flags & boost::archive::no_header)){
// read signature in an archive version independent manner
std::string file_signature;
* this >> file_signature;
if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_signature
)
);
// make sure the version of the reading archive library can
// support the format of the archive being read
boost::archive::version_type input_library_version;
* this >> input_library_version;
// extra little .t is to get around borland quirk
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version.t)
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::unsupported_version
)
);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
this->set_library_version(input_library_version);
//#else
//#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
//detail::
//#endif
boost::archive::detail::basic_iarchive::set_library_version(
input_library_version
);
#endif
}
unsigned char x;
load(x);
m_flags = x << CHAR_BIT;
}
// explicitly instantiate for this
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
template class basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> ;
} // namespace archive
} // namespace boost
+94 -109
View File
@@ -6,42 +6,31 @@
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.hpp
// (C) Copyright 2002-7 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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <boost/serialization/string.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_binary_iprimitive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/archive/shared_ptr_helper.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include "portable_binary_archive.hpp"
#include <ostream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/detail/endian.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_iarchive_exception :
class portable_binary_archive_exception :
public virtual boost::archive::archive_exception
{
public:
typedef enum {
incompatible_integer_size
} exception_code;
portable_binary_iarchive_exception(exception_code c = incompatible_integer_size )
portable_binary_archive_exception(exception_code c = incompatible_integer_size )
{}
virtual const char *what( ) const throw( )
{
@@ -57,132 +46,128 @@ public:
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" input binary archive. It addresses integer size and endienness so
// that binary archives can be passed across systems. Note:floating point types
// not addressed here
// "Portable" input binary archive. This is a variation of the native binary
// archive. it addresses integer size and endienness so that binary archives can
// be passed across systems. Note:floating point types not addressed here
class portable_binary_iarchive :
public boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
// don't derive from binary_iarchive !!!
public boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>,
public boost::archive::detail::common_iarchive<
portable_binary_iarchive
>
,
public boost::archive::detail::shared_ptr_helper
{
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
{
typedef boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_iarchive<
portable_binary_iarchive
> archive_base_t;
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override load below
friend class boost::archive::detail::interface_iarchive<
portable_binary_iarchive
>;
friend class boost::archive::basic_binary_iarchive<portable_binary_iarchive>;
friend class boost::archive::load_access;
protected:
#endif
unsigned int m_flags;
void load_impl(boost::intmax_t & l, char maxsize);
void load_impl(long & l, char maxsize){
char size;
this->archive_base_t::load(size);
if(size > maxsize)
throw portable_binary_archive_exception() ;
l = 0;
load_binary(& l, size);
// we choose to use litle endian
#ifdef BOOST_BIG_ENDIAN
char * first = static_cast<char *>(static_cast<void *>(& l));
char * last = first + sizeof(l) - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
#endif
// extend sign if necessary
if((l >> (size - 1) * 8) & 0x80){
l |= (-1 << (size * 8));
}
}
// default fall through for any types not specified here
template<class T>
void load(T & t){
boost::intmax_t l;
load_impl(l, sizeof(T));
// use cast to avoid compile time warning
t = static_cast<T>(l);
}
void load(std::string & t){
this->primitive_base_t::load(t);
}
#ifndef BOOST_NO_STD_WSTRING
void load(std::wstring & t){
this->primitive_base_t::load(t);
void load(unsigned short & t){
long l;
load_impl(l, sizeof(unsigned short));
t = l;
}
#endif
void load(float & t){
this->primitive_base_t::load(t);
// floats not supported
//BOOST_STATIC_ASSERT(false);
void load(short & t){
long l;
load_impl(l, sizeof(short));
t = l;
}
void load(double & t){
this->primitive_base_t::load(t);
// doubles not supported
//BOOST_STATIC_ASSERT(false);
void load(unsigned int & t){
long l;
load_impl(l, sizeof(unsigned int));
t = l;
}
void load(char & t){
this->primitive_base_t::load(t);
void load(int & t){
long l;
load_impl(l, sizeof(int));
t = l;
}
void load(unsigned char & t){
this->primitive_base_t::load(t);
void load(unsigned long & t){
long l;
load_impl(l, sizeof(unsigned long));
t = l;
}
// intermediate level to support override of operators
// fot templates in the absence of partial function
// template ordering
typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
detail_common_iarchive;
template<class T>
void load_override(T & t, BOOST_PFTO int){
this->detail_common_iarchive::load_override(t, 0);
void load(long & t){
long l;
load_impl(l, sizeof(long));
t = l;
}
void load_override(boost::archive::class_name_type & t, int);
// binary files don't include the optional information
void load_override(
boost::archive::class_id_optional_type & /* t */,
int
){}
void init(unsigned int flags);
public:
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
primitive_base_t(
* is.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
archive_base_t(
is,
flags | boost::archive::no_header // skip default header checking
)
{
init(flags);
}
portable_binary_iarchive(
std::basic_streambuf<
std::istream::char_type,
std::istream::traits_type
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
init(flags);
// use our own header checking
if(0 != (flags & boost::archive::no_header)){
this->archive_base_t::init(flags);
// skip the following for "portable" binary archives
// boost::archive::basic_binary_oprimitive<derived_t, std::ostream>::init();
}
}
};
// required by export in boost version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
#endif
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_iarchive.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>;
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
} // namespace archive
} // namespace boost
// required by export in boost <= 1.34
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
#endif // PORTABLE_BINARY_IARCHIVE_HPP
-96
View File
@@ -1,96 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.cpp
// (C) Copyright 2002-7 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 <ostream>
#include <boost/detail/endian.hpp>
#include "portable_binary_oarchive.hpp"
void
portable_binary_oarchive::save_impl(
const boost::intmax_t l,
const char maxsize
){
char size = 0;
if(l == 0){
this->primitive_base_t::save(size);
return;
}
boost::intmax_t ll;
bool negative = (l < 0);
if(negative)
ll = -l;
else
ll = l;
do{
ll >>= CHAR_BIT;
++size;
}while(ll != 0);
this->primitive_base_t::save(
static_cast<char>(negative ? -size : size)
);
if(negative)
ll = -l;
else
ll = l;
char * cptr = reinterpret_cast<char *>(& ll);
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
if(m_flags & endian_little)
reverse_bytes(size, cptr);
#else
if(m_flags & endian_big)
reverse_bytes(size, cptr);
#endif
this->primitive_base_t::save_binary(cptr, size);
}
void
portable_binary_oarchive::init(unsigned int flags) {
if(m_flags == (endian_big | endian_little)){
boost::serialization::throw_exception(
portable_binary_oarchive_exception()
);
}
if(0 == (flags & boost::archive::no_header)){
// write signature in an archive version independent manner
const std::string file_signature(
boost::archive::BOOST_ARCHIVE_SIGNATURE()
);
* this << file_signature;
// write library version
const boost::archive::version_type v(
boost::archive::BOOST_ARCHIVE_VERSION()
);
* this << v;
}
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
}
// explicitly instantiate for this type of stream
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost {
namespace archive {
template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
template class basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> ;
} // namespace archive
} // namespace boost
+84 -123
View File
@@ -6,11 +6,6 @@
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.hpp
@@ -22,38 +17,9 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/serialization/string.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_binary_oprimitive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include "portable_binary_archive.hpp"
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_oarchive_exception :
public virtual boost::archive::archive_exception
{
public:
typedef enum {
invalid_flags
} exception_code;
portable_binary_oarchive_exception(exception_code c = invalid_flags )
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
switch(code){
case invalid_flags:
msg = "cannot be both big and little endian";
default:
boost::archive::archive_exception::what();
}
return msg;
}
};
#include <boost/archive/binary_oarchive.hpp>
#include <boost/detail/endian.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" output binary archive. This is a variation of the native binary
@@ -61,36 +27,65 @@ public:
// be passed across systems. Note:floating point types not addressed here
class portable_binary_oarchive :
public boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
// don't derive from binary_oarchive !!!
public boost::archive::binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>,
public boost::archive::detail::common_oarchive<
portable_binary_oarchive
>
{
typedef boost::archive::binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> archive_base_t;
typedef boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_oarchive<
portable_binary_oarchive
> archive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override save below
friend class boost::archive::detail::interface_oarchive<
portable_binary_oarchive
>;
friend class boost::archive::basic_binary_oarchive<portable_binary_oarchive>;
friend class boost::archive::save_access;
protected:
#endif
unsigned int m_flags;
void save_impl(const boost::intmax_t l, const char maxsize);
void save_impl(const long l){
long ll = l;
char size = 0;
if(l < 0){
// make sure that enough of data is output
// to include a high order bit indicating the sign
char x;
do{
x = ll;
ll >>= 8;
++size;
}while(ll != -1 && x < 0);
}
else{
do{
ll >>= 8;
++size;
}while(ll != 0);
}
this->archive_base_t::save(size);
// we choose to use litle endian
#ifdef BOOST_BIG_ENDIAN
char * first = static_cast<char *>(static_cast<void *>(& l));
char * last = first + sizeof(l) - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
#endif
save_binary(& l, size);
}
// add base class to the places considered when matching
// save function to a specific set of arguments. Note, this didn't
// work on my MSVC 7.0 system so we use the sure-fire method below
@@ -99,94 +94,60 @@ protected:
// default fall through for any types not specified here
template<class T>
void save(const T & t){
save_impl(t, sizeof(T));
}
void save(const std::string & t){
this->primitive_base_t::save(t);
}
#ifndef BOOST_NO_STD_WSTRING
void save(const std::wstring & t){
this->primitive_base_t::save(t);
void save(const short t){
save_impl(t);
}
#endif
void save(const float & t){
this->primitive_base_t::save(t);
// floats not supported
//BOOST_STATIC_ASSERT(false);
void save(const unsigned short t){
save_impl(t);
}
void save(const double & t){
this->primitive_base_t::save(t);
// doubles not supported
//BOOST_STATIC_ASSERT(false);
void save(const unsigned int t){
save_impl(t);
}
void save(const char & t){
this->primitive_base_t::save(t);
void save(const int t){
save_impl(t);
}
void save(const unsigned char & t){
this->primitive_base_t::save(t);
void save(const unsigned long t){
save_impl(t);
}
// default processing - kick back to base class. Note the
// extra stuff to get it passed borland compilers
typedef boost::archive::detail::common_oarchive<portable_binary_oarchive>
detail_common_oarchive;
template<class T>
void save_override(T & t, BOOST_PFTO int){
this->detail_common_oarchive::save_override(t, 0);
void save(const long t){
save_impl(t);
}
// explicitly convert to char * to avoid compile ambiguities
void save_override(const boost::archive::class_name_type & t, int){
const std::string s(t);
* this << s;
}
// binary files don't include the optional information
void save_override(
const boost::archive::class_id_optional_type & /* t */,
int
){}
void init(unsigned int flags);
public:
portable_binary_oarchive(std::ostream & os, unsigned flags = 0) :
primitive_base_t(
* os.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(flags & (endian_big | endian_little))
archive_base_t(
os,
flags | boost::archive::no_header // skip default header checking
)
{
init(flags);
}
portable_binary_oarchive(
std::basic_streambuf<
std::ostream::char_type,
std::ostream::traits_type
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
init(flags);
// use our own header checking
if(0 != (flags & boost::archive::no_header)){
this->archive_base_t::init(flags);
// skip the following for "portable" binary archives
// boost::archive::basic_binary_iprimitive<derived_t, std::ostream>::init();
}
}
};
#include <boost/archive/impl/basic_binary_oarchive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
// required by export in boost version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive)
#endif
namespace boost {
namespace archive {
// explicitly instantiate for this type of binary stream
template class binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>;
template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
} // namespace archive
} // namespace boost
// required by export in boost <= 1.34
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
#endif // PORTABLE_BINARY_OARCHIVE_HPP
+132
View File
@@ -0,0 +1,132 @@
#ifndef BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP
#define BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP
// (C) Copyright 2005 Matthias Troyer and Dave Abrahams
// 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)
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
namespace boost { namespace archive { namespace array {
// To conveniently array-optimize an input archive X:
//
// * Derive it from iarchive<X, Impl>, where Impl is an
// archive implementation base class from
// Boost.Serialization
//
// * add a member function template that implements the
// procedure for serializing arrays of T (for appropriate T)
//
// template <class T>
// load_array(serialization::array<T> &, unsigned int)
//
// * add a unary MPL lambda expression member called
// use_array_optimization whose result is convertible to
// mpl::true_ iff array elements of type T can be serialized
// with the load_array member function, and to mpl::false_ if
// the unoptimized procedure must be used.
template <class Archive>
class iarchive
: public archive::detail::common_iarchive<Archive>
{
typedef archive::detail::common_iarchive<Archive> Base;
public:
iarchive(unsigned int flags)
: archive::detail::common_iarchive<Archive>(flags)
{}
// save_override for std::vector and serialization::array dispatches to
// save_optimized with an additional argument.
//
// If that argument is of type mpl::true_, an optimized serialization is provided
// If it is false, we just forward to the default serialization in the base class
//the default version dispatches to the base class
template<class T>
void load_optimized(T &t, unsigned int version, mpl::false_)
{
Base::load_override(t, version);
}
// the optimized implementation for vector uses serialization::array
template<class U, class Allocator>
void load_optimized(
std::vector<U, Allocator> &t, unsigned int version, mpl::true_)
{
t.clear();
// retrieve number of elements
serialization::collection_size_type count;
*this->This() >> BOOST_SERIALIZATION_NVP(count);
t.resize(count);
if (!t.empty())
* this->This() >> serialization::make_array(serialization::detail::get_data(t),t.size());
}
// the optimized implementation for serialization::array uses save_array
template<class ValueType>
void load_optimized(
serialization::array<ValueType> &t, unsigned int version, mpl::true_)
{
this->This()->load_array(t,version);
}
// to load a vector:
// if the value type is trivially constructable or an optimized array save exists,
// then we can use the optimized version
template<class ValueType, class Allocator>
void load_override(std::vector<ValueType,Allocator> &x, unsigned int version)
{
typedef typename mpl::and_<
mpl::not_<is_same<ValueType,bool> >,
mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, ValueType>
>::type use_optimized;
load_optimized(x,version, use_optimized() );
}
// dispatch loading of arrays to the optimized version where supported
template<class ValueType>
void load_override(serialization::array<ValueType> const& x, unsigned int version)
{
typedef typename mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, ValueType
>::type use_optimized;
load_optimized(const_cast<serialization::array<ValueType>&>(x),version,use_optimized());
}
// Load everything else in the usual way, forwarding on to the base class
template<class T>
void load_override(T & x, unsigned BOOST_PFTO int version)
{
Base::load_override(x, static_cast<unsigned int>(version));
}
};
} } } // end namespace boost::archive::array
#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
+130
View File
@@ -0,0 +1,130 @@
#ifndef BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
#define BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
// (C) Copyright 2005 Matthias Troyer and Dave Abrahams
// 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)
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
namespace boost { namespace archive { namespace array {
// To conveniently array-optimize an output archive X:
//
// * Derive it from oarchive<X, Impl>, where Impl is an
// archive implementation base class from
// Boost.Serialization
//
// * add a member function template that implements the
// procedure for serializing arrays of T (for appropriate T)
//
// template <class T>
// save_array(serialization::array<T> const &, unsigned int)
//
// * add a unary MPL lambda expression member called
// use_array_optimization whose result is convertible to
// mpl::true_ iff array elements of type T can be serialized
// with the load_array member function, and to mpl::false_ if
// the unoptimized procedure must be used.
template <class Archive>
class oarchive
: public archive::detail::common_oarchive<Archive>
{
typedef archive::detail::common_oarchive<Archive> Base;
public:
oarchive(unsigned int flags)
: archive::detail::common_oarchive<Archive>(flags)
{}
// save_override for std::vector and serialization::array dispatches to
// save_optimized with an additional argument.
//
// If that argument is of type mpl::true_, an optimized serialization is provided
// If it is false, we just forward to the default serialization in the base class
//the default version dispatches to the base class
template<class T>
void save_optimized(T const &t, unsigned int version, mpl::false_)
{
Base::save_override(t, version);
}
// the optimized implementation for vector uses serialization::array
template<class ValueType, class Allocator>
void save_optimized(
const std::vector<ValueType, Allocator> &t, unsigned int, mpl::true_)
{
const serialization::collection_size_type count(t.size());
* this->This() << BOOST_SERIALIZATION_NVP(count);
if (!t.empty())
* this->This() << serialization::make_array(serialization::detail::get_data(t),t.size());
}
// the optimized implementation for serialization::array uses save_array
template<class ValueType>
void save_optimized(
const serialization::array<ValueType> &t, unsigned int version, mpl::true_)
{
this->This()->save_array(t,version);
}
// to save a vector:
// if the value type is trivially constructable or an optimized array save exists,
// then we can use the optimized version
template<class ValueType, class Allocator>
void save_override(std::vector<ValueType,Allocator> const &x, unsigned int version)
{
typedef BOOST_DEDUCED_TYPENAME remove_const<ValueType>::type value_type;
typedef typename mpl::and_<
mpl::not_<is_same<value_type,bool> >,
mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, value_type>
>::type use_optimized;
save_optimized(x,version,use_optimized() );
}
// dispatch saving of arrays to the optimized version where supported
template<class ValueType>
void save_override(serialization::array<ValueType> const& x, unsigned int version)
{
typedef typename mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, BOOST_DEDUCED_TYPENAME remove_const<ValueType>::type
>::type use_optimized;
save_optimized(x,version,use_optimized());
}
// Load everything else in the usual way, forwarding on to the
// Base class
template<class T>
void save_override(T const& x, unsigned BOOST_PFTO int version)
{
Base::save_override(x, static_cast<unsigned int>(version));
}
};
} } } // end namespace boost::archive::array
#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
+5 -5
View File
@@ -17,7 +17,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/serialization/strong_typedef.hpp>
#include <boost/strong_typedef.hpp>
#include <boost/noncopyable.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
@@ -86,17 +86,17 @@ enum archive_flags {
no_header = 1, // suppress archive header info
no_codecvt = 2, // suppress alteration of codecvt facet
no_xml_tag_checking = 4, // suppress checking of xml tags
no_tracking = 8, // suppress ALL tracking
flags_last = 8
no_tracking = 8 // suppress ALL tracking
// no_object_creation = 16 // don't create any new objects
};
#define NULL_POINTER_TAG class_id_type(-1)
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_SIGNATURE();
ARCHIVE_SIGNATURE();
BOOST_ARCHIVE_DECL(unsigned char)
BOOST_ARCHIVE_VERSION();
ARCHIVE_VERSION();
}// namespace archive
}// namespace boost
@@ -22,15 +22,15 @@
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
//#include <cstring>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/iarchive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -40,7 +40,7 @@ namespace archive {
// class basic_binary_iarchive - read serialized objects from a input binary stream
template<class Archive>
class basic_binary_iarchive :
public detail::common_iarchive<Archive>
public array::iarchive<Archive>
{
protected:
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
@@ -56,10 +56,10 @@ public:
// fot templates in the absence of partial function
// template ordering. If we get here pass to base class
// note extra nonsense to sneak it pass the borland compiers
typedef detail::common_iarchive<Archive> detail_common_iarchive;
typedef array::iarchive<Archive> array_iarchive;
template<class T>
void load_override(T & t, BOOST_PFTO int version){
this->detail_common_iarchive::load_override(t, static_cast<int>(version));
void load_override(T & t, BOOST_PFTO int){
this->array_iarchive::load_override(t, 0);
}
// binary files don't include the optional information
void load_override(class_id_optional_type & /* t */, int){}
@@ -113,7 +113,7 @@ public:
init();
basic_binary_iarchive(unsigned int flags) :
detail::common_iarchive<Archive>(flags)
array_iarchive(flags)
{}
};
@@ -6,10 +6,6 @@
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( disable : 4800 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_binary_iprimitive.hpp
//
@@ -45,7 +41,7 @@ namespace std{
#include <boost/cstdint.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/throw_exception.hpp>
//#include <boost/limits.hpp>
//#include <boost/io/ios_state.hpp>
@@ -53,7 +49,7 @@ namespace std{
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -76,11 +72,8 @@ public:
Archive * This(){
return static_cast<Archive *>(this);
}
#ifndef BOOST_NO_STD_LOCALE
boost::scoped_ptr<std::locale> archive_locale;
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
#endif
// main template for serilization of primitive types
template<class T>
@@ -120,12 +113,7 @@ public:
~basic_binary_iprimitive();
public:
// we provide an optimized load for all fundamental types
// typedef serialization::is_bitwise_serializable<mpl::_1>
// use_array_optimization;
struct use_array_optimization {
template <class T>
struct apply : public serialization::is_bitwise_serializable<T> {};
};
typedef is_fundamental<mpl::_1> use_array_optimization;
// the optimized load_array dispatches to load_binary
template <class ValueType>
@@ -144,30 +132,50 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
void *address,
std::size_t count
){
#if 0
assert(
static_cast<std::size_t>((std::numeric_limits<std::streamsize>::max)()) >= count
);
//if(is.fail())
// boost::throw_exception(archive_exception(archive_exception::stream_error));
// note: an optimizer should eliminate the following for char files
std::size_t s = count / sizeof(BOOST_DEDUCED_TYPENAME IStream::char_type);
is.read(
static_cast<BOOST_DEDUCED_TYPENAME IStream::char_type *>(address),
s
);
// note: an optimizer should eliminate the following for char files
s = count % sizeof(BOOST_DEDUCED_TYPENAME IStream::char_type);
if(0 < s){
if(is.fail())
boost::throw_exception(archive_exception(archive_exception::stream_error));
BOOST_DEDUCED_TYPENAME IStream::char_type t;
is.read(& t, 1);
std::memcpy(address, &t, s);
}
#endif
// note: an optimizer should eliminate the following for char files
std::streamsize s = count / sizeof(Elem);
std::streamsize scount = m_sb.sgetn(
static_cast<Elem *>(address),
s
);
if(scount != static_cast<std::streamsize>(s))
boost::serialization::throw_exception(
if(scount != static_cast<std::size_t>(s))
boost::throw_exception(
archive_exception(archive_exception::stream_error)
);
// note: an optimizer should eliminate the following for char files
s = count % sizeof(Elem);
if(0 < s){
// if(is.fail())
// boost::serialization::throw_exception(
// archive_exception(archive_exception::stream_error)
// );
// boost::throw_exception(archive_exception(archive_exception::stream_error));
Elem t;
scount = m_sb.sgetn(& t, 1);
if(scount != 1)
boost::serialization::throw_exception(
boost::throw_exception(
archive_exception(archive_exception::stream_error)
);
std::memcpy(static_cast<char*>(address) + (count - s), &t, s);
std::memcpy(address, &t, s);
}
}
@@ -24,12 +24,13 @@
// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON
#include <boost/config.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/array/oarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/oarchive.hpp>
namespace boost {
namespace archive {
@@ -44,7 +45,7 @@ namespace archive {
// of time. So under some circumstances it may be he right choice.
template<class Archive>
class basic_binary_oarchive :
public archive::detail::common_oarchive<Archive>
public array::oarchive<Archive>
{
protected:
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
@@ -57,12 +58,15 @@ public:
friend class detail::interface_oarchive<Archive>;
#endif
// any datatype not specifed below will be handled by base class
typedef detail::common_oarchive<Archive> detail_common_oarchive;
typedef array::oarchive<Archive> array_oarchive;
template<class T>
void save_override(const T & t, BOOST_PFTO int version){
this->detail_common_oarchive::save_override(t, static_cast<int>(version));
void save_override(const T & t, BOOST_PFTO int){
this->array_oarchive::save_override(t, 0);
}
template<class T>
void save_override(T & t, BOOST_PFTO int){
this->save_override(const_cast<const T &>(t), 0);
}
// binary files don't include the optional information
void save_override(const class_id_optional_type & /* t */, int){}
@@ -113,7 +117,7 @@ public:
init();
basic_binary_oarchive(unsigned int flags) :
detail::common_oarchive<Archive>(flags)
array_oarchive(flags)
{}
};
@@ -26,9 +26,9 @@
#include <iosfwd>
#include <cassert>
#include <locale>
#include <cstddef> // size_t
#include <streambuf> // basic_streambuf
#include <string>
#include <cstddef> // size_t
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
@@ -41,12 +41,12 @@ namespace std{
//#include <boost/limits.hpp>
//#include <boost/io/ios_state.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/throw_exception.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -71,10 +71,9 @@ public:
Archive * This(){
return static_cast<Archive *>(this);
}
#ifndef BOOST_NO_STD_LOCALE
boost::scoped_ptr<std::locale> archive_locale;
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
#endif
// default saving of primitives.
template<class T>
void save(const T & t)
@@ -88,7 +87,8 @@ public:
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
void save(const bool t){
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
int i = t;
assert(0 == i || 1 == i);
save_binary(& t, sizeof(t));
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -113,20 +113,12 @@ public:
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~basic_binary_oprimitive();
public:
// we provide an optimized save for all fundamental types
// typedef serialization::is_bitwise_serializable<mpl::_1>
// use_array_optimization;
// workaround without using mpl lambdas
struct use_array_optimization {
template <class T>
struct apply : public boost::serialization::is_bitwise_serializable<T> {};
};
typedef is_fundamental<mpl::_1> use_array_optimization;
// the optimized save_array dispatches to save_binary
template <class ValueType>
void save_array(boost::serialization::array<ValueType> const& a, unsigned int)
void save_array(serialization::array<ValueType> const& a, unsigned int)
{
save_binary(a.address(),a.count()*sizeof(ValueType));
}
@@ -148,9 +140,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save_binary(
// mode where by cr characters recieve special treatment.
// be sure that the output stream is opened with ios::binary
//if(os.fail())
// boost::serialization::throw_exception(
// archive_exception(archive_exception::stream_error)
// );
// boost::throw_exception(archive_exception(archive_exception::stream_error));
// figure number of elements to output - round up
count = ( count + sizeof(Elem) - 1)
/ sizeof(Elem);
@@ -159,9 +149,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save_binary(
count
);
if(count != static_cast<std::size_t>(scount))
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
//os.write(
// static_cast<const BOOST_DEDUCED_TYPENAME OStream::char_type *>(address),
// count
@@ -25,13 +25,14 @@
// See <http://www.boost.org/libs/io/> for the library's home page.
#ifndef BOOST_NO_STD_LOCALE
#include <locale> // for std::locale
#endif
#include <streambuf> // for std::basic_streambuf
namespace boost{
namespace archive{
#ifndef BOOST_NO_STD_LOCALE
template < typename Ch, class Tr >
class basic_streambuf_locale_saver
{
+11 -1
View File
@@ -25,7 +25,7 @@
// use two template parameters
#include <boost/config.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
@@ -61,6 +61,16 @@ public:
{
this->detail_common_iarchive::load_override(t, 0);
}
#if 0
// Borland compilers has a problem with strong type. Try to fix this here
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
void load_override(version_type & t, int){
unsigned int x;
* this->This() >> x;
t.t = version_type(x);
}
#endif
#endif
// text file don't include the optional information
void load_override(class_id_optional_type & /*t*/, int){}
@@ -43,7 +43,7 @@ namespace std{
#include <boost/archive/dinkumware.hpp>
#endif
#include <boost/serialization/throw_exception.hpp>
#include <boost/throw_exception.hpp>
#include <boost/limits.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/scoped_ptr.hpp>
@@ -68,29 +68,21 @@ public:
IStream &is;
io::ios_flags_saver flags_saver;
io::ios_precision_saver precision_saver;
#ifndef BOOST_NO_STD_LOCALE
boost::scoped_ptr<std::locale> archive_locale;
io::basic_ios_locale_saver<
BOOST_DEDUCED_TYPENAME IStream::char_type, BOOST_DEDUCED_TYPENAME IStream::traits_type
> locale_saver;
#endif
template<class T>
void load(T & t)
{
if(is.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
is >> t;
}
void load(unsigned char & t)
{
if(is.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
unsigned short int i;
is >> i;
t = static_cast<unsigned char>(i);
@@ -98,9 +90,7 @@ public:
void load(signed char & t)
{
if(is.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
signed short int i;
is >> i;
t = static_cast<signed char>(i);
@@ -108,9 +98,7 @@ public:
void load(char & t)
{
if(is.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
short int i;
is >> i;
t = static_cast<char>(i);
@@ -119,9 +107,7 @@ public:
void load(wchar_t & t)
{
if(is.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
unsigned i;
is >> i;
t = static_cast<wchar_t>(i);
@@ -26,7 +26,7 @@
#include <cassert>
#include <boost/config.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
@@ -38,7 +38,7 @@ namespace boost {
namespace archive {
/////////////////////////////////////////////////////////////////////////
// class basic_text_oarchive
// class basic_text_iarchive - read serialized objects from a input text stream
template<class Archive>
class basic_text_oarchive :
public detail::common_oarchive<Archive>
+14 -36
View File
@@ -26,9 +26,9 @@
#include <iomanip>
#include <locale>
#include <cstddef> // size_t
#include <cmath> // isnan
#include <cassert>
#include <cstddef> // size_t
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -48,7 +48,7 @@ namespace std{
#include <boost/limits.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/throw_exception.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -71,21 +71,16 @@ public:
OStream &os;
io::ios_flags_saver flags_saver;
io::ios_precision_saver precision_saver;
#ifndef BOOST_NO_STD_LOCALE
boost::scoped_ptr<std::locale> archive_locale;
io::basic_ios_locale_saver<
BOOST_DEDUCED_TYPENAME OStream::char_type, BOOST_DEDUCED_TYPENAME OStream::traits_type
> locale_saver;
#endif
// default saving of primitives.
template<class T>
void save(const T &t){
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << t;
}
@@ -94,44 +89,35 @@ public:
void save(const bool t){
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
int i = t;
assert(0 == i || 1 == i);
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << t;
}
void save(const signed char t)
{
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << static_cast<short int>(t);
}
void save(const unsigned char t)
{
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << static_cast<short unsigned int>(t);
}
void save(const char t)
{
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << static_cast<short int>(t);
}
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
void save(const wchar_t t)
{
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << static_cast<int>(t);
}
#endif
@@ -139,9 +125,7 @@ public:
{
// must be a user mistake - can't serialize un-initialized data
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << std::setprecision(std::numeric_limits<float>::digits10 + 2);
os << t;
}
@@ -149,9 +133,7 @@ public:
{
// must be a user mistake - can't serialize un-initialized data
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << std::setprecision(std::numeric_limits<double>::digits10 + 2);
os << t;
}
@@ -163,17 +145,13 @@ public:
// unformatted append of one character
void put(int c){
if(os.fail())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
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())
boost::serialization::throw_exception(
archive_exception(archive_exception::stream_error)
);
boost::throw_exception(archive_exception(archive_exception::stream_error));
while('\0' != *s)
os.put(*s++);
}
+43 -8
View File
@@ -24,39 +24,74 @@
namespace boost {
namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by xml archives
//
class xml_archive_exception :
public virtual archive_exception
{
public:
typedef enum {
xml_archive_parsing_error, // see save_register
xml_archive_tag_mismatch,
xml_archive_tag_name_error
} exception_code;
xml_archive_exception(exception_code c)
{}
virtual const char *what( ) const throw( )
{
const char *msg;
switch(code){
case xml_archive_parsing_error:
msg = "unrecognized XML syntax";
break;
case xml_archive_tag_mismatch:
msg = "XML start/end tag mismatch";
break;
case xml_archive_tag_name_error:
msg = "Invalid XML tag name";
break;
default:
msg = archive_exception::what();
break;
}
return msg;
}
};
// constant strings used in xml i/o
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_OBJECT_ID();
OBJECT_ID();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_OBJECT_REFERENCE();
OBJECT_REFERENCE();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_CLASS_ID();
CLASS_ID();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE();
CLASS_ID_REFERENCE();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_CLASS_NAME();
CLASS_NAME();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_TRACKING();
TRACKING();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_VERSION();
VERSION();
extern
BOOST_ARCHIVE_DECL(const char *)
BOOST_ARCHIVE_XML_SIGNATURE();
SIGNATURE();
}// namespace archive
}// namespace boost
+1 -1
View File
@@ -17,7 +17,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
@@ -88,6 +88,5 @@ public:
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive)
#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP
@@ -17,7 +17,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/archive/basic_binary_iprimitive.hpp>
#include <boost/archive/basic_binary_iarchive.hpp>
@@ -42,7 +42,7 @@ protected:
// make this protected so it can be called from a derived archive
template<class T>
void load_override(T & t, BOOST_PFTO int){
this->basic_binary_iarchive<Archive>::load_override(t, 0L);
basic_binary_iarchive<Archive>::load_override(t, 0);
}
void init(unsigned int flags){
if(0 != (flags & no_header))
@@ -50,6 +50,5 @@ typedef binary_oarchive naked_binary_oarchive;
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_oarchive)
#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP
@@ -17,7 +17,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
#include <boost/archive/basic_binary_oprimitive.hpp>
#include <boost/archive/basic_binary_oarchive.hpp>
@@ -42,7 +42,7 @@ protected:
// make this protected so it can be called from a derived archive
template<class T>
void save_override(T & t, BOOST_PFTO int){
this->basic_binary_oarchive<Archive>::save_override(t, 0L);
basic_binary_oarchive<Archive>::save_override(t, 0);
}
void init(unsigned int flags) {
if(0 != (flags & no_header))
+20 -11
View File
@@ -17,16 +17,25 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <locale>
#include <cstddef> // NULL, size_t
#include <cwchar> // for mbstate_t
#include <boost/config.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <cstddef>
#if defined(BOOST_NO_STDC_NAMESPACE)
using ::codecvt;
using ::mbstate_t;
using ::size_t
#endif
#include <boost/config.hpp>
namespace std{
#if defined(__LIBCOMO__)
using ::mbstate_t;
#elif defined(__QNXNTO__)
//using std::mbstate_t;
#elif defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB == 1
using ::mbstate_t;
#elif defined(__SGI_STL_PORT)
#elif defined(BOOST_NO_STDC_NAMESPACE)
using ::codecvt;
using ::mbstate_t;
#elif defined(BOOST_RWSTD_VER)
using ::mbstate_t;
#endif
} // namespace std
namespace boost {
namespace archive {
@@ -49,7 +58,7 @@ public:
template<>
class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
{
virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
virtual std::codecvt_base::result
do_out(
std::mbstate_t & state,
const wchar_t * first1,
@@ -59,7 +68,7 @@ class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
char * last2,
char * & next2
) const;
virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
virtual std::codecvt_base::result
do_in(
std::mbstate_t & state,
const char * first1,
+4 -4
View File
@@ -8,12 +8,12 @@
// See http://www.boost.org for updates, documentation, and revision history.
#if defined( __BORLANDC__ )
#pragma nopushoptwarn
#endif
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#if defined( __BORLANDC__ )
#pragma nopushoptwarn
#endif
@@ -17,7 +17,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <cstddef> // NULL
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -77,7 +76,8 @@ public:
// type_info. returns NULL if there is no such instance. This
// would indicate that the no object of the specified type was loaded
// any where in the code.
static BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *)
static
BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *)
find(
const boost::serialization::extended_type_info & eti
);
@@ -51,7 +51,8 @@ public:
// type_info. returns NULL, if there is no such instance. This
// would indicate that the no object of the specified type was saved
// any where in the code.
static BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *)
static
BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *)
find(
const boost::serialization::extended_type_info & eti
);
@@ -9,7 +9,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// auto_link_archive.hpp
//
// (c) Copyright Robert Ramey 2004
// © Copyright Robert Ramey 2004
// 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,24 +25,23 @@
#include <boost/archive/detail/decl.hpp>
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \
&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \
&& !defined(BOOST_SERIALIZATION_SOURCE)
#if !defined(BOOST_ARCHIVE_SOURCE) \
&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB)
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_serialization
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_serialization
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP
@@ -9,7 +9,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// auto_link_warchive.hpp
//
// (c) Copyright Robert Ramey 2004
// © Copyright Robert Ramey 2004
// 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)
@@ -8,7 +8,7 @@
// basic_config.hpp ---------------------------------------------//
// (c) Copyright Robert Ramey 2004
// © Copyright Robert Ramey 2004
// 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)
+13 -13
View File
@@ -20,13 +20,15 @@
// #include <boost/scoped_ptr.hpp>
#include <boost/config.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/serialization/tracking_enum.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/decl.hpp>
#include <boost/serialization/tracking_enum.hpp>
#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
@@ -64,19 +66,17 @@ public:
// note: NOT part of the public API.
void next_object_pointer(void *t);
void register_basic_serializer(
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_iserializer & bis
const basic_iserializer & bis
);
void load_object(
void *t,
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_iserializer & bis
const basic_iserializer & bis
);
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_pointer_iserializer *
const basic_pointer_iserializer *
load_pointer(
void * & t,
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */
basic_pointer_iserializer * bpis_ptr,
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */
basic_pointer_iserializer * (*finder)(
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & eti
)
);
@@ -99,9 +99,9 @@ public:
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_TT_BROKEN_COMPILER_SPEC(
boost::archive::detail::basic_iarchive
)
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(
boost::archive::detail::basic_iarchive
)
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
@@ -16,12 +16,13 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <cstdlib> // NULL
#include <boost/config.hpp>
#include <boost/archive/detail/decl.hpp>
#include <boost/archive/detail/basic_serializer.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/basic_serializer.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -41,10 +42,10 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer :
public basic_serializer
{
private:
basic_pointer_iserializer *m_bpis;
basic_pointer_iserializer *bpis;
protected:
explicit basic_iserializer(
const boost::serialization::extended_type_info & type
const boost::serialization::extended_type_info & type_
);
// account for bogus gcc warning
#if defined(__GNUC__)
@@ -53,13 +54,13 @@ protected:
~basic_iserializer();
public:
bool serialized_as_pointer() const {
return m_bpis != NULL;
return bpis != NULL;
}
void set_bpis(basic_pointer_iserializer *bpis){
m_bpis = bpis;
void set_bpis(basic_pointer_iserializer *bpis_){
bpis = bpis_;
}
const basic_pointer_iserializer * get_bpis_ptr() const {
return m_bpis;
return bpis;
}
virtual void load_object_data(
basic_iarchive & ar,
@@ -17,8 +17,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <cstddef> // NULL
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/detail/workaround.hpp>
// can't use this - much as I'd like to as borland doesn't support it
// #include <boost/scoped_ptr.hpp>
@@ -29,6 +28,9 @@
#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
@@ -69,15 +71,16 @@ protected:
public:
// note: NOT part of the public interface
void register_basic_serializer(
const basic_oserializer & bos
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer & bos
);
void save_object(
const void *x,
const basic_oserializer & bos
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer & bos
);
void save_pointer(
const void * t,
const basic_pointer_oserializer * bpos_ptr
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_pointer_oserializer * bpos_ptr
);
void save_null_pointer(){
vsave(NULL_POINTER_TAG);
@@ -94,7 +97,7 @@ public:
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_TT_BROKEN_COMPILER_SPEC(
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(
boost::archive::detail::basic_oarchive
)
@@ -16,7 +16,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cstddef> // NULL
#include <cstdlib> // NULL
#include <boost/config.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
@@ -41,7 +41,7 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer :
public basic_serializer
{
private:
basic_pointer_oserializer *m_bpos;
basic_pointer_oserializer *bpos;
protected:
explicit basic_oserializer(
const boost::serialization::extended_type_info & type_
@@ -53,13 +53,13 @@ protected:
~basic_oserializer();
public:
bool serialized_as_pointer() const {
return m_bpos != NULL;
return bpos != NULL;
}
void set_bpos(basic_pointer_oserializer *bpos){
m_bpos = bpos;
void set_bpos(basic_pointer_oserializer *bpos_){
bpos = bpos_;
}
const basic_pointer_oserializer * get_bpos() const {
return m_bpos;
return bpos;
}
virtual void save_object_data(
basic_oarchive & ar, const void * x
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -61,4 +61,4 @@ public:
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
#endif // BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP
#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -40,12 +40,12 @@ protected:
explicit basic_pointer_oserializer(
const boost::serialization::extended_type_info & type_
);
public:
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
~basic_pointer_oserializer();
public:
virtual const basic_oserializer & get_basic_serializer() const = 0;
virtual void save_object_ptr(
basic_oarchive & ar,
@@ -59,4 +59,4 @@ public:
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP
#endif // BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP
@@ -17,7 +17,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <cstddef> // NULL
#include <boost/noncopyable.hpp>
#include <boost/config.hpp>
@@ -35,25 +34,14 @@ protected:
const boost::serialization::extended_type_info & eti
) :
m_eti(eti)
{
assert(NULL != & eti);
}
{}
public:
const boost::serialization::extended_type_info & get_eti() const {
return m_eti;
}
};
inline bool
operator<(const basic_serializer & lhs, const basic_serializer & rhs) {
return & lhs.get_eti() < & rhs.get_eti();
}
class basic_serializer_arg : public basic_serializer {
public:
basic_serializer_arg(const serialization::extended_type_info & eti) :
basic_serializer(eti)
{}
bool operator<(const basic_serializer & rhs) const {
return & m_eti < & rhs.get_eti();
}
};
} // namespace detail
@@ -34,22 +34,32 @@ namespace detail {
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer;
bool operator<(const basic_serializer & lhs, const basic_serializer & rhs);
struct BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) type_info_pointer_compare
{
bool operator()(
const basic_serializer * lhs, const basic_serializer * rhs
) const {
return *lhs < *rhs;
}
) const ;
};
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer_map : public
boost::noncopyable
{
typedef std::set<const basic_serializer *, type_info_pointer_compare> map_type;
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;
void erase(basic_serializer * bs);
basic_serializer_map(bool & deleted);
~basic_serializer_map();
private:
// cw 8.3 requires this
basic_serializer_map& operator=(basic_serializer_map const&);
};
typedef BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) std::set<
const basic_serializer *,
type_info_pointer_compare
> basic_serializer_map;
} // namespace detail
} // namespace archive
} // namespace boost
@@ -20,7 +20,7 @@
#include <boost/archive/detail/interface_iarchive.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/serialization/pfto.hpp>
#include <boost/pfto.hpp>
namespace boost {
namespace archive {
@@ -60,8 +60,8 @@ protected:
}
// default implementations of functions which emit start/end tags for
// archive types that require them.
void load_start(const char * /*name*/){}
void load_end(const char * /*name*/){}
void load_start(const char *name){}
void load_end(const char *name){}
// default archive initialization
common_iarchive(unsigned int flags = 0) :
basic_iarchive(flags),
@@ -63,8 +63,8 @@ protected:
void save_override(T & t, BOOST_PFTO int){
archive::save(* this->This(), t);
}
void save_start(const char * /*name*/){}
void save_end(const char * /*name*/){}
void save_start(const char *name){}
void save_end(const char *name){}
common_oarchive(unsigned int flags = 0) :
basic_oarchive(flags),
interface_oarchive<Archive>()
+1 -1
View File
@@ -9,7 +9,7 @@
/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8
// decl.hpp
//
// (c) Copyright Robert Ramey 2004
// © Copyright Robert Ramey 2004
// 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)
+45
View File
@@ -0,0 +1,45 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP
# define BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP
# include <boost/serialization/force_include.hpp>
namespace boost { namespace archive { namespace detail {
//
// Provides a dynamically-initialized (singleton) instance of T in a
// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or
// http://lists.boost.org/Archives/boost/2006/05/105286.php for
// details.
//
template <class T>
struct dynamically_initialized
{
protected:
static T& instance;
private:
static T& get_instance();
#if defined(__GNUC__)
// Workaround "warning: all member functions in class `
// boost::archive::detail::dynamically_initialized<T>' are private"
public:
void work_around_gcc_warning();
#endif
};
template <class T>
T& dynamically_initialized<T>::instance
= dynamically_initialized<T>::get_instance();
template <class T>
T& dynamically_initialized<T>::get_instance()
{
static T instance_;
return instance_;
}
}}} // namespace boost::archive::detail
#endif // BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP
@@ -16,19 +16,23 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <string>
#include <cstddef> // NULL
#include <boost/cstdint.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/serialization/singleton.hpp>
#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 {
class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
template<class Archive>
class interface_iarchive
@@ -47,12 +51,10 @@ public:
}
template<class T>
const basic_pointer_iserializer *
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer *
register_type(T * = NULL){
const basic_pointer_iserializer & bpis =
boost::serialization::singleton<
pointer_iserializer<Archive, T>
>::get_const_instance();
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer & bpis =
pointer_iserializer<Archive, T>::get_instance();
this->This()->register_basic_serializer(bpis.get_basic_serializer());
return & bpis;
}
@@ -16,7 +16,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <string>
#include <cstddef> // NULL
#include <boost/cstdint.hpp>
#include <boost/mpl/bool.hpp>
@@ -24,13 +23,16 @@
#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
#include <boost/serialization/singleton.hpp>
namespace boost {
namespace boost {
template<class T>
class shared_ptr;
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail {
class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
template<class Archive>
class interface_oarchive
@@ -49,12 +51,10 @@ public:
}
template<class T>
const basic_pointer_oserializer *
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer *
register_type(const T * = NULL){
const basic_pointer_oserializer & bpos =
boost::serialization::singleton<
pointer_oserializer<Archive, T>
>::get_const_instance();
const BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer & bpos =
pointer_oserializer<Archive, T>::get_instance();
this->This()->register_basic_serializer(bpos.get_basic_serializer());
return & bpos;
}
+98 -51
View File
@@ -24,7 +24,7 @@
#include <new> // for placement new
#include <memory> // for auto_ptr
#include <cstddef> // size_t, NULL
#include <cstddef> // size_t
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -33,19 +33,19 @@ namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/serialization/throw_exception.hpp>
#include <boost/serialization/smart_cast.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/serialization/static_warning.hpp>
#include <boost/static_warning.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/remove_all_extents.hpp>
#include <boost/serialization/is_abstract.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/if.hpp>
@@ -67,8 +67,9 @@ namespace std{
#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/archive/detail/basic_iserializer.hpp>
#include <boost/archive/detail/archive_pointer_iserializer.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/detail/dynamically_initialized.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/level.hpp>
@@ -78,8 +79,6 @@ namespace std{
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/singleton.hpp>
namespace boost {
namespace serialization {
@@ -109,34 +108,43 @@ private:
}
// private constructor to inhibit any existence other than the
// static one
public:
explicit iserializer() :
basic_iserializer(
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
* boost::serialization::type_info_implementation<T>::type::get_instance()
)
{}
public:
virtual BOOST_DLLEXPORT void load_object_data(
basic_iarchive & ar,
void *x,
const unsigned int file_version
) const BOOST_USED;
) const BOOST_USED ;
virtual bool class_info() const {
return boost::serialization::implementation_level<T>::value
>= boost::serialization::object_class_info;
}
virtual bool tracking(const unsigned int /* flags */) const {
// 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::tracking_level<T>::value
== boost::serialization::track_selectively
&& serialized_as_pointer());
&& serialized_as_pointer();
}
virtual unsigned int version() const {
return ::boost::serialization::version<T>::value;
}
virtual bool is_polymorphic() const {
return boost::is_polymorphic<T>::value;
typedef BOOST_DEDUCED_TYPENAME
boost::serialization::type_info_implementation<
T
>::type::is_polymorphic::type typex;
return typex::value;
}
static iserializer & get_instance(){
static iserializer instance;
return instance;
}
virtual ~iserializer(){};
};
@@ -150,7 +158,7 @@ BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
// make sure call is routed through the higest interface that might
// be specialized by the user.
boost::serialization::serialize_adl(
boost::serialization::smart_cast_reference<Archive &>(ar),
boost::smart_cast_reference<Archive &>(ar),
* static_cast<T *>(x),
file_version
);
@@ -159,20 +167,32 @@ BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
template<class Archive, class T>
class pointer_iserializer
: public archive_pointer_iserializer<Archive>
, public dynamically_initialized<pointer_iserializer<Archive,T> >
{
private:
virtual const basic_iserializer & get_basic_serializer() const {
return boost::serialization::singleton<
iserializer<Archive, T>
>::get_const_instance();
return iserializer<Archive, T>::get_instance();
}
BOOST_DLLEXPORT virtual void load_object_ptr(
virtual BOOST_DLLEXPORT void load_object_ptr(
basic_iarchive & ar,
void * & x,
const unsigned int file_version
) const BOOST_USED;
#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
public:
pointer_iserializer();
#endif
// private constructor to inhibit any existence other than the
// static one. Note GCC doesn't permit constructor to be private
BOOST_DLLEXPORT pointer_iserializer() BOOST_USED;
friend struct dynamically_initialized<pointer_iserializer<Archive,T> >;
public:
// at least one compiler (CW) seems to require that serialize_adl
// be explicitly instantiated. Still under investigation.
#if !defined(__BORLANDC__)
void (* const m)(Archive &, T &, const unsigned);
boost::serialization::extended_type_info * (* e)();
#endif
BOOST_DLLEXPORT static const pointer_iserializer & get_instance() BOOST_USED;
};
// note trick to be sure that operator new is using class specific
@@ -252,12 +272,11 @@ BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr(
const unsigned int file_version
) const
{
Archive & ar_impl =
boost::serialization::smart_cast_reference<Archive &>(ar);
Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
auto_ptr_with_deleter<T> ap(heap_allocator<T>::invoke());
if(NULL == ap.get())
boost::serialization::throw_exception(std::bad_alloc()) ;
boost::throw_exception(std::bad_alloc()) ;
T * t = ap.get();
x = t;
@@ -286,15 +305,29 @@ BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr(
}
template<class Archive, class T>
pointer_iserializer<Archive, T>::pointer_iserializer() :
#if !defined(__BORLANDC__)
BOOST_DLLEXPORT pointer_iserializer<Archive, T>::pointer_iserializer() :
archive_pointer_iserializer<Archive>(
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
* boost::serialization::type_info_implementation<T>::type::get_instance()
),
m(boost::serialization::serialize_adl<Archive, T>),
e(boost::serialization::type_info_implementation<T>::type::get_instance)
#else
BOOST_DLLEXPORT pointer_iserializer<Archive, T>::pointer_iserializer() :
archive_pointer_iserializer<Archive>(
* boost::serialization::type_info_implementation<T>::type::get_instance()
)
#endif
{
boost::serialization::singleton<
iserializer<Archive, T>
>::get_mutable_instance().set_bpis(this);
iserializer<Archive, T> & bis = iserializer<Archive, T>::get_instance();
bis.set_bpis(this);
}
template<class Archive, class T>
BOOST_DLLEXPORT const pointer_iserializer<Archive, T> &
pointer_iserializer<Archive, T>::get_instance() {
// note: comeau complains without full qualification
return dynamically_initialized<pointer_iserializer<Archive,T> >::instance;
}
template<class Archive, class T>
@@ -328,12 +361,7 @@ struct load_non_pointer_type {
// 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,
boost::serialization::singleton<
iserializer<Archive, T>
>::get_const_instance()
);
ar.load_object(x, iserializer<Archive, T>::get_instance());
}
};
@@ -377,11 +405,6 @@ struct load_non_pointer_type {
> > >::type typex;
static void invoke(Archive & ar, T &t){
// check that we're not trying to serialize something that
// has been marked not to be serialized. If this your program
// traps here, you've tried to serialize a class whose trait
// has been marked "non-serializable". Either reset the trait
// (see level.hpp) or change program not to serialize items of this class
BOOST_STATIC_ASSERT((
mpl::greater_equal<
boost::serialization::implementation_level<T>,
@@ -398,8 +421,12 @@ struct load_pointer_type {
struct abstract
{
static const basic_pointer_iserializer * register_type(Archive & /* ar */){
#if ! defined(__BORLANDC__)
typedef BOOST_DEDUCED_TYPENAME
boost::serialization::type_info_implementation<T>::type::is_polymorphic typex;
// it has? to be polymorphic
BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
BOOST_STATIC_ASSERT(typex::value);
#endif
return static_cast<basic_pointer_iserializer *>(NULL);
}
};
@@ -420,7 +447,7 @@ struct load_pointer_type {
// virtual serialize functions used for plug-ins
typedef BOOST_DEDUCED_TYPENAME
mpl::eval_if<
boost::serialization::is_abstract<const T>,
serialization::is_abstract<T>,
mpl::identity<abstract<T> >,
mpl::identity<non_abstract<T> >
>::type typex;
@@ -437,8 +464,7 @@ struct load_pointer_type {
return static_cast<T *>(
boost::serialization::void_upcast(
eti,
boost::serialization::type_info_implementation<T>::type
::get_const_instance(),
* boost::serialization::type_info_implementation<T>::type::get_instance(),
t
)
);
@@ -471,7 +497,7 @@ struct load_enum_type {
template<class Archive, class T>
struct load_array_type {
static void invoke(Archive &ar, T &t){
typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type value_type;
typedef typename remove_all_extents<T>::type value_type;
// convert integers to correct enum to load
int current_count = sizeof(t) / (
@@ -481,13 +507,34 @@ struct load_array_type {
int count;
ar >> BOOST_SERIALIZATION_NVP(count);
if(count > current_count)
boost::serialization::throw_exception(archive::archive_exception(
boost::throw_exception(archive::archive_exception(
boost::archive::archive_exception::array_size_too_short
));
ar >> serialization::make_array(static_cast<value_type*>(&t[0]),count);
}
};
#if 0
// note bogus arguments to workaround msvc 6 silent runtime failure
template<class Archive, class T>
BOOST_DLLEXPORT
inline const basic_pointer_iserializer &
instantiate_pointer_iserializer(
Archive * /* ar = NULL */,
T * /* t = NULL */
) BOOST_USED;
template<class Archive, class T>
BOOST_DLLEXPORT
inline const basic_pointer_iserializer &
instantiate_pointer_iserializer(
Archive * /* ar = NULL */,
T * /* t = NULL */
){
return pointer_iserializer<Archive,T>::instance;
}
#endif
} // detail
template<class Archive, class T>
@@ -525,7 +572,7 @@ inline void load(Archive &ar, T &t){
// for loading const objects - but I see no alternative
template<class Archive, class T>
inline void load(Archive &ar, const T & t){
load(ar, const_cast<T &>(t));
load(ar, const_cast<T &>(t));
}
#endif
@@ -533,7 +580,7 @@ inline void load(Archive &ar, const T & t){
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template<class Archive, class T>
inline void load_wrapper(Archive &ar, const T&t, mpl::true_){
boost::archive::load(ar, const_cast<T&>(t));
boost::archive::load(ar, const_cast<T&>(t));
}
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
+129 -103
View File
@@ -23,33 +23,32 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <cstddef> // NULL
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/serialization/smart_cast.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/serialization/static_warning.hpp>
#include <boost/static_warning.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_enum.hpp>
//#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_const.hpp>
//#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_all_extents.hpp>
#include <boost/serialization/is_abstract.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/and.hpp>
//#include <boost/mpl/less.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/identity.hpp>
//#include <boost/mpl/list.hpp>
//#include <boost/mpl/empty.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/not.hpp>
#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
@@ -59,7 +58,9 @@
#include <boost/archive/detail/basic_oarchive.hpp>
#include <boost/archive/detail/basic_oserializer.hpp>
#include <boost/archive/detail/archive_pointer_oserializer.hpp>
#include <boost/archive/detail/dynamically_initialized.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/level.hpp>
@@ -69,7 +70,6 @@
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/archive/archive_exception.hpp>
@@ -104,31 +104,39 @@ class oserializer : public basic_oserializer
private:
// private constructor to inhibit any existence other than the
// static one
public:
explicit BOOST_DLLEXPORT oserializer() :
basic_oserializer(
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
* boost::serialization::type_info_implementation<T>::type::get_instance()
)
{}
public:
virtual BOOST_DLLEXPORT void save_object_data(
basic_oarchive & ar,
const void *x
) const BOOST_USED;
) const BOOST_USED ;
virtual bool class_info() const {
return boost::serialization::implementation_level<T>::value
>= boost::serialization::object_class_info;
}
virtual bool tracking(const unsigned int /* flags */) const {
// 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_selectively
&& serialized_as_pointer());
|| boost::serialization::tracking_level<T>::value == boost::serialization::track_selectively
&& serialized_as_pointer();
}
virtual unsigned int version() const {
return ::boost::serialization::version<T>::value;
}
virtual bool is_polymorphic() const {
return boost::is_polymorphic<T>::value;
typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<
T
>::type::is_polymorphic::type typex;
return typex::value;
}
static oserializer & get_instance(){
static oserializer instance;
return instance;
}
virtual ~oserializer(){}
};
@@ -140,9 +148,8 @@ BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
) const {
// make sure call is routed through the highest interface that might
// be specialized by the user.
BOOST_STATIC_ASSERT(boost::is_const<T>::value == false);
boost::serialization::serialize_adl(
boost::serialization::smart_cast_reference<Archive &>(ar),
boost::smart_cast_reference<Archive &>(ar),
* static_cast<T *>(const_cast<void *>(x)),
version()
);
@@ -151,25 +158,33 @@ BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
template<class Archive, class T>
class pointer_oserializer
: public archive_pointer_oserializer<Archive>
, public dynamically_initialized<pointer_oserializer<Archive,T> >
{
const basic_oserializer & get_basic_serializer() const;
private:
virtual const basic_oserializer & get_basic_serializer() const {
return oserializer<Archive, T>::get_instance();
}
virtual BOOST_DLLEXPORT void save_object_ptr(
basic_oarchive & ar,
const void * x
) const BOOST_USED;
) const BOOST_USED ;
#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
public:
#endif
// private constructor to inhibit any existence other than the
// static one. Note GCC doesn't permit constructor to be private
explicit BOOST_DLLEXPORT pointer_oserializer() BOOST_USED;
friend struct dynamically_initialized<pointer_oserializer<Archive,T> >;
public:
#if !defined(__BORLANDC__)
// at least one compiler (CW) seems to require that serialize_adl
// be explicitly instantiated. Still under investigation.
void (* const m)(Archive &, T &, const unsigned);
boost::serialization::extended_type_info * (* e)();
#endif
BOOST_DLLEXPORT static const pointer_oserializer & get_instance() BOOST_USED;
};
template<class Archive, class T>
const basic_oserializer &
pointer_oserializer<Archive, T>::get_basic_serializer() const {
return boost::serialization::singleton<
oserializer<Archive, T>
>::get_const_instance();
}
template<class Archive, class T>
BOOST_DLLEXPORT void pointer_oserializer<Archive, T>::save_object_ptr(
basic_oarchive & ar,
@@ -180,8 +195,7 @@ BOOST_DLLEXPORT void pointer_oserializer<Archive, T>::save_object_ptr(
// be specialized by the user.
T * t = static_cast<T *>(const_cast<void *>(x));
const unsigned int file_version = boost::serialization::version<T>::value;
Archive & ar_impl
= boost::serialization::smart_cast_reference<Archive &>(ar);
Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
boost::serialization::save_construct_data_adl<Archive, T>(
ar_impl,
t,
@@ -191,16 +205,30 @@ BOOST_DLLEXPORT void pointer_oserializer<Archive, T>::save_object_ptr(
}
template<class Archive, class T>
#if !defined(__BORLANDC__)
BOOST_DLLEXPORT pointer_oserializer<Archive, T>::pointer_oserializer() :
archive_pointer_oserializer<Archive>(
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
* boost::serialization::type_info_implementation<T>::type::get_instance()
),
m(boost::serialization::serialize_adl<Archive, T>),
e(boost::serialization::type_info_implementation<T>::type::get_instance)
#else
BOOST_DLLEXPORT pointer_oserializer<Archive, T>::pointer_oserializer() :
archive_pointer_oserializer<Archive>(
* boost::serialization::type_info_implementation<T>::type::get_instance()
)
#endif
{
// make sure appropriate member function is instantiated
boost::serialization::singleton<
oserializer<Archive, T>
>::get_mutable_instance().set_bpos(this);
oserializer<Archive, T> & bos = oserializer<Archive, T>::get_instance();
bos.set_bpos(this);
}
template<class Archive, class T>
BOOST_DLLEXPORT const pointer_oserializer<Archive, T> &
pointer_oserializer<Archive, T>::get_instance() {
// note: comeau complains without full qualification
return dynamically_initialized<pointer_oserializer<Archive,T> >::instance;
}
template<class Archive, class T>
@@ -228,12 +256,7 @@ struct save_non_pointer_type {
// serialization level and class version
struct save_standard {
static void invoke(Archive &ar, const T & t){
ar.save_object(
& t,
boost::serialization::singleton<
oserializer<Archive, T>
>::get_const_instance()
);
ar.save_object(& t, oserializer<Archive, T>::get_instance());
}
};
@@ -277,7 +300,7 @@ struct save_non_pointer_type {
// else
// do a fast save only tracking is turned off
mpl::identity<save_conditional>
> > >::type typex;
> > >::type typex;
static void invoke(Archive & ar, const T & t){
// check that we're not trying to serialize something that
@@ -302,8 +325,10 @@ struct save_pointer_type {
{
static const basic_pointer_oserializer * register_type(Archive & /* ar */){
// it has? to be polymorphic
BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
return NULL;
BOOST_STATIC_ASSERT(
boost::serialization::type_info_implementation<T>::type::is_polymorphic::value
);
return static_cast<const basic_pointer_oserializer *>(NULL);
}
};
@@ -323,7 +348,7 @@ struct save_pointer_type {
// virtual serialize functions used for plug-ins
typedef
BOOST_DEDUCED_TYPENAME mpl::eval_if<
boost::serialization::is_abstract<T>,
serialization::is_abstract<T>,
mpl::identity<abstract<T> >,
mpl::identity<non_abstract<T> >
>::type typex;
@@ -335,14 +360,11 @@ struct save_pointer_type {
{
static void save(
Archive &ar,
T & t
const T & t,
const basic_pointer_oserializer * bpos_ptr
){
const basic_pointer_oserializer & bpos =
boost::serialization::singleton<
pointer_oserializer<Archive, T>
>::get_const_instance();
// save the requested pointer type
ar.save_pointer(& t, & bpos);
ar.save_pointer(& t, bpos_ptr);
}
};
@@ -351,26 +373,20 @@ struct save_pointer_type {
{
static void save(
Archive &ar,
T & t
const T & t,
const basic_pointer_oserializer * bpos_ptr
){
BOOST_DEDUCED_TYPENAME
boost::serialization::type_info_implementation<T>::type const
& i = boost::serialization::type_info_implementation<T>::type
::get_const_instance();
boost::serialization::extended_type_info const * const this_type = & i;
const boost::serialization::extended_type_info * this_type
= boost::serialization::type_info_implementation<T>::type::get_instance();
// retrieve the true type of the object pointed to
// if this assertion fails its an error in this library
assert(NULL != this_type);
const boost::serialization::extended_type_info * true_type =
i.get_derived_extended_type_info(t);
const boost::serialization::extended_type_info * true_type
= boost::serialization::type_info_implementation<T>::type::get_derived_extended_type_info(t);
// note:if this exception is thrown, be sure that derived pointer
// is either registered or exported.
// is either regsitered or exported.
if(NULL == true_type){
boost::serialization::throw_exception(
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
}
@@ -378,54 +394,44 @@ struct save_pointer_type {
// if its not a pointer to a more derived type
const void *vp = static_cast<const void *>(&t);
if(*this_type == *true_type){
const basic_pointer_oserializer * bpos = register_type(ar, t);
ar.save_pointer(vp, bpos);
ar.save_pointer(vp, bpos_ptr);
return;
}
// convert pointer to more derived type. if this is thrown
// it means that the base/derived relationship hasn't be registered
vp = serialization::void_downcast(
*true_type,
*this_type,
static_cast<const void *>(&t)
);
vp = serialization::void_downcast(*true_type, *this_type, &t);
if(NULL == vp){
boost::serialization::throw_exception(
boost::throw_exception(
archive_exception(archive_exception::unregistered_cast)
);
}
// since true_type is valid, and this only gets made if the
// sice true_type is valid, and this only gets made if the
// pointer oserializer object has been created, this should never
// fail
const basic_pointer_oserializer * bpos
= archive_pointer_oserializer<Archive>::find(* true_type);
assert(NULL != bpos);
if(NULL == bpos)
boost::serialization::throw_exception(
bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type);
assert(NULL != bpos_ptr);
if(NULL == bpos_ptr)
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
ar.save_pointer(vp, bpos);
ar.save_pointer(vp, bpos_ptr);
}
};
// out of line selector works around borland quirk
template<class T>
struct conditional {
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
is_polymorphic<T>,
mpl::identity<polymorphic<T> >,
mpl::identity<non_polymorphic<T> >
>::type type;
};
// used to convert TPtr in to a pointer to a T
template<class T>
static void save(
Archive & ar,
const T & t
const T &t,
const basic_pointer_oserializer * bpos_ptr
){
conditional<T>::type::save(ar, const_cast<T &>(t));
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
BOOST_DEDUCED_TYPENAME boost::serialization::
type_info_implementation<T>::type::is_polymorphic,
mpl::identity<polymorphic<T> >,
mpl::identity<non_polymorphic<T> >
>::type typey;
typey::save(ar, const_cast<T &>(t), bpos_ptr);
}
template<class T>
@@ -446,15 +452,14 @@ struct save_pointer_type {
#else
// otherwise remove the const
#endif
register_type(ar, * t);
const basic_pointer_oserializer * bpos_ptr = register_type(ar, * t);
if(NULL == t){
basic_oarchive & boa
= boost::serialization::smart_cast_reference<basic_oarchive &>(ar);
basic_oarchive & boa = boost::smart_cast_reference<basic_oarchive &>(ar);
boa.save_null_pointer();
save_access::end_preamble(ar);
return;
}
save(ar, * t);
save(ar, * t, bpos_ptr);
};
};
@@ -472,7 +477,7 @@ template<class Archive, class T>
struct save_array_type
{
static void invoke(Archive &ar, const T &t){
typedef BOOST_DEDUCED_TYPENAME boost::remove_extent<T>::type value_type;
typedef typename remove_all_extents<T>::type value_type;
save_access::end_preamble(ar);
// consider alignment
@@ -485,6 +490,27 @@ struct save_array_type
}
};
#if 0
// note bogus arguments to workaround msvc 6 silent runtime failure
// declaration to satisfy gcc
template<class Archive, class T>
BOOST_DLLEXPORT const basic_pointer_oserializer &
instantiate_pointer_oserializer(
Archive * /* ar = NULL */,
T * /* t = NULL */
) BOOST_USED ;
// definition
template<class Archive, class T>
BOOST_DLLEXPORT const basic_pointer_oserializer &
instantiate_pointer_oserializer(
Archive * /* ar = NULL */,
T * /* t = NULL */
){
return pointer_oserializer<Archive, T>::instance;
}
#endif
} // detail
template<class Archive, class T>
@@ -535,7 +561,7 @@ inline void save(Archive & ar, T &t){
// serialization library and should be double checked. See documentation on
// object tracking. Also, see the "rationale" section of the documenation
// for motivation for this checking.
BOOST_STATIC_WARNING(check_tracking<T>::value);
BOOST_STATIC_ASSERT(check_tracking<T>::value);
save(ar, const_cast<const T &>(t));
}
#endif
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -7,7 +7,7 @@
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_iarchive_route.hpp
// polymorphic_iarchive_dispatch.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
@@ -16,9 +16,11 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cstddef>
#include <string>
#include <ostream>
#include <cstddef>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
@@ -27,12 +29,12 @@ namespace std{
} // namespace std
#endif
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>
#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
@@ -43,7 +45,7 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
template<class ArchiveImplementation>
class polymorphic_iarchive_route :
class polymorphic_iarchive_dispatch :
public polymorphic_iarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
@@ -178,13 +180,12 @@ public:
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_iarchive_route(
polymorphic_iarchive_dispatch(
std::basic_istream<_Elem, _Tr> & is,
unsigned int flags = 0
) :
ArchiveImplementation(is, flags)
{}
virtual ~polymorphic_iarchive_route(){};
};
} // namespace detail
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -7,7 +7,7 @@
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_oarchive_route.hpp
// polymorphic_oarchive_dispatch.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
@@ -33,6 +33,8 @@ 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
@@ -43,7 +45,7 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
template<class ArchiveImplementation>
class polymorphic_oarchive_route :
class polymorphic_oarchive_dispatch :
public polymorphic_oarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
@@ -166,13 +168,12 @@ public:
}
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_oarchive_route(
polymorphic_oarchive_dispatch(
std::basic_ostream<_Elem, _Tr> & os,
unsigned int flags = 0
) :
ArchiveImplementation(os, flags)
{}
virtual ~polymorphic_oarchive_route(){};
};
} // namespace detail
+5 -11
View File
@@ -4,15 +4,9 @@
#ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP
# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP
namespace boost { namespace archive { namespace detail {
# include <boost/type_traits/add_pointer.hpp>
// No instantiate_ptr_serialization overloads generated by
// BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call
// will be seen *unless* they are in an associated namespace of one of
// the arguments, so we pass one of these along to make sure this
// namespace is considered. See temp.dep.candidate (14.6.4.2) in the
// standard.
struct adl_tag {};
namespace boost { namespace archive { namespace detail {
template <class Archive, class Serializable>
struct ptr_serialization_support;
@@ -32,7 +26,7 @@ struct _ptr_serialization_support
// in overload resolution with the functions declared by
// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below.
template <class Serializable>
void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {}
void instantiate_ptr_serialization(Serializable*, int) {}
// The function declaration generated by this macro never actually
// gets called, but its return type gets instantiated, and that's
@@ -43,8 +37,8 @@ void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {}
namespace boost { namespace archive { namespace detail { \
\
template <class Serializable> \
BOOST_DEDUCED_TYPENAME _ptr_serialization_support<Archive, Serializable>::type \
instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \
typename _ptr_serialization_support<Archive, Serializable>::type \
instantiate_ptr_serialization( Serializable*, Archive* ); \
\
}}}
@@ -1,8 +1,9 @@
// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its suitability
// for any purpose.
#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
@@ -8,17 +8,10 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <utility>
#include <cassert>
#include <cstddef>
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/serialization/singleton.hpp>
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <boost/archive/detail/basic_serializer_map.hpp>
#include <boost/archive/detail/archive_pointer_iserializer.hpp>
@@ -26,11 +19,12 @@ namespace boost {
namespace archive {
namespace detail {
namespace { // anon
template<class Archive>
class iserializer_map : public basic_serializer_map
{
};
template<class Archive>
basic_serializer_map *
iserializer_map(){
static bool deleted = false;
static basic_serializer_map map(deleted);
return deleted ? NULL : & map;
}
template<class Archive>
@@ -40,11 +34,9 @@ archive_pointer_iserializer<Archive>::archive_pointer_iserializer(
) :
basic_pointer_iserializer(eti)
{
std::pair<BOOST_DEDUCED_TYPENAME iserializer_map<Archive>::iterator, bool> result;
result = serialization::singleton<
iserializer_map<Archive>
>::get_mutable_instance().insert(this);
assert(result.second);
basic_serializer_map *mp = iserializer_map<Archive>();
assert(NULL != mp);
mp->insert(this);
}
template<class Archive>
@@ -52,29 +44,20 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *)
archive_pointer_iserializer<Archive>::find(
const boost::serialization::extended_type_info & eti
){
const basic_serializer_arg bs(eti);
BOOST_DEDUCED_TYPENAME iserializer_map<Archive>::const_iterator it;
it = boost::serialization::singleton<
iserializer_map<Archive>
>::get_const_instance().find(& bs);
assert(
it
!=
boost::serialization::singleton<
iserializer_map<Archive>
>::get_const_instance().end()
);
return static_cast<const basic_pointer_iserializer *>(*it);
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(){
std::size_t count;
count = serialization::singleton<
iserializer_map<Archive>
>::get_mutable_instance().erase(this);
assert(count);
// 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

Some files were not shown because too many files have changed in this diff Show More