Compare commits

...

56 Commits

Author SHA1 Message Date
Matthias Troyer 13a86b305c Undid backward-compatibility breaking change in pair serialization level
[SVN r42650]
2008-01-10 12:05:20 +00:00
Robert Ramey 2223e1aab0 Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42286]
2007-12-25 01:09:45 +00:00
Robert Ramey 08acdcf19b Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42284]
2007-12-25 00:57:21 +00:00
Robert Ramey 2f7a34ebf8 Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42283]
2007-12-25 00:09:34 +00:00
Robert Ramey 2dafda2af0 Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42282]
2007-12-25 00:08:55 +00:00
Robert Ramey 68a7c244c8 Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42281]
2007-12-25 00:08:27 +00:00
Robert Ramey 159a79915a Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42280]
2007-12-25 00:07:56 +00:00
Robert Ramey d42d3ba0b2 Adjustments for trak tickets - ready for upload as version 1.36.0
[SVN r42279]
2007-12-25 00:07:30 +00:00
Robert Ramey 5c2b1cb0b2 Fix missing file
[SVN r42258]
2007-12-23 02:19:18 +00:00
Robert Ramey 360d2b6f9d Fix case sensitivity for A.cpp in Jamfile.v2
[SVN r42257]
2007-12-23 02:15:45 +00:00
Robert Ramey a058b66550 Corrections to address TRAK tickets
[SVN r42256]
2007-12-23 02:06:32 +00:00
Robert Ramey 655a665b7f Corrections to address TRAK tickets
[SVN r42255]
2007-12-23 02:03:52 +00:00
Robert Ramey 2f07b1ffce Corrections to address TRAK tickets
[SVN r42254]
2007-12-23 01:59:04 +00:00
Robert Ramey 5bb4f558c8 Corrections to address TRAK tickets
[SVN r42253]
2007-12-23 01:58:26 +00:00
Robert Ramey d1909f5b3b gcc, vc 7.1 and vc8.0 passing all tests !!!
[SVN r41455]
2007-11-29 05:00:11 +00:00
Robert Ramey 674e418969 gcc, vc 7.1 and vc8.0 passing all tests !!!
[SVN r41454]
2007-11-29 04:59:37 +00:00
Robert Ramey 9c5a406cbb gcc, vc 7.1 and vc8.0 passing all tests !!!
[SVN r41453]
2007-11-29 04:58:41 +00:00
Robert Ramey e7a4673ef6 gcc, vc 7.1 and vc8.0 passing all tests !!!
[SVN r41452]
2007-11-29 04:51:43 +00:00
Robert Ramey 2635613ae1 failing only two tests in gcc! Unfortunately, fixing the error requires extended type info to be a little bit more elaborate. So I'm doing a check in now
[SVN r41412]
2007-11-27 06:26:56 +00:00
Robert Ramey 24b9636d62 failing only two tests in gcc! Unfortunately, fixing the error requires extended type info to be a little bit more elaborate. So I'm doing a check in now
[SVN r41411]
2007-11-27 06:18:31 +00:00
Robert Ramey 6530c53884 failing only two tests in gcc! Unfortunately, fixing the error requires extended type info to be a little bit more elaborate. So I'm doing a check in now
[SVN r41410]
2007-11-27 06:17:59 +00:00
Robert Ramey 89bba6d009 tested with statically loaded dlls
[SVN r41298]
2007-11-22 08:17:38 +00:00
Robert Ramey 4845240fb0 tested with statically loaded dlls
[SVN r41295]
2007-11-22 06:10:24 +00:00
Robert Ramey 35d8aee045 tested with statically loaded dlls
[SVN r41294]
2007-11-22 06:09:40 +00:00
Robert Ramey c051e7baa8 tested with statically loaded dlls
[SVN r41293]
2007-11-22 06:09:17 +00:00
Robert Ramey 66aef64228 tested with statically loaded dlls
[SVN r41292]
2007-11-22 05:58:32 +00:00
Robert Ramey 9102a93572 tested with statically loaded dlls
[SVN r41291]
2007-11-22 05:56:28 +00:00
Robert Ramey 9a92df4d54 passing all msvc and gcc tests
except gcc(release) test_no_rtti and test_shared_ptr132
tweaks to suppress uninteresting warnings on gcc

[SVN r40665]
2007-11-01 20:30:48 +00:00
Robert Ramey 4f7d012f83 removed extended_type_info_no_rtti.cpp
it's header only now.

[SVN r40664]
2007-11-01 20:29:29 +00:00
Robert Ramey a72abc7347 class diagram - change from dispatch to route
conents - sync with docs
extended_type_info - synced with code
release - reversed sequence to lifo

[SVN r40663]
2007-11-01 20:28:08 +00:00
Robert Ramey 63bb12581d removed extended_type_info_no_rtti.hpp
it's header only now.

[SVN r40662]
2007-11-01 20:26:27 +00:00
Robert Ramey f86aa78580 passing all msvc and gcc tests
except gcc(release) test_no_rtti and test_shared_ptr132


[SVN r40661]
2007-11-01 20:25:32 +00:00
Robert Ramey cf16287cc2 passing all msvc and gcc tests
except gcc(release) test_no_rtti and test_shared_ptr132


[SVN r40660]
2007-11-01 20:24:36 +00:00
Robert Ramey 351b650d40 passing all msvc and gcc tests
except gcc(release) test_no_rtti and test_shared_ptr132


[SVN r40659]
2007-11-01 20:24:02 +00:00
Robert Ramey f3732264e0 First implementation of thread safe lock free serialization
[SVN r40564]
2007-10-29 20:21:48 +00:00
Robert Ramey d92443b5ff First implementation of thread safe lock free serialization
[SVN r40562]
2007-10-29 19:49:44 +00:00
Robert Ramey 4af2f08941 First implementation of thread safe lock free serialization
[SVN r40561]
2007-10-29 19:47:00 +00:00
Robert Ramey 1208a26e01 First implementation of thread safe lock free serialization
[SVN r40560]
2007-10-29 19:37:09 +00:00
Robert Ramey 9922f32456 First implementation of thread safe lock free serialization
[SVN r40559]
2007-10-29 19:32:22 +00:00
Robert Ramey 714480207b improvements to extended type info system - unfortunately, these break the export.
[SVN r39570]
2007-09-27 04:46:21 +00:00
Robert Ramey 9b64c5cd8f improvements to extended type info system - unfortunately, these break the export.
[SVN r39569]
2007-09-27 04:44:15 +00:00
Robert Ramey ca5be78419 improvements to extended type info system - unfortunately, these break the export.
[SVN r39568]
2007-09-27 04:10:56 +00:00
Robert Ramey c3eed9577f improvements to extended type info system - unfortunately, these break the export.
[SVN r39567]
2007-09-27 04:09:17 +00:00
Robert Ramey 20bd5c3f97 improvements to extended type info system - unfortunately, these break the export.
[SVN r39566]
2007-09-27 04:05:25 +00:00
Robert Ramey 12af6786c1 improvements to extended type info system - unfortunately, these break the export.
[SVN r39565]
2007-09-27 04:03:05 +00:00
Robert Ramey bcd23ebc87 improvements to extended type info system - unfortunately, these break the export.
[SVN r39564]
2007-09-27 04:01:51 +00:00
Robert Ramey c8945462d8 improvements to extended type info system - unfortunately, these break the export.
[SVN r39562]
2007-09-27 01:53:46 +00:00
Robert Ramey c756fe1067 included helper for shared_ptr serialization
[SVN r38733]
2007-08-16 22:38:18 +00:00
Robert Ramey 13d6ea1156 initial checkin
[SVN r38701]
2007-08-15 20:09:24 +00:00
Robert Ramey aa1ba652be common jam stuff for all tests
[SVN r38700]
2007-08-15 19:33:23 +00:00
Robert Ramey 785318bf61 Cumulative changes made during release of 1.34
[SVN r38699]
2007-08-15 19:19:55 +00:00
Robert Ramey 85f769a6e8 Changes made over the course of the year while 1.34 was being worked on
[SVN r38698]
2007-08-15 18:56:04 +00:00
Robert Ramey 3e9b235481 Changes made over the course of the year while 1.34 was being worked on
[SVN r38697]
2007-08-15 18:52:50 +00:00
Robert Ramey 0fa5bef020 Changes made over the course of the year while 1.34 was being worked on
[SVN r38696]
2007-08-15 18:49:43 +00:00
Robert Ramey b1aadada54 Changes made over the course of the year while 1.34 was being worked on
[SVN r38693]
2007-08-15 18:33:11 +00:00
Robert Ramey 6af53e0732 Create branch for next serialization release
[SVN r38613]
2007-08-13 03:23:47 +00:00
432 changed files with 105243 additions and 98645 deletions
-3
View File
@@ -1,3 +0,0 @@
This file is used by the project manager only and should be treated like the project file
-147
View File
@@ -1,147 +0,0 @@
<?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.
+43 -14
View File
@@ -8,14 +8,35 @@
project boost/serialization
: source-location ../src
;
: requirements <dependency>../../config/test//BOOST_NO_STD_LOCALE
: usage-requirements <dependency>../../config/test//BOOST_NO_STD_LOCALE
;
SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
rule include-spirit ( properties * )
{
local result ;
for local tset in borland { # vc iw
if ( <toolset>$(tset) in $(properties) ) {
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) ;
}
else {
echo **** spirit 1.6x required to build library with this compiler **** ;
result = <build>no ;
}
}
}
}
SOURCES =
basic_archive
basic_archive_impl
basic_iarchive
basic_oarchive
basic_iserializer
basic_oarchive
basic_oserializer
basic_pointer_iserializer
basic_pointer_oserializer
@@ -26,8 +47,8 @@ SOURCES =
binary_iarchive
binary_oarchive
extended_type_info
extended_type_info_no_rtti
extended_type_info_typeid
extended_type_info_no_rtti
polymorphic_iarchive
polymorphic_oarchive
stl_port
@@ -40,31 +61,39 @@ SOURCES =
;
WSOURCES =
codecvt_null
utf8_codecvt_facet
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
:
: <link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
: $(SOURCES).cpp
:
<toolset>msvc:<cxxflags>/Gy
<toolset>msvc-6.5:<conditional>@include-spirit
<toolset>msvc-7.0:<conditional>@include-spirit
<toolset>borland:<conditional>@include-spirit
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
lib boost_wserialization
: $(WSOURCES).cpp boost_serialization
: <toolset>msvc:<cxxflags>/Gy
<link>shared:<define>BOOST_WSERIALIZATION_DYN_LINK=1
:
: <link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
<toolset>msvc:<cxxflags>/Gy
<toolset>msvc-6.5:<conditional>@include-spirit
<toolset>msvc-7.0:<conditional>@include-spirit
<toolset>borland:<conditional>@include-spirit
<dependency>../../config/test//BOOST_NO_STD_WSTREAMBUF
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
boost-install boost_serialization boost_wserialization ;
-126
View File
@@ -1,126 +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.
# 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) ;
}
+6
View File
@@ -27,6 +27,12 @@ http://www.boost.org/LICENSE_1_0.txt)
</table>
<hr>
<ul>
<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
enhancement and generalization of the library itself including generalization of
the wrapper concept.
<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
+18 -20
View File
@@ -43,8 +43,7 @@ for archives used for saving data.
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>.
In order to diminish code repetition, input archives included with this library
have all been derived from the following template:
All input archives should be derived from the following template:
<pre><code>
template&lt;class Archive&gt;
detail::common_iarchive;
@@ -227,7 +226,9 @@ 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> as a template parameter rather than simple classes.
<code style="white-space: normal">stream</code> or
<code style="white-space: normal">streambuf</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>
@@ -242,17 +243,15 @@ 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>
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.
To make this work, the following should be included after the archive
class definition.
<pre><code>
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES trivial_oarchive
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES trivial_iarchive
#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
</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
@@ -260,8 +259,7 @@ 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
@@ -303,16 +301,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, make a
header file <code style="white-space: normal">portable_binary_archive.hpp</code>
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>
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 script
<code style="white-space: normal">run_archive_test</code> whose command line is
This process in encapsulated in the shell or cmd script
<code style="white-space: normal">library_test</code> whose command line is
<pre><code>
run_archive_test &lt;test header file&gt; &lt;toolset&gt; [&lt;boost root&gt;] [&lt;target directory&gt;]
library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
</code></pre>
<h3><a name="polymorphic">Polymorphic Archives</a></h3>
@@ -368,9 +366,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_impl_hpp href="../../../boost/archive/detail/polymorphic_iarchive_impl.hpp"><code style="white-space: normal">polymorphic_iarchive_impl.hpp</code></a>
<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>
and
<a target=polymorphic_oarchive_impl_hpp href="../../../boost/archive/detail/polymorphic_oarchive_impl.hpp"><code style="white-space: normal">polymorphic_oarchive_impl.hpp</code></a>.
<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>.
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>
+10 -10
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">Archive Class Diagram</h2>
<h2 align="center">Text Archive Class Diagram</h2>
</td>
</tr>
</table>
@@ -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> <font color="red">polymorphic_iarchive</font> <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> polymorphic_iarchive_impl <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_impl&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt; <a href="../../../boost/archive/detail/polymorphic_iarchive_impl.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>
|
|
|
@@ -68,11 +68,11 @@ 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 identical for saving and for
serialization) for text files. The hierachy and organization is similar 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
type of archive. Other classes whose names are in black implment the library and should
type of archive. Other classes whose names are in black implement the library and should
never change. They are in <code>namespace boost::archive::detail</code>
<dl>
<dt><code>
@@ -146,19 +146,19 @@ 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_impl.hpp">polymorphic_iarchive_impl&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</a>
<a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">polymorphic_iarchive_route&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 forwarded to the implementing class. In this example,
that impelenting class would be text_iarchive_impl.
concrete class. Virtual function calls are routed to the implementing class. In this example,
that implementing class would be text_iarchive_impl.
<p><dt><code>
<a href="../../../boost/archive/polymorphic_text_iarchive.hpp">polymorphic_text_iarchive</a>
</code></dt>
<dd>
this is just a typedef so we can write polymorphic_text_archive rather than
<code style="white-space: normal">polymorphic_iarchive_impl&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</code>
<code style="white-space: normal">polymorphic_iarchive_route&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>UTF-8 Codecvt Facet</h1>
<h1><code>utf8_codecvt_facet</code></h1>
<pre>
+26 -5
View File
@@ -87,7 +87,10 @@ 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#recent_improvements">Differences from version 1.32</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#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>
@@ -146,6 +149,7 @@ 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>
@@ -155,7 +159,9 @@ function initialize() {
<dt><img style="display:none" src="plus.gif" id="wrappers"><a target="detail" href="wrappers.html">Serialization Wrappers</a>
<dd><div id="wrappers_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#binaryobjects">Binary Objects</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#arrays">Arrays</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#strong_type"><code style="white-space: normal">strong_type</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#collection_size_type">Collection Sizes</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#composition">Composition</a>
</dl></div></dd>
@@ -167,6 +173,7 @@ function initialize() {
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#export">Export Key</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#Abstract">Abstract</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#typeinfo">Type Information Implementation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#wrappers">Wrappers</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#templates">Template Serialization Traits</a>
</dl></div></dd>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#models">Models - Serialization Implementations Included in the Library</a>
@@ -174,7 +181,6 @@ 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">
@@ -183,6 +189,11 @@ 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>
<dd><div id="exceptions_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_class"><code>unregistered_class</code></a>
@@ -254,8 +265,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="miscellaneous">Miscellaneous
<dd><div id="miscellaneous_detail"><dl class="page-index">
<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="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>
@@ -264,12 +275,22 @@ 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">utf-8 code_cvt</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="factory.html"><code>BOOST_SERIALIZATION_FACTORY</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="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>
+3 -2
View File
@@ -43,8 +43,9 @@ 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">
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>.
archive_exception.hpp</a>
and <a target="basic_xml_archive_hpp" href="../../../boost/archive/basic_xml_archive.hpp">
basic_xml_archive.hpp</a>.
<pre><code>
namespace boost {
namespace archive {
+127 -129
View File
@@ -30,9 +30,9 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#runtime">Runtime Interface</a>
<dt><a href="#requirements">Requirements</a>
<dt><a href="#models">Models</a>
<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,11 +61,6 @@ 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
@@ -73,97 +68,86 @@ 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>
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.
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.
<li>
permits association of an arbitrary key with a type. Often this key would
permits association of an arbitrary string 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.
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"
<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>
The serialization system maintains two global tables.
<ul>
<li>The first is a global type table. it and has with 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>
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.
<h3><a name="runtime">Runtime Interface</a></h3>
<pre><code">
namespace boost {
namespace serialization {
class BOOST_SERIALIZATION_DECL extended_type_info :
private boost::noncopyable
class extended_type_info
{
protected:
extended_type_info(const char * type_info_key);
// 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();
public:
void self_register();
void key_register(const char *key);
const char * get_key() const;
const char * get_key() const {
return m_key;
}
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!=(const extended_type_info &rhs) const {
return !(operator==(rhs));
}
// for plugins
virtual void * construct(unsigned int count = 0, ...) const;
virtual void destroy(void const * const p) const;
static const extended_type_info * find(const char *key);
static const extended_type_info * find(const extended_type_info * t);
};
} // namespace serialization
} // namespace boost
</code></pre>
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>.
<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.
<dl>
<dt><h4><pre><code>
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();
extended_type_info(unsigned int type_info_key);
</code></pre></h4></dt>
<dd>
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.
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.
</dd>
<dt><h4><pre><code>
@@ -179,6 +163,8 @@ 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>
@@ -188,74 +174,81 @@ instance. If no key has been associated with the instance, then a NULL is retur
</dd>
<dt><h4><pre><code>
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;
bool operator<(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 <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.
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>
<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 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>
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>
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 implement the following:
(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:
<dl>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
virtual bool
ETI::less_than(const extended_type_info &rhs) const;
</pre></code></h4></dt>
<dd>
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;
static const extended_type_info *
ETI::get_derived_extended_type_info(const T & t);
</pre></code></h4></dt>
<dd>
Return a pointer to the
<code style="white-space: normal">extended_type_info</code>
instance that corresponds to
the "true type" of the type T. The "true type" is the lowest type in the
hierarchy of classes. The type T can always be cast to the "true type" with
a static cast. Implemention of this function will vary among type id systems
and sometimes will make presumptions about the type T than can be identified
with a particular <code style="white-space: normal">extended_type_info implementation</code>.
</dd>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
static extended_type_info *
ETI::get_instance();
static extended_type_info &
ETI::get_mutable_instance();
static const extended_type_info &
ETI::get_const:instance();
</pre></code></h4></dt>
<dd>
Return a pointer to the instance of
@@ -265,29 +258,28 @@ 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);
const extended_type_info *
ETI::get_derived_extended_type_info(const T & t) const;
</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.
Return a pointer to the
<code style="white-space: normal">extended_type_info</code>
instance that corresponds to
the "true type" of the type T. The "true type" is the lowest type in the
hierarchy of classes. The type T can always be cast to the "true type" with
a static cast. Implemention of this function will vary among type id systems
and sometimes will make presumptions about the type T than can be identified
with a particular <code style="white-space: normal">extended_type_info</code> implementation.
</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
bool ETI::less_than(const extended_type_info &rhs) const;
</pre></code></h4></dt>
<dd>
Compare this instance to another one using the same
<code style="white-space: normal">extended_type_info</code> implementation.
</dd>
</dl>
<h3><a name="models">Models</a></h3>
@@ -301,19 +293,25 @@ 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, it does require that all classes for which type id is to be used implement
a virtual function of the signiture:
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:
<code><pre>
virtual const char * get_key();
</pre></code>
which returns a unique string the most derived object this class.
This function must be virtual in order to implement the functionality required by
<code style="white-space: normal">ETI::get_derived_extended_type_info</code>
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>
as described above.
<h3><a name="example">Example</a></h3>
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.
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>.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
+23 -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
carfully considered and the code that generates these warning has been
carefully considered and the code that generates these warning has been
unchanged. In this case the warning should should be ignored as in certain
usages of the library, making the destructors virtual could lead to problems.
As an alternative, base class destructors have been make "protected" to
As an alternative, base class destructors have been made "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,7 +223,8 @@ 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 templeted stream implemention
<li>The serialization library depends on the templated stream
implementation to function properly.
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
@@ -245,7 +246,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 templeted code with __decl(dllexport) and
This is due to the way that VC++ handles templated code with __decl(dllexport) and
__decl(dllimport) specifications. Basically, this compiler requires that all the
instantiations have the same specification - even though they have different
template arguments. The example <code style="white-space: normal">
@@ -255,9 +256,19 @@ 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
these switches are enabled if you want to build and run these programs.
enable these features 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
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
<code style="white-space: normal">BJAM</code> builds, you should include this switch
when you compile your own applications.
<h5>Using the Visual C++ IDE</h5>
The library includes a VC++ 7.1 "Solution" - <code style="white-space: normal">BoostSerializationLibrary</code>
along with of a set of project files - one for each demo and test. Consider the following if you
@@ -345,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 succesful.
entailed a ridiculous amount of effort. Even so, the effort wasn't entirely successful.
With this compiler, this message will still appear under the following conditions:
<ul>
<li>When serializing a class with multiple base classes. This problem causes two
failure in the test suite. I have been unable to divise a way to work around this.
failure in the test suite. I have been unable to devise 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>
@@ -361,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 accessable either by making them public or by
<li>If class serialize functions are not accessible 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
@@ -417,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 interator doesn't
<li>the test_set fails to run correctly. It seems the hashed set iterator 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>
+3 -3
View File
@@ -235,9 +235,9 @@ BOOST_SERIALIZATION_TRACKING(construct_from, track_never)
<li><code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code>
is not going to have a single raw pointer shared amongst the instances. Each loaded
<code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code> is going to
have its own distince raw pointer. This will break
have its own distinct raw pointer. This will break
<code style="white-space: normal">shared_ptr</code> and cause a memory leak. Again,
The cause of this problem is very far removed from the point of discovery. It would
The cause of this problem is very far removed from the point of discovery. It could
well be that the problem is not even discovered until after the archives are loaded.
Now we not only have difficult to find and fix program bug, but we have a bunch of
invalid archives and lost data.
@@ -295,7 +295,7 @@ ar &lt;&lt; x
<li>Oh, this trap is suggesting that the default serialization isn't really
what I want. Of course in this particular program it doesn't matter. But
then the code in the trap can't really evaluate code in other modules (which
might not even be written yet). OK, I'll at the following to my
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_SERIALIZATION_TRACKING(construct_from, track_never)
+63 -29
View File
@@ -27,37 +27,80 @@ http://www.boost.org/LICENSE_1_0.txt)
<hr>
<dl class="index">
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#recent_improvements">Differences from version 1.32</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="#todo">Pending Issues</a></dt>
</dl>
This is the Boost 1.33 Serialization Library.
There are currently no known bugs. However, due to compiler/library quirks and or
As of this is written, there are 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 requires Boost version 1.33 or later.
This library has been tested on Boost version 1.34 and 1.35.
<!--
<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 - specificallly MSVC 6, Borland and GCC < 3.0.
older compilers - specifically 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>.
Choose the latest 1.6.x Spirit only version available.
To use this downloaded version rather than the one included with boost,
you have two options: either replace the <code style="white-space: normal">boost/spirit</code> and
<code style="white-space: normal">libs/spirit</code> directories, as well as the
<code style="white-space: normal">boost/spirit.hpp</code> header, with those in the downloaded version,
or extract Spirit 1.6 to a different directory and add the corresponding include directive to your
<code style="white-space: normal">tools/build/v2/user-config.jam</code> file for all the
compilers that need it, as in the following example:
set an environmental variable SPIRIT_ROOT to be equal to the root
directory where the downloaded copy of spirit has been placed. E. G.
<pre><code>
using borland : 5.6.4 : "C:/Program Files/Borland/CBuilder6/Bin/bcc32" :
&lt;cxxflags&gt;-IC:/spirit1.6 ;
set SPIRIT_ROOT=c:/spirit16
</code></pre>
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="recent_improvements"></a>Differences from Boost 1.32</h2>
<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 types 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
may or maynot change in the future.
<li>In previous versions, all types serialized through a pointer were
automatically "registered" as a side-effect. This made it unnecessary to
explicitly register or export these types if they were subsequently
serialized through a pointer to a base class. On rare occasions this
created some difficulties by instantiating undesired code and made
the requirement for registration and/or export dependent on the sequence
of operations. So any type that is to be serialized through a base
class pointer must be either explicitly registered or exported. This
might break some code and result in the throwing of "unregistered type"
exception.
</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.html#auto-link">Automatic Linking on Windows</a>.
@@ -70,7 +113,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 serializaton system in a way which may introduce subtle bugs in
sure that it doesn't use the serialization system in a way which may introduce subtle bugs in
to the program. A fuller explanation of this issue can be found
<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
@@ -82,38 +125,29 @@ 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>Miscelleanous bug fixes.
</ul>
<h2><a name="recent_improvements"></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 noticible faster execution in some cases.
<li>Miscellaneous bug fixes.
</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' 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>
<li>A subtle error in the implementation of serializaton 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.
<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 issus related to specific platforms.
Aside from the above, there are a number of issues related to specific platforms.
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-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>
+26 -29
View File
@@ -48,12 +48,13 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#splittingfreefunctions">Free Functions</a>
</dl>
</dl>
<dt><a href="#pointers">Pointers</a>
<dt><a href="#pointeroperators">Pointers</a>
<dl class="page-index">
<dt><a href="#constructors">Non-Default Constructors</a>
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
<dl class="page-index">
<dt><a href="#registration">Registration</a>
<dt><a href="#export">Export</a>
<dt><a href="#instantiation">Instantiation</a>
<dt><a href="#selectivetracking">Selective Tracking</a>
<dt><a href="#runtimecasting">Runtime Casting</a>
@@ -77,7 +78,8 @@ 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:
<li>It is a class type and one of the following has been declared according
to the prototypes detailed below:
<ul>
<li>a class member function <code style="white-space: normal">serialize</code>
<li>a global function <code style="white-space: normal">serialize</code>
@@ -437,6 +439,9 @@ function guarantees that this is always the case and will minimize the
occurence of hard to find errors related to synchronization of
<code style="white-space: normal">save</code> and <code style="white-space: normal">load</code>
functions.
<p>
Also note that <code style="white-space: normal">BOOST_SERIALIZATION_SPLIT_FREE</code>
must be used outside of any namespace.
<h2><a name="pointeroperators">Pointers</a></h2>
A pointer to any class instance can be serialized with any of the archive
@@ -533,14 +538,18 @@ will have to be overridden. Here is a simple example:
class my_class {
private:
friend class boost::serialization::access;
int member;
const int m_attribute; // some immutable aspect of the instance
int m_state; // mutable state of this instance
template&lt;class Archive&gt;
void serialize(Archive &amp;ar, const unsigned int file_version){
ar &amp; member;
ar &amp; m_state;
}
public:
my_class(int m) :
member(m)
// no default construct guarentees that no invalid object
// ever exists
my_class(int attribute) :
m_attribute(attribute),
m_state(0)
{}
};
</code></pre>
@@ -552,7 +561,7 @@ inline void save_construct_data(
Archive &amp; ar, const my_class * t, const unsigned int file_version
){
// save data required to construct instance
ar &lt;&lt; t-&gt;member;
ar &lt;&lt; t-&gt;m_attribute;
}
template&lt;class Archive&gt;
@@ -560,10 +569,10 @@ inline void load_construct_data(
Archive &amp; ar, my_class * t, const unsigned int file_version
){
// retrieve data from archive required to construct new instance
int m;
ar &gt;&gt; m;
int attribute;
ar &gt;&gt; attribute;
// invoke inplace constructor to initialize instance of my_class
::new(t)my_class(m);
::new(t)my_class(attribute);
}
}} // namespace ...
</code></pre>
@@ -668,8 +677,9 @@ 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.
<p>
This will work but may be inconvenient. We don't always know which derived
<h4><a name="export">Export</a></h4>
The above will work but may be inconvenient. We don't always know which derived
classes we are going to serialize when we write the code to serialize through
a base class pointer. Every time a new derived class is written we have to
go back to all the places where the base class is serialized and update the
@@ -716,22 +726,6 @@ would never be instantiated. So in addition to including export key
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
instantiates the class serialization code for all archive classes used
by the program.
<p>
In order to do this,
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
includes meta programming code to build a <code style="white-space: normal">mpl::list</code>
of all the file types used by the module by checking for definition of the header
inclusion guards.
Using this list,
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> will explicitly instantiate serialization
code for all exported classes.
For this implementaton to function, the header file
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
has to come after all the archive header files. This is enforced
by code at the end of the header file:
<a href="../../../boost/archive/basic_archive.hpp" target="basic_archive_hpp">basic_archive.hpp</a>
which will trip a STATIC_ASSERT if this requirement is violated.
<h4><a name="selectivetracking">Selective Tracking</a></h4>
Whether or not an object is tracked is determined by its
@@ -799,7 +793,10 @@ class derived : public base {
// method 1 : invoke base class serialization
boost::serialization::base_object&lt;base&gt;(*this);
// method 2 : explicitly register base/derived relationship
boost::serialization::void_cast_register&lt;derived, base&gt;();
boost::serialization::void_cast_register&lt;derived, base&gt;(
static_cast&lt;base *&gt;(NULL),
static_cast&lt;derived *&gt;(NULL)
)
}
};
+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> Revisted</h2>
<h2 align="center"><code style="white-space: normal">shared_ptr&lt;class T&gt;</code> Revisited</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 guarenteed to
C++ library. An implementation which depends only on the public interface can be guaranteed 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 seriailize the underlying raw pointer
// just serialize 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 poiter
// recover the underlying raw pointer
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 priniciple this is very much simpler than the original implementation. Completion of
In principle, 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 identifing pointers to the same objects from pointers to their base classes.
<li>A method for identifying 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>.
+229 -104
View File
@@ -27,7 +27,6 @@ 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">
@@ -36,6 +35,11 @@ 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>
<dt><a href="exception_safety.html">Exception Safety</a>
</dl>
@@ -150,108 +154,6 @@ 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.
<p>
There are several ways <code style="white-space: normal">BOOST_CLASS_EXPORT</code> could have been
implemented.
<p>
One approach would be to instantiate serialization code for all archive classes included in the library.
This would add to each executable a large amount of code that is most likely never called.
Also it would needlessly slow down compilations of any program that uses the library. Finally,
the list of archives would be "built-in" to the library which would compilicate the addition of
new or custom archive classes.
<p>
Another approach would be for the library user to somehow explicitly instantiate which archive classes
code should be instantiated for each class to be serialized. Users would have to include
header files corresponding the archive classes to be instantiated.
The list of instantiated archive classes would have to be manually kept in sync with the
archive class headers actually included. This was considered burdensome and error prone.
<p>
This implementation of <code style="white-space: normal">BOOST_CLASS_EXPORT</code> works in the
following way:
<ul>
<li>All header modules of the form &lt;boost/archive/*archive.hpp&gt; are required to precede
the header module <a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>.
<li>The header <a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
builds a list of archive classes whose header modules have been previously included.
It does this by checking to see which inclusion guard constants have been defined.
The header <a href="../../../boost/archive/detail/known_archive_types.hpp" target="known_archive_types_hpp">known_archive_types.hpp</a>
lists the archive header files which whose include guards will be checked. If you create your own
archive class, you probably want to edit this file.
<li><code style="white-space: normal">BOOST_CLASS_EXPORT(my_class)</code> explicitly instantiates
serialization code for <code style="white-space: normal">my_class</code> for each archive in the list.
</ul>
Serialization code will be instantiated for a given archive class
if and only if the module that defines that archive class has been included in the program.
Given this, our program will contain all necessary code instantiations and no other.
<p>
For many styles of code organization this header sequencing requirement presents little problem.
Serialization code organized by class headers that are designed to be independent of archive
implementations will look something like the following:
<code><pre>
// A.hpp
// Note:to preserve independence from any particular archive implementation,
// no headers from &lt;boost/archive/...&gt; are included.
// Headers can be included in any order.
#include &lt;boost/serialization/...&gt;
#include &lt;boost/serialization/export.hpp&gt;
... // include other headers that A depends upon
class A {
...
};
BOOST_CLASS_EXPORT(A) // note: the export name of this class
</pre></code>
This style:
<ul>
<li>permits the header to include all aspects of the serialization implementation.
<li>permits the header to be included anywhere else as part of some other class declaration.
<li>reflects the concept of headers as a "library of types" which
can be used independently in other programs or other parts of the same program.
<li>reflects a fundamental principle of the serialization library design in that the
specification of serialization of any class is independent of any archive implementation.
</ul>
However, it might not always be possible or convenient to conform to the above style. Something
like the following might be required or preferred:
<code><pre>
// A.hpp
// headers can be included in any order
#include &lt;boost/archive/text_oarchive.hpp&gt;
#include &lt;boost/archive/text_iarchive.hpp&gt;
...
#include &lt;boost/serialization/...&gt;
...
// can't do the following because then A.hpp couldn't be included somewhere else
// #include &lt;boost/serialization/export.hpp&gt;
class A {
...
};
// can't do the following because export.hpp is not included !!
//BOOST_CLASS_EXPORT(A) // note: the export name of this class
</pre></code>
As noted in the comments, this would work. But
<code style="white-space: normal">#include &lt;.../export.hpp&gt;</code> can't be used
without conflicting with other modules which use
<code style="white-space: normal">#include &lt;.../*archive.hpp&gt;</code>. In this
case we can move the export to an implementation file:
<code><pre>
// A.cpp
#include "A.hpp"
...
// export.hpp header should be last;
#include &lt;boost/serialization/export.hpp&gt;
...
BOOST_CLASS_EXPORT(A)
...
</pre></code>
<h3><a name="classinfo">Class Information</a></h3>
By default, for each class serialized, class information is written to the archive.
This information includes version number, implementation level and tracking
@@ -311,6 +213,16 @@ saved. For example, the gcc compiler reserves 4 bytes to store a variable of ty
So its possible that a value could be written that couldn't be represented by the loading program. This is a
fairly obvious situation and easily handled by using the numeric types in
<a target="cstding" href="../../../boost/cstdint.hpp">&lt;boost/cstdint.hpp&gt;</a>
<P>
A special integral type is <code>std::size_t</code> which is a typedef
of an integral types guaranteed to be large enough
to hold the size of any collection, but its actual size can differ depending
on the platform. The
<a href="wrappers.html#collection_size_type"><code>collection_size_type</code></a>
wrapper exists to enable a portable serialization of collection sizes by an archive.
Recommended choices for a portable serialization of collection sizes are to
use either 64-bit or variable length integer representation.
<h4><a name="traits">Traits</a></h4>
Another potential problem is illustrated by the following example:
@@ -326,7 +238,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);
@@ -385,6 +297,219 @@ 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
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
<code style="white-space: normal">demo_pimpl.cpp</code>
</a>,
<a href = "../example/demo_pimpl_A.cpp" target="demo_pimpl">
<code style="white-space: normal">demo_pimpl_A.cpp</code>
</a>
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.
<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.
<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.
<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.
<h3><a name="optimizations">Optimizations</a></h3>
In performance critical applications that serialize large sets of contiguous data of homogeneous
types one wants to avoid the overhead of serializing each element individually, which is
the motivation for the <a href="wrappers.html#arrays"><code>array</code></a>
wrapper.
Serialization functions for data types containing contiguous arrays of homogeneous
types, such as for <code>std::vector</code>, <code>std::valarray</code> or
<code>boost::multiarray</code> should serialize them using an
<a href="wrappers.html#arrays"><code>array</code></a> wrapper to make use of
these optimizations.
Archive types that can provide optimized serialization for contiguous arrays of
homogeneous types should implement these by overloading the serialization of
the <a href="wrappers.html#arrays"><code>array</code></a> wrapper, as is done
for the binary archives.
<h3><a href="exceptions.html">Archive Exceptions</a></h3>
<h3><a href="exception_safety.html">Exception Safety</a></h3>
+19 -1
View File
@@ -25,7 +25,25 @@ http://www.boost.org/LICENSE_1_0.txt)
</tr>
</table>
<hr>
To do.
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>.
<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
+77 -2
View File
@@ -32,6 +32,7 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#export">Export Key</a>
<dt><a href="#abstract">Abstract</a>
<dt><a href="#typeinfo">Type Information Implementation</a>
<dt><a href="#wrappers">Wrappers</a>
<dt><a href="#templates">Template Serialization Traits</a>
</dl>
Serialization of data depends on the type of the data. For example, for
@@ -255,6 +256,8 @@ addressable in one over several ways:
<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
@@ -311,6 +314,50 @@ This is illustrated by the test program
Other implementations are possible and might be necessary for
certain special cases.
version.hpp</a>.
<h3><a name="wrappers">Wrappers</a></h3>
Archives need to treat wrappers diffently from other types since, for example,
they usually are non-const object while output archives require that any
serialized object (with the exception of a wrapper) be const.
This header file <a href="../../../boost/serialization/wrapper.hpp">wrapper.hpp</a>
includes the following code:
<pre><code>
namespace boost {
namespace serialization {
template&lt;class T&gt;
struct is_wrapper
: public mpl::false_
{};
} // namespace serialization
} // namespace boost
</code></pre>
For any class <code style="white-space: normal">T</code>, The default definition
of <code style="white-space: normal">boost::serialization::is_wrapper&lt;T&gt;::value</code> is thus false.
If we want to declare that a class <code style="white-space: normal">my_class</code>
is a wrapper we specialize the version template:
<pre><code>
namespace boost {
namespace serialization {
struct is_wrapper&lt;my_class&gt;
: mpl::true_
{};
} // namespace serialization
} // namespace boost
</code></pre>
<p>
To diminish typing and enhance readability, a macro is defined
so that instead of the above, we could write:
<pre><code>
BOOST_CLASS_IS_WRAPPER(my_class)
</code></pre>
which expands to the code above.
<h3><a name="templates">Template Serialization Traits</a></h3>
In some instances it might be convenient to assign serialization traits
to a whole group of classes at once. Consider, the name-value pair
@@ -407,7 +454,8 @@ template&lt;
int Level,
int Tracking,
unsigned int Version = 0,
class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T)
class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T),
class IsWrapper = mpl::false_
&gt;
struct traits
</code></pre>
@@ -420,10 +468,37 @@ and template parameters should be assigned according to the following table:
<tr><td><code>Tracking</code></td><td>tracking level</td><td><code>track_never<br>track_selectivly<br>track_always</code></td><td>none</td></tr>
<tr><td><code>Version</code></td><td><code>class version</td><td>unsigned integer</td><td><code>0</code></td></tr>
<tr><td><code>ETTI</code></td><td><code>type_info</code> implementation</td><td><code>extended_type_info_typeid<br>extended_type_info_no_rtti</code></td><td>default <code>type_info implementation</code></td></tr>
<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>
<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>
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
<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
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
+5 -2
View File
@@ -539,8 +539,11 @@ This is described later in the manual.
<dt><a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp</a>
<dd>This is a variation the original demo which supports xml archives in addition
to the others. The extra wrapping macros are needed to associate a data
item name with the corresponding xml tag. For more information see
to the others. The extra wrapping macro, BOOST_SERIALIZATION_NVP(name), is
needed to associate a data item name with the corresponding xml
tag. It is importanted that 'name' be a valid xml tag, else it
will be impossible to restore the archive.
For more information see
<a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>.
<a href="../example/demo_save.xml" target="demo_save_xml">Here</a>
is what an xml archive looks like.
+2 -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(
const Derived * derived = NULL,
const Base * base = NULL
Derived const * derived = NULL,
Base * const base = NULL
)
</code></pre></h4></dt>
<dd>
+71 -4
View File
@@ -27,7 +27,9 @@ http://www.boost.org/LICENSE_1_0.txt)
<hr>
<dl class="page-index">
<dt><a href="#binaryobjects">Binary Objects</a>
<dt><a href="#arrays">Arrays</a>
<dt><a href="#strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a>
<dt><a href="#collection_size_type">Collection Sizes</a>
<dt><a href="#nvp">Name-Value Pairs</a>
<dt><a href="#composition">Composition</a>
</dl>
@@ -36,6 +38,9 @@ of some underlying data. This permits an archive class to define special
handling of this type. The library includes several such types for varying
purposes.
<p>
Wrappers need to be treated in a special way by some archives, and hence
the <A href="traits.html#wrappers"><code>is_wrapper</code></a> trait for
these wrapper classes is set to true.
<h3><a name="binaryobjects">Binary Objects</a></h3>
A binary object is just an sequence of bytes stored as raw
@@ -56,6 +61,45 @@ Its default serialization is to use archive class primitives
Note that it doesn't allocated any storage or create any objects.
Its sole purpose is to pass the data size and address as pair to the archive class.
<h3><a name="arrays">Arrays</a></h3>
An array is a contiguous sequence of homogeneous data types, such as a builtin
C-array, a <code>boost::array&lt;T></code> or a <code>std::vector&lt;T></code>.
The purpose of this wrapper is to support archive types (such as binary
archives) that provide optimized serialization for contiguous sequences of
objects of the same type.
The header file
<a href="../../../boost/serialization/array.hpp" target="array_hpp">
array.hpp
</a>
includes the function
<pre><code>
template &lt;T>
boost::serialization::make_array(T* t, std::size_t size);
</code></pre>
which will construct a temporary <code>array</code> object
<pre><code>
template<class T>
class array
{
public:
typedef T value_type;
array(value_type* t, std::size_t s);
value_type* address() const;
std::size_t count() const;
};
</code></pre>
that can be serialized just like any other object.
Its default serialization is to use serialize each array element.
Note that it doesn't allocated any storage or create any objects.
Its sole purpose is to pass the data type, size and address to the archive class.
Archive types that can provide optimized implementations for contiguous
arrays of homogeneous data types should overload the serialization of
<code>array</code>.
<h3><a name="strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></h3>
Another example of a serialization wrapper is the
<a href="strong_typedef.html"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a> template.
@@ -67,6 +111,26 @@ as an XML attribute in the form "version=12". In the absence of any specific ov
these types are automatically converted to the underlying integer type so the
special overrides used for XML archives aren't needed for other archives.
<h3><a name="collection_size_type">Collection Sizes</h3>
An example of a strong typedef is the <code>collection_size_type</code> in the
header file
<a href="../../../boost/serialization/collection_size_type.hpp" target="collection_size_type_hpp">
collection_size_type.hpp
</a>. This type should be used for serializaing the size of a C++ collection, so
that the archive can pick the best integral representation for the serialization
of collection sizes. This is necessary since, although <code>std::size_t</code>
is guaranteed to be an integral type large enough to represent the size of
a collection on a specific platform, the archive might want to serialize
the size differently than this type. For example, the <code>collection_size_type</code>
might be serialized as a variable length integer in a portable binary archive.
<h3><a name="nvp">Name-Value Pairs</h3>
XML archives present a somewhat special case. XML format has a nested
structure that maps well to the "recursive class member visitor" pattern used
@@ -120,12 +184,15 @@ Similarly there exists a macro definition that permits us to write:
<pre><code>
BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class)
</code></pre>
Note that these macros must be used in the namespace of the class,
and without qualifying the namespace in the argument.
<p>
Included is
<a href="../example/demo_xml.hpp" target="demo_xml_hpp">demo_xml.hpp<a>
which renders it's data members as <strong>name-value-pair</strong>s and
<a href="../example/demo_gps.hpp" target="demo_gps_hpp">demo_gps.hpp<a>
includes NVP wrappers or all data members.
<a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp<a>
which saves and loads data to an XML archive.
saves and loads data to an XML archive.
<a href="../example/demo_save.xml" target="demo_save_xml">Here</a>
is example of the XML Archive corresponding to our tutorial example.
+55
View File
@@ -0,0 +1,55 @@
# 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 ]
;
+1
View File
@@ -20,6 +20,7 @@
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/is_abstract.hpp>
/////////////////////////////////////////////////////////////
// The intent of this program is to serve as a tutorial for
+284
View File
@@ -0,0 +1,284 @@
#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_gps.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_GPS_HPP
+37 -7
View File
@@ -10,7 +10,6 @@
// should pass compilation and execution
#include <sstream>
#define BOOST_ARCHIVE_SOURCE
#include "portable_binary_oarchive.hpp"
#include "portable_binary_iarchive.hpp"
@@ -20,30 +19,36 @@
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 & i & ui & l & ul ;
ar & c & i & i2 & ui & l & ul ;
}
public:
bool operator==(const A & rhs) const {
return
i == rhs.i && ui == rhs.ui && l == rhs.l && ul == rhs.ul
c == rhs.c
&& i == rhs.i
&& i2 == rhs.i2
&& ui == rhs.ui
&& l == rhs.l
&& ul == rhs.ul
;
}
A() :
c(std::rand()),
i(std::rand()),
i2(0x80),
ui(std::rand()),
l(std::rand()),
l(std::rand() * std::rand()),
ul(std::rand())
{}
};
@@ -62,6 +67,31 @@ 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);
}
-14
View File
@@ -133,13 +133,6 @@ int main(int argc, char *argv[])
std::ofstream ofs(filename.c_str());
boost::archive::text_oarchive oa(ofs);
oa.register_type(static_cast<B *>(NULL));
oa.register_type(
static_cast<
boost::detail::sp_counted_base_impl<
B *, boost::checked_deleter<B>
> *
>(NULL)
);
oa << spa;
oa << spa1;
}
@@ -157,13 +150,6 @@ int main(int argc, char *argv[])
// restore the schedule from the archive
ia.register_type(static_cast<B *>(NULL));
ia.register_type(
static_cast<
boost::detail::sp_counted_base_impl<
B *, boost::checked_deleter<B>
> *
>(NULL)
);
ia >> spa;
ia >> spa1;
}
+1 -1
View File
@@ -24,7 +24,7 @@ namespace std{
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include "demo_xml.hpp"
#include "demo_gps.hpp"
void save_schedule(const bus_schedule &s, const char * filename){
// make an archive
+1 -1
View File
@@ -13,7 +13,7 @@
#include <boost/archive/xml_iarchive.hpp>
#include "demo_xml.hpp"
#include "demo_gps.hpp"
void
restore_schedule(bus_schedule &s, const char * filename)
+1 -1
View File
@@ -13,7 +13,7 @@
#include <boost/archive/xml_oarchive.hpp>
#include "demo_xml.hpp"
#include "demo_gps.hpp"
void save_schedule(const bus_schedule &s, const char * filename){
// make an archive
+42
View File
@@ -0,0 +1,42 @@
#ifndef PORTABLE_BINARY_ARCHIVE_HPP
#define PORTABLE_BINARY_ARCHIVE_HPP
// 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/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
@@ -0,0 +1,130 @@
/////////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/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::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::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::ARCHIVE_SIGNATURE())
boost::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::ARCHIVE_VERSION() < input_library_version.t)
boost::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 type of text stream
#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
+113 -82
View File
@@ -6,31 +6,42 @@
# 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 Robert Ramey - http://www.rrsd.com .
// (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/archive/binary_iarchive.hpp>
#include <boost/detail/endian.hpp>
#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"
/////////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_archive_exception :
class portable_binary_iarchive_exception :
public virtual boost::archive::archive_exception
{
public:
typedef enum {
incompatible_integer_size
} exception_code;
portable_binary_archive_exception(exception_code c = incompatible_integer_size )
portable_binary_iarchive_exception(exception_code c = incompatible_integer_size )
{}
virtual const char *what( ) const throw( )
{
@@ -46,112 +57,132 @@ public:
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "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
// "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
class portable_binary_iarchive :
// don't derive from binary_iarchive !!!
public boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
public boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>,
public boost::archive::detail::common_iarchive<
portable_binary_iarchive
>
{
typedef boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
,
public boost::archive::detail::shared_ptr_helper
{
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> archive_base_t;
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_iarchive<
portable_binary_iarchive
> archive_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::basic_binary_iarchive<portable_binary_iarchive>;
friend class boost::archive::detail::interface_iarchive<
portable_binary_iarchive
>;
friend class boost::archive::load_access;
protected:
#endif
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
}
unsigned int m_flags;
void load_impl(boost::intmax_t & l, char maxsize);
// 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);
}
void load(unsigned int & t){
long l;
load_impl(l, sizeof(unsigned int));
t = l;
#ifndef BOOST_NO_STD_WSTRING
void load(std::wstring & t){
this->primitive_base_t::load(t);
}
void load(int & t){
long l;
load_impl(l, sizeof(int));
t = l;
#endif
void load(float & t){
this->primitive_base_t::load(t);
// floats not supported
//BOOST_STATIC_ASSERT(false);
}
void load(unsigned long & t){
long l;
load_impl(l, sizeof(unsigned long));
t = l;
void load(double & t){
this->primitive_base_t::load(t);
// doubles not supported
//BOOST_STATIC_ASSERT(false);
}
void load(long & t){
long l;
load_impl(l, sizeof(long));
t = l;
void load(char & t){
this->primitive_base_t::load(t);
}
void load(unsigned char & t){
this->primitive_base_t::load(t);
}
// 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_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) :
archive_base_t(
is,
flags | boost::archive::no_header // skip default header checking
)
primitive_base_t(
* is.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
// 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();
}
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);
}
};
// 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 version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
#endif
// 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
@@ -0,0 +1,96 @@
/////////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_big)
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::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::ARCHIVE_SIGNATURE()
);
* this << file_signature;
// write library version
const boost::archive::version_type v(
boost::archive::ARCHIVE_VERSION()
);
* this << v;
}
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
}
// explicitly instantiate for this type of text 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
+125 -68
View File
@@ -6,6 +6,11 @@
# 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
@@ -17,9 +22,38 @@
// 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/binary_oarchive.hpp>
#include <boost/detail/endian.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;
}
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" output binary archive. This is a variation of the native binary
@@ -27,53 +61,36 @@
// be passed across systems. Note:floating point types not addressed here
class portable_binary_oarchive :
// don't derive from binary_oarchive !!!
public boost::archive::binary_oarchive_impl<
portable_binary_oarchive,
public boost::archive::basic_binary_oprimitive<
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::basic_binary_oarchive<portable_binary_oarchive>;
friend class boost::archive::detail::interface_oarchive<
portable_binary_oarchive
>;
friend class boost::archive::save_access;
protected:
#endif
void save_impl(long l){
long ll = l;
char size = 0;;
do{
ll >>= 8;
++size;
}while(ll != -1 && 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);
}
unsigned int m_flags;
void save_impl(const boost::intmax_t l, const char maxsize);
// 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
@@ -82,54 +99,94 @@ public:
// 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);
}
void save(const unsigned int t){
save_impl(t);
#ifndef BOOST_NO_STD_WSTRING
void save(const std::wstring & t){
this->primitive_base_t::save(t);
}
void save(const int 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 long 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 long t){
save_impl(t);
void save(const char & t){
this->primitive_base_t::save(t);
}
void save(const unsigned char & t){
this->primitive_base_t::save(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);
}
// 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) :
archive_base_t(
os,
flags | boost::archive::no_header // skip default header checking
)
primitive_base_t(
* os.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(flags & (endian_big | endian_little))
{
// 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();
}
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);
}
};
#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<
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 version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive)
#endif
// 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
+126
View File
@@ -0,0 +1,126 @@
#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/detail/common_iarchive.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/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
//#include <boost/archive/archive_exception.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)
{}
// load_override for std::vector and serialization::array dispatches to
// load_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 ValueType, class Allocator>
void load_optimized(
std::vector<ValueType, 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
+124
View File
@@ -0,0 +1,124 @@
#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/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
#include <boost/type_traits/remove_const.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
+141
View File
@@ -0,0 +1,141 @@
#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>
#include <boost/static_assert.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_)
{
BOOST_STATIC_ASSERT(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_)
{
BOOST_STATIC_ASSERT(false);
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_)
{
BOOST_STATIC_ASSERT(false);
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() );
}
#if 1
// 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());
}
#else
// 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 Archive::use_array_optimization<ValueType>::type use_optimized;
save_optimized(x,version, use_optimized());
}
#endif
// Save 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
+2 -12
View File
@@ -86,8 +86,8 @@ 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
// no_object_creation = 16 // don't create any new objects
no_tracking = 8, // suppress ALL tracking
flags_last = 8
};
#define NULL_POINTER_TAG class_id_type(-1)
@@ -117,14 +117,4 @@ BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type)
BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type)
BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type)
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// Make sure that the export.hpp header isn't included before any archive header
// Doing so would inhibit construction of correct mpl list of known archive
// types which in turn would inhibit instantiation of all combinations of
// serialization/archive types.
#ifdef BOOST_SERIALIZATION_EXPORT_HPP
#error "export.hpp must not be included before any archive header"
#endif
#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP
+18 -14
View File
@@ -28,9 +28,9 @@
#include <boost/detail/workaround.hpp>
#include <boost/pfto.hpp>
#include <boost/archive/detail/common_iarchive.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,11 +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)
{
this->detail_common_iarchive::load_override(t, 0);
void load_override(T & t, BOOST_PFTO int){
this->array_iarchive::load_override(t, 0L);
}
// binary files don't include the optional information
void load_override(class_id_optional_type & /* t */, int){}
@@ -69,39 +68,44 @@ public:
// for these pseudo prmitive types.
void load_override(version_type & t, int){
// upto 255 versions
unsigned char x;
unsigned char x=0;
* this->This() >> x;
t = version_type(x);
}
void load_override(class_id_type & t, int){
// upto 32K classes
int_least16_t x;
int_least16_t x=0;
* this->This() >> x;
t = class_id_type(x);
}
void load_override(class_id_reference_type & t, int){
// upto 32K classes
int_least16_t x;
int_least16_t x=0;
* this->This() >> x;
t = class_id_reference_type(x);
}
void load_override(object_id_type & t, int){
// upto 2G objects
uint_least32_t x;
uint_least32_t x=0;
* this->This() >> x;
t = object_id_type(x);
}
void load_override(object_reference_type & t, int){
// upto 2G objects
uint_least32_t x;
uint_least32_t x=0;
* this->This() >> x;
t = object_reference_type(x);
}
void load_override(tracking_type & t, int){
char x;
char x=0;
* this->This() >> x;
t = (0 != x);
}
void load_override(serialization::collection_size_type & t, int){
unsigned int x=0;
* this->This() >> x;
t = serialization::collection_size_type(x);
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
load_override(class_name_type & t, int);
@@ -109,7 +113,7 @@ public:
init();
basic_binary_iarchive(unsigned int flags) :
detail::common_iarchive<Archive>(flags)
array_iarchive(flags)
{}
};
@@ -6,6 +6,10 @@
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( disable : 4800 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_binary_iprimitive.hpp
//
@@ -48,6 +52,9 @@ namespace std{
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#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/serialization/array.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -69,8 +76,11 @@ 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>
@@ -86,6 +96,7 @@ public:
load_binary(& t, sizeof(t));
int i = t;
assert(0 == i || 1 == i);
(void)i; // warning suppression for release builds.
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
load(std::string &s);
@@ -108,6 +119,21 @@ public:
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~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> {};
};
// the optimized load_array dispatches to load_binary
template <class ValueType>
void load_array(serialization::array<ValueType>& a, unsigned int)
{
load_binary(a.address(),a.count()*sizeof(ValueType));
}
void
load_binary(void *address, std::size_t count);
};
@@ -118,35 +144,13 @@ 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(count != static_cast<std::size_t>(s))
if(scount != static_cast<std::streamsize>(s))
boost::throw_exception(
archive_exception(archive_exception::stream_error)
);
@@ -157,11 +161,11 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
// boost::throw_exception(archive_exception(archive_exception::stream_error));
Elem t;
scount = m_sb.sgetn(& t, 1);
if(count != 1)
if(scount != 1)
boost::throw_exception(
archive_exception(archive_exception::stream_error)
);
std::memcpy(address, &t, s);
std::memcpy(static_cast<char*>(address) + (count - s), &t, s);
}
}
+24 -13
View File
@@ -27,8 +27,10 @@
#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 {
@@ -41,12 +43,9 @@ namespace archive {
// by a program built with the same tools for the same machne. This class
// does have the virtue of buiding the smalles archive in the minimum amount
// of time. So under some circumstances it may be he right choice.
/////////////////////////////////////////////////////////////////////////
// class basic_text_iarchive - read serialized objects from a input text stream
template<class Archive>
class basic_binary_oarchive :
public detail::common_oarchive<Archive>
public array::oarchive<Archive>
{
protected:
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
@@ -59,33 +58,39 @@ 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){
this->array_oarchive::save_override(t, 0L);
}
/*
template<class T>
void save_override(T & t, BOOST_PFTO int){
this->detail_common_oarchive::save_override(t, 0);
this->save_override(const_cast<const T &>(t), 0L);
}
*/
// binary files don't include the optional information
void save_override(const class_id_optional_type & /* t */, int){}
void save_override(const version_type & t, int){
// upto 255 versions
// note:t.t resolves borland ambguity
unsigned char x = t.t;
const unsigned char x = t.t;
* this->This() << x;
}
void save_override(const class_id_type & t, int){
// upto 32K classes
int_least16_t x = t.t;
const int_least16_t x = t.t;
* this->This() << x;
}
void save_override(const class_id_reference_type & t, int){
// upto 32K classes
int_least16_t x = t.t;
const int_least16_t x = t.t;
* this->This() << x;
}
void save_override(const object_id_type & t, int){
// upto 2G objects
uint_least32_t x = t.t;
const uint_least32_t x = t.t;
* this->This() << x;
}
void save_override(const object_reference_type & t, int){
@@ -94,7 +99,7 @@ public:
* this->This() << x;
}
void save_override(const tracking_type & t, int){
char x = t.t;
const char x = t.t;
* this->This() << x;
}
@@ -104,11 +109,17 @@ public:
* this->This() << s;
}
void save_override(const serialization::collection_size_type & t, int){
// for backward compatibility, 64 bit integer or variable length integer would be preferred
unsigned int x = t.t;
* this->This() << x;
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
init();
basic_binary_oarchive(unsigned int flags) :
detail::common_oarchive<Archive>(flags)
array_oarchive(flags)
{}
};
@@ -46,6 +46,9 @@ namespace std{
#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/mpl/placeholders.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -68,9 +71,10 @@ 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)
@@ -84,8 +88,7 @@ public:
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
void save(const bool t){
int i = t;
assert(0 == i || 1 == i);
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
save_binary(& t, sizeof(t));
}
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
@@ -101,6 +104,7 @@ public:
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
init();
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_binary_oprimitive(
std::basic_streambuf<Elem, Tr> & sb,
@@ -109,6 +113,24 @@ 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 serialization::is_bitwise_serializable<T> {};
};
// the optimized save_array dispatches to save_binary
template <class ValueType>
void save_array(serialization::array<ValueType> const& a, unsigned int)
{
save_binary(a.address(),a.count()*sizeof(ValueType));
}
void save_binary(const void *address, std::size_t count);
};
@@ -25,14 +25,13 @@
// 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
{
@@ -61,16 +61,6 @@ public:
{
this->detail_common_iarchive::load_override(t, 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
// text file don't include the optional information
void load_override(class_id_optional_type & /*t*/, int){}
@@ -68,10 +68,14 @@ 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)
{
+23 -20
View File
@@ -38,7 +38,7 @@ namespace boost {
namespace archive {
/////////////////////////////////////////////////////////////////////////
// class basic_text_iarchive - read serialized objects from a input text stream
// class basic_text_oarchive
template<class Archive>
class basic_text_oarchive :
public detail::common_oarchive<Archive>
@@ -78,36 +78,39 @@ public:
// start new objects on a new line
void save_override(const object_id_type & t, int){
this->This()->newline();
// and and invoke prmitive to underlying value
// note extra .t to funciton with Borland 5.51 compiler
// and invoke prmitive to underlying value
this->This()->save(t.t);
}
void save_override(const object_reference_type & t, int){
this->This()->newline();
// and and invoke prmitive to underlying value
// note extra .t to funciton with Borland 5.51 compiler
// and invoke prmitive to underlying value
this->This()->save(t.t);
}
// note the following four overrides are necessary for some borland
// compilers(5.51) which don't handle BOOST_STRONG_TYPE properly.
void save_override(const version_type & t, int){
// note:t.t resolves borland ambguity
const unsigned int x = t.t;
* this->This() << x;
}
void save_override(const class_id_type & t, int){
// note:t.t resolves borland ambguity
const int x = t.t;
* this->This() << x;
}
void save_override(const class_id_reference_type & t, int){
// note:t.t resolves borland ambguity
const int x = t.t;
* this->This() << x;
}
// text file don't include the optional information
void save_override(const class_id_optional_type & /* t */, int){}
// note the following four overrides are necessary for some borland
// compilers which don't handle BOOST_STRONG_TYPE properly.
void save_override(const version_type & t, int){
// note:t.t resolves borland ambguity
unsigned int x = t.t;
* this->This() << x;
}
void save_override(const class_id_type & t, int){
// note:t.t resolves borland ambguity
int x = t.t;
* this->This() << x;
}
void save_override(const class_id_reference_type & t, int){
// note:t.t resolves borland ambguity
int x = t.t;
* this->This() << x;
}
void save_override(const class_name_type & t, int){
const std::string s(t);
* this->This() << s;
@@ -71,10 +71,13 @@ 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>
@@ -89,10 +92,7 @@ public:
void save(const bool t){
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
#ifndef NDEBUG
int i = t;
assert(0 == i || 1 == i);
#endif
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
if(os.fail())
boost::throw_exception(archive_exception(archive_exception::stream_error));
os << t;
@@ -24,41 +24,6 @@
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
+9 -6
View File
@@ -9,7 +9,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_xml_iarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -25,6 +25,8 @@
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -33,7 +35,7 @@ namespace archive {
/////////////////////////////////////////////////////////////////////////
// class xml_iarchive - read serialized objects from a input text stream
template<class Archive>
class basic_xml_iarchive :
class basic_xml_iarchive :
public detail::common_iarchive<Archive>
{
protected:
@@ -60,7 +62,8 @@ public:
// If your program fails to compile here, its most likely due to
// not specifying an nvp wrapper around the variable to
// be serialized.
BOOST_STATIC_ASSERT(0 == sizeof(T));
BOOST_MPL_ASSERT((serialization::is_wrapper<T>));
this->detail_common_iarchive::load_override(t, 0);
}
// Anything not an attribute - see below - should be a name value
@@ -71,7 +74,7 @@ public:
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
const
#endif
boost::serialization::nvp<T> & t,
boost::serialization::nvp<T> & t,
int
){
load_start(t.name());
@@ -101,9 +104,9 @@ public:
// handle this.
// void load_override(class_name_type & t, int);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_iarchive(unsigned int flags);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~basic_xml_iarchive();
};
+16 -10
View File
@@ -9,7 +9,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_xml_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -24,15 +24,18 @@
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace boost {
namespace archive {
//////////////////////////////////////////////////////////////////////
// class basic_xml_oarchive - write serialized objects to a xml output stream
template<class Archive>
class basic_xml_oarchive :
class basic_xml_oarchive :
public detail::common_oarchive<Archive>
{
protected:
@@ -42,8 +45,10 @@ public:
// for some inexplicable reason insertion of "class" generates compile erro
// on msvc 7.1
friend detail::interface_oarchive<Archive>;
friend class save_access;
#else
friend class detail::interface_oarchive<Archive>;
friend class save_access;
#endif
// special stuff for xml output
unsigned int depth;
@@ -55,13 +60,13 @@ public:
init();
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
write_attribute(
const char *attribute_name,
const char *attribute_name,
int t,
const char *conjunction = "=\""
);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
write_attribute(
const char *attribute_name,
const char *attribute_name,
const char *key
);
// helpers used below
@@ -80,7 +85,8 @@ public:
// If your program fails to compile here, its most likely due to
// not specifying an nvp wrapper around the variable to
// be serialized.
BOOST_STATIC_ASSERT(0 == sizeof(T));
BOOST_MPL_ASSERT((serialization::is_wrapper<T>));
this->detail_common_oarchive::save_override(t, 0);
}
// special treatment for name-value pairs.
@@ -90,7 +96,7 @@ public:
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
const
#endif
::boost::serialization::nvp<T> & t,
::boost::serialization::nvp<T> & t,
int
){
save_start(t.name());
@@ -117,9 +123,9 @@ public:
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
save_override(const tracking_type & t, int);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_oarchive(unsigned int flags);
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
~basic_xml_oarchive();
};
+41 -4
View File
@@ -22,6 +22,43 @@
namespace boost {
namespace archive {
// do not derive from the classes below. If you want to extend this functionality
// via inhertance, derived from text_iarchive_impl instead. This will
// preserve correct static polymorphism.
// same as binary_iarchive below - without the shared_ptr_helper
class naked_binary_iarchive :
public binary_iarchive_impl<
boost::archive::naked_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>
{
public:
naked_binary_iarchive(std::istream & is, unsigned int flags = 0) :
binary_iarchive_impl<
naked_binary_iarchive, std::istream::char_type, std::istream::traits_type
>(is, flags)
{}
naked_binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) :
binary_iarchive_impl<
naked_binary_iarchive, std::istream::char_type, std::istream::traits_type
>(bsb, flags)
{}
};
} // namespace archive
} // namespace boost
// note special treatment of shared_ptr. This type needs a special
// structure associated with every archive. We created a "mix-in"
// class to provide this functionality. Since shared_ptr holds a
// special esteem in the boost library - we included it here by default.
#include <boost/archive/shared_ptr_helper.hpp>
namespace boost {
namespace archive {
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from binary_iarchive_impl instead. This will
// preserve correct static polymorphism.
@@ -30,7 +67,8 @@ class binary_iarchive :
boost::archive::binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>
>,
public detail::shared_ptr_helper
{
public:
binary_iarchive(std::istream & is, unsigned int flags = 0) :
@@ -48,8 +86,7 @@ public:
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::archive::binary_iarchive)
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive)
#endif // BOOST_ARCHIVE_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){
basic_binary_iarchive<Archive>::load_override(t, 0);
this->basic_binary_iarchive<Archive>::load_override(t, 0L);
}
void init(unsigned int flags){
if(0 != (flags & no_header))
+4 -3
View File
@@ -43,11 +43,12 @@ public:
{}
};
typedef binary_oarchive naked_binary_oarchive;
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::archive::binary_oarchive)
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive)
#endif // BOOST_ARCHIVE_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){
basic_binary_oarchive<Archive>::save_override(t, 0);
this->basic_binary_oarchive<Archive>::save_override(t, 0L);
}
void init(unsigned int flags) {
if(0 != (flags & no_header))
+39 -6
View File
@@ -27,9 +27,43 @@
namespace boost {
namespace archive {
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from binary_iarchive_impl instead. This will
// preserve correct static polymorphism.
// same as binary_wiarchive below - without the shared_ptr_helper
class naked_binary_wiarchive :
public binary_iarchive_impl<
boost::archive::naked_binary_wiarchive,
std::wistream::char_type,
std::wistream::traits_type
>
{
public:
naked_binary_wiarchive(std::wistream & is, unsigned int flags = 0) :
binary_iarchive_impl<
naked_binary_wiarchive,
std::wistream::char_type,
std::wistream::traits_type
>(is, flags)
{}
naked_binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) :
binary_iarchive_impl<
naked_binary_wiarchive,
std::wistream::char_type,
std::wistream::traits_type
>(bsb, flags)
{}
};
} // namespace archive
} // namespace boost
// note special treatment of shared_ptr. This type needs a special
// structure associated with every archive. We created a "mix-in"
// class to provide this functionality. Since shared_ptr holds a
// special esteem in the boost library - we included it here by default.
#include <boost/archive/shared_ptr_helper.hpp>
namespace boost {
namespace archive {
class binary_wiarchive :
public binary_iarchive_impl<
binary_wiarchive, std::wistream::char_type, std::wistream::traits_type
@@ -51,9 +85,8 @@ public:
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::archive::binary_wiarchive)
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP
+4 -3
View File
@@ -48,12 +48,13 @@ public:
{}
};
typedef binary_woarchive naked_binary_woarchive;
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::archive::binary_woarchive)
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP
+7 -4
View File
@@ -20,19 +20,22 @@
#include <cstddef>
#include <boost/config.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
namespace std{
#if defined(__LIBCOMO__)
using ::mbstate_t;
#elif defined(__QNXNTO__)
using std::mbstate_t;
//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;
#endif
#elif defined(BOOST_RWSTD_VER)
using ::mbstate_t;
#endif
} // namespace std
namespace boost {
@@ -56,7 +59,7 @@ public:
template<>
class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
{
virtual std::codecvt_base::result
virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
do_out(
std::mbstate_t & state,
const wchar_t * first1,
@@ -66,7 +69,7 @@ class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
char * last2,
char * & next2
) const;
virtual std::codecvt_base::result
virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
do_in(
std::mbstate_t & state,
const char * first1,
@@ -13,3 +13,8 @@
# pragma warning(push)
# pragma warning(disable : 4251 4231 4660 4275)
#endif
#if defined( __BORLANDC__ )
#pragma nopushoptwarn
#endif
@@ -12,3 +12,8 @@
#pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#if defined( __BORLANDC__ )
#pragma nopushoptwarn
#endif
@@ -76,8 +76,7 @@ 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,8 +51,7 @@ 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
);
@@ -25,23 +25,24 @@
#include <boost/archive/detail/decl.hpp>
#if !defined(BOOST_ARCHIVE_SOURCE) \
&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB)
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \
&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \
&& !defined(BOOST_SERIALIZATION_SOURCE)
// 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
@@ -20,7 +20,6 @@
// #include <boost/scoped_ptr.hpp>
#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -35,48 +34,6 @@ namespace detail {
//////////////////////////////////////////////////////////////////////
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_archive_impl
{
//////////////////////////////////////////////////////////////////////
// list of serialization helpers
// at least one compiler sunpro 5.3 erroneously doesn't give access to embedded structs
struct helper_compare;
friend struct helper_compare;
struct helper_type {
shared_ptr<void> m_helper;
const boost::serialization::extended_type_info * m_eti;
helper_type(
shared_ptr<void> h,
const boost::serialization::extended_type_info * const eti
) :
m_helper(h),
m_eti(eti)
{}
};
struct helper_compare {
bool operator()(
const helper_type & lhs,
const helper_type & rhs
) const {
return lhs.m_eti < rhs.m_eti;
}
};
typedef std::set<helper_type, helper_compare> collection;
typedef collection::iterator helper_iterator;
typedef collection::const_iterator helper_const_iterator;
collection m_helpers;
protected:
void
lookup_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
);
void
insert_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
);
};
} // namespace detail
+10 -19
View File
@@ -20,15 +20,12 @@
// #include <boost/scoped_ptr.hpp>
#include <boost/config.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/serialization/tracking_enum.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/decl.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
@@ -65,26 +62,20 @@ protected:
public:
// note: NOT part of the public API.
void next_object_pointer(void *t);
void register_basic_serializer(const basic_iserializer & bis);
void
lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
);
void
insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
void register_basic_serializer(
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_iserializer & bis
);
void load_object(
void *t,
const basic_iserializer & bis
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_iserializer & bis
);
const basic_pointer_iserializer *
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */ basic_pointer_iserializer *
load_pointer(
void * & t,
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */
basic_pointer_iserializer * bpis_ptr,
const /* BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) */
basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & eti
)
);
@@ -16,13 +16,12 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <cassert>
#include <cstdlib> // NULL
#include <boost/config.hpp>
#include <boost/archive/detail/auto_link_archive.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/abi_prefix.hpp> // must be the last header
namespace boost {
@@ -42,10 +41,10 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer :
public basic_serializer
{
private:
basic_pointer_iserializer *bpis;
basic_pointer_iserializer *m_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__)
@@ -54,13 +53,13 @@ protected:
~basic_iserializer();
public:
bool serialized_as_pointer() const {
return bpis != NULL;
return m_bpis != NULL;
}
void set_bpis(basic_pointer_iserializer *bpis_){
bpis = bpis_;
void set_bpis(basic_pointer_iserializer *bpis){
m_bpis = bpis;
}
const basic_pointer_iserializer * get_bpis_ptr() const {
return bpis;
return m_bpis;
}
virtual void load_object_data(
basic_iarchive & ar,
@@ -28,9 +28,6 @@
#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
@@ -62,7 +59,7 @@ class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive
virtual void vsave(const class_name_type & t) = 0;
virtual void vsave(const tracking_type t) = 0;
protected:
basic_oarchive(unsigned int flags);
basic_oarchive(unsigned int flags = 0);
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
@@ -70,16 +67,8 @@ protected:
~basic_oarchive();
public:
// note: NOT part of the public interface
void register_basic_serializer(const basic_oserializer & bos);
void
lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
);
void
insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
void register_basic_serializer(
const basic_oserializer & bos
);
void save_object(
const void *x,
@@ -41,7 +41,7 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer :
public basic_serializer
{
private:
basic_pointer_oserializer *bpos;
basic_pointer_oserializer *m_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 bpos != NULL;
return m_bpos != NULL;
}
void set_bpos(basic_pointer_oserializer *bpos_){
bpos = bpos_;
void set_bpos(basic_pointer_oserializer *bpos){
m_bpos = bpos;
}
const basic_pointer_oserializer * get_bpos() const {
return bpos;
return m_bpos;
}
virtual void save_object_data(
basic_oarchive & ar, const void * x
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP
#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_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_ARCHIVE_POINTER_ISERIALIZER_HPP
#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
@@ -1,5 +1,5 @@
#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP
#ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP
#define BOOST_ARCHIVE_BASIC_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_ARCHIVE_POINTER_OSERIALIZER_HPP
#endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP
@@ -34,7 +34,9 @@ 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;
@@ -44,6 +46,13 @@ public:
}
};
class basic_serializer_arg : public basic_serializer {
public:
basic_serializer_arg(const serialization::extended_type_info & eti) :
basic_serializer(eti)
{}
};
} // namespace detail
} // namespace archive
} // namespace boost
@@ -38,28 +38,16 @@ struct BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) type_info_pointer_compare
{
bool operator()(
const basic_serializer * lhs, const basic_serializer * 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&);
) const {
return *lhs < *rhs;
}
};
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
@@ -19,6 +19,7 @@
#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/archive/detail/interface_iarchive.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/pfto.hpp>
namespace boost {
@@ -31,6 +32,7 @@ class common_iarchive :
public basic_iarchive,
public interface_iarchive<Archive>
{
friend class interface_iarchive<Archive>;
private:
virtual void vload(version_type & t){
* this->This() >> t;
@@ -61,7 +63,7 @@ protected:
void load_start(const char *name){}
void load_end(const char *name){}
// default archive initialization
common_iarchive(unsigned int flags) :
common_iarchive(unsigned int flags = 0) :
basic_iarchive(flags),
interface_iarchive<Archive>()
{}
@@ -19,6 +19,7 @@
#include <boost/archive/detail/basic_oarchive.hpp>
#include <boost/archive/detail/interface_oarchive.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/register_archive.hpp>
namespace boost {
namespace archive {
@@ -30,6 +31,7 @@ class common_oarchive :
public basic_oarchive,
public interface_oarchive<Archive>
{
friend class interface_oarchive<Archive>;
private:
virtual void vsave(const version_type t){
* this->This() << t;
@@ -61,10 +63,9 @@ 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){}
common_oarchive(unsigned int flags) :
common_oarchive(unsigned int flags = 0) :
basic_oarchive(flags),
interface_oarchive<Archive>()
{}
@@ -20,18 +20,14 @@
#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_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
template<class Archive>
class interface_iarchive
@@ -50,28 +46,15 @@ public:
}
template<class T>
const basic_pointer_iserializer * register_type(T * = NULL){
const basic_pointer_iserializer *
register_type(T * = NULL){
const basic_pointer_iserializer & bpis =
instantiate_pointer_iserializer(
static_cast<Archive *>(NULL),
static_cast<T *>(NULL)
);
boost::serialization::singleton<
pointer_iserializer<Archive, T>
>::get_const_instance();
this->This()->register_basic_serializer(bpis.get_basic_serializer());
return & bpis;
}
void lookup_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
){
this->This()->lookup_basic_helper(eti, sph);
}
void insert_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
this->This()->insert_basic_helper(eti, sph);
}
template<class T>
Archive & operator>>(T & t){
this->This()->load_override(t, 0);
@@ -23,16 +23,13 @@
#include <boost/archive/detail/oserializer.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
#include <boost/serialization/singleton.hpp>
namespace boost {
namespace archive {
namespace detail {
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
template<class Archive>
class interface_oarchive
@@ -51,29 +48,16 @@ public:
}
template<class T>
const basic_pointer_oserializer * register_type(const T * = NULL){
const basic_pointer_oserializer *
register_type(const T * = NULL){
const basic_pointer_oserializer & bpos =
instantiate_pointer_oserializer(
static_cast<Archive *>(NULL),
static_cast<T *>(NULL)
);
boost::serialization::singleton<
pointer_oserializer<Archive, T>
>::get_const_instance();
this->This()->register_basic_serializer(bpos.get_basic_serializer());
return & bpos;
}
void lookup_helper(
const boost::serialization::extended_type_info * const eti,
boost::shared_ptr<void> & sph
){
this->This()->lookup_basic_helper(eti, sph);
}
void insert_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
this->This()->insert_basic_helper(eti, sph);
}
template<class T>
Archive & operator<<(T & t){
this->This()->save_override(t, 0);
+66 -126
View File
@@ -40,11 +40,12 @@ namespace std{
#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_all_extents.hpp>
#include <boost/serialization/is_abstract.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/if.hpp>
@@ -57,6 +58,7 @@ namespace std{
#include <boost/mpl/list.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
#include <boost/serialization/extended_type_info_typeid.hpp>
@@ -65,17 +67,17 @@ 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/serialization/force_include.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/binary_object.hpp>
#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 {
@@ -106,49 +108,40 @@ 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_instance()
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
)
{}
public:
virtual BOOST_DLLEXPORT void load_object_data(
virtual void load_object_data(
basic_iarchive & ar,
void *x,
const unsigned int file_version
) const BOOST_USED ;
) const;
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_selectivly
&& 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 {
typedef BOOST_DEDUCED_TYPENAME
boost::serialization::type_info_implementation<
T
>::type::is_polymorphic::type typex;
return typex::value;
}
static iserializer & instantiate(){
static iserializer instance;
return instance;
return boost::is_polymorphic<T>::value;
}
virtual ~iserializer(){};
};
template<class Archive, class T>
BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
void iserializer<Archive, T>::load_object_data(
basic_iarchive & ar,
void *x,
const unsigned int file_version
@@ -162,52 +155,25 @@ BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
);
}
// instantiation of this template creates a static object. Note inversion of
// normal argument order to workaround bizarre error in MSVC 6.0 which only
// manifests iftself during compiler time.
template<class T, class Archive>
class pointer_iserializer : public archive_pointer_iserializer<Archive>
template<class Archive, class T>
class pointer_iserializer
: public archive_pointer_iserializer<Archive>
{
private:
virtual const basic_iserializer & get_basic_serializer() const {
return iserializer<Archive, T>::instantiate();
return boost::serialization::singleton<
iserializer<Archive, T>
>::get_const_instance();
}
virtual BOOST_DLLEXPORT void load_object_ptr(
virtual 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) )
) const ;
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_iserializer() BOOST_USED;
static const pointer_iserializer instance;
public:
// at least one compiler (CW) seems to require that serialize_adl
// be explicitly instantiated. Still under investigation.
#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
void (* const m)(Archive &, T &, const unsigned);
boost::serialization::extended_type_info * (* e)();
#endif
static BOOST_DLLEXPORT const pointer_iserializer & instantiate() BOOST_USED;
virtual ~pointer_iserializer(){};
pointer_iserializer();
};
template<class T, class Archive>
BOOST_DLLEXPORT const pointer_iserializer<T, Archive> &
pointer_iserializer<T, Archive>::instantiate() {
return instance;
}
// note: instances of this template to be constructed before the main
// is called in order for things to be initialized properly. For this
// reason, hiding the instance in a static function as was done above
// won't work here so we created a free instance here.
template<class T, class Archive>
const pointer_iserializer<T, Archive> pointer_iserializer<T, Archive>::instance;
// note trick to be sure that operator new is using class specific
// version if such exists. Due to Peter Dimov.
// note: the following fails if T has no default constructor.
@@ -278,19 +244,15 @@ private:
T* m_p;
};
template<class T, class Archive>
BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr(
template<class Archive, class T>
void pointer_iserializer<Archive, T>::load_object_ptr(
basic_iarchive & ar,
void * & x,
const unsigned int file_version
) const {
) const
{
Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
// if(0 != (ar.get_flags() & no_object_creation)){
// ar_impl >> boost::serialization::make_nvp(NULL, * static_cast<T *>(x));
// return;
// }
auto_ptr_with_deleter<T> ap(heap_allocator<T>::invoke());
if(NULL == ap.get())
boost::throw_exception(std::bad_alloc()) ;
@@ -312,6 +274,7 @@ BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr(
);
}
BOOST_CATCH(...){
ap.release();
BOOST_RETHROW;
}
BOOST_CATCH_END
@@ -320,23 +283,16 @@ BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr(
ap.release();
}
template<class T, class Archive>
#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
template<class Archive, class T>
pointer_iserializer<Archive, T>::pointer_iserializer() :
archive_pointer_iserializer<Archive>(
* 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<T, Archive>::pointer_iserializer() :
archive_pointer_iserializer<Archive>(
* boost::serialization::type_info_implementation<T>::type::get_instance()
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
)
#endif
{
iserializer<Archive, T> & bis = iserializer<Archive, T>::instantiate();
bis.set_bpis(this);
boost::serialization::singleton<
iserializer<Archive, T>
>::get_mutable_instance().set_bpis(this);
}
template<class Archive, class T>
@@ -370,7 +326,12 @@ 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, iserializer<Archive, T>::instantiate());
ar.load_object(
x,
boost::serialization::singleton<
iserializer<Archive, T>
>::get_const_instance()
);
}
};
@@ -414,6 +375,11 @@ 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>,
@@ -430,12 +396,8 @@ 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(typex::value);
#endif
BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
return static_cast<basic_pointer_iserializer *>(NULL);
}
};
@@ -456,7 +418,7 @@ struct load_pointer_type {
// virtual serialize functions used for plug-ins
typedef BOOST_DEDUCED_TYPENAME
mpl::eval_if<
serialization::is_abstract<T>,
serialization::is_abstract<const T>,
mpl::identity<abstract<T> >,
mpl::identity<non_abstract<T> >
>::type typex;
@@ -473,7 +435,8 @@ struct load_pointer_type {
return static_cast<T *>(
boost::serialization::void_upcast(
eti,
* boost::serialization::type_info_implementation<T>::type::get_instance(),
boost::serialization::type_info_implementation<T>::type
::get_const_instance(),
t
)
);
@@ -506,6 +469,8 @@ struct load_enum_type {
template<class Archive, class T>
struct load_array_type {
static void invoke(Archive &ar, T &t){
typedef typename remove_all_extents<T>::type value_type;
// convert integers to correct enum to load
int current_count = sizeof(t) / (
static_cast<char *>(static_cast<void *>(&t[1]))
@@ -517,33 +482,10 @@ struct load_array_type {
boost::throw_exception(archive::archive_exception(
boost::archive::archive_exception::array_size_too_short
));
int i;
for(i = 0; i < count; ++i)
ar >> boost::serialization::make_nvp("item", t[i]);
ar >> serialization::make_array(static_cast<value_type*>(&t[0]),count);
}
};
// 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 */
){
// note: reversal of order of arguments to work around msvc 6.0 bug
// that manifests itself while trying to link.
return pointer_iserializer<T, Archive>::instantiate();
}
} // detail
template<class Archive, class T>
@@ -572,7 +514,7 @@ inline void load(Archive &ar, T &t){
// BORLAND
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
// borland has a couple fo problems
// borland has a couple of problems
// a) if function is partiall specialized - see below
// const paramters are transformed to non-const ones
// b) implementation of base_object can't be made to work
@@ -581,25 +523,23 @@ 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
// let wrappers through. (Someday implement is_wrapper)
// let wrappers through.
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template<class Archive, class T>
inline void load(Archive &ar, const serialization::nvp<T> &t){
boost::archive::load(ar, const_cast<serialization::nvp<T> &>(t));
}
template<class Archive>
inline void load(Archive &ar, const serialization::binary_object &t){
boost::archive::load(ar, const_cast<serialization::binary_object &>(t));
inline void load_wrapper(Archive &ar, const T&t, mpl::true_){
boost::archive::load(ar, const_cast<T&>(t));
}
//template<class Archive, class T>
//inline void load(Archive &ar, const serialization::binary_object &t){
// load(ar, const_cast<binary_object &>(t));
//}
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
template<class Archive, class T>
inline void load(Archive &ar, const T&t){
load_wrapper(ar,t,serialization::is_wrapper<T>());
}
#endif
#endif
} // namespace archive
@@ -1,93 +0,0 @@
#ifndef BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_HPP
#define BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_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
// known_archive_types.hpp: set traits of classes to be serialized
// (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.
// list of archive type shipped with the serialization system
#include <boost/mpl/list.hpp>
#include <boost/mpl/pop_front.hpp>
namespace boost {
namespace archive {
// class text_oarchive;
namespace detail {
class null_type;
struct known_archive_types {
typedef
mpl::pop_front<
mpl::list<
null_type
#if defined(BOOST_ARCHIVE_TEXT_OARCHIVE_HPP)
, boost::archive::text_oarchive
#endif
#if defined(BOOST_ARCHIVE_TEXT_IARCHIVE_HPP)
, boost::archive::text_iarchive
#endif
#if defined(BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP)
, boost::archive::text_woarchive
#endif
#if defined(BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP)
, boost::archive::text_wiarchive
#endif
#if defined(BOOST_ARCHIVE_BINARY_OARCHIVE_HPP)
, boost::archive::binary_oarchive
#endif
#if defined(BOOST_ARCHIVE_BINARY_IARCHIVE_HPP)
, boost::archive::binary_iarchive
#endif
#if defined(BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP)
, boost::archive::binary_woarchive
#endif
#if defined(BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP)
, boost::archive::binary_wiarchive
#endif
#if defined(BOOST_ARCHIVE_XML_OARCHIVE_HPP)
, boost::archive::xml_oarchive
#endif
#if defined(BOOST_ARCHIVE_XML_IARCHIVE_HPP)
, boost::archive::xml_iarchive
#endif
#if defined(BOOST_ARCHIVE_XML_WOARCHIVE_HPP)
, boost::archive::xml_woarchive
#endif
#if defined(BOOST_ARCHIVE_XML_WIARCHIVE_HPP)
, boost::archive::xml_wiarchive
#endif
#if defined(BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP)
, boost::archive::polymorphic_oarchive
#endif
#if defined(BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP)
, boost::archive::polymorphic_iarchive
#endif
#if defined(BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES)
, BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES
#endif
#if defined(BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES)
, BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES
#endif
>::type
>::type type;
};
} // namespace detail
} // namespace archive
} // namespace boost
#endif // BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_HPP
@@ -1,39 +0,0 @@
#ifndef BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_FWD_HPP
#define BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_FWD_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// known_archive_types_fwd.hpp: set traits of classes to be serialized
// (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.
// list of archive type shipped with the serialization system
#include <boost/mpl/list.hpp>
namespace boost {
namespace archive {
namespace detail {
// default implementation of known_archive_types list - 0 elements
// used to generate warning when a polymporhic pointer is serialized
// to an unknown archive - export would otherwise fail silently
template<bool>
struct known_archive_types {
typedef mpl::list<> type;
};
} // namespace detail
} // namespace archive
} // namespace boost
#endif // BOOST_ARCHIVE_KNOWN_ARCHIVE_TYPES_FWD
+98 -134
View File
@@ -32,22 +32,23 @@
#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_same.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/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
@@ -58,7 +59,6 @@
#include <boost/archive/detail/basic_oserializer.hpp>
#include <boost/archive/detail/archive_pointer_oserializer.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/level.hpp>
@@ -66,6 +66,9 @@
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#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>
@@ -100,50 +103,43 @@ class oserializer : public basic_oserializer
private:
// private constructor to inhibit any existence other than the
// static one
public:
explicit oserializer() :
basic_oserializer(
* boost::serialization::type_info_implementation<T>::type::get_instance()
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
)
{}
public:
virtual BOOST_DLLEXPORT void save_object_data(
virtual void save_object_data(
basic_oarchive & ar,
const void *x
) const BOOST_USED ;
) const ;
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_selectivly
&& 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 {
typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<
T
>::type::is_polymorphic::type typex;
return typex::value;
}
static oserializer & instantiate(){
static oserializer instance;
return instance;
return boost::is_polymorphic<T>::value;
}
virtual ~oserializer(){}
};
template<class Archive, class T>
BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
void oserializer<Archive, T>::save_object_data(
basic_oarchive & ar,
const void *x
) 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::smart_cast_reference<Archive &>(ar),
* static_cast<T *>(const_cast<void *>(x)),
@@ -151,53 +147,30 @@ BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
);
}
// instantiation of this template creates a static object. Note inversion of
// normal argument order to workaround bizarre error in MSVC 6.0 which only
// manifests iftself during compiler time.
template<class T, class Archive>
class pointer_oserializer : public archive_pointer_oserializer<Archive>
template<class Archive, class T>
class pointer_oserializer
: public archive_pointer_oserializer<Archive>
{
const basic_oserializer & get_basic_serializer() const;
private:
virtual const basic_oserializer & get_basic_serializer() const {
return oserializer<Archive, T>::instantiate();
}
virtual BOOST_DLLEXPORT void save_object_ptr(
virtual void save_object_ptr(
basic_oarchive & ar,
const void * x
) const BOOST_USED ;
#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
) const ;
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;
static const pointer_oserializer instance;
public:
#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// 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
static BOOST_DLLEXPORT const pointer_oserializer & instantiate() BOOST_USED;
virtual ~pointer_oserializer(){}
explicit pointer_oserializer();
};
template<class T, class Archive>
BOOST_DLLEXPORT const pointer_oserializer<T, Archive> &
pointer_oserializer<T, Archive>::instantiate(){
return instance;
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();
}
// note: instances of this template to be constructed before the main
// is called in order for things to be initialized properly. For this
// reason, hiding the instance in a static function as was done above
// won't work here so we created a free instance here.
template<class T, class Archive>
const pointer_oserializer<T, Archive> pointer_oserializer<T, Archive>::instance;
template<class T, class Archive>
BOOST_DLLEXPORT void pointer_oserializer<T, Archive>::save_object_ptr(
template<class Archive, class T>
void pointer_oserializer<Archive, T>::save_object_ptr(
basic_oarchive & ar,
const void * x
) const {
@@ -215,24 +188,17 @@ BOOST_DLLEXPORT void pointer_oserializer<T, Archive>::save_object_ptr(
ar_impl << boost::serialization::make_nvp(NULL, * t);
}
template<class T, class Archive>
#if ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer() :
template<class Archive, class T>
pointer_oserializer<Archive, T>::pointer_oserializer() :
archive_pointer_oserializer<Archive>(
* 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<T, Archive>::pointer_oserializer() :
archive_pointer_oserializer<Archive>(
* boost::serialization::type_info_implementation<T>::type::get_instance()
boost::serialization::type_info_implementation<T>::type
::get_const_instance()
)
#endif
{
// make sure appropriate member function is instantiated
oserializer<Archive, T> & bos = oserializer<Archive, T>::instantiate();
bos.set_bpos(this);
boost::serialization::singleton<
oserializer<Archive, T>
>::get_mutable_instance().set_bpos(this);
}
template<class Archive, class T>
@@ -260,7 +226,12 @@ 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, oserializer<Archive, T>::instantiate());
ar.save_object(
& t,
boost::serialization::singleton<
oserializer<Archive, T>
>::get_const_instance()
);
}
};
@@ -304,7 +275,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
@@ -329,10 +300,8 @@ struct save_pointer_type {
{
static const basic_pointer_oserializer * register_type(Archive & /* ar */){
// it has? to be polymorphic
BOOST_STATIC_ASSERT(
boost::serialization::type_info_implementation<T>::type::is_polymorphic::value
);
return static_cast<const basic_pointer_oserializer *>(NULL);
BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
return NULL;
}
};
@@ -364,11 +333,14 @@ struct save_pointer_type {
{
static void save(
Archive &ar,
const T & t,
const basic_pointer_oserializer * bpos_ptr
T & t
){
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_ptr);
ar.save_pointer(& t, & bpos);
}
};
@@ -377,18 +349,23 @@ struct save_pointer_type {
{
static void save(
Archive &ar,
const T & t,
const basic_pointer_oserializer * bpos_ptr
T & t
){
const boost::serialization::extended_type_info * this_type
= boost::serialization::type_info_implementation<T>::type::get_instance();
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;
// 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
= boost::serialization::type_info_implementation<T>::type::get_derived_extended_type_info(t);
const boost::serialization::extended_type_info * true_type =
i.get_derived_extended_type_info(t);
// note:if this exception is thrown, be sure that derived pointer
// is either regsitered or exported.
// is either registered or exported.
if(NULL == true_type){
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
@@ -398,7 +375,8 @@ 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){
ar.save_pointer(vp, bpos_ptr);
const basic_pointer_oserializer * bpos = register_type(ar, t);
ar.save_pointer(vp, bpos);
return;
}
// convert pointer to more derived type. if this is thrown
@@ -410,32 +388,37 @@ struct save_pointer_type {
);
}
// sice true_type is valid, and this only gets made if the
// since true_type is valid, and this only gets made if the
// pointer oserializer object has been created, this should never
// fail
bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type);
assert(NULL != bpos_ptr);
if(NULL == bpos_ptr)
const basic_pointer_oserializer * bpos
= archive_pointer_oserializer<Archive>::find(* true_type);
assert(NULL != bpos);
if(NULL == bpos)
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
ar.save_pointer(vp, bpos_ptr);
ar.save_pointer(vp, bpos);
}
};
// 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 basic_pointer_oserializer * bpos_ptr
const 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);
conditional<T>::type::save(ar, const_cast<T &>(t));
}
template<class T>
@@ -456,14 +439,14 @@ struct save_pointer_type {
#else
// otherwise remove the const
#endif
const basic_pointer_oserializer * bpos_ptr = register_type(ar, * t);
register_type(ar, * t);
if(NULL == t){
basic_oarchive & boa = boost::smart_cast_reference<basic_oarchive &>(ar);
boa.save_null_pointer();
save_access::end_preamble(ar);
return;
}
save(ar, * t, bpos_ptr);
save(ar, * t);
};
};
@@ -481,6 +464,8 @@ template<class Archive, class T>
struct save_array_type
{
static void invoke(Archive &ar, const T &t){
typedef typename remove_all_extents<T>::type value_type;
save_access::end_preamble(ar);
// consider alignment
int count = sizeof(t) / (
@@ -488,32 +473,10 @@ struct save_array_type
- static_cast<const char *>(static_cast<const void *>(&t[0]))
);
ar << BOOST_SERIALIZATION_NVP(count);
int i;
for(i = 0; i < count; ++i)
ar << boost::serialization::make_nvp("item", t[i]);
ar << serialization::make_array(static_cast<value_type const*>(&t[0]),count);
}
};
// 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 */
){
// note: reversal of order of arguments to work around msvc 6.0 bug
// that manifests itself while trying to link.
return pointer_oserializer<T, Archive>::instantiate();
}
} // detail
template<class Archive, class T>
@@ -557,12 +520,13 @@ struct check_tracking {
template<class Archive, class T>
inline void save(Archive & ar, T &t){
// if your program traps here, it indicates taht your doing one of the following:
// if your program traps here, it indicates that your doing one of the following:
// a) serializing an object of a type marked "track_never" through a pointer.
// b) saving an non-const object of a type not markd "track_never)
// Either of these conditions may be an indicator of an error usage of the
// serialization library and should be double checked. See documentation on
// object tracking.
// object tracking. Also, see the "rationale" section of the documenation
// for motivation for this checking.
BOOST_STATIC_ASSERT(check_tracking<T>::value);
save(ar, const_cast<const T &>(t));
}
@@ -0,0 +1,196 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_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_iarchive_route.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 <cstddef>
#include <string>
#include <ostream>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
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 :
public polymorphic_iarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
public /*protected*/ ArchiveImplementation,
private boost::noncopyable
{
private:
// these are used by the serialization library.
virtual void load_object(
void *t,
const basic_iserializer & bis
){
ArchiveImplementation::load_object(t, bis);
}
virtual const basic_pointer_iserializer * load_pointer(
void * & t,
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type
)
){
return ArchiveImplementation::load_pointer(t, bpis_ptr, finder);
}
virtual void set_library_version(unsigned int archive_library_version){
ArchiveImplementation::set_library_version(archive_library_version);
}
virtual unsigned int get_library_version() const{
return ArchiveImplementation::get_library_version();
}
virtual unsigned int get_flags() const {
return ArchiveImplementation::get_flags();
}
virtual void delete_created_pointers(){
ArchiveImplementation::delete_created_pointers();
}
virtual void reset_object_address(
const void * new_address,
const void * old_address
){
ArchiveImplementation::reset_object_address(new_address, old_address);
}
virtual void load_binary(void * t, std::size_t size){
ArchiveImplementation::load_binary(t, size);
}
// primitive types the only ones permitted by polymorphic archives
virtual void load(bool & t){
ArchiveImplementation::load(t);
}
virtual void load(char & t){
ArchiveImplementation::load(t);
}
virtual void load(signed char & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned char & t){
ArchiveImplementation::load(t);
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
virtual void load(wchar_t & t){
ArchiveImplementation::load(t);
}
#endif
#endif
virtual void load(short & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned short & t){
ArchiveImplementation::load(t);
}
virtual void load(int & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned int & t){
ArchiveImplementation::load(t);
}
virtual void load(long & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned long & t){
ArchiveImplementation::load(t);
}
#if !defined(BOOST_NO_INTRINSIC_INT64_T)
virtual void load(boost::int64_t & t){
ArchiveImplementation::load(t);
}
virtual void load(boost::uint64_t & t){
ArchiveImplementation::load(t);
}
#endif
virtual void load(float & t){
ArchiveImplementation::load(t);
}
virtual void load(double & t){
ArchiveImplementation::load(t);
}
virtual void load(std::string & t){
ArchiveImplementation::load(t);
}
#ifndef BOOST_NO_STD_WSTRING
virtual void load(std::wstring & t){
ArchiveImplementation::load(t);
}
#endif
// used for xml and other tagged formats default does nothing
virtual void load_start(const char * name){
ArchiveImplementation::load_start(name);
}
virtual void load_end(const char * name){
ArchiveImplementation::load_end(name);
}
virtual void register_basic_serializer(const basic_iserializer & bis){
ArchiveImplementation::register_basic_serializer(bis);
}
public:
// this can't be inheriteded because they appear in mulitple
// parents
typedef mpl::bool_<true> is_loading;
typedef mpl::bool_<false> is_saving;
// the >> operator
template<class T>
polymorphic_iarchive & operator>>(T & t){
return polymorphic_iarchive::operator>>(t);
}
// the & operator
template<class T>
polymorphic_iarchive & operator&(T & t){
return polymorphic_iarchive::operator&(t);
}
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_iarchive_route(
std::basic_istream<_Elem, _Tr> & is,
unsigned int flags = 0
) :
ArchiveImplementation(is, flags)
{}
virtual ~polymorphic_iarchive_route(){};
};
} // namespace detail
} // namespace archive
} // namespace boost
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP
@@ -0,0 +1,184 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_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_oarchive_route.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 <string>
#include <ostream>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp>
#include <cstddef> // size_t
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/archive/polymorphic_oarchive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
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 :
public polymorphic_oarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
public /*protected*/ ArchiveImplementation,
private boost::noncopyable
{
private:
// these are used by the serialization library.
virtual void save_object(
const void *x,
const detail::basic_oserializer & bos
){
ArchiveImplementation::save_object(x, bos);
}
virtual void save_pointer(
const void * t,
const detail::basic_pointer_oserializer * bpos_ptr
){
ArchiveImplementation::save_pointer(t, bpos_ptr);
}
virtual void save_null_pointer(){
ArchiveImplementation::save_null_pointer();
}
// primitive types the only ones permitted by polymorphic archives
virtual void save(const bool t){
ArchiveImplementation::save(t);
}
virtual void save(const char t){
ArchiveImplementation::save(t);
}
virtual void save(const signed char t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned char t){
ArchiveImplementation::save(t);
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
virtual void save(const wchar_t t){
ArchiveImplementation::save(t);
}
#endif
#endif
virtual void save(const short t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned short t){
ArchiveImplementation::save(t);
}
virtual void save(const int t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned int t){
ArchiveImplementation::save(t);
}
virtual void save(const long t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned long t){
ArchiveImplementation::save(t);
}
#if !defined(BOOST_NO_INTRINSIC_INT64_T)
virtual void save(const boost::int64_t t){
ArchiveImplementation::save(t);
}
virtual void save(const boost::uint64_t t){
ArchiveImplementation::save(t);
}
#endif
virtual void save(const float t){
ArchiveImplementation::save(t);
}
virtual void save(const double t){
ArchiveImplementation::save(t);
}
virtual void save(const std::string & t){
ArchiveImplementation::save(t);
}
#ifndef BOOST_NO_STD_WSTRING
virtual void save(const std::wstring & t){
ArchiveImplementation::save(t);
}
#endif
virtual unsigned int get_library_version() const{
return ArchiveImplementation::get_library_version();
}
virtual unsigned int get_flags() const {
return ArchiveImplementation::get_flags();
}
virtual void save_binary(const void * t, std::size_t size){
ArchiveImplementation::save_binary(t, size);
}
// used for xml and other tagged formats default does nothing
virtual void save_start(const char * name){
ArchiveImplementation::save_start(name);
}
virtual void save_end(const char * name){
ArchiveImplementation::save_end(name);
}
virtual void end_preamble(){
ArchiveImplementation::end_preamble();
}
virtual void register_basic_serializer(const detail::basic_oserializer & bos){
ArchiveImplementation::register_basic_serializer(bos);
}
public:
// this can't be inheriteded because they appear in mulitple
// parents
typedef mpl::bool_<false> is_loading;
typedef mpl::bool_<true> is_saving;
// the << operator
template<class T>
polymorphic_oarchive & operator<<(T & t){
return polymorphic_oarchive::operator<<(t);
}
// the & operator
template<class T>
polymorphic_oarchive & operator&(T & t){
return polymorphic_oarchive::operator&(t);
}
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_oarchive_route(
std::basic_ostream<_Elem, _Tr> & os,
unsigned int flags = 0
) :
ArchiveImplementation(os, flags)
{}
virtual ~polymorphic_oarchive_route(){};
};
} // namespace detail
} // namespace archive
} // namespace boost
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP
@@ -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_REGISTER_ARCHIVE_DWA2006521_HPP
# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP
namespace boost { namespace archive { namespace detail {
template <class Archive, class Serializable>
struct ptr_serialization_support;
// We could've just used ptr_serialization_support, above, but using
// it with only a forward declaration causes vc6/7 to complain about a
// missing instantiate member, even if it has one. This is just a
// friendly layer of indirection.
template <class Archive, class Serializable>
struct _ptr_serialization_support
: ptr_serialization_support<Archive,Serializable>
{
typedef int type;
};
// This function gets called, but its only purpose is to participate
// in overload resolution with the functions declared by
// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below.
template <class Serializable>
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
// enough to cause registration of serialization functions between
// Archive and any exported Serializable type. See also:
// boost/serialization/export.hpp
# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \
namespace boost { namespace archive { namespace detail { \
\
template <class Serializable> \
typename _ptr_serialization_support<Archive, Serializable>::type \
instantiate_ptr_serialization( Serializable*, Archive* ); \
\
}}}
}}} // namespace boost::archive::detail
#endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP
@@ -1,9 +1,8 @@
// 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.
// 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)
#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP
@@ -8,10 +8,12 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <utility>
#include <cassert>
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <boost/serialization/singleton.hpp>
#include <boost/archive/detail/basic_serializer_map.hpp>
#include <boost/archive/detail/archive_pointer_iserializer.hpp>
@@ -19,12 +21,11 @@ namespace boost {
namespace archive {
namespace detail {
template<class Archive>
basic_serializer_map *
iserializer_map(){
static bool deleted = false;
static basic_serializer_map map(deleted);
return deleted ? NULL : & map;
namespace { // anon
template<class Archive>
class serializer_map : public basic_serializer_map
{
};
}
template<class Archive>
@@ -34,9 +35,11 @@ archive_pointer_iserializer<Archive>::archive_pointer_iserializer(
) :
basic_pointer_iserializer(eti)
{
basic_serializer_map *mp = iserializer_map<Archive>();
assert(NULL != mp);
mp->insert(this);
std::pair<BOOST_DEDUCED_TYPENAME serializer_map<Archive>::iterator, bool> result;
result = serialization::singleton<
serializer_map<Archive>
>::get_mutable_instance().insert(this);
assert(result.second);
}
template<class Archive>
@@ -44,9 +47,19 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *)
archive_pointer_iserializer<Archive>::find(
const boost::serialization::extended_type_info & eti
){
basic_serializer_map *mp = iserializer_map<Archive>();
assert(NULL != mp);
return static_cast<const basic_pointer_iserializer *>(mp->tfind(eti));
const basic_serializer_arg bs(eti);
BOOST_DEDUCED_TYPENAME serializer_map<Archive>::const_iterator it;
it = boost::serialization::singleton<
serializer_map<Archive>
>::get_const_instance().find(& bs);
assert(
it
!=
boost::serialization::singleton<
serializer_map<Archive>
>::get_const_instance().end()
);
return static_cast<const basic_pointer_iserializer *>(*it);
}
template<class Archive>
@@ -54,10 +67,11 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
archive_pointer_iserializer<Archive>::~archive_pointer_iserializer(){
// note: we need to check that the map still exists as we can't depend
// on static variables being constructed in a specific sequence
basic_serializer_map *mp = iserializer_map<Archive>();
if(NULL == mp)
return;
mp->erase(this);
unsigned int count;
count = serialization::singleton<
serializer_map<Archive>
>::get_mutable_instance().erase(this);
assert(count);
}
} // namespace detail
@@ -8,6 +8,9 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <utility>
#include <cassert>
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <boost/archive/detail/archive_pointer_oserializer.hpp>
@@ -17,12 +20,11 @@ namespace boost {
namespace archive {
namespace detail {
template<class Archive>
basic_serializer_map *
oserializer_map(){
static bool deleted = false;
static basic_serializer_map map(deleted);
return deleted ? NULL : & map;
namespace { // anon
template<class Archive>
class serializer_map : public basic_serializer_map
{
};
}
template<class Archive>
@@ -32,9 +34,14 @@ archive_pointer_oserializer<Archive>::archive_pointer_oserializer(
) :
basic_pointer_oserializer(eti)
{
basic_serializer_map *mp = oserializer_map<Archive>();
assert(NULL != mp);
mp->insert(this);
std::pair<
BOOST_DEDUCED_TYPENAME serializer_map<Archive>::iterator,
bool
> result;
result = serialization::singleton<
serializer_map<Archive>
>::get_mutable_instance().insert(this);
assert(result.second);
}
template<class Archive>
@@ -42,9 +49,19 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *)
archive_pointer_oserializer<Archive>::find(
const boost::serialization::extended_type_info & eti
){
basic_serializer_map *mp = oserializer_map<Archive>();
assert(NULL != mp);
return static_cast<const basic_pointer_oserializer *>(mp->tfind(eti));
const basic_serializer_arg bs(eti);
basic_serializer_map::const_iterator it;
it = boost::serialization::singleton<
serializer_map<Archive>
>::get_const_instance().find(& bs);
assert(
it
!=
boost::serialization::singleton<
serializer_map<Archive>
>::get_const_instance().end()
);
return static_cast<const basic_pointer_oserializer *>(*it);
}
template<class Archive>
@@ -52,10 +69,11 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
archive_pointer_oserializer<Archive>::~archive_pointer_oserializer(){
// note: we need to check that the map still exists as we can't depend
// on static variables being constructed in a specific sequence
basic_serializer_map *mp = oserializer_map<Archive>();
if(NULL == mp)
return;
mp->erase(this);
unsigned int count;
count = serialization::singleton<
serializer_map<Archive>
>::get_mutable_instance().erase(this);
assert(count);
}
} // namespace detail
@@ -22,7 +22,6 @@ namespace std{
#include <boost/detail/workaround.hpp>
#include <boost/archive/basic_binary_iarchive.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -79,7 +79,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
{
std::size_t l;
this->This()->load(l);
load_binary(ws, l);
load_binary(ws, l * sizeof(wchar_t) / sizeof(char));
ws[l / sizeof(wchar_t)] = L'\0';
}
@@ -95,7 +95,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(std::string & s)
#endif
s.resize(l);
// note breaking a rule here - could be a problem on some platform
load_binary(const_cast<char *>(s.data()), l);
if(0 < l)
load_binary(&(*s.begin()), l);
}
#ifndef BOOST_NO_CWCHAR
@@ -133,6 +134,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::basic_binary_iprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
) :
#ifndef BOOST_NO_STD_LOCALE
m_sb(sb),
archive_locale(NULL),
locale_saver(m_sb)
@@ -147,6 +149,10 @@ basic_binary_iprimitive<Archive, Elem, Tr>::basic_binary_iprimitive(
m_sb.pubimbue(* archive_locale);
}
}
#else
m_sb(sb)
{}
#endif
// some libraries including stl and libcomo fail if the
// buffer isn't flushed before the code_cvt facet is changed.
@@ -103,6 +103,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
) :
#ifndef BOOST_NO_STD_LOCALE
m_sb(sb),
archive_locale(NULL),
locale_saver(m_sb)
@@ -117,6 +118,10 @@ basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
m_sb.pubimbue(* archive_locale);
}
}
#else
m_sb(sb)
{}
#endif
// some libraries including stl and libcomo fail if the
// buffer isn't flushed before the code_cvt facet is changed.
@@ -22,7 +22,6 @@ namespace std{
#include <boost/detail/workaround.hpp>
#include <boost/archive/basic_text_iarchive.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -94,7 +94,8 @@ BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_text_iprimitive<IStream>::basic_text_iprimitive(
IStream &is_,
bool no_codecvt
) :
) :
#ifndef BOOST_NO_STD_LOCALE
is(is_),
flags_saver(is_),
precision_saver(is_),
@@ -112,6 +113,12 @@ basic_text_iprimitive<IStream>::basic_text_iprimitive(
}
is >> std::noboolalpha;
}
#else
is(is_),
flags_saver(is_),
precision_saver(is_)
{}
#endif
template<class IStream>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
@@ -75,6 +75,7 @@ basic_text_oprimitive<OStream>::basic_text_oprimitive(
OStream & os_,
bool no_codecvt
) :
#ifndef BOOST_NO_STD_LOCALE
os(os_),
flags_saver(os_),
precision_saver(os_),
@@ -92,6 +93,12 @@ basic_text_oprimitive<OStream>::basic_text_oprimitive(
}
os << std::noboolalpha;
}
#else
os(os_),
flags_saver(os_),
precision_saver(os_)
{}
#endif
template<class OStream>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
@@ -15,7 +15,6 @@
#include <boost/archive/basic_xml_iarchive.hpp>
#include <boost/serialization/tracking.hpp>
//#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace archive {
@@ -18,6 +18,7 @@ namespace std{
#include <boost/archive/basic_xml_archive.hpp>
#include <boost/archive/basic_xml_oarchive.hpp>
#include <boost/archive/xml_archive_exception.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost {
@@ -78,7 +79,7 @@ basic_xml_oarchive<Archive>::write_attribute(
this->This()->put(' ');
this->This()->put(attribute_name);
this->This()->put("=\"");
this->This()->put(key);
this->This()->save(key);
this->This()->put('"');
}
@@ -144,7 +145,7 @@ basic_xml_oarchive<Archive>::end_preamble(){
pending_preamble = false;
}
}
#if 0
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
@@ -168,6 +169,33 @@ basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
int i = t.t; // extra .t is for borland
write_attribute(VERSION(), i);
}
#endif
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
{
// borland doesn't do conversion of STRONG_TYPEDEFs very well
const unsigned int i = t;
write_attribute(OBJECT_ID(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(
const object_reference_type & t,
int
){
const unsigned int i = t;
write_attribute(OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
{
const unsigned int i = t;
write_attribute(VERSION(), i);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const class_id_type & t, int)
@@ -199,11 +227,12 @@ basic_xml_oarchive<Archive>::save_override(const class_name_type & t, int)
return;
write_attribute(CLASS_NAME(), key);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const tracking_type & t, int)
{
write_attribute(TRACKING(), t.t); // extra .t is for borland
write_attribute(TRACKING(), t.t);
}
template<class Archive>
@@ -53,7 +53,8 @@ text_iarchive_impl<Archive>::load(std::string &s)
if(NULL != s.data())
#endif
s.resize(size);
is.read(const_cast<char *>(s.data()), size);
if(0 < size)
is.read(&(*s.begin()), size);
}
#ifndef BOOST_NO_CWCHAR
@@ -32,7 +32,7 @@ namespace std{
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/xml_archive_exception.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
#include <boost/archive/basic_xml_archive.hpp>
#include <boost/archive/xml_iarchive.hpp>
@@ -34,7 +34,7 @@ namespace std{
#include <boost/serialization/string.hpp>
#include <boost/archive/add_facet.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/xml_archive_exception.hpp>
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/archive/iterators/mb_from_wchar.hpp>
@@ -18,23 +18,26 @@
#include <boost/config.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_impl.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
namespace boost {
namespace archive {
typedef detail::polymorphic_iarchive_impl<
binary_iarchive_impl<
binary_iarchive, std::istream::char_type, std::istream::traits_type
>
> polymorphic_binary_iarchive;
class polymorphic_binary_iarchive :
public detail::polymorphic_iarchive_route<naked_binary_iarchive>
{
public:
polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<naked_binary_iarchive>(is, flags)
{}
~polymorphic_binary_iarchive(){}
};
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_binary_iarchive
)
@@ -18,23 +18,24 @@
#include <boost/config.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_impl.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
typedef detail::polymorphic_oarchive_impl<
typedef detail::polymorphic_oarchive_route<
binary_oarchive_impl<
binary_oarchive, std::ostream::char_type, std::ostream::traits_type
naked_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>
> polymorphic_binary_oarchive;
} // namespace archive
} // namespace boost
// required by smart_cast for compilers not implementing
// partial template specialization
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_binary_oarchive
)

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