mirror of
https://github.com/boostorg/serialization.git
synced 2026-07-23 13:54:08 +00:00
Compare commits
556 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76ffe41573 | |||
| c8dbafea2f | |||
| 36a93f9328 | |||
| fe3e8c5ab2 | |||
| b405eb615c | |||
| f8cf831f7e | |||
| 980b86303e | |||
| 787bf2d951 | |||
| 50db978210 | |||
| 19886f90f5 | |||
| 560d912d52 | |||
| b42bfb27f4 | |||
| b17d9dbd7a | |||
| 942fdf07dc | |||
| b2e8e04ff6 | |||
| eedc65dc28 | |||
| 9276d21cf2 | |||
| 91467ba193 | |||
| 6e9a999a4b | |||
| 7ecc858bc1 | |||
| 4d62235d3a | |||
| 01f9d42a23 | |||
| 42c9bc72c1 | |||
| c763c57fa9 | |||
| 10f429dac1 | |||
| 066a615634 | |||
| 34bf772e83 | |||
| f828a336bd | |||
| 58f531541b | |||
| 4364bc44f0 | |||
| 4eedf9ab70 | |||
| 99be4e2168 | |||
| f2c76b43c7 | |||
| fe3857afaa | |||
| 3297e43087 | |||
| f81a766b70 | |||
| 23e0f37d37 | |||
| 852deb8c10 | |||
| 5e424ec896 | |||
| f994293020 | |||
| 6b9974569c | |||
| 575443f8e1 | |||
| cf8bc022f6 | |||
| ecd03e84d7 | |||
| 10faf88465 | |||
| cc808738c4 | |||
| 940aa1df35 | |||
| dcb9c9dd50 | |||
| 014543ff72 | |||
| 365af6450c | |||
| c7dee32206 | |||
| f0be07eff3 | |||
| 9cae70dae7 | |||
| 2cbd120596 | |||
| 44b8a4ffdb | |||
| 4c9a03dcb7 | |||
| de8fa1c425 | |||
| aff3ebb25a | |||
| 5c6f9a495c | |||
| 11bd878431 | |||
| 8ef74d1bd0 | |||
| d26a7830f5 | |||
| 40ca5515f1 | |||
| b1b114de63 | |||
| cca24b471e | |||
| 42b0c2ad3e | |||
| dc153d5e7b | |||
| f6d14c80ea | |||
| 00a143fd3d | |||
| aeb7ca4619 | |||
| 5264194e67 | |||
| ce7dc653df | |||
| b3c87d2dfa | |||
| 0530d1fcaa | |||
| 66b1028d4c | |||
| cfb16a8a9d | |||
| 480d7b2413 | |||
| 1c90e422e6 | |||
| 02ff4b6e31 | |||
| 1efcb23869 | |||
| 5b81643b84 | |||
| e4efa8cf47 | |||
| adab69fc6e | |||
| 1681869ffa | |||
| 23b6906d8c | |||
| 70afb78ebe | |||
| 7d71f523e8 | |||
| 7d0480231d | |||
| e954446f2a | |||
| bec06ca0d4 | |||
| ea37174708 | |||
| 29ce16419f | |||
| b56cb9ba74 | |||
| 58e92cc397 | |||
| 30e6e9dcba | |||
| 5df2c12166 | |||
| 831203f981 | |||
| d2cdb8e73c | |||
| 48f60529ab | |||
| a790233141 | |||
| 1aeba3c035 | |||
| add7159a85 | |||
| c35f7b34e2 | |||
| 752acdafee | |||
| 6f6ccc2e44 | |||
| b0e384ec1a | |||
| c51325635f | |||
| 7f00638dfb | |||
| 0c5bb1d032 | |||
| 268e85f5c1 | |||
| 08a364878c | |||
| e3c144e09a | |||
| 3f5938f35b | |||
| 0986103ceb | |||
| 806db58269 | |||
| 52411aaff4 | |||
| 35dc8ceebf | |||
| 10a5027b29 | |||
| 1e7f3d4b9d | |||
| e26ebab471 | |||
| 727a372834 | |||
| 4609f2c6fb | |||
| 0eefcbe3bd | |||
| 09ef207293 | |||
| dcccc51327 | |||
| 23db071843 | |||
| eda61aea60 | |||
| 099e0fd257 | |||
| e4f0a979e7 | |||
| 5c43de71cf | |||
| 9979fad749 | |||
| 65f7cade32 | |||
| e66fef7d07 | |||
| 3053878538 | |||
| 9be8f7c2ee | |||
| 4488fddadf | |||
| 9c3179680d | |||
| a26e8dc9be | |||
| b56f059ef3 | |||
| 57ee259098 | |||
| 9183c84f38 | |||
| b933c57ea4 | |||
| 06377e7ca9 | |||
| 1ef7246322 | |||
| 92f636b6ed | |||
| abd6e3c3d7 | |||
| 96338cc37e | |||
| d8e47b3a1f | |||
| 13f72ef7c4 | |||
| 6c7b3c7d61 | |||
| 898ca1b294 | |||
| 03fbead691 | |||
| 9cff60d2e8 | |||
| ed522ce134 | |||
| 33814c1296 | |||
| 21e3e4d452 | |||
| ecdcc90ede | |||
| d447c038ef | |||
| 7367a517fb | |||
| f939ebee1a | |||
| fadadb37c9 | |||
| 0a82da5e09 | |||
| 685d1aea26 | |||
| 71e5d4bc98 | |||
| 479977daeb | |||
| 14f0f8271d | |||
| f3cf6293e5 | |||
| 7d9bd7871d | |||
| 1e802d9677 | |||
| 7910677c3a | |||
| 9377f754b0 | |||
| deba15f9b5 | |||
| 080e666ec2 | |||
| f2cf93b688 | |||
| 91770338cd | |||
| 5624bc552a | |||
| 3c64171df1 | |||
| 666100d27e | |||
| 0edcefcdda | |||
| 49a9a29140 | |||
| 320ebce20f | |||
| 9db5b5005c | |||
| ec4e5124f4 | |||
| 5a29bca85c | |||
| 01752ec977 | |||
| 9011c6833d | |||
| fba3d86b5d | |||
| e4d0d3d61e | |||
| 4103202f8d | |||
| 4ebe6da43c | |||
| c3c306214e | |||
| c9f8099931 | |||
| af63fcc0be | |||
| 88ee3bb76c | |||
| 092843d04d | |||
| 3eade6147a | |||
| c9a0dfe045 | |||
| 1a7b698181 | |||
| 3303bd4c3e | |||
| cd709fdba5 | |||
| 625c97e63b | |||
| 32804edc06 | |||
| c496f8441f | |||
| a37379fadb | |||
| 951ab1abca | |||
| 3acfb736d6 | |||
| 0b13678ee0 | |||
| 60e977b85f | |||
| b930154408 | |||
| 3b585d5049 | |||
| 4e5e1e8120 | |||
| 72e8ea4f06 | |||
| a013adf37c | |||
| 846e2d4fa3 | |||
| e9b9eb61db | |||
| 3af3d629bf | |||
| f2f7b5eb64 | |||
| 7459fe85b2 | |||
| 1bebf9f64d | |||
| 88b081a37c | |||
| 1c58902378 | |||
| 6012811e90 | |||
| cbd1a7c55f | |||
| eca551f216 | |||
| 09fa88a526 | |||
| 060c7ff250 | |||
| 727f4bed80 | |||
| 36a5c0acaf | |||
| b20928a387 | |||
| 5b852f3a2d | |||
| 61b7cbb8ba | |||
| 78aff3739e | |||
| c34f4c5310 | |||
| 8deb3b2d2d | |||
| 704b85f9b7 | |||
| 5f575af698 | |||
| 24100ba460 | |||
| b5bf7d0ebf | |||
| d72d0215aa | |||
| eb8b71f507 | |||
| 98808cff3a | |||
| 8fae67f824 | |||
| 09b1872b31 | |||
| e64568d9f3 | |||
| 2050f06a23 | |||
| 91f7a57b7b | |||
| 580ef7b496 | |||
| 1340f6bd4f | |||
| acd0330a2c | |||
| 720dcd01ed | |||
| f138890397 | |||
| 0204a62bab | |||
| 92de1f46e1 | |||
| fff3158667 | |||
| 21b73dd91c | |||
| 8b049537a3 | |||
| 424316396b | |||
| 4cc8e429b1 | |||
| 6f730f6833 | |||
| bb638ef5d2 | |||
| bf46e282ea | |||
| 187cc142f2 | |||
| dca567fe5d | |||
| 7839dbb34b | |||
| d16e356c6d | |||
| 4c3277a4a0 | |||
| 3c63b452be | |||
| ecc2bacb3a | |||
| e1dd4b8997 | |||
| 8354dfa5a3 | |||
| 952c14aeb9 | |||
| dce9cae64d | |||
| 84da232b3b | |||
| a31706b2cd | |||
| 0a091c642f | |||
| 6261c0437c | |||
| 798b3d622f | |||
| f44e93af7c | |||
| d24e68a943 | |||
| 427b4a13d1 | |||
| 0f708c15a4 | |||
| 46d6e11c53 | |||
| a3fa7030c3 | |||
| e5ccfdc907 | |||
| 7d35f9d862 | |||
| 36202ac87e | |||
| 845fc990d1 | |||
| baa9e0e189 | |||
| f73e01955f | |||
| c06f9e9c78 | |||
| 337f8095ce | |||
| 2053d88119 | |||
| 4b2a01cf4d | |||
| f0c99c0f28 | |||
| 7b1049f5f5 | |||
| 853495e336 | |||
| 92844c97c3 | |||
| 8626583733 | |||
| 34a3f29dcf | |||
| 204abedab3 | |||
| 3308629abf | |||
| db18e22b35 | |||
| d87c2565b0 | |||
| ca8ce2a35c | |||
| 570f97acac | |||
| 383fcd2cd6 | |||
| 454aeece14 | |||
| 8ad69e30eb | |||
| fada037a5b | |||
| 422625c5b2 | |||
| d534e6ceef | |||
| 0bee3a5dfd | |||
| 97ae02ebf8 | |||
| d6ca9e07ba | |||
| 204e7a434a | |||
| 8774db8c9e | |||
| aba6b2936b | |||
| 0d2cfa7426 | |||
| 1760473015 | |||
| 2e0d130fbf | |||
| 0db1a88e4e | |||
| f57298ce63 | |||
| c919c4a6eb | |||
| d723141be6 | |||
| 5afeb0274e | |||
| 7063ba837e | |||
| 0968503e63 | |||
| 02d057a556 | |||
| c7d56562aa | |||
| b5c25d7aae | |||
| 2910f0dd69 | |||
| 6813dc1b5d | |||
| b882a9c65c | |||
| 28f9d1d5cd | |||
| 2b48aa5b43 | |||
| 3b239a2d45 | |||
| 5c901572ad | |||
| 1aa8697583 | |||
| 08a9e45567 | |||
| 6df5a45c5d | |||
| a2cfbc098d | |||
| 2d6969e219 | |||
| 26eb0edad7 | |||
| b993792d8a | |||
| 19f36ac863 | |||
| 344250aef6 | |||
| 2be37ae560 | |||
| 2007474c54 | |||
| 115d8e0341 | |||
| b178806cce | |||
| 1f510bb350 | |||
| c068a817e5 | |||
| caa441688a | |||
| d9ce7a497a | |||
| 91176096bc | |||
| 0ac6bb31ef | |||
| c94f84c1b6 | |||
| afbc614faa | |||
| dc16b35bdf | |||
| 4bca617b8c | |||
| 425edc3c4f | |||
| 632bc3391b | |||
| cb7ee163b6 | |||
| a0c216d9a6 | |||
| 6fddb44715 | |||
| f614ba8060 | |||
| c33c9c80c3 | |||
| 2673a73a31 | |||
| a6b15e9af2 | |||
| 337ad96ba7 | |||
| 4ba508bf31 | |||
| f00c93b5a8 | |||
| 70cfef9ce0 | |||
| cc74951fe5 | |||
| cbad649a9d | |||
| 6058a7d2fd | |||
| 8674178f86 | |||
| 5a9927766c | |||
| 3330eac9fa | |||
| 13e9328303 | |||
| ca97418479 | |||
| 1902603a14 | |||
| facedd6a1c | |||
| c9d0eaaeae | |||
| 4cd8d56e12 | |||
| 11cd7d7894 | |||
| c1c2f3a2cb | |||
| 45c866cfd7 | |||
| a486275760 | |||
| eab4767171 | |||
| bf80f93fdb | |||
| 22f89b28ab | |||
| b65682ac40 | |||
| 688121263f | |||
| c0ee335380 | |||
| c21df99e55 | |||
| 515a81861f | |||
| b115070d0c | |||
| d68064782d | |||
| bf8ec5da06 | |||
| 2406780d7f | |||
| f2e21055bb | |||
| 20d6369302 | |||
| 220501b4e3 | |||
| bcd54fb43a | |||
| 5f07e613d2 | |||
| 947020faab | |||
| ec167261fb | |||
| 085f834a23 | |||
| c04b1b7641 | |||
| 4e0d18c09a | |||
| 407f6a7e17 | |||
| 6b766534ec | |||
| 18b4703521 | |||
| 566e415a0b | |||
| b7979a686c | |||
| cb49d5995c | |||
| 38f3fcf019 | |||
| fa9c00cdfb | |||
| 04bf027540 | |||
| e3589203d9 | |||
| 100b7364e3 | |||
| 59f4dbf06d | |||
| c9b4e4083a | |||
| 70647552f5 | |||
| 515592087c | |||
| d619bce3cf | |||
| c17128a127 | |||
| 468f685add | |||
| b917964cc7 | |||
| 710d048883 | |||
| b480820daf | |||
| 42575b38c0 | |||
| 8bd155ac32 | |||
| fa949408ba | |||
| 3f580fe43a | |||
| 2dd4a6da64 | |||
| 379e36c2a8 | |||
| 063c8186fa | |||
| e1e9cb8836 | |||
| fa5a9286a0 | |||
| 3ba71666cd | |||
| d8aa849d26 | |||
| e1155ed616 | |||
| ef79b7809b | |||
| 13d6d5fb65 | |||
| 2fe1df2024 | |||
| 5c65532744 | |||
| 8b87aff208 | |||
| a81056744a | |||
| d67e2d4a6c | |||
| 37641d8661 | |||
| fe996ef4ca | |||
| ab5ad31acd | |||
| 60e379e567 | |||
| d0f0331f64 | |||
| 5c554c81dd | |||
| 0503614360 | |||
| 203b8a26f5 | |||
| b514ea7574 | |||
| 304c59c38a | |||
| 31568eb8d7 | |||
| fb99036d11 | |||
| 9cfac29dc3 | |||
| 05d652eda2 | |||
| f3986639d7 | |||
| 341c08b8ee | |||
| 5db5f348f3 | |||
| 177bd7609a | |||
| 5bae275e7b | |||
| 876f039098 | |||
| efce340904 | |||
| 76408237f6 | |||
| b6add3bc6a | |||
| 8f2f7187a8 | |||
| 63107616cd | |||
| cdbb2df2ce | |||
| 1ee4a18832 | |||
| 73dc3374b1 | |||
| 57e69274ce | |||
| ce1af8ab70 | |||
| 9b0d353b38 | |||
| 8f1eb809a8 | |||
| 965ce4e707 | |||
| 7e21b926b5 | |||
| f097a4efce | |||
| b7bf7086bd | |||
| 08fa1892a4 | |||
| d8d4bdb161 | |||
| fa180480f6 | |||
| 442e4e7e0c | |||
| 6359041a2a | |||
| 1291d2e330 | |||
| 2429cfc74a | |||
| 2bafe4f019 | |||
| e948cd8ff8 | |||
| 37456916e8 | |||
| b559f77aa1 | |||
| 4f93d04c34 | |||
| 71313492d1 | |||
| 8d098e0dfb | |||
| 6894a0d8ba | |||
| 9e2edbf776 | |||
| 8e523711b9 | |||
| 5a2bcb694a | |||
| edb796b30b | |||
| 715d8fec8c | |||
| 9fac53e296 | |||
| 78c3de4104 | |||
| 3a31a1a9ad | |||
| 7a24567b54 | |||
| f957e3c82c | |||
| 4c50ff9a09 | |||
| a0a2f70d9b | |||
| c12a38f875 | |||
| b789f8f81a | |||
| 5e2707e23b | |||
| 081af19476 | |||
| a246ea2455 | |||
| b1a168b22f | |||
| f5b41917ce | |||
| 7697694fe5 | |||
| a259e927f7 | |||
| 7c3106ad85 | |||
| d589ab5a0c | |||
| 8d40bd3c02 | |||
| d5e74bb7cb | |||
| 1c64d5a9f6 | |||
| b69eaef0e9 | |||
| 654759873d | |||
| c6652ac5f5 | |||
| a6767b8370 | |||
| 509886a3cf | |||
| 99973ea4d1 | |||
| 51bf88bf2b | |||
| af3ab0f960 | |||
| a7c9dded25 | |||
| a15aac77e0 | |||
| 417da31df8 | |||
| f6119dd491 | |||
| b3cce4668a | |||
| 63eabb08a1 | |||
| b8cef6d337 | |||
| 5310931d58 | |||
| e09535a131 | |||
| 1424df05ae | |||
| daf73621a9 | |||
| e5fe03dfd9 | |||
| ed92cf7a79 | |||
| 6b17c478db | |||
| 02adb90048 | |||
| 9695257b61 | |||
| 2543b492c1 | |||
| c1da843bd8 | |||
| 1aa9dd7607 | |||
| eb018094ef |
@@ -1,3 +0,0 @@
|
||||
This file is used by the project manager only and should be treated like the project 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"" -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.
@@ -1,3 +0,0 @@
|
||||
This file is used by the project manager only and should be treated like the project 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"" -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.
-107
@@ -1,107 +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.
|
||||
|
||||
subproject libs/serialization/build ;
|
||||
|
||||
SOURCES =
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_oarchive
|
||||
basic_serializer_map
|
||||
basic_text_iprimitive
|
||||
basic_text_oprimitive
|
||||
basic_xml_archive
|
||||
binary_iarchive
|
||||
binary_oarchive
|
||||
extended_type_info
|
||||
extended_type_info_no_rtti
|
||||
extended_type_info_typeid
|
||||
polymorphic_iarchive
|
||||
polymorphic_oarchive
|
||||
text_iarchive
|
||||
text_oarchive
|
||||
void_cast
|
||||
xml_grammar
|
||||
xml_iarchive
|
||||
xml_oarchive
|
||||
;
|
||||
|
||||
WSOURCES =
|
||||
codecvt_null
|
||||
basic_text_wiprimitive
|
||||
basic_text_woprimitive
|
||||
binary_wiarchive
|
||||
binary_woarchive
|
||||
text_wiarchive
|
||||
text_woarchive
|
||||
xml_wgrammar
|
||||
xml_wiarchive
|
||||
xml_woarchive
|
||||
utf8_codecvt_facet
|
||||
;
|
||||
|
||||
lib boost_serialization
|
||||
: ## sources ##
|
||||
../src/$(SOURCES).cpp
|
||||
: ## requirements ##
|
||||
std::locale-support
|
||||
<msvc><*><include>$(SPIRIT_ROOT)
|
||||
<msvc-stlport><*><include>$(SPIRIT_ROOT)
|
||||
<vc7><*><include>$(SPIRIT_ROOT)
|
||||
<borland><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_5_1><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_6_4><*><include>$(SPIRIT_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>"-w-8080 -w-8071 -w-8057"
|
||||
<msvc><*><cxxflags>-Gy
|
||||
<vc7><*><cxxflags>-Gy
|
||||
<vc7_1><*><cxxflags>-Gy
|
||||
<define>BOOST_TEST_NO_AUTO_LINK=1
|
||||
: ## default-build
|
||||
<runtime-link>static/dynamic <threading>single/multi
|
||||
;
|
||||
|
||||
lib boost_wserialization
|
||||
: ## sources ##
|
||||
../src/$(WSOURCES).cpp
|
||||
: ## requirements ##
|
||||
std::locale-support
|
||||
<msvc><*><include>$(SPIRIT_ROOT)
|
||||
<msvc-stlport><*><include>$(SPIRIT_ROOT)
|
||||
<vc7><*><include>$(SPIRIT_ROOT)
|
||||
<borland><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_5_1><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_6_4><*><include>$(SPIRIT_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>"-w-8080 -w-8071 -w-8057"
|
||||
<msvc><*><cxxflags>-Gy
|
||||
<vc7><*><cxxflags>-Gy
|
||||
<vc7_1><*><cxxflags>-Gy
|
||||
<define>BOOST_TEST_NO_AUTO_LINK=1
|
||||
<vacpp><*><define>BOOST_MPL_USE_APPLY_INTERNALLY
|
||||
: ## default-build
|
||||
<runtime-link>static/dynamic <threading>single/multi
|
||||
;
|
||||
|
||||
install serialization lib :
|
||||
<lib>boost_serialization
|
||||
<lib>boost_wserialization
|
||||
;
|
||||
|
||||
stage stage/lib :
|
||||
<lib>boost_serialization
|
||||
<lib>boost_wserialization
|
||||
:
|
||||
<locate>$(BOOST_ROOT)
|
||||
common-stage-tag
|
||||
<tag><postfix>-$(version-tag)
|
||||
<target>stage
|
||||
<target>all
|
||||
:
|
||||
debug release
|
||||
;
|
||||
+63
-10
@@ -8,24 +8,66 @@
|
||||
|
||||
project boost/serialization
|
||||
: source-location ../src
|
||||
;
|
||||
: requirements <dependency>../../config/test/all//BOOST_NO_STD_LOCALE
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
|
||||
SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
|
||||
rule include-spirit ( properties * )
|
||||
{
|
||||
local old-compiler ;
|
||||
if <toolset>borland in $(properties)
|
||||
{
|
||||
old-compiler = true ;
|
||||
}
|
||||
else if <toolset>msvc in $(properties)
|
||||
{
|
||||
if <toolset-msvc:version>6.5 in $(properties)
|
||||
|| <toolset-msvc:version>7.0 in $(properties)
|
||||
{
|
||||
old-compiler = true ;
|
||||
}
|
||||
}
|
||||
|
||||
local result ;
|
||||
if $(old-compiler)
|
||||
{
|
||||
if $(SPIRIT_ROOT)
|
||||
{
|
||||
# note - we can't use <include>$(SPIRIT_ROOT) because
|
||||
# it puts -I$(SPIRIT_ROOT) AFTER the "../../.." in the command line.
|
||||
# so use these instead
|
||||
result = <cxxflags>-I$(SPIRIT_ROOT) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo **** spirit 1.6x required to build library with this compiler **** ;
|
||||
result = <build>no ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
SOURCES =
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_iserializer
|
||||
basic_oarchive
|
||||
basic_oserializer
|
||||
basic_pointer_iserializer
|
||||
basic_pointer_oserializer
|
||||
basic_serializer_map
|
||||
basic_text_iprimitive
|
||||
basic_text_oprimitive
|
||||
basic_xml_archive
|
||||
binary_iarchive
|
||||
binary_oarchive
|
||||
codecvt_null
|
||||
extended_type_info
|
||||
extended_type_info_no_rtti
|
||||
extended_type_info_typeid
|
||||
extended_type_info_no_rtti
|
||||
polymorphic_iarchive
|
||||
polymorphic_oarchive
|
||||
stl_port
|
||||
text_iarchive
|
||||
text_oarchive
|
||||
void_cast
|
||||
@@ -37,18 +79,29 @@ SOURCES =
|
||||
WSOURCES =
|
||||
basic_text_wiprimitive
|
||||
basic_text_woprimitive
|
||||
binary_wiarchive
|
||||
binary_woarchive
|
||||
text_wiarchive
|
||||
text_woarchive
|
||||
utf8_codecvt_facet
|
||||
xml_wgrammar
|
||||
xml_wiarchive
|
||||
xml_woarchive
|
||||
utf8_codecvt_facet
|
||||
codecvt_null
|
||||
;
|
||||
|
||||
lib boost_serialization : $(SOURCES).cpp :
|
||||
<toolset>msvc:<cxxflags>/Gy ;
|
||||
|
||||
lib boost_wserialization : $(WSOURCES).cpp :
|
||||
<toolset>msvc:<cxxflags>/Gy ;
|
||||
lib boost_serialization
|
||||
: $(SOURCES).cpp
|
||||
:
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
|
||||
lib boost_wserialization
|
||||
: $(WSOURCES).cpp boost_serialization
|
||||
:
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<dependency>../../config/test/all//BOOST_NO_STD_WSTREAMBUF
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
|
||||
boost-install boost_serialization boost_wserialization ;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Acknowledgments</title>
|
||||
@@ -27,23 +27,30 @@ 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
|
||||
<li><a href="../../../people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
|
||||
<li><a href="http://www.boost.org/people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
|
||||
Code Warrior, toolset configuration and bjam and much else.
|
||||
<li>Martin Ecker detected (and fixed!) a number of sublte errors regarding cyclic
|
||||
pointers, shared pointers. He also built the library as a DLL and raised some issues
|
||||
(still pending at the writing) regarding this.
|
||||
<li>Pavel Vozenilek invested much effort in review of code and documentation
|
||||
resulting in many improvements. In addition he help a lot with porting to other
|
||||
platforms including VC 6.0, Intel, and especially Borland.
|
||||
<li><a href="../../../people/jens_maurer.htm">Jens Maurer</a> and
|
||||
<a href="../../../people/beman_dawes.html">Beman Dawes</a> who got the boost
|
||||
<li><a href="http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a> and
|
||||
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> who got the boost
|
||||
serialization ball rolling. It was one or both of these two that invented
|
||||
the much beloved <code>&</code> syntax used to implement both save and
|
||||
load in one fuction specification.
|
||||
<li><a href="../../../people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
|
||||
<li><a href="http://www.boost.org/people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
|
||||
early draft and contributing the diamond inheritance example.
|
||||
<li><a href="../../../people/william_kempf.htm">William E. Kempf</a>
|
||||
<li><a href="http://www.boost.org/people/william_kempf.htm">William E. Kempf</a>
|
||||
who made the templates for this and other boost manuals. This relieved
|
||||
me of much aggravation.
|
||||
<li><a href="mailto:vahan@unicad.am">Vahan Margaryan</a> and
|
||||
|
||||
+62
-44
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - More on Archives</title>
|
||||
@@ -32,27 +32,43 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#polymorphic">Polymorphic Archives</a>
|
||||
</dl>
|
||||
<h3><a name="implementation">Implementation</a></h3>
|
||||
All input archives should be derived from the following template:
|
||||
The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
|
||||
class must implement to in order to be used to serialize
|
||||
<a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
|
||||
|
||||
The library implements a family of archives appropriate for different purposes.
|
||||
This section describes how they have been implemented and one way one
|
||||
can implement his own archive class.
|
||||
|
||||
Our discussion will focus on archives used for loading as the hierarchy is exactly analogous
|
||||
for archives used for saving data.
|
||||
|
||||
|
||||
<p>
|
||||
Our archives have been factored in to a tree of classes in order to minimize
|
||||
repetition of code. This is shown in the accompanying
|
||||
<a target="class_diagram" href="class_diagram.html">class diagram</a>.
|
||||
|
||||
Any class which fullfills the following requirements will function as
|
||||
a loading archive.
|
||||
|
||||
|
||||
<h4>Minimum Requirments</h4>
|
||||
The archive class is derived from:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
detail::common_iarchive;
|
||||
</code></pre>
|
||||
|
||||
This class uses the "Curiously Recurring Template Pattern" (CRTP)
|
||||
to implement static (I.E. compile time) polymorphism. It traps common
|
||||
functions and invokes functionality in the most derived class.
|
||||
In order to do the latter, the class is a template with the class
|
||||
name of the most derived class as an argument.
|
||||
|
||||
<h4>Minimum Requirments</h4>
|
||||
A new archive class derived from the above <strong>must</strong> contain
|
||||
the following declarations:
|
||||
An instance of the this template handles all the "bookkeeping" associated
|
||||
with serialization. In order to be a functional only the following additional
|
||||
functions <strong>must</strong> be declared:
|
||||
<dl>
|
||||
<dt><h4><code>void load(T &t);</code></h4></dt>
|
||||
<dd>
|
||||
This function must be implemented for all primitive data types. This can be
|
||||
accomplished through the use of a member template or explict declarations
|
||||
for all prmititive types.
|
||||
accomplished through the use of a member template or explicit declarations
|
||||
for all primitive types.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>void load_binary(void *address, std::size_t size);</code></h4></dt>
|
||||
@@ -76,13 +92,12 @@ So, the most trivial implementation of an input archive would look like this:
|
||||
<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
</a>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class trivial_iarchive - read serialized objects from a input text stream
|
||||
class trivial_iarchive :
|
||||
public boost::archive::detail::common_iarchive<trivial_iarchive>
|
||||
{
|
||||
// permit serialization system priviledged access to permit
|
||||
// permit serialization system privileged access to permit
|
||||
// implementation of inline templates for maximum speed.
|
||||
friend class boost::archive::load_access;
|
||||
|
||||
@@ -105,7 +120,8 @@ The simplest possible output archive class is exactly analogous to the above.
|
||||
In the following discussion, only input archives will be addressed.
|
||||
Output archives are exactly symmetrical to input archives.
|
||||
<p>
|
||||
Given a suitable definition of <code style="white-space: normal">load</code>,
|
||||
Given a suitable definitions of <code style="white-space: normal">load</code>
|
||||
and <code style="white-space: normal">load_binary</code>,
|
||||
any program using serialization with a conforming C++ compiler should compile
|
||||
and run with this archive class.
|
||||
|
||||
@@ -115,7 +131,6 @@ The <code style="white-space: normal">detail::common_iarchive</code> class conta
|
||||
a number of functions that are used by various parts of the serialization library
|
||||
to help render the archive in a particular form.
|
||||
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>void load_start()</code></h4></dt>
|
||||
@@ -137,8 +152,8 @@ by XML archive to inject "</name>" after data.
|
||||
<dt><h4><code>void end_preamble()</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Does nothing.<br>
|
||||
<strong>Purpose</strong>:Called <strong>each time</strong> user data data is saved.
|
||||
Its not called when archive book keeping data is saved. This is used by XML archives
|
||||
<strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
|
||||
It's not called when archive book keeping data is saved. This is used by XML archives
|
||||
to determine when to inject a ">" character at end of XML header. XML output archives
|
||||
keep their own internal flag indicating that data being written is header data. This
|
||||
internal flag is reset when an object start tag is written. When
|
||||
@@ -175,7 +190,9 @@ This data includes things like object ids, version numbers, class names etc. Ea
|
||||
of these objects is included in a wrapper so that the archive class can override the
|
||||
implementation of <code style="white-space: normal">void load_override(T & t, int);</code>.
|
||||
For example, in the XML archive, the override for this type renders an object_id equal to 23 as
|
||||
"object_id=_23". The following table lists the types used by the serialization library:
|
||||
"object_id=_23". The following table lists the types defined in the
|
||||
<code style="white-space: normal">boost::archive namespace</code>
|
||||
used internally by the serialization library:
|
||||
<p>
|
||||
<table border>
|
||||
<tr><th align=left>type</th><th align=left><code style="white-space: normal">default<br>serialed as</code></th>
|
||||
@@ -198,7 +215,7 @@ These are defined in
|
||||
All of these types have been assigned an
|
||||
<a target="detail" href="traits.html#level">implementation level</a> of
|
||||
<code style="white-space: normal">primitive</code> and are convertible to types such as int, unsigned int, etc.
|
||||
So that they have default implementations. This is illustrated by
|
||||
so that they have default implementations. This is illustrated by
|
||||
<a href="../../../boost/archive/basic_text_iarchive.hpp" target="basic_text_iarchive_hpp"><code style="white-space: normal">basic_text_iarchive.hpp</code></a>.
|
||||
which relies upon the default. However, in some cases, overrides will have to be
|
||||
explicitly provided for these types. For an example see
|
||||
@@ -219,7 +236,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>
|
||||
@@ -234,17 +253,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
|
||||
@@ -252,8 +269,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
|
||||
@@ -265,12 +281,14 @@ In addition, there are 22 other tests which aren't related to any particular arc
|
||||
class.
|
||||
<p>
|
||||
The default <code style="white-space: normal">bjam</code> testing setup will run all
|
||||
the above described tests. This will result in as many as 36 archive tests * 5
|
||||
standard archives + 22 general tests = 202 tests.
|
||||
the above described tests. This will result in as many as 39 archive tests * 5
|
||||
standard archives + 25 general tests = 220 tests. Note that a complete test of the
|
||||
library would include DLL vs static library, release vs debug so the actual total
|
||||
would be closer to 880 tests.
|
||||
<p>
|
||||
For each archive there is a header file in the test directory similar to the one below.
|
||||
The name of this archive is passed to the test program by setting the
|
||||
environmental variable <code style="white-space: normal">BOOST_TEST_ARCHIVE</code>
|
||||
environmental variable <code style="white-space: normal">BOOST_ARCHIVE_TEST</code>
|
||||
to the name of the header. Here is the header file
|
||||
<code style="white-space: normal">test_archive.hpp</code> . Test header files for
|
||||
other archives are similar.
|
||||
@@ -293,16 +311,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 <test header file> <toolset> [<boost root>] [<target directory>]
|
||||
library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
|
||||
</code></pre>
|
||||
<h3><a name="polymorphic">Polymorphic Archives</a></h3>
|
||||
|
||||
@@ -316,7 +334,7 @@ However:
|
||||
<ul>
|
||||
<li>Much inline code may be replicated.
|
||||
<li>If there are several archive classes, code will be regenerated for each archive class.
|
||||
<li>If seriaiization code is placed in a library, that library must be rebuilt
|
||||
<li>If serialization code is placed in a library, that library must be rebuilt
|
||||
each time a new archive class is created.
|
||||
<li>If serialization code is placed in a DLL,
|
||||
<ul>
|
||||
@@ -358,9 +376,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>
|
||||
|
||||
+349
-467
@@ -1,7 +1,7 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archives</title>
|
||||
@@ -14,371 +14,194 @@
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Archive Class Usage</h2>
|
||||
<h2 align="center">Archive Concepts</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#creation">Archive Classes</a>
|
||||
<dt><a href="#interface">Library Interface</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#saving_interface">Saving</a>
|
||||
<dt><a href="#loading_interface">Loading</a>
|
||||
</dl>
|
||||
<dt><a href="#details_by_type">Details by Type</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#primitiveoperators">Primitive Types</a>
|
||||
<dt><a href="#classoperators">Class Types</a>
|
||||
<dt><a href="#baseclasses">Base Classes</a>
|
||||
<dt><a href="#pointeroperators">Pointers</a>
|
||||
<dt><a href="#referenceoperators">References</a>
|
||||
</dl>
|
||||
<dt><a href="#saving_interface">Saving Archive Concept</a>
|
||||
<dt><a href="#loading_interface">Loading Archive Concept</a>
|
||||
<dt><a href="#archive_models">Models</a>
|
||||
<dt><a href="#exceptions">Exceptions</a>
|
||||
<dt><a href="#charactersets">Character Sets</a>
|
||||
</dl>
|
||||
|
||||
<h3><a name="archive_classes">Archive Classes</a></h3>
|
||||
An archive is defined by two complementary classes. One is for saving data while
|
||||
the other is for loading it.
|
||||
The system includes a number of archive implementations "ready to go" for the
|
||||
most common requirements. These can be used "as is" or as a basis for developing
|
||||
one's own particular type of archive. To invoke serialization using one of
|
||||
these archives, one or more of the following header files must be
|
||||
included in the code module containing the serialization code.
|
||||
<pre><code>
|
||||
// a portable text archive</a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive(istream &s)</a> // loading
|
||||
|
||||
// a portable text archive using a wide character stream</a>
|
||||
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive(wistream &s)</a> // loading
|
||||
|
||||
// a non-portable native binary archive</a>
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive(istream &s)</a> // loading
|
||||
<!--
|
||||
// a non-portable native binary archive which use wide character streams
|
||||
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive(wistream &s)</a> // loading
|
||||
-->
|
||||
// a portable XML archive</a>
|
||||
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive(istream &s)</a> // loading
|
||||
|
||||
// a portable XML archive which uses wide characters - use for utf-8 output</a>
|
||||
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive(wistream &s)</a> // loading
|
||||
</code></pre>
|
||||
<h3><a name="interface">Archive Library Interface</a></h3>
|
||||
An <strong>archive</strong> contains a sequence of bytes created from
|
||||
an arbitrary nested set of C++ data structures. Archives are implemented as a
|
||||
hierarchy of classes. However, the interface to all archives included with
|
||||
the library can best be represented by the following public interface.
|
||||
|
||||
<h4><a name="saving_interface">Saving</a></h4>
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
enum archive_flags {
|
||||
no_header = 1, // suppress archive header info
|
||||
no_codecvt = 2, // suppress alteration of codecvt facet
|
||||
no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
<pre><code>
|
||||
template<class OStream>
|
||||
class oarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
// called to save objects
|
||||
template<class T>
|
||||
oarchive & operator<<(const T & t);
|
||||
|
||||
template<class T>
|
||||
oarchive & operator&(T & t)
|
||||
{
|
||||
return *this << t;
|
||||
}
|
||||
|
||||
void save_binary(const void *address, std::size_t count);
|
||||
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
|
||||
unsigned int library_version() const;
|
||||
|
||||
struct is_saving {
|
||||
typedef mpl::bool_<true> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
|
||||
struct is_loading {
|
||||
typedef mpl::bool_<false> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
};
|
||||
|
||||
oarchive(OStream & os, unsigned int flags = 0);
|
||||
|
||||
~oarchive();
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
oarchive & operator<<(const T & t);
|
||||
|
||||
template<class T>
|
||||
oarchive & operator&(T & t);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<p>
|
||||
Appends an object of type T to the archive. The object may be
|
||||
<h4>Notation</h4>
|
||||
In the following descriptions
|
||||
<ul>
|
||||
<li>A primitive data type such as int, char, float, etc.
|
||||
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
|
||||
function has been defined.
|
||||
<li>A pointer to a serializable object.
|
||||
<li><code>SA</code> is an type modeling the <a href="#saving_interface">Saving Archive Concept</a>
|
||||
<li><code>sa</code> is an instance of type SA.
|
||||
<li><code>LA</code> is an type modeling the <a href="#loading_interface">Loading Archive Concept</a>
|
||||
<li><code>la</code> is an instance of type LA.
|
||||
<li><code>T</code> is an <a href="serialization.html"><strong>Serializable</strong></a> Type
|
||||
<li><code>x</code> is an instance of type T Type</li>.
|
||||
<li><code>u,v</code> is a pointer to a an instance of type T
|
||||
<li><code>count</code> is an instance of a type that can be converted to <code>std::size_t</code>.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void save_binary(const void *address, std::size_t count);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends to the archive <code style="white-space: normal">count</code> bytes found at
|
||||
<code style="white-space: normal">address</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends a sequential integer to the archive. This integer becomes the "key" used
|
||||
to look up the class type when the archive is later loaded. This process is
|
||||
referred to as "class registration". It is only necessary to invoke this function for
|
||||
objects of derived classes which are serialized through a base class pointer. This
|
||||
is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
unsigned int library_version() const;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the version number of the serialization library that created the archive.
|
||||
This number will be incremented each time the library is altered in such a way
|
||||
that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
is_saving::type = mpl::bool<true>;
|
||||
is_saving::value= true;
|
||||
is_loading::type = mpl::bool<false>;
|
||||
is_loading::value= false;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These integral constants permit archive attributes to be queried at compiler
|
||||
or execution time. They can used to generate code with boost
|
||||
<a href="../../mpl/doc/index.html">mpl</a>
|
||||
. For and example
|
||||
showing how these can beused, see the implementation of
|
||||
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
oarchive(OStream & os, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs and archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. For most applications there will be no need to use
|
||||
flags. Flags are taken from the following table and can be combined with the
|
||||
<code style="white-space: normal">|</code> operator.By default, archives prepend
|
||||
output with initial data which helps identify them as archives produced by this system.
|
||||
This permits a more graceful in the case where attempt is made to load an archive
|
||||
from an invalid file format. In addition to this, each type of archive might have
|
||||
its own information. For example, native binary archives include information about
|
||||
sizes of native types and endianess to gracefully handle the case where it has been
|
||||
erroneously assumed that such an archive is portable across platforms. In some cases
|
||||
where this extra overhead might be considered objectionable, it can be suppressed with the
|
||||
<code style="white-space: normal">no_header</code> flag.
|
||||
<h4><a name="saving_interface">Saving Archive Concept</a></h4>
|
||||
<h4>Associated Types</h4>
|
||||
Intuitively, a type modeling this concept will generate a sequence of bytes
|
||||
corresponding to an arbitrary set of C++ data structures. Each type modeling the
|
||||
Saving Archive concept (SA) may be associated with another type modeling the
|
||||
<a href="#loading_interface">Loading Archive Concept</a>(LA).
|
||||
This associated type will perform the inverse operation.
|
||||
That is, given a sequence of bytes generated by SA, it will generate a set of
|
||||
C++ data structures that is equivalent to the original.
|
||||
The notion of equivalence is defined by the implementations of the pair of archives and the
|
||||
way the data are rendered <a href="serialization.html">serializable</a>.
|
||||
<p>
|
||||
In some cases, an archive may alter (and later restore)
|
||||
the codecvt facet of the stream locale. To suppress this action,
|
||||
include the <code style="white-space: normal">no_codecvt</code> flag.
|
||||
<p>
|
||||
XML archives contain nested tags signifying the start and end of data fields.
|
||||
These tags are normally checked for aggreement with the object name when
|
||||
data is loaded. If a mismatch occurs an exception is thrown. Its possible
|
||||
that this may not be desired behavior. To suppress this checking of XML
|
||||
tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~oarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to thier state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
|
||||
<h4>Valid Expressions</h4>
|
||||
<dl>
|
||||
<dt><h4><code>
|
||||
SA::is_saving
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
SA::is_loading
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa << x
|
||||
<br>
|
||||
sa & x
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These expressions must perform exactly the same function. They append the
|
||||
value of <code style="white-space: normal">x</code> along with other information to <code>sa</code>.
|
||||
This other information is defined by the implementation of the archive.
|
||||
Typically this information is that which is required by a corresponding
|
||||
Loading Archive type to properly restore the value of <code>x</code>.
|
||||
<p>
|
||||
Returns a reference to <code>sa</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.save_binary(u, count)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends to the archive <code style="white-space: normal">size_t(count)</code> bytes found at
|
||||
<code style="white-space: normal">u</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.register_type<T>()
|
||||
<br>
|
||||
sa.register_type(u)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends information about class T to the archive. This information is used to
|
||||
construct the correct class when a derived pointer is loaded by a corresponding
|
||||
Loading Archive type.
|
||||
Invocation of this member function is referred to as "class registration".
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
|
||||
The second syntax is included to permit this function to be called on non-conforming
|
||||
compilers when <code style="white-space: normal">sa</code> is a template argument.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the current version number of the serialization
|
||||
library. This number will be incremented each time the library is altered in such a
|
||||
way that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h4><a name="loading_interface">Loading</a></h4>
|
||||
|
||||
<pre><code>
|
||||
template<class IStream>
|
||||
class iarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
// called to load objects
|
||||
template<class T>
|
||||
iarchive & operator>>(T & t);
|
||||
|
||||
template<class T>
|
||||
iarchive & operator&(T & t)
|
||||
{
|
||||
return *this >> t;
|
||||
}
|
||||
|
||||
void delete_created_pointers();
|
||||
|
||||
void load_binary(void *address, std::size_t count);
|
||||
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
|
||||
unsigned int library_version() const;
|
||||
|
||||
struct is_saving {
|
||||
typedef mpl::bool_<false> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
};
|
||||
|
||||
struct is_loading {
|
||||
typedef mpl::bool_<true> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
|
||||
iarchive(IStream & is, unsigned int flags = 0);
|
||||
|
||||
~iarchive();
|
||||
};
|
||||
|
||||
} //namespace archive
|
||||
) //namespace boost
|
||||
|
||||
</code></pre>
|
||||
|
||||
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
|
||||
<h4>Associated Types</h4>
|
||||
Each model of this concept presumes the
|
||||
existence of a corresponding type modeling the
|
||||
<a href="#saving_interface">Saving Archive Concept</a>.
|
||||
The purpose of an instance of this concept is to convert a sequence of bytes
|
||||
generated by this corresponding type to a set of C++ data structures
|
||||
equivalent to the original.
|
||||
<h4>Valid Expressions</h4>
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
iarchive & operator>>(T & t);
|
||||
|
||||
template<class T>
|
||||
iarchive & operator&(T & t);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<p>
|
||||
Retrieves an object of type T from the archive. The object may be
|
||||
<ul>
|
||||
<li>A primitive data type such as int, char, float, etc.
|
||||
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
|
||||
function has been defined.
|
||||
<li>A pointer to a serializable object.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void load_binary(void *address, std::size_t count);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves from the archive <code style="white-space: normal">count</code> bytes and stores
|
||||
them in memory starting at <code style="white-space: normal">address</code>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void delete_created_pointers();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Deletes all objects created by the loading of pointers. This can be used to
|
||||
avoid memory leaks that might otherwise occur if pointers are being loaded
|
||||
and the archive load encounters an exception.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves the next integer from the archive and adds an entry to a table which
|
||||
relates the integer to the type T. When pointers are loaded, this integer is
|
||||
used to indicate which object type should be created. This process is
|
||||
referred to as "class registration". It is only necessary to invoke this function for
|
||||
objects of derived classes which are serialized through a base class pointer. If this
|
||||
function is called during the saving of data to the archive, it should be called during the
|
||||
loading of the data from the archive at the same point in the serialization process.
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
unsigned int library_version() const;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the version number of the serialization library that created the archive.
|
||||
This number will be incremented each time the library is altered in such a way
|
||||
that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
is_saving::type = mpl::bool<false>;
|
||||
is_saving::value= false;
|
||||
is_loading::type = mpl::bool<true>;
|
||||
is_loading::value= true;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These integral constants permit archive attributes to be queried at compiler
|
||||
or execution time. They can used to generate code with boost
|
||||
<a href="../../mpl/doc/index.html">mpl</a>
|
||||
. For and example
|
||||
showing how these can beused, see the implementation of
|
||||
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
iarchive(IStream & is, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. If flags are used, they should be the same
|
||||
as those used when the archive was created. Function and usage of flags is described
|
||||
above.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~iarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to thier state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
LA::is_saving
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
LA::is_loading
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la >> x
|
||||
<br>
|
||||
la & x
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These expressions must perform exactly the same function.
|
||||
Sets <code>x</code> to a value retrieved from <code>la</code>.
|
||||
<p>
|
||||
Returns a reference to <code>la</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.load_binary(u, count)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves from <code style="white-space: normal">la</code> <code style="white-space: normal">size_t(count)</code> bytes and stores
|
||||
them in memory starting at <code style="white-space: normal">u</code>.
|
||||
</dd>
|
||||
<dt>
|
||||
<dt><h4><code>
|
||||
la.register_type<T>()
|
||||
<br>
|
||||
la.register_type(u)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves information about class T from the archive. This information is used to
|
||||
construct the correct class when loading a pointer to a derived class not
|
||||
otherwise referred to in the program by name.
|
||||
Invocation of this member function is referred to as "class registration".
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
|
||||
The second syntax is included to permit this function to be called on non-conforming
|
||||
compilers when <code style="white-space: normal">la</code> is a template argument.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the version number of the serialization
|
||||
library that created the archive. This number will be incremented each time the
|
||||
library is altered in such a way that serialization could be altered for some type.
|
||||
For example, suppose the type used for a count of collection members is changed.
|
||||
The code that loads collections might be conditioned on the library version to make
|
||||
sure that libraries created by previous versions of the library can still be read.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.reset_object_address(v, u)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Communicates to the archive that the object originally at address u has been
|
||||
moved to address v.
|
||||
<p>
|
||||
When an object is loaded to a temporary variable and later moved to another location,
|
||||
this function must be called in order communicate this fact. This permits the
|
||||
archive to properly implement object tracking. Object tracking is required in order
|
||||
to correctly implement serialization of pointers to instances of derived classes.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.delete_created_pointers()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Deletes all objects created by the loading of pointers. This can be used to
|
||||
avoid memory leaks that might otherwise occur if pointers are being loaded
|
||||
and the archive load encounters an exception.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
There are archives based on text, binary and XML file
|
||||
@@ -392,7 +215,7 @@ archives is discussed in
|
||||
|
||||
<p>
|
||||
The existence of the <code style="white-space: normal"><<</code>
|
||||
and <code style="white-space: normal">>></code> suggest
|
||||
and <code style="white-space: normal">>></code> suggests
|
||||
a relationship between archives and C++ i/o streams. <strong>Archives are not
|
||||
C++ i/o streams</strong>. All the archives included with this system take a stream
|
||||
as an argument in the constructor and that stream is used for output or input.
|
||||
@@ -400,132 +223,191 @@ However, this is not a requirement of the serialization functions or the
|
||||
archive interface. It just turns out that the archives written so far have
|
||||
found it useful to base their implementation on streams.
|
||||
|
||||
<h3><a name="details_by_type">Details by Type</a></h3>
|
||||
<h3><a name="archive_models">Archive Models</a></h3>
|
||||
This library includes various implementations of the Archive concept.
|
||||
|
||||
<h4><a name="primitiveoperators">Primitive Types</a></h4>
|
||||
In this document, we use the term primitive type to mean
|
||||
types whose data is simply saved/loaded to/from an archive
|
||||
with no further processing. By default, arithmetic (including characters),
|
||||
bool, and enum types are primitive types. Using
|
||||
<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.
|
||||
<p>
|
||||
The template operators &, <<, and >> of the archive classes
|
||||
described above will generate code to save/load all primitive types
|
||||
to/from an archive. This code will usually just add the
|
||||
data to the archive according to the archive format.
|
||||
For example, a four byte integer is appended to a binary archive
|
||||
as 4 binary bytes while a to a text archive it would be
|
||||
rendered as a space followed by a string representation.
|
||||
An archive is defined by two complementary classes. One is for saving data while
|
||||
the other is for loading it.
|
||||
|
||||
<h4><a name="classoperators">Class Types</a></h4>
|
||||
For class/struct types, the template operators &, <<, and >>
|
||||
will generate code that invokes the programmer's serialization code for the
|
||||
particular data type. There is no default. An attempt to serialize a
|
||||
class/struct for which no serialization has been explicitly specified
|
||||
will result in a compile time error. Specification of serialization
|
||||
for user defined types is explained in detail in the next section
|
||||
of this manual.
|
||||
This library includes a number of archive implementations that are "ready to go" for the
|
||||
most common requirements. These classes implement the archive concept for differing data formats.
|
||||
They can be used "as is" or as a basis for developing one's own particular type of archive.
|
||||
An archive is defined by two complementary classes. One is for saving data while the other is for loading it.
|
||||
|
||||
<h4><a name="baseclasses">Base Classes</a></h4>
|
||||
The header file
|
||||
<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
|
||||
base_object.hpp
|
||||
</a>
|
||||
includes the template:
|
||||
To invoke serialization using one of
|
||||
these archives, one or more of the following header files must be
|
||||
included in the code module containing the serialization code.
|
||||
<pre><code>
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
// a portable text archive</a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive</a> // loading
|
||||
|
||||
// a portable text archive using a wide character stream</a>
|
||||
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive</a> // loading
|
||||
|
||||
// a portable XML archive</a>
|
||||
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive</a> // loading
|
||||
|
||||
// a portable XML archive which uses wide characters - use for utf-8 output</a>
|
||||
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive</a> // loading
|
||||
|
||||
// a non-portable native binary archive</a>
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive</a> // loading
|
||||
|
||||
<!--
|
||||
// a non-portable native binary archive which use wide character streams
|
||||
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive</a> // loading
|
||||
-->
|
||||
|
||||
</code></pre>
|
||||
which should be used to create a reference to an object of the base
|
||||
which can be used as an argument to the archive save/load operators:
|
||||
|
||||
All of these archives implement the same inteface. Hence, it should suffice to describe only one
|
||||
of them in detail. For this purpose we will use the text archive.
|
||||
|
||||
|
||||
<pre><code>
|
||||
ar & boost::serialization::base_object<Base>(*this);
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
enum archive_flags {
|
||||
no_header = 1, // suppress archive header info
|
||||
no_codecvt = 2, // suppress alteration of codecvt facet
|
||||
no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
|
||||
};
|
||||
|
||||
} // archive
|
||||
} // boost
|
||||
</code></pre>
|
||||
Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
|
||||
This might seem to work but may fail to invoke code necessary for
|
||||
proper serialization.
|
||||
<h4><a name="pointeroperators">Pointers</a></h4>
|
||||
A pointer to any class instance can be serialized with any of the archive
|
||||
save/load operators.
|
||||
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
class text_oarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Saving Archive</strong> concept
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
~text_oarchive();
|
||||
};
|
||||
|
||||
} // archive
|
||||
} // boost
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Constructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. For most applications there will be no need to use flags.
|
||||
Flags are defined by <code style="white-space: normal">enum archive_flags</code> enumerator.
|
||||
Multiple flags can be combined with the <code style="white-space: normal">|</code> operator.
|
||||
|
||||
By default, archives prepend
|
||||
output with initial data which helps identify them as archives produced by this system.
|
||||
This permits a more graceful handling of the case where an attempt is made to load an archive
|
||||
from an invalid file format. In addition to this, each type of archive might have
|
||||
its own information. For example, native binary archives include information about
|
||||
sizes of native types and endianess to gracefully handle the case where it has been
|
||||
erroneously assumed that such an archive is portable across platforms. In some cases,
|
||||
where this extra overhead might be considered objectionable, it can be suppressed with the
|
||||
<code style="white-space: normal">no_header</code> flag.
|
||||
<p>
|
||||
To properly save and restore an object through a pointer the
|
||||
following situations must be addressed:
|
||||
<ol>
|
||||
<li>If the same object is saved multiple times through different
|
||||
pointers, only one copy of the object need be saved.
|
||||
<li>If an object is loaded multiple times through different pointers,
|
||||
only one new object should be created and all returned pointers
|
||||
should point to it.
|
||||
<li>The system must detect the case where an object is first
|
||||
saved through a pointer then the object itself is saved.
|
||||
Without taking extra precautions, loading would result in the
|
||||
creation of multiple copies of the original object. This system detects
|
||||
this case when saving and throws an exception - see below.
|
||||
<li>An object of a derived class may be stored through a
|
||||
pointer to the base class. The true type of the object must
|
||||
be determined and saved. Upon restoration the correct type
|
||||
must be created and its address correctly cast to the base
|
||||
class. That is, polymorphic pointers have to be considered.
|
||||
<li>NULL pointers must be dectected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
In some cases, an archive may alter (and later restore)
|
||||
the codecvt facet of the stream locale. To suppress this action,
|
||||
include the <code style="white-space: normal">no_codecvt</code> flag.
|
||||
<p>
|
||||
XML archives contain nested tags signifying the start and end of data fields.
|
||||
These tags are normally checked for agreement with the object name when
|
||||
data is loaded. If a mismatch occurs an exception is thrown. It's possible
|
||||
that this may not be desired behavior. To suppress this checking of XML
|
||||
tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
|
||||
</dd>
|
||||
|
||||
This serialization library addresses all of the above
|
||||
considerations. The process of saving and loading an object
|
||||
through a pointer is non-trivial. It can be summarized as
|
||||
follows:
|
||||
<p>Saving a pointer:
|
||||
<ol>
|
||||
<li>determine the true type of the object being pointed to.
|
||||
<li>write a special tag to the archive
|
||||
<li>if the object pointed to has not already been written
|
||||
to the archive, do so now
|
||||
</ol>
|
||||
Loading a pointer:
|
||||
<ol>
|
||||
<li>read a tag from the archive.
|
||||
<li>determine the type of object to be created
|
||||
<li>if the object has already been loaded, return it's address.
|
||||
<li>otherwise, create a new instance of the object
|
||||
<li>read the data back in using the operators described above
|
||||
<li>return the address of the newly created object.
|
||||
</ol>
|
||||
<dt><h4><code>
|
||||
~text_oarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to their state before the
|
||||
archive was opened.
|
||||
</dd>
|
||||
|
||||
Given that class instances are saved/loaded to/from the archive
|
||||
only once, regardless of how many times they are serialized with
|
||||
the <code style="white-space: normal"><<</code>
|
||||
and <code style="white-space: normal">>></code> operators
|
||||
<ul>
|
||||
<li>Loading the same pointer object multiple times
|
||||
results in only one object being created, thereby replicating
|
||||
the original pointer configuration.
|
||||
<li>Structures such as collections of polymorphic pointers,
|
||||
are handled with no special effort on the part of users of this library.
|
||||
</ul>
|
||||
Serialization of pointers of derived types through a pointer to the
|
||||
base class may require a little extra "help". Also, the programmer
|
||||
may desire to modify the process described above for his own reasons.
|
||||
For example, it might be desired to suppress the tracking of objects
|
||||
as it is known a priori that the application in question can never
|
||||
create duplicate objects. Serialization of pointers can be "fine tuned"
|
||||
via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
as described in
|
||||
<a target="detail" href="special.html#derivedpointers">
|
||||
another section of this manual
|
||||
</a>
|
||||
<h4><a name="referenceoperators">References</a></h4>
|
||||
In general, references are serialized just as any other objects are.
|
||||
However, references have the property that several references may
|
||||
refer to the same object - much like pointers. So, there exists
|
||||
the opportunity to gain some storage efficiency by storing only
|
||||
one copy. This subject is addressed the chapter Class Serialization Traits -
|
||||
<a target="detail" href="traits.html#tracking">Object Tracking</a>.
|
||||
</dl>
|
||||
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
class text_iarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Loading Archive</strong> concept
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
~text_iarchive();
|
||||
};
|
||||
|
||||
} //namespace archive
|
||||
) //namespace boost
|
||||
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. If flags are used, they should be the same
|
||||
as those used when the archive was created. Function and usage of flags is described
|
||||
above.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~text_iarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to thier state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
The <code style="white-space: normal">binary_oarchive</code> and
|
||||
<code style="white-space: normal">binary_iarchive</code> classes are
|
||||
implemented in terms of the more basic
|
||||
<code style="white-space: normal">std::streambuf</code>. So, in addition
|
||||
to the common class interface described above, they include the following
|
||||
constructors:
|
||||
<dl>
|
||||
<dt><h4><code>
|
||||
binary_oarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
and
|
||||
<dt><h4><code>
|
||||
binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
</dl>
|
||||
|
||||
<h3><a name="exceptions">Exceptions</h3>
|
||||
All of the archive classes included may throw exceptions. The list of exceptions that might
|
||||
be thrown can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
|
||||
of this documentation.
|
||||
|
||||
<h3><a name="charactersets">Character Sets</h3>
|
||||
This library includes two archive classes for XML. The wide character
|
||||
version (<code style="white-space: normal">xml_w?archive</code>) renders it output as UTF-8 which can
|
||||
version (<code style="white-space: normal">xml_w?archive</code>) renders its output as UTF-8 which can
|
||||
handle any wide character without loss of information.
|
||||
<code style="white-space: normal">std::string</code> data is converted from multi-byte format to wide
|
||||
character format using the current <code style="white-space: normal">
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Bibliography</title>
|
||||
|
||||
+23
-23
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
@@ -7,7 +7,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archive Class Diagram</title>
|
||||
@@ -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>
|
||||
@@ -34,10 +34,10 @@ basic_iarchive <a href="../../../boost/archive/detail/basic_iarchive.hpp">-></a>
|
||||
|
|
||||
| interface_iarchive<text_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| ______________/
|
||||
| /
|
||||
| _________/
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
common_iarchive<text_iarchive> <a href="../../../boost/archive/detail/common_iarchive.hpp">-></a>
|
||||
|
|
||||
@@ -46,20 +46,20 @@ common_iarchive<text_iarchive> <a href="../../../boost/archive/detail/comm
|
||||
|
|
||||
|
|
||||
| <font color="blue">basic_text_iprimitive<basic_istream></font> <a href="../../../boost/archive/basic_text_iprimitive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
| ____________/ interface_iarchive<polymorphic_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| / /
|
||||
| / /
|
||||
| / /
|
||||
<font color="blue">text_iarchive_impl<text_iarchive></font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
|
||||
| \ /
|
||||
| \ /
|
||||
| \_________________________________________ /
|
||||
| _________/ interface_iarchive<polymorphic_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| / |
|
||||
| / |
|
||||
| / |
|
||||
<font color="blue">text_iarchive_impl<text_iarchive></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<text_iarchive_impl<text_iarchive> > <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<text_iarchive_impl<text_iarchive> > <a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">-></a>
|
||||
|
|
||||
|
|
||||
|
|
||||
@@ -68,11 +68,11 @@ common_iarchive<text_iarchive> <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<text_iarchive_impl<text_iarchive> ></a>
|
||||
<a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">polymorphic_iarchive_route<text_iarchive_impl<text_iarchive> ></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<text_iarchive_impl<text_iarchive> ></code>
|
||||
<code style="white-space: normal">polymorphic_iarchive_route<text_iarchive_impl<text_iarchive> ></code>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
== representations about the suitability of this software for any
|
||||
== purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<head>
|
||||
@@ -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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Configuration</title>
|
||||
|
||||
+126
-69
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<title>Serialization</title>
|
||||
|
||||
@@ -87,8 +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#Platforms">Platforms</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#recent_improvements">Differences from Draft #20</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>
|
||||
@@ -109,43 +111,61 @@ function initialize() {
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#versioning">Class Versioning</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#splitting">Splitting <code>serialize</code> into <code>save/load</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#archives">Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#examples">List of Examples</a>
|
||||
</dl></div></dd>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="archives.html">Reference</a></dt>
|
||||
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="reference.html">Reference</a></dt>
|
||||
<dd><div id="reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_class"><a target="detail" href="archives.html">Archive Class Usage</a>
|
||||
<dd>
|
||||
<div id="archive_class_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#archive_classes">Archive Classes</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="library_interface"><a target="detail" href="archives.html#interface">Library Interface</a>
|
||||
|
||||
<dd><div id="library_interface_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#saving_interface">Saving Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#loading_interface">Loading Interface</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="details_by_type"><a target="detail" href="archives.html#details_by_type">Details by Type</a>
|
||||
<dd><div id="details_by_type_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#primitiveoperators">Primitive Types</a>
|
||||
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#classoperators">Class Types</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#baseclasses">Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#pointeroperators">Pointers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#referenceoperators">References</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_concept"><a target="detail" href="archives.html">Archive Concepts</a>
|
||||
<dd><div id="archive_concept_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#saving_interface">Saving Archive Concept</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#loading_interface">Loading Archive Concept</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#archive_models">Archive Models</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#exceptions">Exceptions</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#charactersets">Character Sets</a>
|
||||
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="serialization"><a target="detail" href="serialization.html">Class Serialization</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="serialization"><a target="detail" href="serialization.html">Serializable Concept</a>
|
||||
<dd><div id="serialization_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#member">Member Function</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Free">Free Function</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Base">Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Versioning">Versioning</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Splitting">Splitting <code>serialize</code> into <code>save/load</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#const"><code>const</code> Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#constructors">Non-Default Constructors</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#templates">Templates</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="traits"><a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#primitiveoperators">Primitive Types</a>
|
||||
<dt><img style="display:none" src="dot.gif" id="class"><a target="detail" href="serialization.html#classoperators">Class Types</a>
|
||||
<dd><div id="class_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#member">Member Function</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="splitfree"><a target="detail" href="serialization.html#free">Free Function</a>
|
||||
<dd><div id="splitfree_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#namespaces">Namespaces for Free Function Overrides</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="members"><a target="detail" href="serialization.html#classmembers">Class Members</a>
|
||||
<dd><div id="members_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#base">Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#const"><code>const</code> Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#templates">Templates</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#versioning">Versioning</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#splitting">Splitting <code>serialize</code> into <code>save/load</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="pointers"><a target="detail" href="serialization.html#pointeroperators">Pointers</a>
|
||||
<dd><div id="pointers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#constructors">Non-Default Constructors</a>
|
||||
<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>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#references">References</a>
|
||||
<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>
|
||||
<dt><img style="display:none" src="plus.gif" id="traits"><a target="detail" href="traits.html">Class Serialization Traits</a>
|
||||
<dd><div id="traits_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#version">Version</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#level">Implementation Level</a>
|
||||
@@ -153,26 +173,13 @@ 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="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#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#nvp">Name-Value Pairs</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#composition">Composition</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Implementations">Serialization Implementations Included in the Library</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#models">Models - Serialization Implementations Included in the Library</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="special"><a target="detail" href="special.html">Special Considerations</a>
|
||||
<dd><div id="special_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="derivedpointers"><a target="detail" href="special.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="special.html#registration">Registration</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#instantiation">Instantiation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#selectivetracking">Selective Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#runtimecasting">Runtime Casting</a>
|
||||
</dl></div></dd>
|
||||
<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#classinfo">Class Information</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
@@ -182,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>
|
||||
@@ -193,18 +205,19 @@ function initialize() {
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#stream_error"><code>stream_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_class_name"><code>invalid_class_name</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_cast"><code>unregistered_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parse_error"><code>xml_archive_parse_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parsing_error"><code>xml_archive_parsing_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_mismatch"><code>xml_archive_tag_mismatch</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_name_error"><code>xml_archive_tag_name_error</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exception_safety.html">Exception Safety</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
|
||||
<dd><div id="archive_reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">Implementation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#usage">Usage</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#testing">Testing</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#polymorphic">Polymorphic Archives</a>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
|
||||
<dd><div id="archive_reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">Implementation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#usage">Usage</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#testing">Testing</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#polymorphic">Polymorphic Archives</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="implementation"><a target="detail" href="implementation.html">Implementation Notes</a>
|
||||
<dd><div id="implementation_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#functiontemplateordering">Partial Function Template Ordering</a>
|
||||
@@ -213,23 +226,27 @@ function initialize() {
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#partialtemplatespecialization">Partial Template Specialization</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="othercompilerissues"><a target="detail" href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>
|
||||
<div id="othercompilerissues_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.x</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.X,4.X</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc295">GCC 2.95</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#intel80">Intel 8.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc80">Visual C++ 8.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc71">Visual C++ 7.1</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc70">Visual C++ 7.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc6">Visual C++ 6.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland564">Borland 5.64</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland551">Borland 5.51</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland">Borland 5.64 and 5.51</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#comeau">Comeau 4.3.3</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#codewarrior">Code Warrior 8.3</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#tru64">TRU64</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#dinkumware">Dinkumware Library</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#stlport">STLPort 4.5.3</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="plus.gif" id="headers"><a target="detail" href="headers.html">Code Structure</a>
|
||||
<div id="headers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="userincludes"><a target="detail" href="headers.html#userincludes">Files Included by User Programs</a>
|
||||
<div id="userincludes_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveimplementations">Archive Implementations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#serializationdeclarations">Serialization Declarations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#serializationimplementations">Serialization Implementations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveimplementations">Archive Implementations</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="plus.gif" id="libraryimplementation"><a target="detail" href="headers.html#libraryimplementation">Files Which Implement the Library</a>
|
||||
<div id="libraryimplementation_detail"><dl class="page-index">
|
||||
@@ -244,22 +261,63 @@ function initialize() {
|
||||
<dt><img style="display:none" src="plus.gif" id="case_studies">Case Studies
|
||||
<dd><div id="case_studies_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr.html">Template serialization - <code>shared_ptr<class T></code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr<class T></code>Revisited</a>
|
||||
<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="dot.gif"><a target="detail" href="codecvt.html">utf-8 code_cvt</a>
|
||||
<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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#runtime">Runtime Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#requirements">Requirements</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="void_cast.html"><code>void_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html"><code>utf8_codecvt_facet</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="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>
|
||||
</dl></div></dd>
|
||||
<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>
|
||||
-->
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html">Rationale</a></dt>
|
||||
<dt><img style="display:none" src="plus.gif" id="rationale"><a target="detail" href="rationale.html">Rationale</a></dt>
|
||||
<dd><div id="rationale_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#serialization">The term "serialization" is preferred to "persistence"</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#archives">Archives are not streams</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#trap">Compile time trap when saving a non-const value</a></dt>
|
||||
</dl></div></dd>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="todo"><a target="detail" href="todo.html">To Do</a></dt>
|
||||
<dd><div id="todo_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#portablebinaryarchive">Portable Binary Archive</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#performancetesting">Performance Testing and Profiling</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#backversioning">Back Versioning</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#nortti">Environments without RTTI</a></dt>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="newcasestudies"><a target="detail" href="new_case_studies.html">Proposed Case Studies</a></dt>
|
||||
<dd><div id="newcasestudies_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#functionobject">Serializing a Function Object</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archiveadaptor">Archive Adaptors</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archivehelper">Archive Helpers</a></dt>
|
||||
</dl></div></dd>
|
||||
|
||||
</dl></div></dd>
|
||||
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="history.html">History</a>
|
||||
<!--
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="definitions.html">Definitions</a></dt>
|
||||
@@ -267,7 +325,6 @@ function initialize() {
|
||||
-->
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="bibliography.html">Bibliography</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="acknowledgments.html">Acknowledgments</a></dt>
|
||||
|
||||
</dl></div>
|
||||
</small>
|
||||
</body>
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Dataflow Iterators</title>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Definitions</title>
|
||||
|
||||
+6
-2
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Derivation from an Existing Archive</title>
|
||||
@@ -73,7 +73,11 @@ the base classes.
|
||||
typedef portable_binary_oarchive derived_t;
|
||||
friend class detail::common_oarchive<derived_t>;
|
||||
friend class basic_binary_oarchive<derived_t>;
|
||||
friend class basic_binary_oprimitive<derived_t, std::ostream>;
|
||||
friend class basic_binary_oprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class boost::serialization::save_access;
|
||||
</code></pre>
|
||||
<li><i>Base class functions will usually need to be explicitly invoked</i>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Reference</title>
|
||||
|
||||
+33
-21
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archive Exceptions</title>
|
||||
@@ -37,12 +37,15 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
|
||||
<dt><a href="#xml_archive_parsing_error"><code style="white-space: normal">xml_archive_parsing_error</code></a>
|
||||
<dt><a href="#xml_archive_tag_mismatch"><code style="white-space: normal">xml_archive_tag_mismatch</code></a>
|
||||
<dt><a href="#xml_archive_tag_name_error"><code style="white-space: normal">xml_archive_tag_name_error</code></a>
|
||||
</dl>
|
||||
|
||||
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>.
|
||||
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 {
|
||||
@@ -66,6 +69,11 @@ public:
|
||||
// on incompatible platform
|
||||
array_size_too_short, // array being loaded doesn't fit in array allocated
|
||||
stream_error // i/o error on stream
|
||||
invalid_class_name, // class name greater than the maximum permitted.
|
||||
// most likely a corrupted archive or an attempt
|
||||
// to insert virus via buffer overrun method.
|
||||
unregistered_cast // base - derived relationship not registered with
|
||||
// void_cast_register
|
||||
} exception_code;
|
||||
exception_code code;
|
||||
archive_exception(exception_code c) : code(c) {}
|
||||
@@ -77,24 +85,12 @@ class xml_archive_exception : public virtual archive_exception
|
||||
public:
|
||||
typedef enum {
|
||||
xml_archive_parsing_error, // archive doesn't contain expected data
|
||||
xml_archive_tag_mismatch // start/end tag in archive doesn't match program
|
||||
xml_archive_tag_mismatch, // start/end tag in archive doesn't match program
|
||||
xml_archive_tag_name_error // tag name contains invalid characters
|
||||
|
||||
} exception_code;
|
||||
xml_archive_exception(exception_code c){}
|
||||
virtual const char *what( ) const throw( )
|
||||
{
|
||||
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;
|
||||
default:
|
||||
archive_exception::what();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
virtual const char *what( ) const throw();
|
||||
};
|
||||
|
||||
} // archive
|
||||
@@ -167,7 +163,11 @@ This should only occur when the size of an array in code is reduced after an
|
||||
archive has already been created.
|
||||
|
||||
<h3><a name="stream_error"><code style="white-space: normal">stream_error</code></a></h3>
|
||||
An error has occured durring stream input or ouput. This includes
|
||||
An error has occured during stream input or ouput. Aside from the common
|
||||
situations such as a corrupted or truncated input file, there are
|
||||
several less obvious ones that sometimes occur.
|
||||
<p>
|
||||
This includes
|
||||
an attempt to read past the end of the file. Text files need a terminating
|
||||
new line character at the end of the file which is appended when the
|
||||
archive destructor is invoked. Be sure that an output archive on a stream
|
||||
@@ -194,6 +194,13 @@ std::vector<V> v;
|
||||
ia >> v;
|
||||
}
|
||||
</code></pre>
|
||||
<p>
|
||||
Another one is the passing of uninitialized data. In general, the behavior
|
||||
of the serialization library when passed uninitialized data is undefined.
|
||||
If it can be detected, it will invoke an assertion in debug builds.
|
||||
Otherwise, depending on the type of archive, it may pass through without
|
||||
incident or it may result in an archive with unexpected data in it.
|
||||
This, in turn, can result in the throwing of this exception.
|
||||
|
||||
<h3><a name="invalid_class_name"><code style="white-space: normal">invalid_class_name</code></a></h3>
|
||||
Class name length greater than the maximum permitted. Most likely cause is a corrupted
|
||||
@@ -205,7 +212,7 @@ at runtime, a collection of legitimate conversions is maintained by the system.
|
||||
Normally this collection is maintained without any explicit action
|
||||
on the part of the user of the library. However, there are special cases
|
||||
where this might have to be done explicitly and could be overlooked. This
|
||||
is described in <a href="special.html#runtimecasting">Runtime Casting</a>.
|
||||
is described in <a href="serialization.html#runtimecasting">Runtime Casting</a>.
|
||||
This exception is thrown if an attempt is made to convert between two pointers
|
||||
whose relationship has not been registered,
|
||||
|
||||
@@ -226,9 +233,14 @@ properly deserialize previously created archives.
|
||||
</ul>
|
||||
|
||||
<h3><a name="xml_archive_tag_mismatch"><code style="white-space: normal">xml_archive_tag_mismatch</code></a></h3>
|
||||
This exception will be thrown if he start or end tag of and XML element doesn't match
|
||||
This exception will be thrown if the start or end tag of and XML element doesn't match
|
||||
the name specified for the object in the program.
|
||||
|
||||
<h3><a name="xml_archive_tag_name_error"><code style="white-space: normal">xml_archive_tag_name_error</code></a></h3>
|
||||
This exception will be thrown if the tag name contains invalid characters. Valid characters
|
||||
for an XML tag are: upper and lower case letters, digits, and the following punctuation: .(period),
|
||||
_(underscore), :(colon), and -(hyphen).
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - extended_type_info</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">extended_type_info</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#motivation">Motivation</a>
|
||||
<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
|
||||
the following functions
|
||||
<ol>
|
||||
<li>
|
||||
given a pointer to a type T discover the true type pointed to.
|
||||
<li>
|
||||
given an "external" key - determine what type of object to create.
|
||||
</ol>
|
||||
<h3>The problem with <code style="white-space: normal">std::type_info</code></h3>
|
||||
<ul>
|
||||
<li>
|
||||
The main function we require - <code style="white-space: normal">std::typeid()</code>
|
||||
is not available in all environments. Support for this function depends upon
|
||||
runtime typing(RTTI) support from the compiler. This may be non-existent
|
||||
or not enabled for reasons such as a percieved inefficiency.
|
||||
<li>
|
||||
<code style="white-space: normal">std::type_info</code> includes a string
|
||||
containing type name. This would seem to satisfy 2) above.
|
||||
But the format of this string is not consistent accross compilers, libraries,
|
||||
and operating systems. This makes it unusable for support of portable archives.
|
||||
<li>
|
||||
Even if the type name string could somehow be made portable, there is no
|
||||
guarentee that class headers would be included in the same name space accross
|
||||
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>
|
||||
There exists the possibility that different classes use different type id
|
||||
mechanism. The class header might include this information. If we want to
|
||||
import class headers accross applications, its convenient that the type id
|
||||
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
|
||||
of <code style="white-space: normal">std::type_info</code> functionality with the
|
||||
following features:
|
||||
<ul>
|
||||
<li>
|
||||
Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">extended_type_info</a></code> records - one for each type
|
||||
serialized.
|
||||
<li>
|
||||
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. 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>
|
||||
|
||||
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 extended_type_info
|
||||
{
|
||||
protected:
|
||||
// this class can't be used as is. It's just the
|
||||
// common functionality for all type_info replacement
|
||||
// systems. Hence, make these protected
|
||||
const char * m_key;
|
||||
extended_type_info(const unsigned int type_info_key);
|
||||
~extended_type_info();
|
||||
public:
|
||||
void key_register(const char *key);
|
||||
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 {
|
||||
return !(operator==(rhs));
|
||||
}
|
||||
// for plugins
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
virtual void destroy(void const * const p) const;
|
||||
static const extended_type_info * find(const char *key);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
<p>
|
||||
Generally, there will be one and only one
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. However, this is enforced only at the executable
|
||||
module level. That is, if a program includes some shared libraries or DLLS,
|
||||
there may be more than one instance of this class correponding to a particular type.
|
||||
For this reason the comparison functions below can't just compare the addresses of
|
||||
this instance but rather must be programmed to compare the the actual information
|
||||
the instances contain.
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
extended_type_info(unsigned int type_info_key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This constructor should be called by all derived classes.
|
||||
The argument should be the particular implementation. For
|
||||
this default implementation base on typeid(), this is the
|
||||
value 1. Each system must have its own integer. This value
|
||||
is used to permit the inter-operability of different typeinfo
|
||||
systems.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void key_register(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Assign a unique character string identifier to this
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance and add it to the corresponding global trable.
|
||||
This key is used to identify a type accross different instances of the program.
|
||||
In this way, one instance may know what type to create when necessary.
|
||||
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>
|
||||
<dd>
|
||||
Retrieves the key for <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance. If no key has been associated with the instance, then a NULL is returned.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
bool operator<(const extended_type_info & rhs) const;
|
||||
bool operator==(const extended_type_info & rhs) const;
|
||||
bool operator!=(const extended_type_info & rhs) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
These functions are used to compare two
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
objects. They a strict total ordering on all instances of this class.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Construct a new instance of the type to which this
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
record corresponds. This function takes variable list of up to 4 arguments
|
||||
of any type. These arguments are passed to the type's constructor
|
||||
at runtime. In order to use the facility,
|
||||
one must declare a type sequence for the constructor arguments.
|
||||
Arguments for this function must match in number and type
|
||||
with those specified when the type was exported.
|
||||
This function permits one to create instances of
|
||||
any exported type given only the exported <strong>GUID</strong> assigned
|
||||
with BOOST_CLASS_EXPORT.
|
||||
If these types are defined in DLLS or shared libraries. When these modules
|
||||
are loaded at runtime, these constructor can be called until the module
|
||||
is unloaded. These modules are referred to as <b>plugin</b>.
|
||||
</code>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void destroy(void const * const p) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance created by the above constructor.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of a
|
||||
corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
object.
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="requirements">Requirements</a></h3>
|
||||
In order to be used by the serialization library, an implementation of
|
||||
<code style="white-space: normal">extended_type_info</code>,
|
||||
(referred to as ETI here), must be derived from
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
and also implement the following:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
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
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
which corresponds to type T. Normally these instances are static objects so
|
||||
this just amounts to returning the address of this static object.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t) const;
|
||||
</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</code> implementation.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
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>
|
||||
The serialization library includes two distinct
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href="../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
implementations.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
|
||||
extended_type_info_typeid</a></h4></code>is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled
|
||||
by the compiler.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
|
||||
extended_type_info_no_rtti</a></h4></code>
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
However, if the export facility is to be used to serialize types
|
||||
through base class pointers, those types are required to implement
|
||||
a virtual function with the signature:
|
||||
|
||||
<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.
|
||||
<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. It also demostrates the
|
||||
inter-operability with between two different implementations of
|
||||
<code style="white-space: normal">extended_type_info</code>.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - FAQ</title>
|
||||
|
||||
+68
-68
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Code Structure</title>
|
||||
@@ -29,9 +29,9 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dl class="page-index">
|
||||
<dt><a href="#userincludes">Files Included by User Programs</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#archiveimplementations">Archive Implementations</a>
|
||||
<dt><a href="#serializationdeclarations">Serialization Declarations</a>
|
||||
<dt><a href="#serializationimplementations">Serialization Implementations</a>
|
||||
<dt><a href="#archiveimplementations">Archive Implementations</a>
|
||||
</dl>
|
||||
<dt><a href="#libraryimplementation">Files Which Implement the Library</a>
|
||||
<dl class="page-index">
|
||||
@@ -60,6 +60,70 @@ is included with the following declaration
|
||||
Using this library entails including headers listed in this section.
|
||||
It should not be necessary to explictly include any other header files.
|
||||
|
||||
<a name="archiveimplementations">
|
||||
<h4>Archive Implementations</h4>
|
||||
These header files contain declarations used to save and restore data to each type
|
||||
of archive. Include the archives according to the facilities the code module requires.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><a target="archive_exception" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_exception.hpp
|
||||
</a>
|
||||
<dd>Exceptions which might be invoked by the library.</dd>
|
||||
|
||||
<dt><a target="binary_iarchive" href="../../../boost/archive/binary_iarchive.hpp">
|
||||
boost/archive/binary_iarchive.hpp
|
||||
</a>
|
||||
<dd>native binary input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="binary_oarchive" href="../../../boost/archive/binary_oarchive.hpp">
|
||||
boost/archive/binary_oarchive.hpp
|
||||
</a>
|
||||
<dd>native binary output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_iarchive" href="../../../boost/archive/text_iarchive.hpp">
|
||||
boost/archive/text_iarchive.hpp
|
||||
</a>
|
||||
<dd>text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/text_oarchive.hpp">
|
||||
boost/archive/text_oarchive.hpp
|
||||
</a>
|
||||
<dd>text output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/text_wiarchive.hpp">
|
||||
boost/archive/text_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used forloading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
|
||||
boost/archive/text_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used for saving.</dd>
|
||||
|
||||
<dt><a target="xml_iarchive" href="../../../boost/archive/xml_iarchive.hpp">
|
||||
boost/archive/xml_iarchive.hpp
|
||||
</a>
|
||||
<dd>xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/xml_oarchive.hpp">
|
||||
boost/archive/xml_oarchive.hpp
|
||||
</a>
|
||||
<dd>xml output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/xml_wiarchive.hpp">
|
||||
boost/archive/xml_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/xml_woarchive.hpp">
|
||||
boost/archive/xml_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml output archive used for saving.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<a name="serializationdeclarations">
|
||||
<h4>Serialization Declarations</h4>
|
||||
To specify how a type is serialized, one codes templates for serialization functions.
|
||||
@@ -170,70 +234,6 @@ as templates for <code style="white-space: normal">boost::optional</code>,
|
||||
<code style="white-space: normal">boost::scoped_ptr</code>.
|
||||
Presumably, this list will expand with the passage of time.
|
||||
|
||||
<a name="archiveimplementations">
|
||||
<h4>Archive Implementations</h4>
|
||||
These header files contain declarations used to save and restore data to each type
|
||||
of archive. Include the archives according to the facilities the code module requires.
|
||||
|
||||
<dl/>
|
||||
|
||||
<dt><a target="archive_exception" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_exception.hpp
|
||||
</a>
|
||||
<dd>Exceptions which might be invoked by the library.</dd>
|
||||
|
||||
<dt><a target="binary_iarchive" href="../../../boost/archive/binary_iarchive.hpp">
|
||||
boost/archive/binary_iarchive.hpp
|
||||
</a>
|
||||
<dd>native binary input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="binary_oarchive" href="../../../boost/archive/binary_oarchive.hpp">
|
||||
boost/archive/binary_oarchive.hpp
|
||||
</a>
|
||||
<dd>native binary output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_iarchive" href="../../../boost/archive/text_iarchive.hpp">
|
||||
boost/archive/text_iarchive.hpp
|
||||
</a>
|
||||
<dd>text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/text_oarchive.hpp">
|
||||
boost/archive/text_oarchive.hpp
|
||||
</a>
|
||||
<dd>text output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/text_wiarchive.hpp">
|
||||
boost/archive/text_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used forloading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
|
||||
boost/archive/text_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used for saving.</dd>
|
||||
|
||||
<dt><a target="xml_iarchive" href="../../../boost/archive/xml_iarchive.hpp">
|
||||
boost/archive/xml_iarchive.hpp
|
||||
</a>
|
||||
<dd>xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/xml_oarchive.hpp">
|
||||
boost/archive/xml_oarchive.hpp
|
||||
</a>
|
||||
<dd>xml output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/xml_wiarchive.hpp">
|
||||
boost/archive/xml_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/xml_woarchive.hpp">
|
||||
boost/archive/xml_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml output archive used for saving.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<a name="libraryimplementation">
|
||||
<h3>Files Which Implement the Library</h3>
|
||||
|
||||
@@ -328,7 +328,7 @@ boost/archive/detail/common_iarchive.hpp
|
||||
boost/archive/detail/common_oarchive.hpp
|
||||
</a>
|
||||
<dd>
|
||||
All archive implmentations are derived from these header files. They provide
|
||||
All archive implementations are derived from these header files. They provide
|
||||
the interface to the internal implementation details of the library.
|
||||
</dd>
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - History</title>
|
||||
|
||||
+170
-26
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Implementation Notes</title>
|
||||
@@ -32,15 +32,20 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#partialtemplatespecialization">Partial Template Specialization</a>
|
||||
<dt><a href="#othercompilerissues">Specific Compiler/Library Issues</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#gcc">GCC 3.X</a>
|
||||
<dt><a href="#gcc">GCC 2.95</a>
|
||||
<dt><a href="#gcc3x">GCC 3.X, 4.X</a>
|
||||
<dt><a href="#gcc295">GCC 2.95</a>
|
||||
<dt><a href="#intel80">Intel 8.0</a>
|
||||
<dt><a href="#vc80">Visual C++ 8.0</a>
|
||||
<dt><a href="#vc71">Visual C++ 7.1</a>
|
||||
<dt><a href="#vc70">Visual C++ 7.0</a>
|
||||
<dt><a href="#vc6">Visual C++ 6.0</a>
|
||||
<dt><a href="#borland564">Borland 5.64</a>
|
||||
<dt><a href="#borland551">Borland 5.51 and earlier</a>
|
||||
<dt><a href="#borland">Borland 5.64 and 5.51</a>
|
||||
<dt><a href="#comeau">Comeau 4.3.3</a>
|
||||
<dt><a href="#codewarrior9">Code Warrior 9.x</a>
|
||||
<dt><a href="#codewarrior">Code Warrior 8.3</a>
|
||||
<dt><a href="#tru64">TRU64</a>
|
||||
<dt><a href="#dinkumware">Dinkumware Library</a>
|
||||
<dt><a href="#stlport">STLPort 4.5.3</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
@@ -195,29 +200,136 @@ the syntax described above.
|
||||
</ul>
|
||||
<h3><a name="othercompilerissues">Specific Compiler/Library Issues</a></h3>
|
||||
|
||||
<h4><a name="gcc3x">GCC 3.X</a></h4>
|
||||
GCC versions for Cygwin and MinGW fail to support wide character I/O.
|
||||
So all tests using wide char I/O fail. Note that if wide character I/O support
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<h4><a name="gcc3x">GCC 3.X, 4.X</a></h4>
|
||||
<ul>
|
||||
<li>GCC versions for Cygwin and MinGW fail to support wide character I/O.
|
||||
So all tests using wide char I/O fail. Note that if wide character I/O support
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<li>This compiler generates long warning messages related to the usage of
|
||||
non virtual destructors in polymorphic classes. These warnings have been
|
||||
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 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
|
||||
adding the following to the compiler command line:
|
||||
<pre><code>
|
||||
-Wno-non-virtual-dtor
|
||||
-Wno-ctor-dtor-privacy
|
||||
</code></pre>
|
||||
</ul>
|
||||
<h4><a name="gcc295">GCC 2.95</a></h4>
|
||||
All of the above plus:<br>
|
||||
<ul>
|
||||
<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
|
||||
and use this library with this compiler, one must use version 1.6x rather than the
|
||||
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
|
||||
</ul>
|
||||
<h4><a name="Intel80">Intel C++ 8.0</a></h4>
|
||||
No known issues. All tests compile and run in debug and release modes.
|
||||
|
||||
<h4><a name="vc80">Visual C++ 8.0</a></h4>
|
||||
This compiler emits warnings for calls to functions from the standard
|
||||
library which are deemed security risks. The serialization depends upon
|
||||
making some of these calls so programs which use the serialization library
|
||||
will get warning messages. These messages can be suppressed from the command
|
||||
line by including the following switch:
|
||||
<pre><code>
|
||||
/wd4996
|
||||
</code></pre>
|
||||
|
||||
<h4><a name="vc71">Visual C++ 7.1</a></h4>
|
||||
No known issues. All tests compile and run in debug and release modes.
|
||||
Derivation from an archive class defined in a DLL as described in ... will not work.
|
||||
This is due to the way that VC++ handles templated code with __decl(dllexport) and
|
||||
__decl(dllimport) specifications. Basically, this compiler requires that all the
|
||||
instantiations have the same specification - even though they have different
|
||||
template arguments. The example <code style="white-space: normal">
|
||||
demo_portable_iarchive.cpp</code> would have to reformulated as a library or dll
|
||||
similar to the pre-defined archives in order to function.
|
||||
<p>
|
||||
This compiler does not have RTTI or exception handling turned on by default. Although
|
||||
they are not strictly necessary to use the serialization package, the example and test
|
||||
program presume that they are enabled. So be sure your command line or IDE settings
|
||||
enable these features if you want to build and run these programs.
|
||||
<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
|
||||
decided to use these configurations.
|
||||
<ul>
|
||||
<li>The projects assume that the tests have been built with bjam using the default
|
||||
locations. This will result in a <code style="white-space: normal">bin</code> subdirectory
|
||||
within one's main boost directory. Below this there is a whole structure which maintains
|
||||
object and library files according to the type of build. The easiest way to build this is to
|
||||
invoke the runtest script which uses bjam. (see below) If the libraries are not in these locations,
|
||||
the projects will have to be modified accordingly.
|
||||
<li>There are project configurations for all the combinations of build variants that boost
|
||||
supports. That is for release, debug, static, static multi-threading, etc..
|
||||
<li>If you want to use/debug the DLL versions of libraries and corresponding tests, alter
|
||||
the project file to define <code style="white-space: normal">BOOST_ALL_DYN_LINK=1</code>.
|
||||
Note that for the executables to run, the <code style="white-space: normal">PATH</code>
|
||||
environmental variable will have to include the directories that contain the DLL versions of
|
||||
the boost libraries.
|
||||
<li>If you have difficulties building your own projects and linking with the boost libraries,
|
||||
compare the project settings of your own projects with the ones here. VC sometimes requires
|
||||
consistent settings between projects and the libraries they use in order to link properly.
|
||||
In particular, check support for exceptions, runtime typing(RTTI), and intrinsic support for
|
||||
wide characters. The standard version of this library presumes that these facilities are
|
||||
enabled. Projects generated by the IDE wizard do not have these features enabled by default.
|
||||
<li>Frequently when trying to build a project or view project properties, one is presented with
|
||||
a message box with the message "unspecified error". This seems to occur when one changes the
|
||||
build configuration selection. It turns out this can be "fixed" by going to the "Build"
|
||||
menu item, selecting "Configuration Manager" and selecting a build configuration for the project
|
||||
you're working with.
|
||||
<li>To test that boost libraries are built correctly, one can build and test them the way we do.
|
||||
This entails:
|
||||
<ol>
|
||||
<li>downloading a copy of bjam.exe
|
||||
<li>building process_jam_log
|
||||
<li>building compiler_status
|
||||
<li>invoking runtest.bat
|
||||
</ol>
|
||||
This will build the serialization library and run the tests on your system. If there are more than a
|
||||
a couple of test failures, you likely won't be able to get your own projects working. If most of the
|
||||
tests pass, you can be confident that your own projects will work once you get your project settings
|
||||
in sync with those included here.
|
||||
</ul>
|
||||
|
||||
<h4><a name="vc70">Visual C++ 7.0</a></h4>
|
||||
<ul>
|
||||
<li>The "pimpl" demo fails to link. Cause and workaround for this is unknown
|
||||
<li>XML serialization only works with version 1.6x of spirit. In order to build and use this
|
||||
library with this compiler, one must use version 1.6x rather than the latest version
|
||||
shipped with boost. See <a href="release.html#Installation">Release Notes</a>.
|
||||
shipped with boost. See <a href="release.html">Release Notes</a>.
|
||||
<li>This compiler does not support partial template specialization.
|
||||
The implementation of the new <code>shared_ptr</code> serialization depends upon
|
||||
compiler support for partial template specialization. This compiler doesn't implement this
|
||||
feature. In order to serialize <code style="white-space: normal">shared_ptr<A></code>,
|
||||
invoke the macro <code style="white-space: normal">BOOST_SERIALIZATION_SHARED_PTR(A)</code>
|
||||
in the header code.
|
||||
<li>Lack of support for partial template specialization also creates problems for
|
||||
serialization of <code style="white-space: normal">std::map</code>. In order to serialize
|
||||
instances of this type include the invocation of BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
|
||||
for the key type of the map.
|
||||
</ul>
|
||||
<h4><a name="vc6">Visual C++ 6.0</a></h4>
|
||||
<h4><a name="vc6">Visual C++ 6.5</a></h4>
|
||||
all the above issues for Visual C++ 7.0 plus:
|
||||
<ul>
|
||||
<li>Out of line template definitions are not recognized and fail with a confusing
|
||||
@@ -244,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>
|
||||
@@ -256,24 +368,46 @@ all the above issues for Visual C++ 7.0 plus:
|
||||
<i>fatal error C1204: compiler limit : internal structure overflow</i>. This can be addressed
|
||||
by dividing the module into smaller ones.
|
||||
</ul>
|
||||
<h4><a name="borland564">Borland 5.64</a></h4>
|
||||
<h4><a name="borland">Borland 5.64 and 5.51</a></h4>
|
||||
<ul>
|
||||
<li><code style="white-space: normal">enum</code> data members cannot be serialized.
|
||||
Conversion to/from integers will work around the problem.
|
||||
<li>Default array serialization fails. Workaround this by doing it with a loop.
|
||||
<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.
|
||||
<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
|
||||
and use this library with this compiler, one must use version 1.6x rather than the
|
||||
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
|
||||
</ul>
|
||||
<h4><a name="borland551">Borland 5.51 and earlier</a></h4>
|
||||
All of the above issues for Borland 5.64 plus:
|
||||
<h4><a name="comeau">Comeau 4.3.3</a></h4>
|
||||
<ul>
|
||||
<li>Most tests using Wide character XML files fail. This happens somewhere within the
|
||||
spirit library but we've been unable to track it further than this.
|
||||
<li>A couple of other tests fail.
|
||||
<li>This compiler fails to make a DLL with export under windows.
|
||||
<li>The associated library - libcomo fails when using a codecvt facet.
|
||||
This generates a failure with all wide character archives.
|
||||
<li>the test_set fails by going into an infinite memory leak.
|
||||
</ul>
|
||||
|
||||
<h4><a name="codewarrior9">Code Warrior 9.x</a></h4>
|
||||
<ul>
|
||||
<li>Some tests and demos demos fail - still under investigation
|
||||
</ul>
|
||||
|
||||
<h4><a name="codewarrior">Code Warrior 8.3</a></h4>
|
||||
all the above issues for Code Warrior 9.x plus:
|
||||
<ul>
|
||||
<li>This compiler only supports templated streams with the static library version.
|
||||
<li>The above inhibits the build of DLL versions of the library.
|
||||
<li>Some demos fail - still under investigation
|
||||
</ul>
|
||||
|
||||
<h4><a name="tru64">TRU64</a></h4>
|
||||
All tests and demos pass except for test_variant. Boost Variant doesn't function
|
||||
wih this compiler
|
||||
|
||||
<h4><a name="dinkumware">Dinkumware Library</a></h4>
|
||||
Several compilers, including Visual C++ 6.0, use an older dinkumware library.
|
||||
These platforms have several issues:
|
||||
@@ -281,14 +415,24 @@ These platforms have several issues:
|
||||
<li>The dinkumware library shipped with this compiler does not change the locale facet
|
||||
of an i/o stream unless the <code style="white-space: normal">imbue</code> function is called before the the
|
||||
stream is opened. In order to use this library with this environment to generate UTF-8
|
||||
files, one cannot depend on the "automatic" setting of local that archives implement. The
|
||||
stream local must be set explicitly on the stream before an archive is opened on it. The
|
||||
files, one cannot depend on the "automatic" setting of locale that archives implement. The
|
||||
stream locale must be set explicitly on the stream before an archive is opened on it. The
|
||||
archive should be opened with the <code style="white-space: normal">no_codecvt</code> flag. Note this problem will
|
||||
occur on all compilers shipped with this library.
|
||||
<li>Other issues have been worked around in the file.
|
||||
<a href="../../../boost/archive/dinkumware.hpp" target="dinkumware_hpp">dinkumware.hpp</a>
|
||||
</ul>
|
||||
|
||||
<h4><a name="stlport">STLPort 4.5.3</a></h4>
|
||||
<ul>
|
||||
<li>when built to use dynamic linking versions of C++ runtime code (<runtime-link>dynamic)
|
||||
all tests fail to link. This is due to a missing symbol in the stlport library related
|
||||
to custom codecvt facets.
|
||||
<li>the test_set fails to run correctly. It seems the hashed set iterator doesn't
|
||||
implement the ++ operator correctly. This causes the test to fail by consuming all available
|
||||
memory. Given this, this test is commented out.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2004
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ Revised 1 November, 2004
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<title>Serialization</title>
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Proposed Case Studies</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Proposed Case Studies</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#functionobject">Serializing a Function Object</a></dt>
|
||||
<dt><a href="#archiveadaptor">Archive Adaptors</a></dt>
|
||||
<dt><a href="#archivehelper">Archive Helpers</a></dt>
|
||||
</dl>
|
||||
|
||||
These are not part of the library itself, but rather
|
||||
techiques on how to use the library to address specific situations.
|
||||
|
||||
<h2><a name="functionobject"></a>Serializing a Function Object</h2>
|
||||
An example on how to serialize a function object. I believe this
|
||||
could be done by serializing pointer to the object in question. Since
|
||||
the Serialization library resurrects pointer of the correct type
|
||||
this should be easily implementable.
|
||||
<p>
|
||||
If a group of function objects were all derived from the
|
||||
same polymorphic base class - perhaps via multiple inheritance,
|
||||
the the function object effectively becomes a "variable" which
|
||||
encapsulates code.
|
||||
<p>
|
||||
This case study would show how to do this.
|
||||
|
||||
<h2><a name="archiveadaptor"></a>Archive Adaptors</h2>
|
||||
|
||||
Often users want to add their own special functionality to an
|
||||
existing archive. Examples of this are performance enhancements
|
||||
for specific types, Adjustment of output syntax for xml archives,
|
||||
and logging/debug output as archives are written and/or read.
|
||||
If this functionalty is implemented as an "adaptor" template
|
||||
which takes the base class as a template argument, such functionality
|
||||
appended to any archive for which that funtionality makes sense.
|
||||
For example, an adaptor for generating an xml schema could be
|
||||
appended to both wide narrow character versions of xml archives.
|
||||
<p>
|
||||
This case study would show how to make a useful archive adaptor.
|
||||
|
||||
<h2><a name="archivehelper"></a>Archive Helpers</h2>
|
||||
Some types are not serializable as they stand. That is - they
|
||||
do not fullfill the requirements of the "Serializable Concept".
|
||||
The iconic example of this is boost::shared_ptr. Sometimes
|
||||
these types could be made serializable by adding code inside
|
||||
the library. Of course, doing that would create a lifetime
|
||||
of unpaid employment for the library author. Rather than
|
||||
adding a bunch of special code to the library itself, this
|
||||
code can packaged as a "helper" or "mix-in" class. Then
|
||||
a new archive is derived from both the "base" archive class
|
||||
AND the "helper" class. This is how boost::shared_ptr
|
||||
has been implemented.
|
||||
<p>
|
||||
It would also be possible to make a "generic runtime helper"
|
||||
which would effectively extend the API of the library. Previously
|
||||
the library included such a helper class. It was removed
|
||||
in favor of the current implementation. But this functionality
|
||||
should be added back in with another adaptor which would
|
||||
become part of the library.
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2008
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+2
-2
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Overview</title>
|
||||
@@ -36,7 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
the reversible deconstruction of an arbitrary set of C++ data structures
|
||||
to a sequence of bytes. Such a system can be used to reconstitute
|
||||
an equivalent structure in another program context. Depending on
|
||||
this context, this might used implement object persistence, remote
|
||||
the context, this might used implement object persistence, remote
|
||||
parameter passing or other facility. In this system we use the term
|
||||
<strong>"archive"</strong> to refer to a specific rendering of this
|
||||
stream of bytes. This could be a file of binary data, text data,
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Boost Library Status Automatic Test</title>
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td><img border="0" src="C:/BoostTrunk/boost.png" width="277" height="86"></td>
|
||||
<td>
|
||||
<h1>Library Status: serialization</h1>
|
||||
<b>Run Date:</b> 02:42:48 UTC, Tuesday 10 June 2008
|
||||
</td>
|
||||
</table>
|
||||
<br>
|
||||
<table border="1" cellspacing="0" cellpadding="5">
|
||||
<tr>
|
||||
<td rowspan="2">Test Name</td>
|
||||
<td align="center" >gcc-3.4.4</td>
|
||||
</tr><tr>
|
||||
<td align="center" >profile</td>
|
||||
</tr><tr><td>peformance_array_binary_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_text_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_text_warchive</a></td><td align="right"><i>Missing</i></td></tr>
|
||||
<tr><td>peformance_array_xml_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_xml_warchive</a></td><td align="right"><i>Missing</i></td></tr>
|
||||
<tr><td>performance_iterators</a></td><td align="right">Pass <a href="profile2.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>performance_iterators_base64</a></td><td align="right">Pass <a href="profile3.txt"><i>Profile</i></a></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - PIMPL</title>
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
Flat profile:
|
||||
|
||||
Each sample counts as 0.01 seconds.
|
||||
no time accumulated
|
||||
|
||||
% cumulative self self total
|
||||
time seconds seconds calls Ts/call Ts/call name
|
||||
0.00 0.00 0.00 200 0.00 0.00 void accumulate<unsigned long>(unsigned int&, unsigned long const&)
|
||||
0.00 0.00 0.00 150 0.00 0.00 _pei386_runtime_relocator
|
||||
0.00 0.00 0.00 1 0.00 0.00 std::ostream::operator<<(void const*)
|
||||
0.00 0.00 0.00 1 0.00 0.00 __divdi3
|
||||
|
||||
% the percentage of the total running time of the
|
||||
time program used by this function.
|
||||
|
||||
cumulative a running sum of the number of seconds accounted
|
||||
seconds for by this function and those listed above it.
|
||||
|
||||
self the number of seconds accounted for by this
|
||||
seconds function alone. This is the major sort for this
|
||||
listing.
|
||||
|
||||
calls the number of times this function was invoked, if
|
||||
this function is profiled, else blank.
|
||||
|
||||
self the average number of milliseconds spent in this
|
||||
ms/call function per call, if this function is profiled,
|
||||
else blank.
|
||||
|
||||
total the average number of milliseconds spent in this
|
||||
ms/call function and its descendents per call, if this
|
||||
function is profiled, else blank.
|
||||
|
||||
name the name of the function. This is the minor sort
|
||||
for this listing. The index shows the location of
|
||||
the function in the gprof listing. If the index is
|
||||
in parenthesis it shows where it would appear in
|
||||
the gprof listing if it were to be printed.
|
||||
|
||||
Call graph (explanation follows)
|
||||
|
||||
|
||||
granularity: each sample hit covers 4 byte(s) no time propagated
|
||||
|
||||
index % time self children called name
|
||||
0.00 0.00 200/200 setvbuf [1286]
|
||||
[4] 0.0 0.00 0.00 200 void accumulate<unsigned long>(unsigned int&, unsigned long const&) [4]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 150/150 _cygwin_crt0_common@8 [1230]
|
||||
[5] 0.0 0.00 0.00 150 _pei386_runtime_relocator [5]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 _lseek64 [1234]
|
||||
[6] 0.0 0.00 0.00 1 std::ostream::operator<<(void const*) [6]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 __tcf_1 [1221]
|
||||
[7] 0.0 0.00 0.00 1 __divdi3 [7]
|
||||
-----------------------------------------------
|
||||
2 main [1263]
|
||||
[1263] 0.0 0.00 0.00 0+2 main [1263]
|
||||
2 main [1263]
|
||||
-----------------------------------------------
|
||||
|
||||
This table describes the call tree of the program, and was sorted by
|
||||
the total amount of time spent in each function and its children.
|
||||
|
||||
Each entry in this table consists of several lines. The line with the
|
||||
index number at the left hand margin lists the current function.
|
||||
The lines above it list the functions that called this function,
|
||||
and the lines below it list the functions this one called.
|
||||
This line lists:
|
||||
index A unique number given to each element of the table.
|
||||
Index numbers are sorted numerically.
|
||||
The index number is printed next to every function name so
|
||||
it is easier to look up where the function in the table.
|
||||
|
||||
% time This is the percentage of the `total' time that was spent
|
||||
in this function and its children. Note that due to
|
||||
different viewpoints, functions excluded by options, etc,
|
||||
these numbers will NOT add up to 100%.
|
||||
|
||||
self This is the total amount of time spent in this function.
|
||||
|
||||
children This is the total amount of time propagated into this
|
||||
function by its children.
|
||||
|
||||
called This is the number of times the function was called.
|
||||
If the function called itself recursively, the number
|
||||
only includes non-recursive calls, and is followed by
|
||||
a `+' and the number of recursive calls.
|
||||
|
||||
name The name of the current function. The index number is
|
||||
printed after it. If the function is a member of a
|
||||
cycle, the cycle number is printed between the
|
||||
function's name and the index number.
|
||||
|
||||
|
||||
For the function's parents, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the function into this parent.
|
||||
|
||||
children This is the amount of time that was propagated from
|
||||
the function's children into this parent.
|
||||
|
||||
called This is the number of times this parent called the
|
||||
function `/' the total number of times the function
|
||||
was called. Recursive calls to the function are not
|
||||
included in the number after the `/'.
|
||||
|
||||
name This is the name of the parent. The parent's index
|
||||
number is printed after it. If the parent is a
|
||||
member of a cycle, the cycle number is printed between
|
||||
the name and the index number.
|
||||
|
||||
If the parents of the function cannot be determined, the word
|
||||
`<spontaneous>' is printed in the `name' field, and all the other
|
||||
fields are blank.
|
||||
|
||||
For the function's children, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the child into the function.
|
||||
|
||||
children This is the amount of time that was propagated from the
|
||||
child's children to the function.
|
||||
|
||||
called This is the number of times the function called
|
||||
this child `/' the total number of times the child
|
||||
was called. Recursive calls by the child are not
|
||||
listed in the number after the `/'.
|
||||
|
||||
name This is the name of the child. The child's index
|
||||
number is printed after it. If the child is a
|
||||
member of a cycle, the cycle number is printed
|
||||
between the name and the index number.
|
||||
|
||||
If there are any cycles (circles) in the call graph, there is an
|
||||
entry for the cycle-as-a-whole. This entry shows who called the
|
||||
cycle (as parents) and the members of the cycle (as children.)
|
||||
The `+' recursive calls entry shows the number of function calls that
|
||||
were internal to the cycle, and the calls entry for each member shows,
|
||||
for that member, how many times it was called from other members of
|
||||
the cycle.
|
||||
|
||||
|
||||
Index by function name
|
||||
|
||||
[4] void accumulate<unsigned long>(unsigned int&, unsigned long const&) [7] __divdi3
|
||||
[6] std::ostream::operator<<(void const*) [5] _pei386_runtime_relocator
|
||||
@@ -0,0 +1,203 @@
|
||||
Flat profile:
|
||||
|
||||
Each sample counts as 0.01 seconds.
|
||||
% cumulative self self total
|
||||
time seconds seconds calls Ts/call Ts/call name
|
||||
100.00 0.01 0.01 __gnu_cxx::__atomic_add(int volatile*, int)
|
||||
0.00 0.01 0.00 51 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
|
||||
0.00 0.01 0.00 36 0.00 0.00 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill()
|
||||
0.00 0.01 0.00 30 0.00 0.00 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
|
||||
0.00 0.01 0.00 11 0.00 0.00 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&)
|
||||
0.00 0.01 0.00 9 0.00 0.00 void test_transform_width<6, 8>(unsigned int)
|
||||
0.00 0.01 0.00 9 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain()
|
||||
0.00 0.01 0.00 5 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*)
|
||||
0.00 0.01 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
|
||||
0.00 0.01 0.00 1 0.00 0.00 void test_xml_escape<char const>(char const*, char const*, unsigned int)
|
||||
0.00 0.01 0.00 1 0.00 0.00 void test_xml_unescape<char const>(char const*, char const*, unsigned int)
|
||||
0.00 0.01 0.00 1 0.00 0.00 void test_stream_iterators<char>(char const*, unsigned int)
|
||||
0.00 0.01 0.00 1 0.00 0.00 test_main(int, char**)
|
||||
0.00 0.01 0.00 1 0.00 0.00 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
|
||||
0.00 0.01 0.00 1 0.00 0.00 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
|
||||
|
||||
% the percentage of the total running time of the
|
||||
time program used by this function.
|
||||
|
||||
cumulative a running sum of the number of seconds accounted
|
||||
seconds for by this function and those listed above it.
|
||||
|
||||
self the number of seconds accounted for by this
|
||||
seconds function alone. This is the major sort for this
|
||||
listing.
|
||||
|
||||
calls the number of times this function was invoked, if
|
||||
this function is profiled, else blank.
|
||||
|
||||
self the average number of milliseconds spent in this
|
||||
ms/call function per call, if this function is profiled,
|
||||
else blank.
|
||||
|
||||
total the average number of milliseconds spent in this
|
||||
ms/call function and its descendents per call, if this
|
||||
function is profiled, else blank.
|
||||
|
||||
name the name of the function. This is the minor sort
|
||||
for this listing. The index shows the location of
|
||||
the function in the gprof listing. If the index is
|
||||
in parenthesis it shows where it would appear in
|
||||
the gprof listing if it were to be printed.
|
||||
|
||||
Call graph (explanation follows)
|
||||
|
||||
|
||||
granularity: each sample hit covers 4 byte(s) for 100.00% of 0.01 seconds
|
||||
|
||||
index % time self children called name
|
||||
<spontaneous>
|
||||
[1] 100.0 0.01 0.00 __gnu_cxx::__atomic_add(int volatile*, int) [1]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 51/51 void test_transform_width<6, 8>(unsigned int) [9]
|
||||
[5] 0.0 0.00 0.00 51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 36/36 void test_transform_width<6, 8>(unsigned int) [9]
|
||||
[6] 0.0 0.00 0.00 36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 30/30 void test_transform_width<6, 8>(unsigned int) [9]
|
||||
[7] 0.0 0.00 0.00 30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 11/11 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
|
||||
[8] 0.0 0.00 0.00 11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 9/9 test_main(int, char**) [16]
|
||||
[9] 0.0 0.00 0.00 9 void test_transform_width<6, 8>(unsigned int) [9]
|
||||
0.00 0.00 51/51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
|
||||
0.00 0.00 36/36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
|
||||
0.00 0.00 30/30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 9/9 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
|
||||
[10] 0.0 0.00 0.00 9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
|
||||
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
|
||||
[11] 0.0 0.00 0.00 5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/2 global constructors keyed to main [38]
|
||||
0.00 0.00 1/2 global destructors keyed to main [35]
|
||||
[12] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [12]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 test_main(int, char**) [16]
|
||||
[13] 0.0 0.00 0.00 1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
|
||||
0.00 0.00 11/11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 test_main(int, char**) [16]
|
||||
[14] 0.0 0.00 0.00 1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
|
||||
0.00 0.00 9/9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 test_main(int, char**) [16]
|
||||
[15] 0.0 0.00 0.00 1 void test_stream_iterators<char>(char const*, unsigned int) [15]
|
||||
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 main [1211]
|
||||
[16] 0.0 0.00 0.00 1 test_main(int, char**) [16]
|
||||
0.00 0.00 9/9 void test_transform_width<6, 8>(unsigned int) [9]
|
||||
0.00 0.00 1/1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
|
||||
0.00 0.00 1/1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
|
||||
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
|
||||
[17] 0.0 0.00 0.00 1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
|
||||
[18] 0.0 0.00 0.00 1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
|
||||
0.00 0.00 1/1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
|
||||
-----------------------------------------------
|
||||
|
||||
This table describes the call tree of the program, and was sorted by
|
||||
the total amount of time spent in each function and its children.
|
||||
|
||||
Each entry in this table consists of several lines. The line with the
|
||||
index number at the left hand margin lists the current function.
|
||||
The lines above it list the functions that called this function,
|
||||
and the lines below it list the functions this one called.
|
||||
This line lists:
|
||||
index A unique number given to each element of the table.
|
||||
Index numbers are sorted numerically.
|
||||
The index number is printed next to every function name so
|
||||
it is easier to look up where the function in the table.
|
||||
|
||||
% time This is the percentage of the `total' time that was spent
|
||||
in this function and its children. Note that due to
|
||||
different viewpoints, functions excluded by options, etc,
|
||||
these numbers will NOT add up to 100%.
|
||||
|
||||
self This is the total amount of time spent in this function.
|
||||
|
||||
children This is the total amount of time propagated into this
|
||||
function by its children.
|
||||
|
||||
called This is the number of times the function was called.
|
||||
If the function called itself recursively, the number
|
||||
only includes non-recursive calls, and is followed by
|
||||
a `+' and the number of recursive calls.
|
||||
|
||||
name The name of the current function. The index number is
|
||||
printed after it. If the function is a member of a
|
||||
cycle, the cycle number is printed between the
|
||||
function's name and the index number.
|
||||
|
||||
|
||||
For the function's parents, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the function into this parent.
|
||||
|
||||
children This is the amount of time that was propagated from
|
||||
the function's children into this parent.
|
||||
|
||||
called This is the number of times this parent called the
|
||||
function `/' the total number of times the function
|
||||
was called. Recursive calls to the function are not
|
||||
included in the number after the `/'.
|
||||
|
||||
name This is the name of the parent. The parent's index
|
||||
number is printed after it. If the parent is a
|
||||
member of a cycle, the cycle number is printed between
|
||||
the name and the index number.
|
||||
|
||||
If the parents of the function cannot be determined, the word
|
||||
`<spontaneous>' is printed in the `name' field, and all the other
|
||||
fields are blank.
|
||||
|
||||
For the function's children, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the child into the function.
|
||||
|
||||
children This is the amount of time that was propagated from the
|
||||
child's children to the function.
|
||||
|
||||
called This is the number of times the function called
|
||||
this child `/' the total number of times the child
|
||||
was called. Recursive calls by the child are not
|
||||
listed in the number after the `/'.
|
||||
|
||||
name This is the name of the child. The child's index
|
||||
number is printed after it. If the child is a
|
||||
member of a cycle, the cycle number is printed
|
||||
between the name and the index number.
|
||||
|
||||
If there are any cycles (circles) in the call graph, there is an
|
||||
entry for the cycle-as-a-whole. This entry shows who called the
|
||||
cycle (as parents) and the members of the cycle (as children.)
|
||||
The `+' recursive calls entry shows the number of function calls that
|
||||
were internal to the cycle, and the calls entry for each member shows,
|
||||
for that member, how many times it was called from other members of
|
||||
the cycle.
|
||||
|
||||
|
||||
Index by function name
|
||||
|
||||
[13] void test_xml_escape<char const>(char const*, char const*, unsigned int) [16] test_main(int, char**) [5] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
|
||||
[14] void test_xml_unescape<char const>(char const*, char const*, unsigned int) [8] boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [1] __gnu_cxx::__atomic_add(int volatile*, int)
|
||||
[9] void test_transform_width<6, 8>(unsigned int) [11] boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [17] char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
|
||||
[15] void test_stream_iterators<char>(char const*, unsigned int) [10] boost::archive::iterators::xml_unescape<char const*>::drain() [18] std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
|
||||
[12] __static_initialization_and_destruction_0(int, int) (performance_iterators.cpp) [6] boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [7] std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
|
||||
@@ -0,0 +1,153 @@
|
||||
Flat profile:
|
||||
|
||||
Each sample counts as 0.01 seconds.
|
||||
no time accumulated
|
||||
|
||||
% cumulative self self total
|
||||
time seconds seconds calls Ts/call Ts/call name
|
||||
0.00 0.00 0.00 200 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
|
||||
0.00 0.00 0.00 150 0.00 0.00 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill()
|
||||
0.00 0.00 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
|
||||
0.00 0.00 0.00 1 0.00 0.00 void test_base64<char>()
|
||||
0.00 0.00 0.00 1 0.00 0.00 std::_List_base<char, std::allocator<char> >::_M_clear()
|
||||
|
||||
% the percentage of the total running time of the
|
||||
time program used by this function.
|
||||
|
||||
cumulative a running sum of the number of seconds accounted
|
||||
seconds for by this function and those listed above it.
|
||||
|
||||
self the number of seconds accounted for by this
|
||||
seconds function alone. This is the major sort for this
|
||||
listing.
|
||||
|
||||
calls the number of times this function was invoked, if
|
||||
this function is profiled, else blank.
|
||||
|
||||
self the average number of milliseconds spent in this
|
||||
ms/call function per call, if this function is profiled,
|
||||
else blank.
|
||||
|
||||
total the average number of milliseconds spent in this
|
||||
ms/call function and its descendents per call, if this
|
||||
function is profiled, else blank.
|
||||
|
||||
name the name of the function. This is the minor sort
|
||||
for this listing. The index shows the location of
|
||||
the function in the gprof listing. If the index is
|
||||
in parenthesis it shows where it would appear in
|
||||
the gprof listing if it were to be printed.
|
||||
|
||||
Call graph (explanation follows)
|
||||
|
||||
|
||||
granularity: each sample hit covers 4 byte(s) no time propagated
|
||||
|
||||
index % time self children called name
|
||||
0.00 0.00 200/200 void test_base64<char>() [7]
|
||||
[4] 0.0 0.00 0.00 200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 150/150 void test_base64<char>() [7]
|
||||
[5] 0.0 0.00 0.00 150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/2 global constructors keyed to main [27]
|
||||
0.00 0.00 1/2 global destructors keyed to main [24]
|
||||
[6] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [6]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 main [1156]
|
||||
[7] 0.0 0.00 0.00 1 void test_base64<char>() [7]
|
||||
0.00 0.00 200/200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
|
||||
0.00 0.00 150/150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
|
||||
0.00 0.00 1/1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 1/1 void test_base64<char>() [7]
|
||||
[8] 0.0 0.00 0.00 1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
|
||||
-----------------------------------------------
|
||||
|
||||
This table describes the call tree of the program, and was sorted by
|
||||
the total amount of time spent in each function and its children.
|
||||
|
||||
Each entry in this table consists of several lines. The line with the
|
||||
index number at the left hand margin lists the current function.
|
||||
The lines above it list the functions that called this function,
|
||||
and the lines below it list the functions this one called.
|
||||
This line lists:
|
||||
index A unique number given to each element of the table.
|
||||
Index numbers are sorted numerically.
|
||||
The index number is printed next to every function name so
|
||||
it is easier to look up where the function in the table.
|
||||
|
||||
% time This is the percentage of the `total' time that was spent
|
||||
in this function and its children. Note that due to
|
||||
different viewpoints, functions excluded by options, etc,
|
||||
these numbers will NOT add up to 100%.
|
||||
|
||||
self This is the total amount of time spent in this function.
|
||||
|
||||
children This is the total amount of time propagated into this
|
||||
function by its children.
|
||||
|
||||
called This is the number of times the function was called.
|
||||
If the function called itself recursively, the number
|
||||
only includes non-recursive calls, and is followed by
|
||||
a `+' and the number of recursive calls.
|
||||
|
||||
name The name of the current function. The index number is
|
||||
printed after it. If the function is a member of a
|
||||
cycle, the cycle number is printed between the
|
||||
function's name and the index number.
|
||||
|
||||
|
||||
For the function's parents, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the function into this parent.
|
||||
|
||||
children This is the amount of time that was propagated from
|
||||
the function's children into this parent.
|
||||
|
||||
called This is the number of times this parent called the
|
||||
function `/' the total number of times the function
|
||||
was called. Recursive calls to the function are not
|
||||
included in the number after the `/'.
|
||||
|
||||
name This is the name of the parent. The parent's index
|
||||
number is printed after it. If the parent is a
|
||||
member of a cycle, the cycle number is printed between
|
||||
the name and the index number.
|
||||
|
||||
If the parents of the function cannot be determined, the word
|
||||
`<spontaneous>' is printed in the `name' field, and all the other
|
||||
fields are blank.
|
||||
|
||||
For the function's children, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the child into the function.
|
||||
|
||||
children This is the amount of time that was propagated from the
|
||||
child's children to the function.
|
||||
|
||||
called This is the number of times the function called
|
||||
this child `/' the total number of times the child
|
||||
was called. Recursive calls by the child are not
|
||||
listed in the number after the `/'.
|
||||
|
||||
name This is the name of the child. The child's index
|
||||
number is printed after it. If the child is a
|
||||
member of a cycle, the cycle number is printed
|
||||
between the name and the index number.
|
||||
|
||||
If there are any cycles (circles) in the call graph, there is an
|
||||
entry for the cycle-as-a-whole. This entry shows who called the
|
||||
cycle (as parents) and the members of the cycle (as children.)
|
||||
The `+' recursive calls entry shows the number of function calls that
|
||||
were internal to the cycle, and the calls entry for each member shows,
|
||||
for that member, how many times it was called from other members of
|
||||
the cycle.
|
||||
|
||||
|
||||
Index by function name
|
||||
|
||||
[7] void test_base64<char>() [5] boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [8] std::_List_base<char, std::allocator<char> >::_M_clear()
|
||||
[6] __static_initialization_and_destruction_0(int, int) (performance_iterators_base64.cpp) [4] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
|
||||
+222
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Seriealization - Rationale</title>
|
||||
@@ -31,6 +31,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#archives">Archives are not streams</a></dt>
|
||||
<dt><a href="#strings">Strings are treated specially in text archives</a></dt>
|
||||
<dt><a href="#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
|
||||
<dt><a href="#trap">Compile time trap when saving a non-const value</a></dt>
|
||||
<!--
|
||||
<dt><a href="#footnotes">Footnotes</a></dt>
|
||||
-->
|
||||
@@ -108,7 +109,227 @@ pointers never before loaded/saved. This is addressed with the <code style="whi
|
||||
and/or <code style="white-space: normal">export</code> facilities described in the reference.
|
||||
In effect, <code style="white-space: normal">export</code> generates a portable equivalent to
|
||||
<code style="white-space: normal">typeid</code> information.
|
||||
|
||||
<h2><a name="trap"></a>Compile time trap when saving a non-const value</h2>
|
||||
</p>
|
||||
The following code will fail to compile. The failure will occur on a line with a
|
||||
<code style="white-space: normal">BOOST_STATIC_ASSERT</code>.
|
||||
Here, we refer to this as a compile time trap.
|
||||
<code style="white-space: normal"><pre>
|
||||
T t;
|
||||
ar << t;
|
||||
</pre></code>
|
||||
|
||||
unless the tracking_level serialization trait is set to "track_never". The following
|
||||
will compile without problem:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
const T t
|
||||
ar << t;
|
||||
</pre></code>
|
||||
|
||||
Likewise, the following code will trap at compile time:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
T * t;
|
||||
ar >> t;
|
||||
</pre></code>
|
||||
|
||||
if the tracking_level serialization trait is set to "track_never".
|
||||
<p>
|
||||
|
||||
This behavior has been contraversial and may be revised in the future. The criticism
|
||||
is that it will flag code that is in fact correct and force users to insert
|
||||
<code style="white-space: normal">const_cast</code>. My view is that:
|
||||
<ul>
|
||||
<li>The trap is useful in detecting a certain class of programming errors.
|
||||
<li>Such errors would otherwise be difficult to detect.
|
||||
<li>The incovenience caused by including this trap is very small in relation
|
||||
to its benefits.
|
||||
</ul>
|
||||
|
||||
The following case illustrates my position. It was originally used as an example in the
|
||||
mailing list by Peter Dimov.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class construct_from
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
Suppose that there is no trap as described above.
|
||||
<ol>
|
||||
<li>this example compiles and executes fine. No tracking is done because
|
||||
construct_from has never been serialized through a pointer. Now some time
|
||||
later, the next programmer(2) comes along and makes an enhancement. He
|
||||
wants the archive to be sort of a log.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
...
|
||||
x.f(); // change x in some way
|
||||
...
|
||||
ar << x
|
||||
}
|
||||
</pre></code>
|
||||
<p>
|
||||
Again no problem. He gets two different of copies in the archive, each one is different.
|
||||
That is he gets exactly what he expects and is naturally delighted.
|
||||
<p>
|
||||
<li>Now sometime later, a third programmer(3) sees construct_from and says -
|
||||
oh cool, just what I need. He writes a function in a totally disjoint
|
||||
module. (The project is so big, he doesn't even realize the existence of
|
||||
the original usage) and writes something like:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class K {
|
||||
shared_ptr <construct_from> z;
|
||||
template <class Archive>
|
||||
void serialize(Archive & ar, const unsigned version){
|
||||
ar << z;
|
||||
}
|
||||
};
|
||||
</pre></code>
|
||||
|
||||
<p>
|
||||
He builds and runs the program and tests his new functionality. It works
|
||||
great and he's delighted.
|
||||
<p>
|
||||
<li>Things continue smoothly as before. A month goes by and it's
|
||||
discovered that when loading the archives made in the last month (reading the
|
||||
log). Things don't work. The second log entry is always the same as the
|
||||
first. After a series of very long and increasingly acrimonius email exchanges,
|
||||
its discovered
|
||||
that programmer (3) accidently broke programmer(2)'s code .This is because by
|
||||
serializing via a pointer, the "log" object now being tracked. This is because
|
||||
the default tracking behavior is "track_selectively". This means that class
|
||||
instances are tracked only if they are serialized through pointers anywhere in
|
||||
the program. Now multiple saves from the same address result in only the first one
|
||||
being written to the archive. Subsequent saves only add the address - even though the
|
||||
data might have been changed. When it comes time to load the data, all instances of the log record show the same data.
|
||||
In this way, the behavior of a functioning piece of code is changed due the side
|
||||
effect of a change in an otherwise disjoint module.
|
||||
Worse yet, the data has been lost and cannot not be now recovered from the archives.
|
||||
People are really upset and disappointed with boost (at least the serialization system).
|
||||
<p>
|
||||
<li>
|
||||
After a lot of investigation, it's discovered what the source of the problem
|
||||
and class construct_from is marked "track_never" by including:
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
<li>Now everything works again. Or - so it seems.
|
||||
<p>
|
||||
<li><code style="white-space: normal">shared_ptr<construct_from></code>
|
||||
is not going to have a single raw pointer shared amongst the instances. Each loaded
|
||||
<code style="white-space: normal">shared_ptr<construct_from></code> is going to
|
||||
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 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.
|
||||
</ol>
|
||||
|
||||
Now consider what happens when the trap is enabled:.
|
||||
|
||||
<ol>
|
||||
<p>
|
||||
<li>Right away, the program traps at
|
||||
<code style="white-space: normal"><pre>
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
<li>The programmer curses (another %^&*&* hoop to jump through). If he's in a
|
||||
hurry (and who isn't) and would prefer not to <code style="white-space: normal">const_cast</code>
|
||||
- because it looks bad. So he'll just make the following change an move on.
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
Things work fine and he moves on.
|
||||
<p>
|
||||
<li>Now programer (2) wants to make his change - and again another
|
||||
annoying const issue;
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
...
|
||||
x.f(); // change x in some way ; compile error f() is not const
|
||||
...
|
||||
ar << x
|
||||
</pre></code>
|
||||
<p>
|
||||
He's mildly annoyed now he tries the following:
|
||||
<ul>
|
||||
<li>He considers making f() a const - but presumable that shifts the const
|
||||
error to somewhere else. And his doesn't want to fiddle with "his" code to
|
||||
work around a quirk in the serializaition system
|
||||
<p>
|
||||
<li>He removes the <code style="white-space: normal">const</code>
|
||||
from <code style="white-space: normal">const construct_from</code> above - damn now he
|
||||
gets the trap. If he looks at the comment code where the
|
||||
<code style="white-space: normal">BOOST_STATIC_ASSERT</code>
|
||||
occurs, he'll do one of two things
|
||||
<ol>
|
||||
<p>
|
||||
<li>This is just crazy. Its making my life needlessly difficult and flagging
|
||||
code that is just fine. So I'll fix this with a <code style="white-space: normal">const_cast</code>
|
||||
and fire off a complaint to the list and mabe they will fix it.
|
||||
In this case, the story branches off to the previous scenario.
|
||||
<p>
|
||||
<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 add the following to my
|
||||
construct_from.hpp to solve the problem.
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
</ol>
|
||||
</ul>
|
||||
<p>
|
||||
<li>Now programmer (3) comes along and make his change. The behavior of the
|
||||
original (and distant module) remains unchanged because the
|
||||
<code style="white-space: normal">construct_from</code> trait has been set to
|
||||
"track_never" so he should always get copies and the log should be what we expect.
|
||||
<p>
|
||||
<li>But now he gets another trap - trying to save an object of a
|
||||
class marked "track_never" through a pointer. So he goes back to
|
||||
construct_from.hpp and comments out the
|
||||
<code style="white-space: normal">BOOST_CLASS_TRACKING</code> that
|
||||
was inserted. Now the second trap is avoided, But damn - the first trap is
|
||||
popping up again. Eventually, after some code restructuring, the differing
|
||||
requirements of serializating <code style="white-space: normal">construct_from</code>
|
||||
are reconciled.
|
||||
</ol>
|
||||
Note that in this second scenario
|
||||
<ul>
|
||||
<li>all errors are trapped at compile time.
|
||||
<li>no invalid archives are created.
|
||||
<li>no data is lost.
|
||||
<li>no runtime errors occur.
|
||||
</ul>
|
||||
|
||||
It's true that these traps may sometimes flag code that is currently correct and
|
||||
that this may be annoying to some programmers. However, this example illustrates
|
||||
my view that these traps are useful and that any such annoyance is small price to
|
||||
pay to avoid particularly vexing programming errors.
|
||||
|
||||
<!--
|
||||
<h2><a name="footnotes"></a>Footnotes</h2>
|
||||
<dl>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization of Classes</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Serializable Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="archives.html">Archive Concepts</a>
|
||||
<dt><a href="serialization.html">Serializable Concept</a>
|
||||
<dt><a href="special.html">Special Considerations</a>
|
||||
<dt><a href="archive_reference.html">Archive Class Reference</a>
|
||||
<dt><a href="implementation.html">Implementation Notes</a>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+87
-22
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Release Notes</title>
|
||||
@@ -27,51 +27,116 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#requirements">Requirements</a></dt>
|
||||
<dt><a href="#Platforms">Platforms</a></dt>
|
||||
<dt><a href="#recent_improvements">Differences from Draft #20</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.32 Serialization Library.
|
||||
There are currently no known bugs. However, due to compiler/library quirks and or
|
||||
bugs, some tests fail.
|
||||
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.32 or later. Depending on the compiler used,
|
||||
It may also require spirit 1.6x which is not part of the standard boost distribution.
|
||||
This library has been tested on Boost version 1.34 and 1.35.
|
||||
|
||||
<!--
|
||||
<p>
|
||||
The serialization library requires the boost spirit package to load XML archives.
|
||||
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.
|
||||
If you are using one of these two compilers, you may download a version
|
||||
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>.
|
||||
To use this downloaded version rather than the one included with boost,
|
||||
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>
|
||||
set SPIRIT_ROOT=c:/spirit161
|
||||
set SPIRIT_ROOT=c:/spirit16
|
||||
</code></pre>
|
||||
If you're not using bjam and the jamfile to build the library, be sure that
|
||||
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 Draft #20</h2>
|
||||
<h2><a name="differences_1_35"></a>Differences from Boost 1.35</h2>
|
||||
<ul>
|
||||
<li>Support for <em>Argument Dependent Looup</em> for serialization override invocations.
|
||||
<li>The library is now thread safe. That is, multiple archives can be open
|
||||
in different threads. This has been implmented with a lock-free algorithm
|
||||
to avoid any performance bottlenecks.
|
||||
<li>Serialization of types defined in shared libraries is now supported.
|
||||
shared libraries (DLLS) can be loaded/unloaded dynamically at runtime.
|
||||
This includes the serialization of instances of abstract base classes so that
|
||||
a program can be written so as to be compatible with as yet undefined
|
||||
and un-implemented code.
|
||||
<li>The extended type info system has been enhanced to in order to implement
|
||||
the above. It is now a general purpose system for creating and casting of
|
||||
types about which is only known a string ID and an abstract base class.
|
||||
<li>All bug reports filed as TRAK tickets have been addressed.
|
||||
<li>As of this writing, the library will fail build on older compilers such
|
||||
as MSVC before version 7.1 and older versions of Borland compilers. This
|
||||
might or might not change in the future.
|
||||
</ul>
|
||||
|
||||
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</h2>
|
||||
<ul>
|
||||
<li>Enhanced support for fast serialization for native binary archives. By Mattias Troyer.
|
||||
<li>Improved implementation of "export" functionality. Removes header ordering
|
||||
requirement and eliminates the maintenance of a pre-determined list of "known archives"
|
||||
By David Abrahams.
|
||||
<li>Improved support for STLPort.
|
||||
</ul>
|
||||
|
||||
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
|
||||
<ul>
|
||||
<li>Native Binary archives use the <code style="white-space: normal">std::streambuf</code> interface.
|
||||
This should result in noticeably faster execution in many cases.
|
||||
</ul>
|
||||
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
|
||||
<ul>
|
||||
<li>Dynamic Linking Library (DLLs and shared libraries) for platforms which support them. See
|
||||
<a href="../../../more/getting_started/windows.html#auto-linking">Automatic Linking on Windows</a>.
|
||||
<li>Implementation of auto-link for compilers which can support this.
|
||||
<li>Better support for <em>Argument Dependent Lookup</em> and two-phase lookup.
|
||||
This results in simpler rules regarding the placing of serialization specializations
|
||||
namespaces.
|
||||
<li>Enhanced documentation to help explain usage of the above.
|
||||
<li>Adjustments to improve support for less conformant compilers.
|
||||
<li>A few bug fixes.
|
||||
<li>Improved <code>const</code> correctness for save/load operators. Note that this may
|
||||
produce compile time errors in code which compiled without problem in earlier boost releases.
|
||||
In most cases the fix is trivial. In other cases, code should be scrutinized to be
|
||||
sure that it doesn't use the serialization system in a way which may introduce subtle bugs in
|
||||
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<T></code>. This
|
||||
is compatible with public interface of <code style="white-space: normal">shared_ptr<T></code>
|
||||
so it should be more robust and not have to change in the future. The implementation optionally
|
||||
includes code to load <code style="white-space: normal">shared_ptr<T></code> stored in
|
||||
archives created with boost 1.32. This code is stored in the header:
|
||||
<code style="white-space: normal">boost/serialization/shared_ptr_132.hpp</code>. If your application
|
||||
needs to load archives created with boost 1.32 libraries, include the above header
|
||||
before each inclusion of <code style="white-space: normal">boost/serialization/shared_ptr.hpp</code>.
|
||||
<li>More compilers tested and supported.
|
||||
<li>Miscellaneous bug fixes.
|
||||
</ul>
|
||||
|
||||
<h2><a name="todo"></a>Pending issues</h2>
|
||||
<ul>
|
||||
<li>Compile, and test on more platforms
|
||||
<li>implement <code>is_virtual_base<T></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.
|
||||
</ul>
|
||||
<li>Its possible that <code style="white-space: normal">std::string</code>
|
||||
and <code style="white-space: normal">std::wstring</code> contain characters such as
|
||||
'\0' and -1 (EOF) which cannot be rendered in text and XML archives without an escape mechanism.
|
||||
Currently there is no such escape mechanism implemented.
|
||||
<li>A subtle error in the implementation of serializaton of <code style="white-space: normal">std::map</code>
|
||||
is fixed in this version. Unfortunately, the fix breaks serialization of
|
||||
<code style="white-space: normal">std::map</code> for those compilers which do not support
|
||||
partial template specialization.
|
||||
</ul>
|
||||
<p>
|
||||
Aside from the above, there are a number of issues related to specific platforms.
|
||||
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
<p><i>© 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>
|
||||
|
||||
+541
-184
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization of Classes</title>
|
||||
@@ -20,58 +20,117 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Class Serialization</h2>
|
||||
<h2 align="center">Serializable Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#member">Member Function</a>
|
||||
<dt><a href="#Free">Free Function</a>
|
||||
<dt><a href="#Base">Base Classes</a>
|
||||
<dt><a href="#Versioning">Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
|
||||
<code style="white-space: normal">save/load</code></a>
|
||||
<dt><a href="#primitiveoperators">Primitive Types</a>
|
||||
<dt><a href="#classoperators">Class Types</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#splittingmemberfunctions">Member Functions</a>
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
<dt><a href="#member">Member Function</a>
|
||||
<dt><a href="#free">Free Function</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#namespaces">Namespaces for Free Function Overrides</a>
|
||||
</dl>
|
||||
<dt><a href="#classmembers">Class Members</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#base">Base Classes</a>
|
||||
<dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
|
||||
<dt><a href="#templates">Templates</a>
|
||||
</dl>
|
||||
<dt><a href="#versioning">Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
|
||||
<code style="white-space: normal">save/load</code></a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#splittingmemberfunctions">Member Functions</a>
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
</dl>
|
||||
</dl>
|
||||
<dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
|
||||
<dt><a href="#constructors">Non-Default Constructors</a>
|
||||
<dt><a href="#referencemembers">Reference Members</a>
|
||||
<dt><a href="#templates">Templates</a>
|
||||
<dt><a href="traits.html">Class Serialization Traits</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>
|
||||
</dl>
|
||||
</dl>
|
||||
<dt><a href="#references">References</a>
|
||||
<dt><a href="#arrays">Arrays</a>
|
||||
<dt><a href="wrappers.html">Serialization Wrappers</a>
|
||||
<dt><a href="#implementations">Serialization Implementations Included in the Library</a>
|
||||
<dt><a href="traits.html">Class Serialization Traits</a>
|
||||
<dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
|
||||
</dl>
|
||||
The header file <a target="serialization_hpp"
|
||||
href="../../../boost/serialization/serialization.hpp">
|
||||
<code style="white-space: normal">serialization.hpp</code></a> contains public interface to the
|
||||
serialization library. This entire interface consists of three overridable
|
||||
function templates.
|
||||
<h4><a name="member">Member Function</a></h4>
|
||||
The first of these three templates is:
|
||||
|
||||
A type <code style="white-space: normal">T</code> is <strong>Serializable</strong>
|
||||
if and only if one of the following is true:
|
||||
<ul>
|
||||
<li>it is a primitive type.<br>
|
||||
In this document, we use the term primitive type to mean
|
||||
types whose data is simply saved/loaded to/from an archive
|
||||
with no further processing. Arithmetic (including characters),
|
||||
bool, enum and stl::string and stl::wstring types are primitive types. Using
|
||||
<a target="detail" href="traits.html#Traits">serialization traits</a>,
|
||||
any user type can also be designated as "primitive"
|
||||
so that it is handled in this way.
|
||||
<li>It is a class type and one of the following has been declared according
|
||||
to the prototypes detailed below:
|
||||
<ul>
|
||||
<li>a class member function <code style="white-space: normal">serialize</code>
|
||||
<li>a global function <code style="white-space: normal">serialize</code>
|
||||
</ul>
|
||||
<li>it is a pointer to a <strong>Serializable</strong> type.
|
||||
<li>it is a reference to a <strong>Serializable</strong> type.
|
||||
<li>it is a native C++ Array of <strong>Serializable</strong> type.
|
||||
</ul>
|
||||
|
||||
<h2><a name="primitiveoperators">Primitive Types</a></h2>
|
||||
The template operators &, <<, and >> of the archive classes
|
||||
described above will generate code to save/load all primitive types
|
||||
to/from an archive. This code will usually just add the
|
||||
data to the archive according to the archive format.
|
||||
For example, a four byte integer is appended to a binary archive
|
||||
as 4 binary bytes while a to a text archive it would be
|
||||
rendered as a space followed by a string representation.
|
||||
|
||||
<h2><a name="classoperators">Class Types</a></h2>
|
||||
For class/struct types, the template operators &, <<, and >>
|
||||
will generate code that invokes the programmer's serialization code for the
|
||||
particular data type. There is no default. An attempt to serialize a
|
||||
class/struct for which no serialization has been explicitly specified
|
||||
will result in a compile time error. The serialiation of a class can
|
||||
be specified via either a class member function or a free funcation which
|
||||
takes a reference to an instance of the class as an argument.
|
||||
|
||||
<h3><a name="member">Member Function</a></h3>
|
||||
The serialization library invokes the following code to save or load a class instance
|
||||
to/from and archive.
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned long int file_version
|
||||
const unsigned int file_version
|
||||
){
|
||||
// invoke member function for class T
|
||||
t.serialize(ar, file_version);
|
||||
}
|
||||
</code></pre>
|
||||
It is invoked each time the data members of a class instance are to be saved to
|
||||
or loaded from an archive. The default definition of this template presumes the
|
||||
existence of a class member function template of the following signature:
|
||||
That is, the default definition of template <code style="white-space: normal">serialize</code>
|
||||
presumes the existence of a class member function template of the following
|
||||
signature:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version){
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
If this is not declared, then a compile time error will occur. In order
|
||||
If such a member function is not declared, a compile time error will occur. In order
|
||||
that the member function generated by this template can be called to
|
||||
append the data to an archive, it either must be public or the class must
|
||||
be made accessible to the serialization library by including:
|
||||
@@ -108,7 +167,7 @@ template<class Archive>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
my_class & t,
|
||||
const unsigned long int file_version
|
||||
const unsigned int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
@@ -124,8 +183,26 @@ class to be serialized will be necessary even when using this "non-intrusive"
|
||||
method. In practice this may not be such a problem as many libraries
|
||||
(E.G. STL) expose enough information to permit implementation of non-intrusive
|
||||
serialization with absolutly no changes to the library.
|
||||
|
||||
<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
|
||||
For maximum portability, include any free functions templates and definitions in the
|
||||
namespace <code style="white-space: normal">boost::serialization</code>. If portability is not a concern and the
|
||||
compiler being used supports ADL (Argument Dependent Lookup) the free functions and
|
||||
templates can be in any of the following namespaces:
|
||||
<ul>
|
||||
<li><code style="white-space: normal">boost::serialization</code>
|
||||
<li>namespace of the archive class
|
||||
<li>namespace of the type being serialized
|
||||
</ul>
|
||||
<p>
|
||||
Regardless of which method is used the body of the serialize function will
|
||||
Note that, at first glance, this suggestion may seem to be wrong for compilers which implement
|
||||
two phase lookup. In fact, the serialization library used a perhaps overly clever
|
||||
method to support this rule even for such compilers. Those with an interest in studying
|
||||
this furter will find more information in
|
||||
<a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
|
||||
|
||||
<h3><a name="classmembers">Serialization of Class Members</a></h3>
|
||||
Regardless of which of the above methods is used, the body of the serialize function must
|
||||
specify the data to be saved/loaded by sequential application of the archive
|
||||
<code style="white-space: normal">operator &</code> to all the data members of the class.
|
||||
<pre><code>
|
||||
@@ -136,76 +213,21 @@ specify the data to be saved/loaded by sequential application of the archive
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
|
||||
The question arises as to which <code>namespace</code> free serialization functions should be part of.
|
||||
<p>
|
||||
The options for this depend on:
|
||||
<ul>
|
||||
<li>Whether or not the compiler implements Argument Dependent Lookup.
|
||||
<li>whether or not the compiler implements Two Phase Lookup
|
||||
<li>whether or not the type to be serialized is a dependent type.
|
||||
</ul>
|
||||
according to the following table:
|
||||
<p>
|
||||
<table border>
|
||||
<tr><th align="right">ADL</th><th align="right">Two Phase<br>Lookup</th><th align="right">Dependent<br>Type T?</th><th>Namespace permitted</th></tr>
|
||||
<tr><td align="right">no<td align="right">no<td align="right">-<td><code>boost::serialization</tr>
|
||||
<tr><td align="right">no<td align="right">yes<td align="right">-<td>no compilers do this</tr>
|
||||
<tr><td align="right">yes<td align="right">no<td align="right">-<td><code>boost::serialzation</code><br><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
<tr><td align="right">yes<td align="right">yes<td align="right">no<td><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
<tr><td align="right">yes<td align="right">yes<td align="right">yes<td><code>boost::serialization<br><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
</table>
|
||||
<p>
|
||||
To deal with this while maintaining portability, the test programs use the following
|
||||
before specifying free function overloads:
|
||||
<h4><a name="base">Base Classes</a></h4>
|
||||
The header file
|
||||
<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
|
||||
base_object.hpp
|
||||
</a>
|
||||
includes the template:
|
||||
<pre><code>
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace boost { namespace serialization {
|
||||
#endif
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
</code></pre>
|
||||
which works for all compilers.
|
||||
<p>
|
||||
|
||||
From Vandervoorde and Josuttis book
|
||||
"C++ Templates - A Complete Guide"<a href="bibliography.html#14">[14]</a>
|
||||
page 509:
|
||||
<blockquote>
|
||||
<strong>dependant name</strong><br>
|
||||
A name the meaning of which depends on a template parameter.
|
||||
For example, A<T>::x is a dependant name when A or T is a template parameter.
|
||||
The name of a function in a function call is also dependant if any of the arguments in the call
|
||||
has a type that depends on a template parameter.
|
||||
For example, f in f((T*)0) is dependent if T is a template parameter.
|
||||
The name of a template parameter is not considered dependent, however.
|
||||
</blockquote>
|
||||
|
||||
and page 515:
|
||||
<blockquote>
|
||||
<strong>two-phase lookup</strong><br>
|
||||
The name lookup mechanism used for names in templates. The "two phases" are
|
||||
(1) the phase during which a template definition is first encountered by a compiler, and
|
||||
(2) the instantiation of a template. <i>Nondependant names</i> are looked up only in the first phase,
|
||||
but during this first phase <i>nondepdendent</i> base class are not considered.
|
||||
<i>Dependant</i> names with a scope qualifier(::) are looked up only in the second phase.
|
||||
Dependant names without a scop qualifier may be looked up in both places, but in the
|
||||
second phase only argument-dependant lookup is performed.
|
||||
</blockquote>
|
||||
|
||||
In this library, the file <code style="white-space: normal">serialization.hpp</code>,
|
||||
which calls the serialization override,
|
||||
is included by including any archive classes. This would suggest that all serialization
|
||||
overrides could be in any of the three possible namespaces if the serialization code is
|
||||
included before the archives. However, this is not always possible. Our implementation
|
||||
of "export" functionality requires just the opposite.
|
||||
|
||||
<p>
|
||||
This is consided inelegant to say the least. Hopefully, this may be improved in the future.
|
||||
|
||||
<h3><a name="Base">Base Classes</a></h3>
|
||||
If the class to be serialized is derived from another class, its data
|
||||
should be serialized with the following syntax:
|
||||
which should be used to create a reference to an object of the base
|
||||
which can be used as an argument to the archive serialization operators.
|
||||
So for a class of <strong>Serializable</strong> type
|
||||
<code style="white-space: normal">T</code> the base class state should be
|
||||
serialized like this:
|
||||
<pre><code>
|
||||
{
|
||||
// invoke serialization of the base class
|
||||
@@ -215,13 +237,76 @@ should be serialized with the following syntax:
|
||||
ar & member2;
|
||||
}
|
||||
</code></pre>
|
||||
Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
|
||||
This might seem to work but may fail to invoke code necessary for
|
||||
proper serialization.
|
||||
<p>
|
||||
Note that this is <strong>NOT</strong> the same as calling the <code style="white-space: normal">serialize</code>
|
||||
function of the base class. This might seem to work but will circumvent
|
||||
certain code used for tracking of objects, and registering base-derived
|
||||
relationships and other bookkeeping that is required for the serialization
|
||||
system to function as designed. For this reason, all <code style="white-space: normal">serialize</code>
|
||||
member functions should be <code style="white-space: normal">private</code>.
|
||||
<h3><a name="Versioning">Versioning</a></h3>
|
||||
|
||||
<h4><a name="const"><code style="white-space: normal">const</code> Members</a></h4>
|
||||
Saving <code style="white-space: normal">const</code> members to an archive
|
||||
requires no special considerations.
|
||||
Loading <code style="white-space: normal">const</code> members can be addressed by using a
|
||||
<code style="white-space: normal">const_cast</code>:
|
||||
<pre><code>
|
||||
ar & const_cast<T &>(t);
|
||||
</code></pre>
|
||||
Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
|
||||
keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
|
||||
is constructed and not changed thereafter. However, this may
|
||||
be most appropriate in many cases. Ultimately, it comes down to
|
||||
the question about what <code style="white-space: normal">const</code> means in the context
|
||||
of serialization.
|
||||
|
||||
<h4><a name="templates"></a>Templates</h4>
|
||||
Implementation serialization for templates is exactly the same process
|
||||
as for normal classes and requires no additional considerations. Among
|
||||
other things, this implies that serialization of compositions of templates
|
||||
are automatically generated when required if serialization of the
|
||||
component templates is defined. For example, this library includes
|
||||
definition of serialization for <code style="white-space: normal">boost::shared_ptr<T></code> and for
|
||||
<code style="white-space: normal">std::list<T></code>. If I have defined serialization for my own
|
||||
class <code style="white-space: normal">my_t</code>, then serialization for
|
||||
<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
|
||||
for use.
|
||||
<p>
|
||||
See for an example that shows how this idea might be implemented for your own
|
||||
class templates, see
|
||||
<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
|
||||
demo_auto_ptr.cpp</a>.
|
||||
This shows how non-intrusive serialization
|
||||
for the template <code style="white-space: normal">auto_ptr</code> from the standard library
|
||||
can be implemented.
|
||||
<p>
|
||||
A somewhat trickier addition of serialization to a standard template
|
||||
can be found in the example
|
||||
<a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
|
||||
shared_ptr.hpp
|
||||
</a>
|
||||
<!--
|
||||
Only the most minimal change to
|
||||
<code>shared_count.hpp</code>
|
||||
(to gain access to some private members) was necessary to achieve this.
|
||||
This should demonstrate how easy it is to non-intrusively
|
||||
implement serialization to any data type or template.
|
||||
-->
|
||||
<p>
|
||||
In the specification of serialization for templates, its common
|
||||
to split <code style="white-space: normal">serialize</code>
|
||||
into a <code style="white-space: normal">load/save</code> pair.
|
||||
Note that the convenience macro described
|
||||
<a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
|
||||
isn't helpful in these cases as the number and kind of
|
||||
template class arguments won't match those used when splitting
|
||||
<code style="white-space: normal">serialize</code> for a simple class. Use the override
|
||||
syntax instead.
|
||||
|
||||
<h3><a name="versioning">Versioning</a></h3>
|
||||
It will eventually occur that class definitions change after archives have
|
||||
been created. When a class instance is saved, the current version
|
||||
in included in the class information stored in the archive. When the class instance
|
||||
@@ -247,7 +332,8 @@ The current version of the class is assigned as a
|
||||
ar & member3;
|
||||
}
|
||||
</code></pre>
|
||||
<h3><a name="Splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
|
||||
|
||||
<h3><a name="splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
|
||||
There are times when it is inconvenient to use the same
|
||||
template for both save and load functions. For example, this might occur if versioning
|
||||
gets complex.
|
||||
@@ -353,29 +439,83 @@ 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.
|
||||
|
||||
<h3><a name="const"><code style="white-space: normal">const</code> Members</a></h3>
|
||||
Saving <code style="white-space: normal">const</code> members to an archive
|
||||
requires no special considerations.
|
||||
Loading <code style="white-space: normal">const</code> members can be addressed by using a
|
||||
<code style="white-space: normal">const_cast</code>:
|
||||
<pre><code>
|
||||
ar & const_cast<T &>(t);
|
||||
</code></pre>
|
||||
Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
|
||||
keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
|
||||
is constructed and not changed thereafter. However, this may
|
||||
be most appropriate in many cases. Ultimately, it comes down to
|
||||
the question about what <code style="white-space: normal">const</code> means in the context
|
||||
of serialization.
|
||||
<h2><a name="pointeroperators">Pointers</a></h2>
|
||||
A pointer to any class instance can be serialized with any of the archive
|
||||
save/load operators.
|
||||
<p>
|
||||
To properly save and restore an object through a pointer the
|
||||
following situations must be addressed:
|
||||
<ol>
|
||||
<li>If the same object is saved multiple times through different
|
||||
pointers, only one copy of the object need be saved.
|
||||
<li>If an object is loaded multiple times through different pointers,
|
||||
only one new object should be created and all returned pointers
|
||||
should point to it.
|
||||
<li>The system must detect the case where an object is first
|
||||
saved through a pointer then the object itself is saved.
|
||||
Without taking extra precautions, loading would result in the
|
||||
creation of multiple copies of the original object. This system detects
|
||||
this case when saving and throws an exception - see below.
|
||||
<li>An object of a derived class may be stored through a
|
||||
pointer to the base class. The true type of the object must
|
||||
be determined and saved. Upon restoration the correct type
|
||||
must be created and its address correctly cast to the base
|
||||
class. That is, polymorphic pointers have to be considered.
|
||||
<li>NULL pointers must be dectected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
|
||||
This serialization library addresses all of the above
|
||||
considerations. The process of saving and loading an object
|
||||
through a pointer is non-trivial. It can be summarized as
|
||||
follows:
|
||||
<p>Saving a pointer:
|
||||
<ol>
|
||||
<li>determine the true type of the object being pointed to.
|
||||
<li>write a special tag to the archive
|
||||
<li>if the object pointed to has not already been written
|
||||
to the archive, do so now
|
||||
</ol>
|
||||
Loading a pointer:
|
||||
<ol>
|
||||
<li>read a tag from the archive.
|
||||
<li>determine the type of object to be created
|
||||
<li>if the object has already been loaded, return it's address.
|
||||
<li>otherwise, create a new instance of the object
|
||||
<li>read the data back in using the operators described above
|
||||
<li>return the address of the newly created object.
|
||||
</ol>
|
||||
|
||||
Given that class instances are saved/loaded to/from the archive
|
||||
only once, regardless of how many times they are serialized with
|
||||
the <code style="white-space: normal"><<</code>
|
||||
and <code style="white-space: normal">>></code> operators
|
||||
<ul>
|
||||
<li>Loading the same pointer object multiple times
|
||||
results in only one object being created, thereby replicating
|
||||
the original pointer configuration.
|
||||
<li>Structures such as collections of polymorphic pointers,
|
||||
are handled with no special effort on the part of users of this library.
|
||||
</ul>
|
||||
Serialization of pointers of derived types through a pointer to the
|
||||
base class may require a little extra "help". Also, the programmer
|
||||
may desire to modify the process described above for his own reasons.
|
||||
For example, it might be desired to suppress the tracking of objects
|
||||
as it is known a priori that the application in question can never
|
||||
create duplicate objects. Serialization of pointers can be "fine tuned"
|
||||
via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
as described in
|
||||
<a target="detail" href="special.html#derivedpointers">
|
||||
another section of this manual
|
||||
</a>
|
||||
|
||||
<h3><a name="constructors">Non-Default Constructors</a></h3>
|
||||
The general procedure used for serialization of objects
|
||||
through a pointer has been described in a
|
||||
<a href="archives.html#pointeroperators">previous section</a>.
|
||||
This is implemented by code in the serialization library
|
||||
which is similar to the following:
|
||||
|
||||
Serialization of pointers is implemented in the library with code
|
||||
similar to the following:
|
||||
<pre><code>
|
||||
// load data required for construction and invoke constructor in place
|
||||
template<class Archive, class T>
|
||||
@@ -398,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<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int file_version){
|
||||
ar & member;
|
||||
ar & 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>
|
||||
@@ -414,28 +558,271 @@ the overrides would be:
|
||||
namespace boost { namespace serialization {
|
||||
template<class Archive>
|
||||
inline void save_construct_data(
|
||||
Archive & ar, const my_class * t, const unsigned long int file_version
|
||||
Archive & ar, const my_class * t, const unsigned int file_version
|
||||
){
|
||||
// save data required to construct instance
|
||||
ar << t->member;
|
||||
ar << t->m_attribute;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void load_construct_data(
|
||||
Archive & ar, my_class * t, const unsigned long int file_version
|
||||
Archive & ar, my_class * t, const unsigned int file_version
|
||||
){
|
||||
// retrieve data from archive required to construct new instance
|
||||
int m;
|
||||
ar >> m;
|
||||
int attribute;
|
||||
ar >> attribute;
|
||||
// invoke inplace constructor to initialize instance of my_class
|
||||
::new(t)my_class(m);
|
||||
::new(t)my_class(attribute);
|
||||
}
|
||||
}} // namespace ...
|
||||
</code></pre>
|
||||
In addition to the deserialization of pointers, these overrides are used
|
||||
in the deserialization of STL containers whose element type has no default
|
||||
constructor.
|
||||
<h3><a name="referencemembers"></a>Reference Members</h3>
|
||||
|
||||
<h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
|
||||
<h4><a name="registration">Registration</a></h4>
|
||||
Consider the following:
|
||||
<pre><code>
|
||||
class base {
|
||||
...
|
||||
};
|
||||
class derived_one : public base {
|
||||
...
|
||||
};
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When saving <code style="white-space: normal">b</code> what kind of object should be saved?
|
||||
When loading <code style="white-space: normal">b</code> what kind of object should be created?
|
||||
Should it be an object of class <code style="white-space: normal">derived_one</code>,
|
||||
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
|
||||
<p>
|
||||
It turns out that the kind of object serialized depends upon whether the base class
|
||||
(<code style="white-space: normal">base</code> in this case) is polymophic or not.
|
||||
If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
|
||||
virtual functions, then an object of the type <code style="white-space: normal">base</code>
|
||||
will be serialized. Information in any derived classes will be lost. If this is what is desired
|
||||
(it usually isn't) then no other effort is required.
|
||||
<p>
|
||||
|
||||
If the base class is polymorphic, an object of the most derived type
|
||||
(<code style="white-space: normal">derived_one</code>
|
||||
or <code style="white-space: normal">derived_two</code>
|
||||
in this case) will be serialized. The question of which type of object is to be
|
||||
serialized is (almost) automatically handled by the library.
|
||||
<p>
|
||||
The system "registers" each class in an archive the first time an object of that
|
||||
class it is serialized and assigns a sequential number to it. Next time an
|
||||
object of that class is serialized in that same archive, this number is written
|
||||
in the archive. So every class is identified uniquely within the archive.
|
||||
When the archive is read back in, each new sequence number is re-associated with
|
||||
the class being read. Note that this implies that "registration" has to occur
|
||||
during both save and load so that the class-integer table built on load
|
||||
is identical to the class-integer table built on save. In fact, the key to
|
||||
whole serialization system is that things are always saved and loaded in
|
||||
the same sequence. This includes "registration".
|
||||
<p>
|
||||
Expanding our previous example:
|
||||
<pre><code>
|
||||
main(){
|
||||
derived_one d1;
|
||||
derived_two d2:
|
||||
...
|
||||
ar & d1;
|
||||
ar & d2;
|
||||
// A side effect of serialization of objects d1 and d2 is that
|
||||
// the classes derived_one and derived_two become known to the archive.
|
||||
// So subsequent serialization of those classes by base pointer works
|
||||
// without any special considerations.
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When <code style="white-space: normal">b</code> is read it is
|
||||
preceded by a unique (to the archive) class identifier which
|
||||
has previously been related to class <code style="white-space: normal">derived_one</code> or
|
||||
<code style="white-space: normal">derived_two</code>.
|
||||
<p>
|
||||
If a derived class has NOT been automatically "registered" as described
|
||||
above, an <a target="detail" href="exceptions.html#unregistered_class">
|
||||
<code style="white-space: normal">unregistered_class</code></a> exception
|
||||
will be thrown when serialization is invoked.
|
||||
<p>
|
||||
This can be addressed by registering the derived class explicitly. All archives are
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type();
|
||||
</code></pre>
|
||||
So our problem could just as well be addressed by writing:
|
||||
<pre><code>
|
||||
main(){
|
||||
...
|
||||
ar.template register_type<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Note that if the serialization function is split between save and load, both
|
||||
functions must include the registration. This is required to keep the save
|
||||
and corresponding load in syncronization.
|
||||
|
||||
<h4><a name="export">Export</a></h4>
|
||||
The above will work but may be inconvenient. We don't always know which derived
|
||||
classes we are going to serialize when we write the code to serialize through
|
||||
a base class pointer. Every time a new derived class is written we have to
|
||||
go back to all the places where the base class is serialized and update the
|
||||
code.
|
||||
<p>
|
||||
So we have another method:
|
||||
<pre><code>
|
||||
#include <boost/serialization/export.hpp>
|
||||
...
|
||||
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
|
||||
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
|
||||
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
|
||||
with a class. In the above example we've used a string rendering
|
||||
of the class name. If a object of such an "exported" class is serialized
|
||||
through a pointer and is otherwise unregistered, the "export" string is
|
||||
included in the archive. When the archive
|
||||
is later read, the string literal is used to find the class which
|
||||
should be created by the serialization library.
|
||||
This permits each class to be in a separate header file along with its
|
||||
string identifier. There is no need to maintain a separate "pre-registration"
|
||||
of derived classes that might be serialized. This method of
|
||||
registration is referred to as "key export". More information on this
|
||||
topic is found in the section Class Traits -
|
||||
<a target="detail" href="traits.html#export">Export Key</a>.
|
||||
<p>
|
||||
<h4><a name="instantiation">Instantiation</a></h4>
|
||||
Registration by means of any of the above methods fulfill another role
|
||||
whose importance might not be obvious. This system relies on templated
|
||||
functions of the form <code style="white-space: normal">template<class Archive, class T></code>.
|
||||
This means that serialization code must be instantiated for each
|
||||
combination of archive and data type that is serialized in the program.
|
||||
<p>
|
||||
Polymorphic pointers of derived classes may never be referred to
|
||||
explictly by the program so normally code to serialize such classes
|
||||
would never be instantiated. So in addition to including export key
|
||||
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
|
||||
instantiates the class serialization code for all archive classes used
|
||||
by the program.
|
||||
|
||||
<h4><a name="selectivetracking">Selective Tracking</a></h4>
|
||||
Whether or not an object is tracked is determined by its
|
||||
<a target="detail" href="traits.html#tracking">object tracking trait</a>.
|
||||
The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
|
||||
That is, track objects if and only if they are serialized through pointers anywhere
|
||||
in the program. Any objects that are "registered" by any of the above means are presumed
|
||||
to be serialized through pointers somewhere in the program and therefore
|
||||
would be tracked. In certain situations this could lead to an inefficiency.
|
||||
Suppose we have a class module used by multiple programs. Because
|
||||
some programs serializes polymorphic pointers to objects of this class, we
|
||||
<a target="detail" href="traits.html#export">export</a> a class
|
||||
identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
|
||||
class header. When this module is included by another program,
|
||||
objects of this class will always be tracked even though it
|
||||
may not be necessary. This situation could be addressed by using
|
||||
<a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
in those programs.
|
||||
<p>
|
||||
It could also occur that even though a program serializes through
|
||||
a pointer, we are more concerned with efficiency than avoiding the
|
||||
the possibility of creating duplicate objects. It could be
|
||||
that we happen to know that there will be no duplicates. It could
|
||||
also be that the creation of a few duplicates is benign and not
|
||||
worth avoiding given the runtime cost of tracking duplicates.
|
||||
Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
can be used.
|
||||
<h4><a name="runtimecasting">Runtime Casting</a></h4>
|
||||
In order to properly translate between base and derived pointers
|
||||
at runtime, the system requires each base/derived pair be found
|
||||
in a table. A side effect of serializing a base object with
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
is to ensure that the base/derived pair is added to the table
|
||||
before the <code style="white-space: normal">main</code> function is entered.
|
||||
This is very convenient and results in a clean syntax. The only
|
||||
problem is that it can occur where a derived class serialized
|
||||
through a pointer has no need to invoke the serialization of
|
||||
its base class. In such a case, there are two choices. The obvious
|
||||
one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
|
||||
and specify an empty function for the base class serialization.
|
||||
The alternative is to "register" the Base/Derived relationship
|
||||
explicitly by invoking the template
|
||||
<code style="white-space: normal">void_cast_register<Derived, Base>();</code>.
|
||||
Note that this usage of the term "register" is not related
|
||||
to its usage in the previous section. Here is an example of how this is done:
|
||||
<pre><code>
|
||||
#include <sstream>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class base {
|
||||
friend class boost::serialization::access;
|
||||
//...
|
||||
// only required when using method 1 below
|
||||
// no real serialization required - specify a vestigial one
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){}
|
||||
};
|
||||
|
||||
class derived : public base {
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<derived, base>(
|
||||
static_cast<derived *>(NULL),
|
||||
static_cast<base *>(NULL)
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
base *b;
|
||||
ar >> b;
|
||||
}
|
||||
</code></pre>
|
||||
<p>
|
||||
|
||||
In order for this template to be invoked in code compiled by non-conforming
|
||||
compilers, the following syntax may be used:
|
||||
<pre><code>
|
||||
boost::serialization::void_cast_register(
|
||||
static_cast<Derived *>(NULL),
|
||||
static_cast<Base *>(NULL)
|
||||
);
|
||||
</code></pre>
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
|
||||
<h3><a name="references"></a>References</h3>
|
||||
Classes that contain reference members will generally require
|
||||
non-default constructors as references can only be set when
|
||||
an instance is constructed. The example of the previous section
|
||||
@@ -493,58 +880,11 @@ inline void load_construct_data(
|
||||
}} // namespace ...
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="templates"></a>Templates</h3>
|
||||
Implementation serialization for templates is exactly the same process
|
||||
as for normal classes and requires no additional considerations. Among
|
||||
other things, this implies that serialization of compositions of templates
|
||||
are automatically generateded when required if serialization of the
|
||||
component templates is defined. For example, this library includes
|
||||
definition of serialization for <code style="white-space: normal">boost::shared_ptr<T></code> and for
|
||||
<code style="white-space: normal">std::list<T></code>. If I have defined serialization for my own
|
||||
class <code style="white-space: normal">my_t</code>, then serialization for
|
||||
<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
|
||||
for use.
|
||||
<p>
|
||||
See for an example that shows how this idea might be implemented for your own
|
||||
class templates, see
|
||||
<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
|
||||
demo_auto_ptr.cpp</a>.
|
||||
This shows how non-intrusive serialization
|
||||
for the template <code style="white-space: normal">auto_ptr</code> from the standard library
|
||||
can be implemented.
|
||||
<p>
|
||||
A somewhat trickier addition of serialization to a standard template
|
||||
can be found in the example
|
||||
<a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
|
||||
shared_ptr.hpp
|
||||
</a>
|
||||
<!--
|
||||
Only the most minimal change to
|
||||
<a href="../../../boost/serialization/shared_count.hpp" target="shared_count_hpp">
|
||||
shared_count.hpp</a>
|
||||
(to gain access to some private members) was necessary to achieve this.
|
||||
This should demonstrate how easy it is to non-intrusively
|
||||
implement serialization to any data type or template.
|
||||
-->
|
||||
<p>
|
||||
In the specification of serialization for templates, its common
|
||||
to split <code style="white-space: normal">serialize</code>
|
||||
into a <code style="white-space: normal">load/save</code> pair.
|
||||
Note that the convenience macro described
|
||||
<a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
|
||||
isn't helpful in these cases as the number and kind of
|
||||
template class arguments won't match those used when splitting
|
||||
<code style="white-space: normal">serialize</code> for a simple class. Use the override
|
||||
syntax instead.
|
||||
|
||||
<h2><a href="traits.html">Class Serialization Traits</a></h2>
|
||||
|
||||
<h2><a href="wrappers.html">Serialization Wrappers</a></h2>
|
||||
|
||||
|
||||
<h2><a name="implementations"></a>Serialization Implementations Included in the Library</h2>
|
||||
This library includes code to serialize C style arrays of other
|
||||
serializable types. That is, if T is a serializable type, then the following
|
||||
<h3><a name="arrays"></a>Arrays</h3>
|
||||
If <code style="white-space: normal">T</code> is a serializable type,
|
||||
then any native C++ array of type T is a serializable type.
|
||||
That is, if <code style="white-space: normal">T</code>
|
||||
is a serializable type, then the following
|
||||
is automatically available and will function as expected:
|
||||
<pre><code>
|
||||
T t[4];
|
||||
@@ -552,6 +892,12 @@ ar << t;
|
||||
...
|
||||
ar >> t;
|
||||
</code></pre>
|
||||
|
||||
<h2><a href="traits.html">Class Serialization Traits</a></h2>
|
||||
|
||||
<h2><a href="wrappers.html">Serialization Wrappers</a></h2>
|
||||
|
||||
<h2><a name="models"></a>Models - Serialization Implementations Included in the Library</h2>
|
||||
The facilities described above are sufficient to implement
|
||||
serialization for all STL containers. In fact, this has been done
|
||||
and has been included in the library. For example, in order to use
|
||||
@@ -566,6 +912,17 @@ rather than
|
||||
Since the former includes the latter, this all that is necessary.
|
||||
The same holds true for all STL collections as well as templates
|
||||
required to support them (e.g. <code style="white-space: normal">std::pair</code>).
|
||||
<p>
|
||||
As of this writing, the library contains serialization of the following boost clases:
|
||||
<ul>
|
||||
<li>optional
|
||||
<li>variant
|
||||
<li>scoped_ptr
|
||||
<li>shared_ptr
|
||||
<li>auto_ptr (demo)
|
||||
</ul>
|
||||
Others are being added to the list so check the boost files section and headers for
|
||||
new implementations!
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
+11
-2
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Template serialization - shared_ptr</title>
|
||||
@@ -193,8 +193,8 @@ base object serialization with:
|
||||
// register the relationship between each derived class
|
||||
// its polymorphic base
|
||||
void_cast_register<
|
||||
boost::detail::sp_counted_base,
|
||||
boost::detail::sp_counted_base_impl<P, D>
|
||||
boost::detail::sp_counted_base,
|
||||
>();
|
||||
</code></pre>
|
||||
and we don't have to include a trival serializer for <code style="white-space: normal">sp_counted_base</code>
|
||||
@@ -212,6 +212,15 @@ this implementation are:
|
||||
<li>Exception handling hasn't been exhaustively considered.
|
||||
<li>Other issues yet to be discovered.
|
||||
</ul>
|
||||
One thing that has been considered is export of shared_ptr. The header which
|
||||
declares shared pointer serialization includes some special macros for exporting
|
||||
shared pointers:
|
||||
<code><pre>
|
||||
BOOST_SHARED_POINTER_EXPORT(T)
|
||||
BOOST_SHARED_POINTER_EXPORT_GUID(T, K)
|
||||
</pre></code>
|
||||
These are specialize versions of the macros used for exporting classes serialized through raw pointers.
|
||||
<p>
|
||||
Clearly, complete, correct and exception safe serialization of smart pointers is going to
|
||||
be a challenge. I hope that this implementation provides a useful
|
||||
starting point for such an effort.
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Template serialization - shared_ptr</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisited</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
The previously described serialization of <code style="white-space: normal">shared_ptr</code>
|
||||
illustrates the straightforward way of serializing a moderately complicated class structure.
|
||||
Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<ul>
|
||||
<li>It was dependent on the Boost implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
The <code style="white-space: normal">shared_ptr</code> interface has been included
|
||||
in <code style="white-space: normal">std::tr1</code> and may someday be included in the standard
|
||||
C++ library. An implementation which depends only on the public interface can be guaranteed to
|
||||
function with any other future implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
<li>It required extra macros for export.
|
||||
</ul>
|
||||
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void save(
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
const T * t_ptr = t.get();
|
||||
// just serialize the underlying raw pointer
|
||||
ar <<: boost::serialization::make_nvp("px", t_ptr);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
T* r;
|
||||
// recover the underlying raw pointer
|
||||
ar >> boost::serialization::make_nvp("px", r);
|
||||
|
||||
// To Do - match up with other shared pointers which
|
||||
// use this same raw pointer.
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
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 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>.
|
||||
</ol>
|
||||
|
||||
The result of this effort can be found in
|
||||
<a target = serialization_shared_ptr href="../../../boost/serialization/shared_ptr.hpp">
|
||||
<code style="white-space: normal">boost::serialization::shared_ptr.hpp</code>
|
||||
</a>
|
||||
<p>
|
||||
Note that if your code needs to read archives created under boost version 1.32, you will
|
||||
have to include the following
|
||||
|
||||
<pre><code>
|
||||
#include <boost/serialization/shared_ptr_132.hpp>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
</code></pre>
|
||||
rather than just
|
||||
<pre><code>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
</code></pre>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,241 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - singleton</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">singleton</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#motivation">Motivation</a>
|
||||
<dt><a href="#features">Features</a>
|
||||
<dt><a href="#classinterface">Class Interface</a>
|
||||
<dt><a href="#requirements">Requirements</a>
|
||||
<dt><a href="#example">Examples</a>
|
||||
<dt><a href="#multithreading">Multi-Threading</a>
|
||||
</dl>
|
||||
|
||||
<h3><a name="motivation">Motivation</a></h3>
|
||||
The serialization library relies on the existence of a number
|
||||
of static variables and tables to store information related
|
||||
to runtime types. Examples are tables which relate exported
|
||||
names to types and tables which relate base classes to derived
|
||||
classes. Construction, destruction and usage of these variables
|
||||
requires consideration of the following issues:
|
||||
<ul>
|
||||
<li>Some static data variables and constants entries refer to others.
|
||||
The sequence of initialization cannot be arbitrary but must be in proper
|
||||
sequence.</li>
|
||||
<li>A number of static variables aren't referred explicitly and, without
|
||||
special precautions, will be stripped by most code optimizers</li>
|
||||
<li>Many of these variables are created by templates and special care must
|
||||
be taken to be sure that they are instantiated</li>
|
||||
<li>In a multi-threading system, its possible that these static variables
|
||||
will be accessed concurrently by separate threads. This would create a
|
||||
race condition with unpredictabe behavior</li>
|
||||
</ul>
|
||||
This singleton class addresses all of the above issues.
|
||||
|
||||
<h3><a name="features">Features</a></h3>
|
||||
This singleton implementation has the following features:
|
||||
<ul>
|
||||
<li>
|
||||
Any instance will be constructed before any attempt is made to access it.</li>
|
||||
<li>
|
||||
Any instance created with a template is guarenteed to be instantiated.
|
||||
<li>
|
||||
Regardless of whether or not an instance has been explicitly
|
||||
referred to, it will not be stripped by the optimizer when the
|
||||
executable is built in release mode.
|
||||
<li>
|
||||
All instances are constructed before
|
||||
<code style="white-space: normal">main</code> is called
|
||||
regardless of where they might be referenced within the program.
|
||||
In a multi-tasking system, this guarentees that there will be no
|
||||
race conditions during the construction of any instance. No
|
||||
thread locking is required to guarentee this.
|
||||
<li>
|
||||
The above implies that any <code style="white-space: normal">const</code>
|
||||
instances are thread-safe during the whole program. Again, no
|
||||
thread locking is required.
|
||||
<li>
|
||||
If a mutable instance is created, and such an instance is modified
|
||||
after main is called in a mult-threading system, there exists
|
||||
the possibility that a race condition will occur. The serialization
|
||||
library takes care that in the few places where a mutable
|
||||
singleton is required, it is not altered after
|
||||
<code style="white-space: normal">main</code> is called.
|
||||
For a more general purpose usage, thread locking on this
|
||||
singleton could easily be implemented. But as the serialization
|
||||
library didn't require it, it wasn't implemented.
|
||||
</ul>
|
||||
|
||||
<h3><a name="classinterface">Class Interface</a></h3>
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template <class T>
|
||||
class singleton : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
static const T & get_const_instance();
|
||||
static T & get_mutable_instance();
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const T & get_const_instance();</code></pre></h4></dt>
|
||||
<dd>
|
||||
Retrieve a constant reference to the singleton for this type.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static T & get_mutable_instance();</code></pre></h4></dt>
|
||||
<dd>
|
||||
Retrieve a mutable reference to the singleton for this type.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="requirements">Requirements</a></h3>
|
||||
In order to be used as
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
, the type T must be default constructable.
|
||||
It doesn't require static variables - though it may have them.
|
||||
Since the library guarentees that only one instance of
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
and all accesss is through the above static interface
|
||||
functions, common member functions of T become
|
||||
the functional equivalent of
|
||||
<code style="white-space: normal">static</code> functions.
|
||||
|
||||
<h3><a name="example">Examples</a></h3>
|
||||
There are at least two different ways to use this class template.
|
||||
Both are used in the serialization library.
|
||||
<p>
|
||||
The first way is illustrated by and excerpt from the file
|
||||
<code style="white-space: normal"><a target="extended_type_info" href="../src/extended_type_info.cpp">extended_type_info.cpp</a></code>.
|
||||
which contains the following code:
|
||||
|
||||
<pre><code>
|
||||
typedef std::set<const extended_type_info *, key_compare> ktmap;
|
||||
...
|
||||
void
|
||||
extended_type_info::key_register(const char *key) {
|
||||
...
|
||||
result = singleton<ktmap>::get_mutable_instance().insert(this);
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
Just by referring to the singleton instance anywhere in the program
|
||||
will guarentee that one and only one instance for the specified
|
||||
type (<code style="white-space: normal">ktmap</code> in this example)
|
||||
will exist throughout the program. There is no need for anyother
|
||||
declaration or definition.
|
||||
<p>
|
||||
A second way is to use
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
as one of the base classes of the type. This is illustrated by a simplified
|
||||
excerpt from
|
||||
<a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info_typeid.hpp
|
||||
</code>
|
||||
</a>
|
||||
|
||||
<pre><code>
|
||||
template<class T>
|
||||
class extended_type_info_typeid :
|
||||
public detail::extended_type_info_typeid_0,
|
||||
public singleton<extended_type_info_typeid<const T> >
|
||||
{
|
||||
friend class singleton<extended_type_info_typeid<const T> >;
|
||||
private:
|
||||
// private constructor to inhibit any existence other than the
|
||||
// static one. Note: not all compilers support this !!!
|
||||
extended_type_info_typeid() :
|
||||
detail::extended_type_info_typeid_0()
|
||||
{
|
||||
type_register(typeid(T));
|
||||
}
|
||||
~extended_type_info_typeid(){}
|
||||
...
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
This usage will permit a more natural syntax to be used:
|
||||
<pre><code>
|
||||
extended_type_info_typeid<T>::get_const_instance()
|
||||
</code></pre>
|
||||
|
||||
Again, including one or more of the above statements anywhere
|
||||
in the program will guarentee that one and only one instance
|
||||
is created and referred to.
|
||||
|
||||
<h3><a name="multithreading">Multi-Threading</a></h3>
|
||||
This singleton CAN be safely used in multi-threading applications if one
|
||||
is careful follow a simple rule:
|
||||
<p>
|
||||
<b>Do not call get_mutable_instance when more than one thread is running!</b>
|
||||
<p>
|
||||
All singletons used in the serialization library follow this rule.
|
||||
In order to help detect accidental violations of this rule there
|
||||
exists an singleton lock/unlock functions.
|
||||
<pre><code>
|
||||
boost::serialization::global_lock::get_mutable_instance().lock();
|
||||
boost::serialization::global_lock::get_mutable_instance().unlock();
|
||||
</code></pre>
|
||||
In a program compiled for debug, any invocation of
|
||||
<code style="white-space: normal">get_mutable_instance()</code>
|
||||
while the library is in a "locked" state will trap in an assertion.
|
||||
The global_lock state is initialized as "unlocked" to permit
|
||||
alteration of static variables before
|
||||
<code style="white-space: normal">main</code> is called. All
|
||||
serialization tests invoke <code style="white-space: normal">lock()</code>
|
||||
at the start of the progam. For programs compiled in release
|
||||
mode these functions have no effect.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
|
||||
+280
-248
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Special Considerations</title>
|
||||
@@ -26,13 +26,6 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#registration">Registration</a>
|
||||
<dt><a href="#instantiation">Instantiation</a>
|
||||
<dt><a href="#selectivetracking">Selective Tracking</a>
|
||||
<dt><a href="#runtimecasting">Runtime Casting</a>
|
||||
</dl>
|
||||
<dt><a href="#objecttracking">Object Tracking</a>
|
||||
<dt><a href="#classinfo">Class Information</a>
|
||||
<dt><a href="#portability">Archive Portability</a>
|
||||
@@ -42,241 +35,24 @@ 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>
|
||||
<h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
|
||||
<h4><a name="registration">Registration</a></h4>
|
||||
Consider the following:
|
||||
<pre><code>
|
||||
class base {
|
||||
...
|
||||
};
|
||||
class derived_one : public base {
|
||||
...
|
||||
};
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When loading <code style="white-space: normal">b</code> what kind of object should be created?
|
||||
An object of class <code style="white-space: normal">derived_one</code>,
|
||||
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
|
||||
<p>
|
||||
If this situation is not addressed by one of the methods described below,
|
||||
an <a target="detail" href="exceptions.html#unregistered_class">
|
||||
<code style="white-space: normal">unregistered_class</code></a> exception will be thrown when serialization is
|
||||
invoked.
|
||||
<p>Many times this situation is resolved automatically by the serialization
|
||||
library.
|
||||
<p>
|
||||
The system "registers" each class in an archive the first time an object of that
|
||||
class it is serialized and assigns a sequential number to it. Next time an
|
||||
object of that class is serialized in that same archive, this number is written
|
||||
in the archive. So every class is identified uniquely within the archive.
|
||||
When the archive is read back in, each new sequence number is re-associated with
|
||||
the class being read. Note that this implies that "registration" has to occur
|
||||
during both save and load so that the class-integer table built on load
|
||||
is identical to the class-integer table built on save. In fact, the key to
|
||||
whole serialization system is that things are always saved and loaded in
|
||||
the same sequence. This includes "registration"
|
||||
<p>
|
||||
In many situations the problem never comes up. Consider:
|
||||
<pre><code>
|
||||
main(){
|
||||
derived_one d1;
|
||||
derived_two d2:
|
||||
...
|
||||
ar >> d1;
|
||||
ar >> d2;
|
||||
// A side effect of serialization of objects d1 and d2 is that
|
||||
// the classes derived_one and derived_two become known to the archive.
|
||||
// So subsequent serialization of those classes by base pointer works
|
||||
// without any special considerations.
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Here, the problem doesn't present itself. When <code style="white-space: normal">b</code> is read it is
|
||||
preceded by a unique (to the archive) class identifier which
|
||||
has previously been related to class <code style="white-space: normal">derived_one</code> or
|
||||
<code style="white-space: normal">derived_two</code>.
|
||||
<p>
|
||||
If a derived class hasn't been automatically "registered" as described
|
||||
above, we have the option of registering it explicitly. All archives are
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type();
|
||||
</code></pre>
|
||||
So our problem could just as well be addressed by writing:
|
||||
<pre><code>
|
||||
main(){
|
||||
...
|
||||
ar.template register_type<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Note that if the serialization function is split between save and load, both
|
||||
functions must include the registration. This is required to keep the save
|
||||
and corresponding load in syncronization.
|
||||
<p>
|
||||
This will work but may be inconvenient. We don't always know which derived
|
||||
classes we are going to serialize when we write the code to serialize through
|
||||
a base class pointer. Every time a new derived class is written we have to
|
||||
go back to all the places where the base class is serialized and update the
|
||||
code.
|
||||
<p>
|
||||
So we have another method:
|
||||
<pre><code>
|
||||
#include <boost/serialization/export.hpp>
|
||||
...
|
||||
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
|
||||
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
|
||||
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
|
||||
with a class. In the above example we've used a string rendering
|
||||
of the class name. If a object of such an "exported" class is serialized
|
||||
through a pointer and is otherwise unregistered, the "export" string is
|
||||
included in the archive. When the archive
|
||||
is later read, the string literal is used to find the class which
|
||||
should be created by the serialization library.
|
||||
This permits each class to be in a separate header file along with its
|
||||
string identifier. There is no need to maintain a separate "pre-registration"
|
||||
of derived classes that might be serialized. This method of
|
||||
registration is referred to as "key export". More information on this
|
||||
topic is found in the section Class Traits -
|
||||
<a target="detail" href="traits.html#export">Export Key</a>.
|
||||
<p>
|
||||
<h4><a name="instantiation">Instantiation</a></h4>
|
||||
Registration by means of any of the above methods fulfill another role
|
||||
whose importance might not be obvious. This system relies on templated
|
||||
functions of the form <code style="white-space: normal">template<class Archive, class T></code>.
|
||||
This means that serialization code must be instantiated for each
|
||||
combination of archive and data type that is serialized in the program.
|
||||
<p>
|
||||
Polymorphic pointers of derived classes may never be referred to
|
||||
explictly by the program so normally code to serialize such classes
|
||||
would never be instantiated. So in addition to including export key
|
||||
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
|
||||
instantiates the class serialization code for all archive classes used
|
||||
by the program.
|
||||
<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
|
||||
<a target="detail" href="traits.html#tracking">object tracking trait</a>.
|
||||
The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
|
||||
That is, track objects if and only if they are serialized through pointers anywhere
|
||||
in the program. Any objects that are "registered" by any of the above means are presumed
|
||||
to be serialized through pointers somewhere in the program and therefore
|
||||
would be tracked. In certain situations this could lead to an inefficiency.
|
||||
Suppose we have a class module used by multiple programs. Because
|
||||
some programs serializes polymorphic pointers to objects of this class, we
|
||||
<a target="detail" href="traits.html#export">export</a> a class
|
||||
identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
|
||||
class header. When this module is included by another program,
|
||||
objects of this class will always be tracked even though it
|
||||
may not be necessary. This situation could be addressed by using
|
||||
<a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
in those programs.
|
||||
<p>
|
||||
It could also occur that even though a program serializes through
|
||||
a pointer, we are more concerned with efficiency than avoiding the
|
||||
the possibility of creating duplicate objects. It could be
|
||||
that we happen to know that there will be no duplicates. It could
|
||||
also be that the creation of a few duplicates is benign and not
|
||||
worth avoiding given the runtime cost of tracking duplicates.
|
||||
Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
can be used.
|
||||
<h4><a name="runtimecasting">Runtime Casting</a></h4>
|
||||
In order to properly translate between base and derived pointers
|
||||
at runtime, the system requires each base/derived pair be found
|
||||
in a table. A side effect of serializing a base object with
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
is to ensure that the base/derived pair is added to the table
|
||||
before the <code style="white-space: normal">main</code> function is entered.
|
||||
This is very convenient and results in a clean syntax. The only
|
||||
problem is that it can occur where a derived class serialized
|
||||
through a pointer has no need to invoke the serialization of
|
||||
its base class. In such a case, there are two choices. The obvious
|
||||
one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
|
||||
and specify an empty function for the base class serialization.
|
||||
The alternative is to "register" the Base/Derived relationship
|
||||
explicitly by invoking the template
|
||||
<code style="white-space: normal">void_cast_register<Base, Derived>();</code>.
|
||||
Note that this usage of the term "register" is not related
|
||||
to its usage in the previous section. Here is an example of how this is done:
|
||||
<pre><code>
|
||||
#include <sstream>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class base {
|
||||
friend class boost::serialization::access;
|
||||
//...
|
||||
// only required when using method 1 below
|
||||
// no real serialization required - specify a vestigial one
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){}
|
||||
};
|
||||
|
||||
class derived : public base {
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<base, derived>();
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
base *b;
|
||||
ar >> b;
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="objecttracking">Object Tracking</a></h3>
|
||||
Depending on how the class is used and other factors, serialized objects
|
||||
may be tracked by memory address. This prevents the same object from being
|
||||
written to or read from an archive multiple times. This could cause problems in
|
||||
progams where the copies of different objects are serialized from the same address.
|
||||
written to or read from an archive multiple times. These stored addresses
|
||||
can also be used to delete objects created during a loading process
|
||||
that has been interrupted by throwing of an exception.
|
||||
<p>
|
||||
This could cause problems in
|
||||
progams where the copies of different objects are saved from the same address.
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
@@ -309,25 +85,57 @@ void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
}
|
||||
</code></pre>
|
||||
which will compile and run without problem.
|
||||
<p>
|
||||
The usage of <code style="white-space: normal">const</code> by the output archive operators
|
||||
will ensure that the process of serialization doesn't
|
||||
change the state of the objects being serialized. An attempt to do this
|
||||
would constitute augmentation of the concept of saving of state with
|
||||
some sort of non-obvious side effect. This would almost surely be a mistake
|
||||
and a likely source of very subtle bugs. As described
|
||||
<a target="detail" href="traits.html#tracking">above</a>,
|
||||
addresses of objects serialized as pointers are stored in memory to
|
||||
prevent saving/loading of duplicate objects. These stored addresses
|
||||
can also be used to delete objects created during a loading process
|
||||
that has been interrupted by throwing of an exception. By default, code
|
||||
to implement this tracking is instantiated if and only if an object of the class
|
||||
is serialized through a pointer. If it is known a priori that no pointer
|
||||
and a likely source of very subtle bugs.
|
||||
<p>
|
||||
Unfortunately, implementation issues currently prevent the detection of this kind of
|
||||
error when the data item is wrapped as a name-value pair.
|
||||
<p>
|
||||
A similar problem can occur when different objects are loaded to and address
|
||||
which is different from the final location:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
ar >> x;
|
||||
std::m_set.insert(x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
In this case, the address of <code>x</code> is the one that is tracked rather than
|
||||
the address of the new item added to the set. Left unaddressed
|
||||
this will break the features that depend on tracking such as loading object through a pointer.
|
||||
Subtle bugs will be introduced into the program. This can be
|
||||
addressed by altering the above code thusly:
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void load(boost::basic_iarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
ar >> x;
|
||||
std::pair<std::set::const_iterator, bool> result;
|
||||
result = std::m_set.insert(x);
|
||||
ar.reset_object_address(& (*result.first), &x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
This will adjust the tracking information to reflect the final resting place of
|
||||
the moved variable and thereby rectify the above problem.
|
||||
<p>
|
||||
If it is known a priori that no pointer
|
||||
values are duplicated, overhead associated with object tracking can
|
||||
be eliminated by setting the object tracking class serialization trait
|
||||
appropriately.
|
||||
<p>
|
||||
By definition, data types designated primitive by
|
||||
By default, data types designated primitive by
|
||||
<a target="detail" href="traits.html#level">Implementation Level</a>
|
||||
class serialization trait are never tracked. If it is desired to
|
||||
track a shared primitive object through a pointer (e.g. a
|
||||
@@ -345,6 +153,7 @@ redundant save/load operations.
|
||||
<pre><code>
|
||||
BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
|
||||
</code></pre>
|
||||
|
||||
<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
|
||||
@@ -404,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"><boost/cstdint.hpp></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:
|
||||
@@ -419,7 +238,7 @@ struct my_wrapper {
|
||||
class my_class {
|
||||
wchar_t a;
|
||||
short unsigned b;
|
||||
template<<class Archive>
|
||||
template<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
@@ -478,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 <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
... // other archives
|
||||
|
||||
#include "a.hpp" // header declaration for class a
|
||||
BOOST_CLASS_EXPORT(a)
|
||||
... // other class headers and exports
|
||||
</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 <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
... // other archives
|
||||
|
||||
#include "a.hpp" // header declaration for class a
|
||||
|
||||
// this class has a default constructor
|
||||
BOOST_SERIALIZATION_FACTORY_0(a)
|
||||
// as well as one that takes one integer argument
|
||||
BOOST_SERIALIZATION_FACTORY_1(a, int)
|
||||
|
||||
// specify the GUID for this class
|
||||
BOOST_CLASS_EXPORT(a)
|
||||
... // other class headers and exports
|
||||
</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>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - <code style="white-space: normal">state_saver</code></title>
|
||||
@@ -65,7 +65,7 @@ void func(A & a)
|
||||
</pre></code>
|
||||
|
||||
<h3>History</h3>
|
||||
This is a generalization if Daryle Walker's
|
||||
This is a generalization of Daryle Walker's
|
||||
<a href="../../../libs/io/doc/ios_state.html">io_state_saver</a> library.
|
||||
<p>
|
||||
Robert Ramey made an initial version for the serialization library.
|
||||
|
||||
+20
-2
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
@@ -25,7 +25,25 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
To do.
|
||||
|
||||
The header <code><boost/static_warning.hpp></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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - To Do</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">To Do</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#portablebinaryarchives">Portable Binary Archives</a></dt>
|
||||
<dt><a href="#performancetesting">Performance Testing and Profiling</a></dt>
|
||||
<dt><a href="#backversioning">Back Versioning</a></dt>
|
||||
<dt><a href="#nortti">Testing for Environments with No RTTI</a></dt>
|
||||
<dt><a href="new_case_studies.htm">Additional Case Studies</a></dt>
|
||||
</dl>
|
||||
|
||||
These are enhancements that the serialization library needs but have not been done.
|
||||
Some of these projects, though tricky, are not huge and would be suitable
|
||||
for someone who has a limited time to spend on them. In particular, they
|
||||
might be of interest as student projects such as the Google Summer of Code.
|
||||
|
||||
<h2><a name="portablebinaryarchives"></a>Portable Binary Archives</h2>
|
||||
Currently there is a portable binary archive in the examples directory.
|
||||
It is not regularly submitted to the exhaustive boost testing regimen
|
||||
but it is tested occasionally and has been used in production code.
|
||||
<p>
|
||||
Its missing the following:
|
||||
<ul>
|
||||
<li>Addition of portable floating point types. This is not trivial. In addition to
|
||||
handling floating point types of varying sizes, It requires
|
||||
handling invalid floating point numbers (NaNs) in a portable manner.
|
||||
<li>Some way to test archive portability within the Boost testing regimen.
|
||||
<li>Integration into the Boost testing similar to the other archive classes.
|
||||
</ul>
|
||||
|
||||
<h2><a name="performancetesting"></a>Performance Testing and Profiling</h2>
|
||||
|
||||
I've managed to setup performance profiling using the following:
|
||||
<ul>
|
||||
<li>current (as I write this) Boost.Build tools.
|
||||
<li>the gcc compiler.
|
||||
<li>and a shell script - profile.sh
|
||||
<li>library_status program from the tools/regression/src directory
|
||||
</ul>
|
||||
Invoking profile script produces a
|
||||
<a href=performance_status.html">table</a>
|
||||
which shows the results of each test and links to the actual
|
||||
profile.
|
||||
<p>
|
||||
The first thing I did was include some of the serialization library tests.
|
||||
It became immediatly apparent that these tests were totally unsuitable
|
||||
for performance testing and that new tests needed to be written for this
|
||||
purpose. These tests would highlight the location of any performance
|
||||
bottlenecks in the serialization library. Whenever I've subjected my
|
||||
code in the past to this type of analysis, I've always been suprised
|
||||
to find bottlenecks in totally unanticipated places and fixing those
|
||||
has always lead to large improvements in performance. I expect that
|
||||
this project would have a huge impact on the utility of the serialization
|
||||
library.
|
||||
|
||||
<h2><a name="backversioning"></a>Back Versioning</h2>
|
||||
|
||||
It has been suggested that a useful feature of the library would be
|
||||
the ability to create "older versions" of archives. Currently,
|
||||
the library permits one make programs that are guarenteed
|
||||
the ability to load archives with classes of a previous version.
|
||||
But there is not way to save classes in accordance with a
|
||||
previous version. At first I dismissed this a a huge project
|
||||
with small demand. A cursory examination of the code revealed
|
||||
that this would not be very difficult. It would require some
|
||||
small changes in code and some additional tests. Also it
|
||||
would require special treatment in the documentation - perhaps
|
||||
a case study.
|
||||
|
||||
|
||||
<h2><a name="nortti"></a>Environments without RTTI</h2>
|
||||
|
||||
I note that some have commented that this library requires RTTI.
|
||||
This is not strictly true. The examples and almost all the
|
||||
tests presume the existence of RTTI. But it should be possible
|
||||
to use the library without it. The example used for testing is an
|
||||
<code style="white-space: normal">extended_typeinfo</code>
|
||||
implemenation which presumes that all classes names have been exported.
|
||||
So, to make this library compatible for platforms without RTTI,
|
||||
a set of tests, examples and new manual section would have to be created
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2008
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+146
-31
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Class Serialization Traits</title>
|
||||
@@ -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
|
||||
@@ -171,12 +172,24 @@ A corresponding macro is defined so that we can use:
|
||||
<pre><code>
|
||||
BOOST_CLASS_TRACKING(my_class, boost::serialization::track_never)
|
||||
</code></pre>
|
||||
The default value for primitive types is <code style="white-space: normal">track_never</code>.
|
||||
<p>
|
||||
The default value for all other types is <code style="white-space: normal">track_selectivly</code>.
|
||||
That is addresses of serialized objects are tracked if and only if
|
||||
an object of the same type is anywhere in the program serialized
|
||||
through a pointer.
|
||||
Default tracking traits are:
|
||||
<ul>
|
||||
<li>For primitive, <code style="white-space: normal">track_never</code>.
|
||||
<li>For pointers, <code style="white-space: normal">track_never</code>.
|
||||
That is, addresses of addresses are not tracked by default.
|
||||
<li>All current serialization wrappers such as <code style="white-space: normal">boost::serialization::nvp</code>,
|
||||
<code style="white-space: normal">track_never</code>.
|
||||
<li>For all other types, <code style="white-space: normal">track_selectively</code>.
|
||||
That is addresses of serialized objects are tracked if and only if
|
||||
one or more of the following is true:
|
||||
<ul>
|
||||
<li>an object of this type is anywhere in the program serialized
|
||||
through a pointer.
|
||||
<li>the class is explicitly "exported" - see below.
|
||||
<li>the class is explicitly "registered" in the archive
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
The default behavior is almost always the most convenient one. However,
|
||||
there a few cases where it would be desirable to override the
|
||||
@@ -229,21 +242,20 @@ BOOST_CLASS_EXPORT_GUID(my_class, "my_class")
|
||||
</code></pre>
|
||||
If the an external name is required somewhere in the program and none
|
||||
has been assigned, a static assertion will be invoked.
|
||||
|
||||
<h3><a name="abstract">Abstract</a></h3>
|
||||
When serializing an object through a pointer to its base class
|
||||
and that base class is abstract (i.e. has at least one virtual function
|
||||
assigned a value of 0), A compile error will be emitted. This is
|
||||
addressable in one over several ways:
|
||||
<ul>
|
||||
<li>remove the =0 in the base classes so that the base class is no
|
||||
longer abstract.
|
||||
<li>implement is_abstract for your compiler. (code written according to
|
||||
the C++ standard is included with this library. But it is known to fail
|
||||
on several compilers.
|
||||
<li>use the macro <code style="white-space: normal">BOOST_IS_ABSTRACT(my_class)</code> to indicate
|
||||
that the class is an abstract base class. This will cause the compiler
|
||||
to avoid generating code that causes this error.
|
||||
</ul>
|
||||
When serializing an object through a pointer to its base class,
|
||||
the library needs to determine whether or not the bas is abstract
|
||||
(i.e. has at least one virtual function). The library uses the
|
||||
type trait macro <code style="white-space: normal">BOOST_IS_ABSTRACT(T)</code>
|
||||
to do this. Not all compilers support this type trait and corresponding
|
||||
macro. To address this, the macro <code style="white-space: normal">
|
||||
BOOST_SERIALIZATION_ASSUME_ABSTRACT(T)</code> has been
|
||||
implemented to permit one to explicitly indicate that a specified
|
||||
type is in fact abstract. This will guarentee that
|
||||
<code style="white-space: normal">BOOST_IS_ABSTRACT</code>
|
||||
will return the correct value for all compilers.
|
||||
|
||||
<h3><a name="typeinfo">Type Information Implementation</a></h3>
|
||||
This last trait is also related to the serialization of objects
|
||||
through a base class pointer. The implementation of this facility
|
||||
@@ -284,8 +296,8 @@ target="extended_type_info_rtti_hpp">extended_type_info_no_rtti.hpp</a>.
|
||||
By invoking the macro:
|
||||
<pre><code>
|
||||
BOOST_CLASS_TYPE_INFO(
|
||||
derived_class,
|
||||
extended_type_info_no_rtti<base_class>
|
||||
my_class,
|
||||
extended_type_info_no_rtti<my_class>
|
||||
)
|
||||
</code></pre>
|
||||
we can assign the type information implementation to each class on a case by
|
||||
@@ -299,6 +311,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<class T>
|
||||
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<T>::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<my_class>
|
||||
: 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
|
||||
@@ -324,10 +380,11 @@ convenience macros, use the original definitions
|
||||
template<class T>
|
||||
struct implementation_level<nvp<T> >
|
||||
{
|
||||
typedef mpl::int_<object_serializable> type; \
|
||||
typedef mpl::integral_c_tag tag;
|
||||
typedef mpl::int_<object_serializable> type;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
enum level_type,
|
||||
value = static_cast<enum level_type>(type::value)
|
||||
int,
|
||||
value = implementation_level::type::value
|
||||
);
|
||||
};
|
||||
|
||||
@@ -335,10 +392,11 @@ struct implementation_level<nvp<T> >
|
||||
template<class T>
|
||||
struct tracking_level<nvp<T> >
|
||||
{
|
||||
typedef mpl::integral_c_tag tag;
|
||||
typedef mpl::int_<track_never> type;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
enum tracking_type,
|
||||
value = static_cast<enum tracking_type>(type::value)
|
||||
int,
|
||||
value = tracking_level::type::value
|
||||
);
|
||||
};
|
||||
</code></pre>
|
||||
@@ -393,7 +451,8 @@ template<
|
||||
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_
|
||||
>
|
||||
struct traits
|
||||
</code></pre>
|
||||
@@ -406,10 +465,66 @@ 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>
|
||||
|
||||
<<<<<<< .working
|
||||
|
||||
<h3><a name="tracking">Bitwise serialization</a></h3>
|
||||
Some simple classes could be serialized just by directly copying all bits
|
||||
of the class. This is, in particular, the case for POD data types containing
|
||||
no pointer members, and which are neither versioned nor tracked. Some archives,
|
||||
such as non-portable binary archives can make us of this information to
|
||||
substantially speed up serialization.
|
||||
|
||||
To indicate the possibility of bitwise serialization the type trait defined
|
||||
in the header
|
||||
file <a href="../../../boost/serialization/is_bitwise_serializable.hpp" target="is_bitwise_serializable">is_bitwise_serializable.hpp</a>
|
||||
is used:
|
||||
<pre><code>
|
||||
namespace boost { namespace serialization {
|
||||
template<class T>
|
||||
struct is_bitwise_serializable
|
||||
: public is_arithmetic<T>
|
||||
{};
|
||||
} }
|
||||
</code></pre>
|
||||
is used, and can be specialized for other classes. The specialization
|
||||
is made easy by the corresponding macro:
|
||||
<pre><code>
|
||||
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
|
||||
</code></pre>
|
||||
|
||||
=======
|
||||
|
||||
<h3><a name="tracking">Bitwise serialization</a></h3>
|
||||
Some simple classes could be serialized just by directly copying all bits
|
||||
of the class. This is, in particular, the case for POD data types containing
|
||||
no pointer members, and which are neither versioned nor tracked. Some archives,
|
||||
such as non-portable binary archives can make us of this information to
|
||||
substantially speed up Serialization.
|
||||
|
||||
To indicate the possibility of bitwise serialization the type trait defined
|
||||
in the header
|
||||
file <a href="../../../boost/serialization/is_bitwise_serializable.hpp" target="is_bitwise_serializable">is_bitwise_serializable.hpp</a>
|
||||
is used:
|
||||
<pre><code>
|
||||
namespace boost { namespace serialization {
|
||||
template<class T>
|
||||
struct is_bitwise_serializable
|
||||
: public is_arithmetic<T>
|
||||
{};
|
||||
} }
|
||||
</code></pre>
|
||||
is used, and can be specialized for other classes. The specialization
|
||||
is made easy by the corresponding macro:
|
||||
<pre><code>
|
||||
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
|
||||
</code></pre>
|
||||
|
||||
>>>>>>> .merge-right.r41077
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
<p><i>© 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>
|
||||
|
||||
+107
-44
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Tutorial</title>
|
||||
@@ -36,6 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#versioning">Class Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into <code style="white-space: normal">save/load</code></a>
|
||||
<dt><a href="#archives">Archives</a>
|
||||
<dt><a href="#examples">List of examples</a>
|
||||
</dl>
|
||||
An output archive is similar to an output data stream. Data can be saved to the archive
|
||||
with either the << or the & operator:
|
||||
@@ -59,7 +60,7 @@ all the data contained in the class is saved/loaded.
|
||||
|
||||
<h3><a name="simplecase">A Very Simple Case</a></h3>
|
||||
These operators are used inside the <code style="white-space: normal">serialize</code>
|
||||
function> to save and load class data members.
|
||||
function to save and load class data members.
|
||||
<p>
|
||||
Included in this library is a program called
|
||||
<a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a> which illustrates how
|
||||
@@ -106,24 +107,28 @@ public:
|
||||
int main() {
|
||||
// create and open a character archive for output
|
||||
std::ofstream ofs("filename");
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
|
||||
// create class instance
|
||||
const gps_position g(35, 59, 24.567f);
|
||||
// write class instance to archive
|
||||
oa << g;
|
||||
// close archive
|
||||
ofs.close();
|
||||
|
||||
// save data to archive
|
||||
{
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
// write class instance to archive
|
||||
oa << g;
|
||||
// archive and stream closed when destructors are called
|
||||
}
|
||||
|
||||
// ... some time later restore the class instance to its orginal state
|
||||
// create and open an archive for input
|
||||
std::ifstream ifs("filename", std::ios::binary);
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
// read class state from archive
|
||||
gps_position newg;
|
||||
ia >> newg;
|
||||
// close archive
|
||||
ifs.close();
|
||||
{
|
||||
// create and open an archive for input
|
||||
std::ifstream ifs("filename");
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
// read class state from archive
|
||||
ia >> newg;
|
||||
// archive and stream closed when destructors are called
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
@@ -294,7 +299,7 @@ public:
|
||||
</code>
|
||||
</pre>
|
||||
Each member of the array <code style="white-space: normal">stops</code> will be serialized.
|
||||
But, remember each member is a pointer - so what can this really
|
||||
But remember each member is a pointer - so what can this really
|
||||
mean? The whole object of this serialization is to permit
|
||||
reconstruction of the original data structures at another place
|
||||
and time. In order to accomplish this with a pointer, it is
|
||||
@@ -303,6 +308,27 @@ object it points to must be saved. When the member is later
|
||||
loaded, a new object has to be created and a new pointer has
|
||||
to be loaded into the class member.
|
||||
<p>
|
||||
If the same pointer is serialized more than once, only one instance
|
||||
is be added to the archive. When read back, no data is read back in.
|
||||
The only operation that occurs is for the second pointer is set equal to the first
|
||||
<p>
|
||||
Note that, in this example, the array consists of polymorphic pointers.
|
||||
That is, each array element point to one of several possible
|
||||
kinds of bus stops. So when the pointer is saved, some sort of class
|
||||
identifier must be saved. When the pointer is loaded, the class
|
||||
identifier must be read and and instance of the corresponding class
|
||||
must be constructed. Finally the data can be loaded to newly created
|
||||
instance of the correct type.
|
||||
|
||||
As can be seen in
|
||||
<a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>,
|
||||
serialization of pointers to derived classes through a base
|
||||
clas pointer may require explicit enumeration of the derived
|
||||
classes to be serialized. This is referred to as "registration" or "export"
|
||||
of derived classes. This requirement and the methods of
|
||||
satisfying it are explained in detail
|
||||
<a href="serialization.html#derivedpointers">here</a>
|
||||
<p>
|
||||
All this is accomplished automatically by the serialization
|
||||
library. The above code is all that is necessary to accomplish
|
||||
the saving and loading of objects accessed through pointers.
|
||||
@@ -479,39 +505,76 @@ to be usable with any archive.
|
||||
<p>
|
||||
In this tutorial, we have used a particular
|
||||
archive class - <code style="white-space: normal">text_oarchive</code> for saving and
|
||||
<code style="white-space: normal">text_iarchive</code> for loading. There other archives
|
||||
included in with the library and their interfaces are identical
|
||||
(with one exception). Once serialization has been defined for
|
||||
a class, that class can be serialized to any type of archive.
|
||||
<code style="white-space: normal">text_iarchive</code> for loading.
|
||||
text archives render data as text and are portable across platforms. In addition
|
||||
to text archives, the library includes archive class for native binary data
|
||||
and xml formatted data. Interfaces to all archive classes are all identical.
|
||||
Once serialization has been defined for a class, that class can be serialized to
|
||||
any type of archive.
|
||||
<p>
|
||||
If the current set of archives doesn't provide one with the
|
||||
attributes, format, or behavior need for a particular application,
|
||||
one can either make a new one or derive from an existing one.
|
||||
If the current set of archive classes doesn't provide the
|
||||
attributes, format, or behavior needed for a particular application,
|
||||
one can either make a new archive class or derive from an existing one.
|
||||
This is described later in the manual.
|
||||
|
||||
<h3><a name="examples">List of Examples</h3>
|
||||
<dl>
|
||||
<dt><a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>
|
||||
<dd>This is the completed example used in this tutorial.
|
||||
It does the following:
|
||||
<ol>
|
||||
<li>Creates a structure of differing kinds of stops, routes and schedules
|
||||
<li>Displays it
|
||||
<li>Serializes it to a file named "testfile.txt" with one
|
||||
statement
|
||||
<li>Restores to another structure
|
||||
<li>Displays the restored structure
|
||||
</ol>
|
||||
<a href="../example/demo_output.txt" target="demo_output">Output of
|
||||
this program</a> is sufficient to verify that all the
|
||||
originally stated requirements for a serialization system
|
||||
are met with this system. The <a href="../example/demofile.txt"
|
||||
target="test_file">contents of the archive file</a> can
|
||||
also be displayed as serialization files are ASCII text.
|
||||
|
||||
<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 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.
|
||||
|
||||
<dt><a href="../example/demo_xml_save.cpp" target="demo_xml_save_cpp">demo_xml_save.cpp</a>
|
||||
and <a href="../example/demo_xml_load.cpp" target="demo_xml_load_cpp">demo_xml_load.cpp</a>
|
||||
<dd>Note also that though our examples save and load the program data
|
||||
to an archive within the same program, this merely a convenience
|
||||
for purposes of illustration. In general, the archive may or may
|
||||
not be loaded by the same program that created it.
|
||||
</dl>
|
||||
<p>
|
||||
Note also that though our examples save and load the program data
|
||||
to an archive within the same program, this merely a convenience
|
||||
for purposes of illustration. In general, the archive may or may
|
||||
not be loaded by the same program that created it.
|
||||
The astute reader might notice that these examples contain a subtle but important flaw.
|
||||
They leak memory. The bus stops are created in the <code style="white-space: normal">
|
||||
main</code> function. The bus schedules may refer to these bus stops
|
||||
any number of times. At the end of the main function after the bus schedules are destroyed,
|
||||
the bus stops are destroyed. This seems fine. But what about the structure
|
||||
<code style="white-space: normal">new_schedule</code> data item created by the
|
||||
process of loading from an archive? This contains its own separate set of bus stops
|
||||
that are not referenced outside of the bus schedule. These won't be destroyed
|
||||
anywhere in the program - a memory leak.
|
||||
<p>
|
||||
The complete demo program - <a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>
|
||||
does the following:
|
||||
<ol>
|
||||
<li>Creates a structure of differing kinds of stops, routes
|
||||
and schedules
|
||||
<li>Displays it
|
||||
<li>Serializes it to a file named "testfile.txt" with one
|
||||
statement
|
||||
<li>Restores to another structure
|
||||
<li>Displays the restored structure
|
||||
</ol>
|
||||
<p>
|
||||
<a href="../example/demo_output.txt" target="demo_output">Output of
|
||||
this program</a> is sufficient to verify that all the
|
||||
originally stated requirements for a serialization system
|
||||
are met with this system. The <a href="../example/demofile.txt"
|
||||
target="test_file">contents of the archive file</a> can
|
||||
also be displayed as serialization files are ASCII text.
|
||||
There are couple of ways of fixing this. One way is to explicitly manage the bus stops.
|
||||
However, a more robust and transparent is to use
|
||||
<code style="white-space: normal">shared_ptr</code> rather than raw pointers. Along
|
||||
with serialization implemenations for the Standard Library, the serialization library
|
||||
includes implementation of serialization for
|
||||
<code style="white-space: normal">boost::shared ptr</code>. Given this, it should be
|
||||
easy to alter any of these examples to eliminate the memory leak. This is left
|
||||
as an excercise for the reader.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code>void_cast</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h3>Motivation</h3>
|
||||
C++ includes the operator <code style="white-space: normal">dynamic_cast<T>(U * u)</code>
|
||||
for casting a pointer at runtime between two related types. However, this can only be
|
||||
used for polymorphic classes. That is, it can only be used with related classes which have at least one virtual function.
|
||||
Limiting the serializaton of pointers to only such class would diminish the applicability
|
||||
of the library.
|
||||
|
||||
<h3>Usage</h3>
|
||||
|
||||
The following functions are defined in the header
|
||||
<a target="void_cast" href="../../../boost/serialization/void_cast.hpp">void_cast.hpp</a>.
|
||||
They are declared in the namespace
|
||||
<code style="white-space: normal">boost::serialization</code>.
|
||||
|
||||
<dl>
|
||||
<dt><h4><pre><code>
|
||||
template<class Derived, class Base>
|
||||
const void_cast_detail::void_caster &
|
||||
void_cast_register(
|
||||
Derived const * derived = NULL,
|
||||
Base * const base = NULL
|
||||
)
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This function "registers" a pair of related types. It stores the fact that
|
||||
<code style="white-space: normal">Derived</code> is immediately derived from
|
||||
<code style="white-space: normal">Base</code> in a global table.
|
||||
<ul>
|
||||
<li>This "registration" can be invoked anywhere in the program. The table is built at
|
||||
pre-runtime and is available anywhere else in the program.
|
||||
<li>only adjacent base/derived pairs need be registered. That is,
|
||||
<pre><code>
|
||||
void_cast_register<A, B>();
|
||||
void_cast_register<B, C>();
|
||||
</code></pre>
|
||||
automatically derives the fact that A can be upcast to C and vice-versa.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_upcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_downcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
These functions cast a void pointer from one type to another. The source and
|
||||
definition types are specified by passing references to the corresponding
|
||||
<a href="extended_type_info.html"><code style="white-space: normal">
|
||||
extended_type_info</code></a>
|
||||
records. An attempt to cast between types not "registered" with
|
||||
<code style="white-space: normal">void_cast_register</code>
|
||||
will throw a
|
||||
<a href="exceptions.html"><code style="white-space: normal">boost::archive::archive_exception</code></a>
|
||||
with value equal to
|
||||
<code style="white-space: normal">unregistered_cast</code>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+84
-25
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization Wrappers</title>
|
||||
@@ -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<T></code> or a <code>std::vector<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 <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
|
||||
@@ -79,7 +143,17 @@ Our solution is to wrap class members to be serialized in a
|
||||
<strong>name-value-pair</strong>. This structure is defined in
|
||||
<a href="../../../boost/serialization/nvp.hpp" target="nvp_hpp">nvp.hpp</a>.
|
||||
It is just a reference to the data member coupled with a pointer to
|
||||
to a <code style="white-space: normal">const char *</code> which corresponds to the XML name.
|
||||
to a <code style="white-space: normal">const char *</code> which
|
||||
corresponds to the XML name. It implements the default
|
||||
serialization functions for a name-value pair. This default
|
||||
action is to just ignore the item name and serialize the
|
||||
data value in the normal manner. For archive classes that
|
||||
don't make any special provision for name-value pairs, this
|
||||
is the action which will be invoked when the name-value pair
|
||||
is serialized. Hence, wrapping a data value into a name-value
|
||||
pair will have no effect when used with archives which
|
||||
make no special provision for this wrapper.
|
||||
<p>
|
||||
The xml archive classes contain code similar to:
|
||||
<pre><code>
|
||||
// special treatment for name-value pairs.
|
||||
@@ -96,24 +170,6 @@ xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
end_tag(t.name());
|
||||
}
|
||||
</code></pre>
|
||||
Archive classes which don't use the name of the data item include
|
||||
code similar to the following:
|
||||
<pre><code>
|
||||
// special treatment for name-value pairs. In a simple
|
||||
// text archive, just output the value in the normal way.
|
||||
// the name is not used
|
||||
template<class IStream, class T>
|
||||
text_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
{
|
||||
*this & t.value();
|
||||
}
|
||||
</code></pre>
|
||||
That is, the name part is ignored and and the value part is serialized
|
||||
as usual.
|
||||
<p>
|
||||
Hence, adding the name of the data item does not in any way affect the usage
|
||||
of archives which don't use it.
|
||||
<p>
|
||||
The most obvious and convient name to assign to as the XML data item name
|
||||
is - surpise! - the name of the C++ class data member. So our serialization
|
||||
code will look like:
|
||||
@@ -128,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.
|
||||
|
||||
|
||||
+4
-2
@@ -15,15 +15,17 @@ rule demo-bsl-build ( demo-name )
|
||||
$(demo-name).cpp
|
||||
<lib>../build/boost_serialization
|
||||
: # requirements
|
||||
# copy to a path rooted at BOOST_ROOT:
|
||||
<locate>$(BOOST_ROOT)
|
||||
<include>$(BOOST_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>-w-8080
|
||||
<msvc><release><cxxflags>-Gy
|
||||
<vc7><release><cxxflags>-Gy
|
||||
<vc7.1><release><cxxflags>-Gy
|
||||
<vc-7_0><release><cxxflags>-Gy
|
||||
<vc-7_1><release><cxxflags>-Gy
|
||||
: # default build
|
||||
debug
|
||||
<runtime-link>static
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ]
|
||||
;
|
||||
|
||||
+5
-3
@@ -13,12 +13,14 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/assume_abstract.hpp>
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// The intent of this program is to serve as a tutorial for
|
||||
@@ -91,7 +93,7 @@ public:
|
||||
virtual ~bus_stop(){}
|
||||
};
|
||||
|
||||
BOOST_IS_ABSTRACT(bus_stop)
|
||||
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
|
||||
{
|
||||
|
||||
@@ -20,21 +20,13 @@ namespace std{
|
||||
#endif
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
|
||||
#include <boost/serialization/split_free.hpp>
|
||||
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace boost { namespace serialization {
|
||||
#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
namespace _STLP_STD {
|
||||
#else
|
||||
namespace std {
|
||||
#endif
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// implement serialization for auto_ptr<T>
|
||||
@@ -48,7 +40,8 @@ inline void save(
|
||||
){
|
||||
// only the raw pointer has to be saved
|
||||
// the ref count is rebuilt automatically on load
|
||||
ar << t.get();
|
||||
const T * const tx = t.get();
|
||||
ar << tx;
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
@@ -79,14 +72,8 @@ inline void serialize(
|
||||
boost::serialization::split_free(ar, t, file_version);
|
||||
}
|
||||
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
#else
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// test auto_ptr serialization
|
||||
@@ -104,14 +91,14 @@ public:
|
||||
~A(){} // default destructor
|
||||
};
|
||||
|
||||
void save(std::auto_ptr<A> &spa, const char *filename)
|
||||
void save(const std::auto_ptr<A> & spa, const char *filename)
|
||||
{
|
||||
std::ofstream ofs(filename);
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
oa << spa;
|
||||
}
|
||||
|
||||
void load(std::auto_ptr<A> &spa, const char *filename)
|
||||
void load(std::auto_ptr<A> & spa, const char *filename)
|
||||
{
|
||||
// open the archive
|
||||
std::ifstream ifs(filename);
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// test_derived_class.cpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// should pass compilation and execution
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <cstdio> // remove
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#include "B.hpp"
|
||||
#include "A.ipp"
|
||||
|
||||
int test_main( int argc, char* argv[] )
|
||||
{
|
||||
const char * testfile = boost::archive::tmpnam(NULL);
|
||||
|
||||
BOOST_REQUIRE(NULL != testfile);
|
||||
|
||||
B b, b1;
|
||||
|
||||
{
|
||||
test_ostream os(testfile, TEST_STREAM_FLAGS);
|
||||
test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
|
||||
oa << boost::serialization::make_nvp("b", b);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("b1", b1);
|
||||
}
|
||||
BOOST_CHECK(b == b1);
|
||||
std::remove(testfile);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// EOF
|
||||
@@ -0,0 +1,321 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_A_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// A.hpp simple class test
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib> // for rand()
|
||||
#include <cmath> // for fabs()
|
||||
#include <cstddef> // size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
using ::fabs;
|
||||
using ::size_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include <boost/test/test_exec_monitor.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
#include <boost/archive/dinkumware.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
// note: from an aesthetic perspective, I would much prefer to have this
|
||||
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
|
||||
// compiler. So hold our nose and put it her to permit running of tests.
|
||||
template<class Archive>
|
||||
void serialize(
|
||||
Archive &ar,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
ar & BOOST_SERIALIZATION_NVP(b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
ar & BOOST_SERIALIZATION_NVP(f);
|
||||
ar & BOOST_SERIALIZATION_NVP(g);
|
||||
#endif
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 )
|
||||
int i;
|
||||
if(Archive::is_saving::value){
|
||||
i = l;
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
}
|
||||
else{
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
l = i;
|
||||
}
|
||||
#else
|
||||
ar & BOOST_SERIALIZATION_NVP(l);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(m);
|
||||
ar & BOOST_SERIALIZATION_NVP(n);
|
||||
ar & BOOST_SERIALIZATION_NVP(o);
|
||||
ar & BOOST_SERIALIZATION_NVP(p);
|
||||
ar & BOOST_SERIALIZATION_NVP(q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
ar & BOOST_SERIALIZATION_NVP(r);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(c);
|
||||
ar & BOOST_SERIALIZATION_NVP(s);
|
||||
ar & BOOST_SERIALIZATION_NVP(t);
|
||||
ar & BOOST_SERIALIZATION_NVP(u);
|
||||
ar & BOOST_SERIALIZATION_NVP(v);
|
||||
ar & BOOST_SERIALIZATION_NVP(w);
|
||||
ar & BOOST_SERIALIZATION_NVP(x);
|
||||
ar & BOOST_SERIALIZATION_NVP(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
ar & BOOST_SERIALIZATION_NVP(z);
|
||||
#endif
|
||||
}
|
||||
bool b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
boost::int64_t f;
|
||||
boost::uint64_t g;
|
||||
#endif
|
||||
enum h {
|
||||
i = 0,
|
||||
j,
|
||||
k
|
||||
} l;
|
||||
std::size_t m;
|
||||
signed long n;
|
||||
unsigned long o;
|
||||
signed short p;
|
||||
unsigned short q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
wchar_t r;
|
||||
#endif
|
||||
char c;
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
std::string y;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
std::wstring z;
|
||||
#endif
|
||||
public:
|
||||
A();
|
||||
bool operator==(const A &rhs) const;
|
||||
bool operator!=(const A &rhs) const;
|
||||
bool operator<(const A &rhs) const; // used by less
|
||||
// hash function for class A
|
||||
operator std::size_t () const;
|
||||
friend std::ostream & operator<<(std::ostream & os, A const & a);
|
||||
friend std::istream & operator>>(std::istream & is, A & a);
|
||||
};
|
||||
|
||||
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
|
||||
|
||||
template<class S>
|
||||
void randomize(S &x)
|
||||
{
|
||||
assert(0 == x.size());
|
||||
for(;;){
|
||||
unsigned int i = std::rand() % 27;
|
||||
if(0 == i)
|
||||
break;
|
||||
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void accumulate(std::size_t & s, const T & t){
|
||||
const char * tptr = (const char *)(& t);
|
||||
unsigned int count = sizeof(t);
|
||||
while(count-- > 0){
|
||||
s += *tptr++;
|
||||
}
|
||||
}
|
||||
|
||||
A::operator std::size_t () const {
|
||||
std::size_t retval = 0;
|
||||
accumulate(retval, b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
accumulate(retval, f);
|
||||
accumulate(retval, g);
|
||||
#endif
|
||||
accumulate(retval, l);
|
||||
accumulate(retval, m);
|
||||
accumulate(retval, n);
|
||||
accumulate(retval, o);
|
||||
accumulate(retval, p);
|
||||
accumulate(retval, q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
accumulate(retval, r);
|
||||
#endif
|
||||
accumulate(retval, c);
|
||||
accumulate(retval, s);
|
||||
accumulate(retval, t);
|
||||
accumulate(retval, u);
|
||||
accumulate(retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline A::A() :
|
||||
b(true),
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
f(std::rand() * std::rand()),
|
||||
g(std::rand() * std::rand()),
|
||||
#endif
|
||||
l(static_cast<enum h>(std::rand() % 3)),
|
||||
m(std::rand()),
|
||||
n(std::rand()),
|
||||
o(std::rand()),
|
||||
p(std::rand()),
|
||||
q(std::rand()),
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
r(std::rand()),
|
||||
#endif
|
||||
c(std::rand()),
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand()),
|
||||
x((double)std::rand())
|
||||
{
|
||||
randomize(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
randomize(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool A::operator==(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return false;
|
||||
if(l != rhs.l)
|
||||
return false;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return false;
|
||||
if(g != rhs.g)
|
||||
return false;
|
||||
#endif
|
||||
if(m != rhs.m)
|
||||
return false;
|
||||
if(n != rhs.n)
|
||||
return false;
|
||||
if(o != rhs.o)
|
||||
return false;
|
||||
if(p != rhs.p)
|
||||
return false;
|
||||
if(q != rhs.q)
|
||||
return false;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r)
|
||||
return false;
|
||||
#endif
|
||||
if(c != rhs.c)
|
||||
return false;
|
||||
if(s != rhs.s)
|
||||
return false;
|
||||
if(t != rhs.t)
|
||||
return false;
|
||||
if(u != rhs.u)
|
||||
return false;
|
||||
if(v != rhs.v)
|
||||
return false;
|
||||
if(w == 0 && std::fabs(rhs.w) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(std::fabs(rhs.w/w - 1.0) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(x == 0 && std::fabs(rhs.x - x) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(std::fabs(rhs.x/x - 1.0) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(0 != y.compare(rhs.y))
|
||||
return false;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
if(0 != z.compare(rhs.z))
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool A::operator!=(const A &rhs) const
|
||||
{
|
||||
return ! (*this == rhs);
|
||||
}
|
||||
|
||||
inline bool A::operator<(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return b < rhs.b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return f < rhs.f;
|
||||
if(g != rhs.g)
|
||||
return g < rhs.g;
|
||||
#endif
|
||||
if(l != rhs.l )
|
||||
return l < rhs.l;
|
||||
if(m != rhs.m )
|
||||
return m < rhs.m;
|
||||
if(n != rhs.n )
|
||||
return n < rhs.n;
|
||||
if(o != rhs.o )
|
||||
return o < rhs.o;
|
||||
if(p != rhs.p )
|
||||
return p < rhs.p;
|
||||
if(q != rhs.q )
|
||||
return q < rhs.q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r )
|
||||
return r < rhs.r;
|
||||
#endif
|
||||
if(c != rhs.c )
|
||||
return c < rhs.c;
|
||||
if(s != rhs.s )
|
||||
return s < rhs.s;
|
||||
if(t != rhs.t )
|
||||
return t < rhs.t;
|
||||
if(u != rhs.u )
|
||||
return u < rhs.u;
|
||||
if(v != rhs.v )
|
||||
return v < rhs.v;
|
||||
if(w != rhs.w )
|
||||
return w < rhs.w;
|
||||
if(x != rhs.x )
|
||||
return x < rhs.x;
|
||||
int i = y.compare(rhs.y);
|
||||
if(i != 0 )
|
||||
return i < 0;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
int j = z.compare(rhs.z);
|
||||
if(j != 0 )
|
||||
return j < 0;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_A_HPP
|
||||
@@ -0,0 +1,321 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_A_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// A.hpp simple class test
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib> // for rand()
|
||||
#include <cmath> // for fabs()
|
||||
#include <cstddef> // size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
using ::fabs;
|
||||
using ::size_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include <boost/test/test_exec_monitor.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
#include <boost/archive/dinkumware.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
// note: from an aesthetic perspective, I would much prefer to have this
|
||||
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
|
||||
// compiler. So hold our nose and put it her to permit running of tests.
|
||||
template<class Archive>
|
||||
void serialize(
|
||||
Archive &ar,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
ar & BOOST_SERIALIZATION_NVP(b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
ar & BOOST_SERIALIZATION_NVP(f);
|
||||
ar & BOOST_SERIALIZATION_NVP(g);
|
||||
#endif
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 )
|
||||
int i;
|
||||
if(Archive::is_saving::value){
|
||||
i = l;
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
}
|
||||
else{
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
l = i;
|
||||
}
|
||||
#else
|
||||
ar & BOOST_SERIALIZATION_NVP(l);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(m);
|
||||
ar & BOOST_SERIALIZATION_NVP(n);
|
||||
ar & BOOST_SERIALIZATION_NVP(o);
|
||||
ar & BOOST_SERIALIZATION_NVP(p);
|
||||
ar & BOOST_SERIALIZATION_NVP(q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
ar & BOOST_SERIALIZATION_NVP(r);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(c);
|
||||
ar & BOOST_SERIALIZATION_NVP(s);
|
||||
ar & BOOST_SERIALIZATION_NVP(t);
|
||||
ar & BOOST_SERIALIZATION_NVP(u);
|
||||
ar & BOOST_SERIALIZATION_NVP(v);
|
||||
ar & BOOST_SERIALIZATION_NVP(w);
|
||||
ar & BOOST_SERIALIZATION_NVP(x);
|
||||
ar & BOOST_SERIALIZATION_NVP(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
ar & BOOST_SERIALIZATION_NVP(z);
|
||||
#endif
|
||||
}
|
||||
bool b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
boost::int64_t f;
|
||||
boost::uint64_t g;
|
||||
#endif
|
||||
enum h {
|
||||
i = 0,
|
||||
j,
|
||||
k
|
||||
} l;
|
||||
std::size_t m;
|
||||
signed long n;
|
||||
unsigned long o;
|
||||
signed short p;
|
||||
unsigned short q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
wchar_t r;
|
||||
#endif
|
||||
char c;
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
std::string y;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
std::wstring z;
|
||||
#endif
|
||||
public:
|
||||
A();
|
||||
bool operator==(const A &rhs) const;
|
||||
bool operator!=(const A &rhs) const;
|
||||
bool operator<(const A &rhs) const; // used by less
|
||||
// hash function for class A
|
||||
operator std::size_t () const;
|
||||
friend std::ostream & operator<<(std::ostream & os, A const & a);
|
||||
friend std::istream & operator>>(std::istream & is, A & a);
|
||||
};
|
||||
|
||||
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
|
||||
|
||||
template<class S>
|
||||
void randomize(S &x)
|
||||
{
|
||||
assert(0 == x.size());
|
||||
for(;;){
|
||||
unsigned int i = std::rand() % 27;
|
||||
if(0 == i)
|
||||
break;
|
||||
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void accumulate(std::size_t & s, const T & t){
|
||||
const char * tptr = (const char *)(& t);
|
||||
unsigned int count = sizeof(t);
|
||||
while(count-- > 0){
|
||||
s += *tptr++;
|
||||
}
|
||||
}
|
||||
|
||||
A::operator std::size_t () const {
|
||||
std::size_t retval = 0;
|
||||
accumulate(retval, b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
accumulate(retval, f);
|
||||
accumulate(retval, g);
|
||||
#endif
|
||||
accumulate(retval, l);
|
||||
accumulate(retval, m);
|
||||
accumulate(retval, n);
|
||||
accumulate(retval, o);
|
||||
accumulate(retval, p);
|
||||
accumulate(retval, q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
accumulate(retval, r);
|
||||
#endif
|
||||
accumulate(retval, c);
|
||||
accumulate(retval, s);
|
||||
accumulate(retval, t);
|
||||
accumulate(retval, u);
|
||||
accumulate(retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline A::A() :
|
||||
b(true),
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
f(std::rand() * std::rand()),
|
||||
g(std::rand() * std::rand()),
|
||||
#endif
|
||||
l(static_cast<enum h>(std::rand() % 3)),
|
||||
m(std::rand()),
|
||||
n(std::rand()),
|
||||
o(std::rand()),
|
||||
p(std::rand()),
|
||||
q(std::rand()),
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
r(std::rand()),
|
||||
#endif
|
||||
c(std::rand()),
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand()),
|
||||
x((double)std::rand())
|
||||
{
|
||||
randomize(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
randomize(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool A::operator==(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return false;
|
||||
if(l != rhs.l)
|
||||
return false;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return false;
|
||||
if(g != rhs.g)
|
||||
return false;
|
||||
#endif
|
||||
if(m != rhs.m)
|
||||
return false;
|
||||
if(n != rhs.n)
|
||||
return false;
|
||||
if(o != rhs.o)
|
||||
return false;
|
||||
if(p != rhs.p)
|
||||
return false;
|
||||
if(q != rhs.q)
|
||||
return false;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r)
|
||||
return false;
|
||||
#endif
|
||||
if(c != rhs.c)
|
||||
return false;
|
||||
if(s != rhs.s)
|
||||
return false;
|
||||
if(t != rhs.t)
|
||||
return false;
|
||||
if(u != rhs.u)
|
||||
return false;
|
||||
if(v != rhs.v)
|
||||
return false;
|
||||
if(w == 0 && std::fabs(rhs.w) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(std::fabs(rhs.w/w - 1.0) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(x == 0 && std::fabs(rhs.x - x) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(std::fabs(rhs.x/x - 1.0) > std::numeric_limits<float>::epsilon())
|
||||
return false;
|
||||
if(0 != y.compare(rhs.y))
|
||||
return false;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
if(0 != z.compare(rhs.z))
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool A::operator!=(const A &rhs) const
|
||||
{
|
||||
return ! (*this == rhs);
|
||||
}
|
||||
|
||||
inline bool A::operator<(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return b < rhs.b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return f < rhs.f;
|
||||
if(g != rhs.g)
|
||||
return g < rhs.g;
|
||||
#endif
|
||||
if(l != rhs.l )
|
||||
return l < rhs.l;
|
||||
if(m != rhs.m )
|
||||
return m < rhs.m;
|
||||
if(n != rhs.n )
|
||||
return n < rhs.n;
|
||||
if(o != rhs.o )
|
||||
return o < rhs.o;
|
||||
if(p != rhs.p )
|
||||
return p < rhs.p;
|
||||
if(q != rhs.q )
|
||||
return q < rhs.q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r )
|
||||
return r < rhs.r;
|
||||
#endif
|
||||
if(c != rhs.c )
|
||||
return c < rhs.c;
|
||||
if(s != rhs.s )
|
||||
return s < rhs.s;
|
||||
if(t != rhs.t )
|
||||
return t < rhs.t;
|
||||
if(u != rhs.u )
|
||||
return u < rhs.u;
|
||||
if(v != rhs.v )
|
||||
return v < rhs.v;
|
||||
if(w != rhs.w )
|
||||
return w < rhs.w;
|
||||
if(x != rhs.x )
|
||||
return x < rhs.x;
|
||||
int i = y.compare(rhs.y);
|
||||
if(i != 0 )
|
||||
return i < 0;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
int j = z.compare(rhs.z);
|
||||
if(j != 0 )
|
||||
return j < 0;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_A_HPP
|
||||
@@ -0,0 +1,112 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_B_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// B.hpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cstdlib> // for rand()
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
|
||||
#include "A.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Derived class test
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void save(Archive &ar, const unsigned int /* file_version */) const
|
||||
{
|
||||
// write any base class info to the archive
|
||||
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
|
||||
// write out members
|
||||
ar << BOOST_SERIALIZATION_NVP(s);
|
||||
ar << BOOST_SERIALIZATION_NVP(t);
|
||||
ar << BOOST_SERIALIZATION_NVP(u);
|
||||
ar << BOOST_SERIALIZATION_NVP(v);
|
||||
ar << BOOST_SERIALIZATION_NVP(w);
|
||||
ar << BOOST_SERIALIZATION_NVP(x);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, const unsigned int file_version)
|
||||
{
|
||||
// read any base class info to the archive
|
||||
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
switch(file_version){
|
||||
case 1:
|
||||
case 2:
|
||||
ar >> BOOST_SERIALIZATION_NVP(s);
|
||||
ar >> BOOST_SERIALIZATION_NVP(t);
|
||||
ar >> BOOST_SERIALIZATION_NVP(u);
|
||||
ar >> BOOST_SERIALIZATION_NVP(v);
|
||||
ar >> BOOST_SERIALIZATION_NVP(w);
|
||||
ar >> BOOST_SERIALIZATION_NVP(x);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
public:
|
||||
B();
|
||||
virtual ~B(){};
|
||||
bool operator==(const B &rhs) const;
|
||||
};
|
||||
|
||||
B::B() :
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand() / std::rand()),
|
||||
x((double)std::rand() / std::rand())
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(B, 2)
|
||||
|
||||
inline bool B::operator==(const B &rhs) const
|
||||
{
|
||||
return
|
||||
A::operator==(rhs)
|
||||
&& s == rhs.s
|
||||
&& t == rhs.t
|
||||
&& u == rhs.u
|
||||
&& v == rhs.v
|
||||
&& std::fabs(w - rhs.w) <= std::numeric_limits<float>::round_error()
|
||||
&& std::fabs(x - rhs.x) <= std::numeric_limits<float>::round_error()
|
||||
;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_B_HPP
|
||||
@@ -0,0 +1,112 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_B_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// B.hpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cstdlib> // for rand()
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
|
||||
#include "A.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Derived class test
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void save(Archive &ar, const unsigned int /* file_version */) const
|
||||
{
|
||||
// write any base class info to the archive
|
||||
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
|
||||
// write out members
|
||||
ar << BOOST_SERIALIZATION_NVP(s);
|
||||
ar << BOOST_SERIALIZATION_NVP(t);
|
||||
ar << BOOST_SERIALIZATION_NVP(u);
|
||||
ar << BOOST_SERIALIZATION_NVP(v);
|
||||
ar << BOOST_SERIALIZATION_NVP(w);
|
||||
ar << BOOST_SERIALIZATION_NVP(x);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, const unsigned int file_version)
|
||||
{
|
||||
// read any base class info to the archive
|
||||
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
switch(file_version){
|
||||
case 1:
|
||||
case 2:
|
||||
ar >> BOOST_SERIALIZATION_NVP(s);
|
||||
ar >> BOOST_SERIALIZATION_NVP(t);
|
||||
ar >> BOOST_SERIALIZATION_NVP(u);
|
||||
ar >> BOOST_SERIALIZATION_NVP(v);
|
||||
ar >> BOOST_SERIALIZATION_NVP(w);
|
||||
ar >> BOOST_SERIALIZATION_NVP(x);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
public:
|
||||
B();
|
||||
virtual ~B(){};
|
||||
bool operator==(const B &rhs) const;
|
||||
};
|
||||
|
||||
B::B() :
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand() / std::rand()),
|
||||
x((double)std::rand() / std::rand())
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(B, 2)
|
||||
|
||||
inline bool B::operator==(const B &rhs) const
|
||||
{
|
||||
return
|
||||
A::operator==(rhs)
|
||||
&& s == rhs.s
|
||||
&& t == rhs.t
|
||||
&& u == rhs.u
|
||||
&& v == rhs.v
|
||||
&& std::fabs(w - rhs.w) <= std::numeric_limits<float>::round_error()
|
||||
&& std::fabs(x - rhs.x) <= std::numeric_limits<float>::round_error()
|
||||
;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_B_HPP
|
||||
@@ -36,12 +36,12 @@ namespace std{
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
|
||||
template<class TPTR>
|
||||
struct deleter
|
||||
{
|
||||
@@ -213,7 +213,7 @@ void init(School *school){
|
||||
// carol has no courses
|
||||
}
|
||||
|
||||
void save(School *school, const char *filename){
|
||||
void save(const School * const school, const char *filename){
|
||||
std::ofstream ofile(filename);
|
||||
boost::archive::text_oarchive ar(ofile);
|
||||
ar << school;
|
||||
|
||||
@@ -13,42 +13,58 @@
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/pfto.hpp>
|
||||
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
|
||||
using namespace boost::archive;
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include <boost/archive/binary_oarchive_impl.hpp>
|
||||
#include <boost/archive/binary_iarchive_impl.hpp>
|
||||
|
||||
// include template definitions for base classes used. Otherwise
|
||||
// you'll get link failure with undefined symbols
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oarchive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iarchive.ipp>
|
||||
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
|
||||
|
||||
using namespace boost::archive;
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// "Fast" output binary archive. This is a variation of the native binary
|
||||
class fast_binary_oarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<fast_binary_oarchive>
|
||||
public binary_oarchive_impl<
|
||||
fast_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>
|
||||
{
|
||||
typedef fast_binary_oarchive derived_t;
|
||||
typedef binary_oarchive_impl<
|
||||
fast_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class boost::archive::detail::interface_oarchive<derived_t>;
|
||||
friend class basic_binary_oarchive<derived_t>;
|
||||
friend class basic_binary_oprimitive<derived_t, std::ostream>;
|
||||
friend class basic_binary_oprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class boost::archive::save_access;
|
||||
#endif
|
||||
// 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
|
||||
// using binary_oarchive_impl<derived_t>::load_override;
|
||||
// work on my MSVC 7.0 system using
|
||||
// binary_oarchive_impl<derived_t>::load_override;
|
||||
// so we use the sure-fire method below. This failed to work as well
|
||||
template<class T>
|
||||
void save_override(const T & t, BOOST_PFTO int){
|
||||
binary_oarchive_impl<fast_binary_oarchive>::save_override(t, 0);
|
||||
void save_override(T & t, BOOST_PFTO int){
|
||||
base_t::save_override(t, 0);
|
||||
// verify that this program is in fact working by making sure
|
||||
// that arrays are getting passed here
|
||||
BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) );
|
||||
@@ -71,7 +87,10 @@ public:
|
||||
}
|
||||
public:
|
||||
fast_binary_oarchive(std::ostream & os, unsigned flags = 0) :
|
||||
binary_oarchive_impl<derived_t>(os, flags)
|
||||
base_t(os, flags)
|
||||
{}
|
||||
fast_binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) :
|
||||
base_t(bsb, flags)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -79,25 +98,38 @@ public:
|
||||
// "Fast" input binary archive. This is a variation of the native binary
|
||||
class fast_binary_iarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_iarchive_impl<fast_binary_iarchive>
|
||||
public binary_iarchive_impl<
|
||||
fast_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>
|
||||
{
|
||||
typedef fast_binary_iarchive derived_t;
|
||||
typedef binary_iarchive_impl<
|
||||
fast_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class boost::archive::detail::interface_iarchive<derived_t>;
|
||||
friend class basic_binary_iarchive<derived_t>;
|
||||
friend class basic_binary_iprimitive<derived_t, std::istream>;
|
||||
friend class basic_binary_iprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class boost::archive::load_access;
|
||||
#endif
|
||||
// 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
|
||||
// using binary_oarchive_impl<derived_t>::load_override;
|
||||
// work on my MSVC 7.0 system using
|
||||
// binary_oarchive_impl<derived_t>::load_override;
|
||||
// so we use the sure-fire method below. This failed to work as well
|
||||
template<class T>
|
||||
void load_override(T & t, BOOST_PFTO int){
|
||||
binary_iarchive_impl<derived_t>::load_override(t, 0);
|
||||
base_t::load_override(t, 0);
|
||||
BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) );
|
||||
}
|
||||
template<int N>
|
||||
@@ -117,14 +149,17 @@ public:
|
||||
load_binary(t, sizeof(t));
|
||||
}
|
||||
public:
|
||||
fast_binary_iarchive(std::istream & is, unsigned flags = 0) :
|
||||
binary_iarchive_impl<derived_t>(is,flags)
|
||||
fast_binary_iarchive(std::istream & is, unsigned int flags = 0) :
|
||||
base_t(is, flags)
|
||||
{}
|
||||
fast_binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) :
|
||||
base_t(bsb, flags)
|
||||
{}
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int a[3] = {1, 2, 3};
|
||||
const int a[3] = {1, 2, 3};
|
||||
int a1[3] = {4, 5, 6};
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -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_SERIALIZATION_ASSUME_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
|
||||
@@ -19,12 +19,12 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
A a, a1;
|
||||
|
||||
const A a;
|
||||
{
|
||||
boost::archive::text_oarchive oa(ss);
|
||||
oa << a;
|
||||
}
|
||||
A a1;
|
||||
{
|
||||
boost::archive::text_iarchive ia(ss);
|
||||
ia >> a1;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
// 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/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include "demo_pimpl_A.hpp"
|
||||
|
||||
// "hidden" definition of class B
|
||||
@@ -32,9 +35,6 @@ void A::serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
// without the explicit instantiations below, the program will
|
||||
// fail to link for lack of instantiantiation of the above function
|
||||
// note: the following failed to fix link errors for vc 7.0 !
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
template void A::serialize<boost::archive::text_iarchive>(
|
||||
boost::archive::text_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
A a, a1;
|
||||
const A a;
|
||||
A a1;
|
||||
{
|
||||
// test with a text archive
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "demo_polymorphic_A.hpp"
|
||||
|
||||
#include <boost/archive/polymorphic_iarchive.hpp>
|
||||
#include <boost/archive/polymorphic_oarchive.hpp>
|
||||
|
||||
#include "demo_polymorphic_A.hpp"
|
||||
|
||||
// now we can define the serialization for class A
|
||||
void A::serialize(
|
||||
boost::archive::polymorphic_iarchive & ar,
|
||||
|
||||
@@ -26,6 +26,9 @@ struct A {
|
||||
bool operator==(const A & rhs) const {
|
||||
return data == rhs.data;
|
||||
}
|
||||
A() :
|
||||
data(0)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP
|
||||
|
||||
@@ -19,37 +19,44 @@
|
||||
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==(A & rhs){
|
||||
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())
|
||||
{}
|
||||
};
|
||||
|
||||
int main( int /* argc */, char* /* argv */[] )
|
||||
{
|
||||
A a, a1;
|
||||
const A a;
|
||||
A a1;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
@@ -60,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);
|
||||
}
|
||||
|
||||
|
||||
+12
-22
@@ -22,11 +22,11 @@ namespace std{
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
|
||||
///////////////////////////
|
||||
// test shared_ptr serialization
|
||||
@@ -41,10 +41,11 @@ private:
|
||||
}
|
||||
public:
|
||||
static int count;
|
||||
A::A(){++count;} // default constructor
|
||||
virtual A::~A(){--count;} // default destructor
|
||||
A(){++count;} // default constructor
|
||||
virtual ~A(){--count;} // default destructor
|
||||
};
|
||||
|
||||
BOOST_SERIALIZATION_SHARED_PTR(A)
|
||||
|
||||
/////////////////
|
||||
// ADDITION BY DT
|
||||
@@ -59,9 +60,12 @@ private:
|
||||
}
|
||||
public:
|
||||
static int count;
|
||||
B::B() : A() {};
|
||||
virtual B::~B() {};
|
||||
B() : A() {};
|
||||
virtual ~B() {};
|
||||
};
|
||||
|
||||
BOOST_SERIALIZATION_SHARED_PTR(B)
|
||||
|
||||
/////////////////
|
||||
|
||||
int A::count = 0;
|
||||
@@ -77,7 +81,7 @@ void display(boost::shared_ptr<A> &spa, boost::shared_ptr<A> &spa1)
|
||||
std::cout << "unique element count = " << A::count << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int /* argc */, char /* *argv[] */)
|
||||
{
|
||||
std::string filename(boost::archive::tmpdir());
|
||||
filename += "/testfile";
|
||||
@@ -129,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;
|
||||
}
|
||||
@@ -153,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
virtual ~bus_stop(){}
|
||||
};
|
||||
|
||||
BOOST_IS_ABSTRACT(bus_stop);
|
||||
BOOST_IS_ABSTRACT(bus_stop)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
|
||||
{
|
||||
@@ -265,8 +265,8 @@ public:
|
||||
bus_schedule(){}
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(bus_schedule::trip_info, 3);
|
||||
BOOST_CLASS_VERSION(bus_schedule, 2);
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// polymorphic_portable_binary_iarchive.cpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <istream>
|
||||
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include "polymorphic_portable_binary_iarchive.hpp"
|
||||
|
||||
// explicitly instantiate for this type of text stream
|
||||
#include <boost/archive/impl/basic_binary_iarchive.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template class binary_iarchive_impl<
|
||||
polymorphic_portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>;
|
||||
template class detail::archive_pointer_iserializer<
|
||||
polymorphic_portable_binary_iarchive
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP
|
||||
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// polymorphic_portable_binary_iarchive.hpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/archive/detail/polymorphic_iarchive_dispatch.hpp>
|
||||
#include "portable_binary_iarchive.hpp"
|
||||
|
||||
typedef boost::archive::detail::polymorphic_iarchive_dispatch<
|
||||
portable_binary_iarchive
|
||||
> polymorphic_portable_binary_iarchive;
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION > 103401
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
|
||||
polymorphic_portable_binary_iarchive
|
||||
)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// polymorphic_portable_binary_oarchive.cpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include "polymorphic_portable_binary_oarchive.hpp"
|
||||
|
||||
// explicitly instantiate for this type of text stream
|
||||
#include <boost/archive/impl/basic_binary_oarchive.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
// explicitly instantiate for this type of binary stream
|
||||
template class binary_oarchive_impl<
|
||||
polymorphic_portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
template class detail::archive_pointer_oserializer<
|
||||
polymorphic_portable_binary_oarchive
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
|
||||
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// polymorphic_portable_binary_oarchive.hpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/archive/detail/polymorphic_oarchive_dispatch.hpp>
|
||||
#include "portable_binary_oarchive.hpp"
|
||||
|
||||
typedef boost::archive::detail::polymorphic_oarchive_dispatch<
|
||||
portable_binary_oarchive
|
||||
> polymorphic_portable_binary_oarchive;
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION > 103401
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
|
||||
polymorphic_portable_binary_oarchive
|
||||
)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
|
||||
@@ -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
|
||||
@@ -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
|
||||
#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
|
||||
@@ -6,30 +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 <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( )
|
||||
{
|
||||
@@ -45,94 +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_oarchive !!!
|
||||
public boost::archive::binary_iarchive_impl<portable_binary_iarchive>
|
||||
{
|
||||
typedef portable_binary_iarchive derived_t;
|
||||
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
|
||||
>
|
||||
,
|
||||
public boost::archive::detail::shared_ptr_helper
|
||||
{
|
||||
typedef boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> primitive_base_t;
|
||||
typedef boost::archive::detail::common_iarchive<
|
||||
portable_binary_iarchive
|
||||
> archive_base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class boost::archive::basic_binary_iarchive<derived_t>;
|
||||
friend class boost::archive::basic_binary_iprimitive<derived_t, std::istream>;
|
||||
friend archive_base_t;
|
||||
friend primitive_base_t; // since with override load below
|
||||
friend class boost::archive::detail::interface_iarchive<
|
||||
portable_binary_iarchive
|
||||
>;
|
||||
friend class boost::archive::load_access;
|
||||
protected:
|
||||
#endif
|
||||
void load_impl(long & l, char maxsize){
|
||||
char size;
|
||||
size = is.get();
|
||||
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 = *first;
|
||||
*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::archive::binary_iarchive_impl<derived_t>::load(t);
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(T));
|
||||
// use cast to avoid compile time warning
|
||||
t = static_cast<T>(l);
|
||||
}
|
||||
void load(unsigned int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned int));
|
||||
t = l;
|
||||
void load(std::string & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(int));
|
||||
t = l;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void load(std::wstring & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(unsigned long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned long));
|
||||
t = l;
|
||||
#endif
|
||||
void load(float & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// floats not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
}
|
||||
void load(long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(long));
|
||||
t = l;
|
||||
void load(double & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// doubles not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
}
|
||||
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) :
|
||||
boost::archive::binary_iarchive_impl<derived_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)){
|
||||
boost::archive::basic_binary_iarchive<derived_t>::init();
|
||||
// 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/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template class basic_binary_iprimitive<portable_binary_iarchive, std::istream> ;
|
||||
template class binary_iarchive_impl<portable_binary_iarchive> ;
|
||||
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
|
||||
|
||||
@@ -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_little)
|
||||
reverse_bytes(size, cptr);
|
||||
#else
|
||||
if(m_flags & endian_big)
|
||||
reverse_bytes(size, cptr);
|
||||
#endif
|
||||
this->primitive_base_t::save_binary(cptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_oarchive::init(unsigned int flags) {
|
||||
if(m_flags == (endian_big | endian_little)){
|
||||
boost::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 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
|
||||
@@ -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,8 +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/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
|
||||
@@ -26,91 +61,132 @@
|
||||
// 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 portable_binary_oarchive derived_t;
|
||||
typedef boost::archive::basic_binary_oprimitive<
|
||||
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 class boost::archive::basic_binary_oarchive<derived_t>;
|
||||
friend class boost::archive::basic_binary_oprimitive<derived_t, std::ostream>;
|
||||
friend archive_base_t;
|
||||
friend primitive_base_t; // since with override save below
|
||||
friend class boost::archive::detail::interface_oarchive<
|
||||
portable_binary_oarchive
|
||||
>;
|
||||
friend class boost::archive::save_access;
|
||||
protected:
|
||||
#endif
|
||||
void save_impl(long l){
|
||||
long ll = l;
|
||||
char size = 0;;
|
||||
do{
|
||||
ll >>= 8;
|
||||
++size;
|
||||
}while(ll != -1 && ll != 0);
|
||||
|
||||
os.put(size);
|
||||
|
||||
// we choose to use litle endian
|
||||
#ifdef BOOST_BIG_ENDIAN
|
||||
char * first = static_cast<char *>(static_cast<void *>(& l));
|
||||
char * last = first + size - 1;
|
||||
for(;first < last;++first, --last){
|
||||
char x = *first;
|
||||
*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
|
||||
// using binary_oarchive_impl<derived_t>::save;
|
||||
// using archive_base_t::save;
|
||||
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void save(const T & t){
|
||||
boost::archive::binary_oarchive_impl<derived_t>::save(t);
|
||||
save_impl(t, sizeof(T));
|
||||
}
|
||||
void save(const unsigned int t){
|
||||
save_impl(t);
|
||||
void save(const std::string & t){
|
||||
this->primitive_base_t::save(t);
|
||||
}
|
||||
void save(const 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 unsigned long 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 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 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) :
|
||||
boost::archive::binary_oarchive_impl<derived_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)){
|
||||
boost::archive::basic_binary_oarchive<derived_t>::init();
|
||||
// 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/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 basic_binary_oprimitive<portable_binary_oarchive, std::ostream> ;
|
||||
template class binary_oarchive_impl<portable_binary_oarchive> ;
|
||||
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
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// does STLport uses native STL for locales?
|
||||
#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) \
|
||||
&& defined(_STLP_NO_OWN_IOSTREAMS)
|
||||
#if (defined(__SGI_STL_PORT)&& defined(_STLP_NO_OWN_IOSTREAMS))
|
||||
// and this native STL lib is old Dinkumware (has not defined _CPPLIB_VER)
|
||||
# if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||
# if (defined(_YVALS) && !defined(__IBMCPP__)) || !defined(_CPPLIB_VER)
|
||||
# define BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <exception>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
@@ -28,7 +25,8 @@ namespace archive {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// exceptions thrown by archives
|
||||
//
|
||||
class archive_exception : public virtual std::exception
|
||||
class archive_exception :
|
||||
public virtual std::exception
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
@@ -114,5 +112,4 @@ protected:
|
||||
}// namespace archive
|
||||
}// namespace boost
|
||||
|
||||
#endif //BOOST_NO_EXCEPTIONS
|
||||
#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/strong_typedef.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
@@ -81,17 +85,24 @@ struct class_name_type : private boost::noncopyable {
|
||||
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_xml_tag_checking = 4, // suppress checking of xml tags
|
||||
no_tracking = 8, // suppress ALL tracking
|
||||
flags_last = 8
|
||||
};
|
||||
|
||||
extern const class_id_type null_pointer_tag;
|
||||
#define NULL_POINTER_TAG class_id_type(-1)
|
||||
|
||||
extern const char * ARCHIVE_SIGNATURE;
|
||||
extern const version_type ARCHIVE_VERSION;
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
ARCHIVE_SIGNATURE();
|
||||
|
||||
BOOST_ARCHIVE_DECL(unsigned char)
|
||||
ARCHIVE_VERSION();
|
||||
|
||||
}// namespace archive
|
||||
}// namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#include <boost/serialization/level.hpp>
|
||||
|
||||
// set implementation level to primitive for all types
|
||||
@@ -106,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
|
||||
|
||||
@@ -22,48 +22,44 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{ using ::memcpy; }
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/pfto.hpp>
|
||||
|
||||
#include <boost/archive/detail/interface_iarchive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
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>
|
||||
class basic_binary_iarchive :
|
||||
public detail::common_iarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
#else
|
||||
friend class detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
#endif
|
||||
// intermediate level to support override of operators
|
||||
// fot templates in the absence of partial function
|
||||
// template ordering
|
||||
// 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;
|
||||
template<class T>
|
||||
void load_override(T & t, BOOST_PFTO int)
|
||||
{
|
||||
archive::load(* this->This(), t);
|
||||
void load_override(T & t, BOOST_PFTO int version){
|
||||
this->detail_common_iarchive::load_override(t, static_cast<int>(version));
|
||||
}
|
||||
// binary files don't include the optional information
|
||||
void load_override(class_id_optional_type & /* t */, int){}
|
||||
@@ -72,57 +68,58 @@ protected:
|
||||
// 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);
|
||||
}
|
||||
|
||||
void load_override(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(
|
||||
archive_exception(archive_exception::invalid_class_name)
|
||||
);
|
||||
std::memcpy(t, cn.data(), cn.size());
|
||||
// .t is a borland tweak
|
||||
t.t[cn.size()] = '\0';
|
||||
}
|
||||
|
||||
basic_binary_iarchive() {}
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(class_name_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init();
|
||||
|
||||
basic_binary_iarchive(unsigned int flags) :
|
||||
detail::common_iarchive<Archive>(flags)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP
|
||||
|
||||
@@ -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
|
||||
//
|
||||
@@ -25,34 +29,40 @@
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
|
||||
#include <locale>
|
||||
#include <cstring> // std::memcpy
|
||||
#include <cstddef> // std::size_t
|
||||
#include <cstring>
|
||||
#include <streambuf> // basic_streambuf
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::memcpy;
|
||||
using ::strcpy;
|
||||
using ::size_t;
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
//#include <boost/limits.hpp>
|
||||
//#include <boost/io/ios_state.hpp>
|
||||
|
||||
#include <boost/archive/basic_streambuf_locale_saver.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/codecvt_null.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 {
|
||||
namespace archive {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class binary_iarchive - read serialized objects from a input binary stream
|
||||
template<class Archive, class IStream>
|
||||
template<class Archive, class Elem, class Tr>
|
||||
class basic_binary_iprimitive
|
||||
{
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -61,19 +71,16 @@ protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
std::basic_streambuf<Elem, Tr> & m_sb;
|
||||
// return a pointer to the most derived class
|
||||
Archive * This(){
|
||||
return static_cast<Archive *>(this);
|
||||
}
|
||||
// native streams are always handled as bytes
|
||||
IStream &is;
|
||||
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
boost::scoped_ptr<std::locale> archive_locale;
|
||||
// boost::scoped_ptr<
|
||||
// codecvt_null<BOOST_DEDUCED_TYPENAME IStream::char_type>
|
||||
// > archive_codecvt;
|
||||
io::basic_ios_locale_saver<
|
||||
BOOST_DEDUCED_TYPENAME IStream::char_type, BOOST_DEDUCED_TYPENAME IStream::traits_type
|
||||
> locale_saver;
|
||||
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
|
||||
#endif
|
||||
|
||||
// main template for serilization of primitive types
|
||||
template<class T>
|
||||
@@ -81,48 +88,90 @@ public:
|
||||
load_binary(& t, sizeof(T));
|
||||
}
|
||||
|
||||
void load(char * t);
|
||||
void load(wchar_t * t);
|
||||
void load(std::string &s);
|
||||
/////////////////////////////////////////////////////////
|
||||
// fundamental types that need special treatment
|
||||
|
||||
// trap usage of invalid uninitialized boolean
|
||||
void load(bool & t){
|
||||
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);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void load(std::wstring &ws);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load(std::wstring &ws);
|
||||
#endif
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load(char * t);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load(wchar_t * t);
|
||||
|
||||
void init();
|
||||
basic_binary_iprimitive(IStream &is_, bool no_codecvt);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init();
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_binary_iprimitive(
|
||||
std::basic_streambuf<Elem, Tr> & sb,
|
||||
bool no_codecvt
|
||||
);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
~basic_binary_iprimitive();
|
||||
public:
|
||||
void load_binary(void *address, std::size_t count);
|
||||
// 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);
|
||||
};
|
||||
|
||||
template<class Archive, class IStream>
|
||||
inline void basic_binary_iprimitive<Archive, IStream>::load_binary(
|
||||
template<class Archive, class Elem, class Tr>
|
||||
inline void
|
||||
basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
|
||||
void *address,
|
||||
std::size_t count
|
||||
){
|
||||
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),
|
||||
std::streamsize s = count / sizeof(Elem);
|
||||
std::streamsize scount = m_sb.sgetn(
|
||||
static_cast<Elem *>(address),
|
||||
s
|
||||
);
|
||||
if(scount != static_cast<std::streamsize>(s))
|
||||
boost::throw_exception(
|
||||
archive_exception(archive_exception::stream_error)
|
||||
);
|
||||
// note: an optimizer should eliminate the following for char files
|
||||
s = count % sizeof(BOOST_DEDUCED_TYPENAME IStream::char_type);
|
||||
s = count % sizeof(Elem);
|
||||
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);
|
||||
// if(is.fail())
|
||||
// boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
Elem t;
|
||||
scount = m_sb.sgetn(& t, 1);
|
||||
if(scount != 1)
|
||||
boost::throw_exception(
|
||||
archive_exception(archive_exception::stream_error)
|
||||
);
|
||||
std::memcpy(static_cast<char*>(address) + (count - s), &t, s);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pop pragams
|
||||
|
||||
#endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP
|
||||
|
||||
@@ -27,10 +27,9 @@
|
||||
#include <boost/pfto.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/archive/detail/interface_oarchive.hpp>
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -43,52 +42,49 @@ 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>
|
||||
class basic_binary_oarchive :
|
||||
public archive::detail::common_oarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
#else
|
||||
friend class detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
#endif
|
||||
// any datatype not specifed below will be handled
|
||||
// by this function
|
||||
// any datatype not specifed below will be handled by base class
|
||||
typedef detail::common_oarchive<Archive> detail_common_oarchive;
|
||||
template<class T>
|
||||
void save_override(const T & t, BOOST_PFTO int)
|
||||
{
|
||||
archive::save(* this->This(), t);
|
||||
void save_override(const T & t, BOOST_PFTO int version){
|
||||
this->detail_common_oarchive::save_override(t, static_cast<int>(version));
|
||||
}
|
||||
|
||||
// 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){
|
||||
@@ -97,16 +93,28 @@ protected:
|
||||
* this->This() << x;
|
||||
}
|
||||
void save_override(const tracking_type & t, int){
|
||||
char x = t.t;
|
||||
const char x = t.t;
|
||||
* this->This() << x;
|
||||
}
|
||||
|
||||
// explicitly convert to char * to avoid compile ambiguities
|
||||
void save_override(const class_name_type & t, int){
|
||||
* this->This() << std::string(static_cast<const char *>(t));
|
||||
const std::string s(t);
|
||||
* this->This() << s;
|
||||
}
|
||||
|
||||
basic_binary_oarchive(unsigned int flags = 0){}
|
||||
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)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <cassert>
|
||||
#include <locale>
|
||||
#include <cstddef> // size_t
|
||||
#include <streambuf> // basic_streambuf
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
@@ -36,12 +38,18 @@ namespace std{
|
||||
#endif
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
//#include <boost/limits.hpp>
|
||||
//#include <boost/io/ios_state.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/archive/basic_streambuf_locale_saver.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/serialization/is_bitwise_serializable.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -49,7 +57,7 @@ namespace archive {
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class basic_binary_oprimitive - binary output of prmitives
|
||||
|
||||
template<class Archive, class OStream>
|
||||
template<class Archive, class Elem, class Tr>
|
||||
class basic_binary_oprimitive
|
||||
{
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -58,18 +66,15 @@ protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
std::basic_streambuf<Elem, Tr> & m_sb;
|
||||
// return a pointer to the most derived class
|
||||
Archive * This(){
|
||||
return static_cast<Archive *>(this);
|
||||
}
|
||||
// native binary streams are handled as bytes
|
||||
OStream &os;
|
||||
#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;
|
||||
|
||||
basic_streambuf_locale_saver<Elem, Tr> locale_saver;
|
||||
#endif
|
||||
// default saving of primitives.
|
||||
template<class T>
|
||||
void save(const T & t)
|
||||
@@ -77,45 +82,92 @@ public:
|
||||
save_binary(& t, sizeof(T));
|
||||
}
|
||||
|
||||
void save(const char * t);
|
||||
void save(const wchar_t * t);
|
||||
void save(const std::string &s);
|
||||
/////////////////////////////////////////////////////////
|
||||
// fundamental types that need special treatment
|
||||
|
||||
// trap usage of invalid uninitialized boolean which would
|
||||
// otherwise crash on load.
|
||||
void save(const bool t){
|
||||
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
|
||||
save_binary(& t, sizeof(t));
|
||||
}
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save(const std::string &s);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void save(const std::wstring &ws);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save(const std::wstring &ws);
|
||||
#endif
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save(const char * t);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save(const wchar_t * t);
|
||||
|
||||
void init();
|
||||
basic_binary_oprimitive(OStream & os, bool no_codecvt);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init();
|
||||
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_binary_oprimitive(
|
||||
std::basic_streambuf<Elem, Tr> & sb,
|
||||
bool no_codecvt
|
||||
);
|
||||
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);
|
||||
};
|
||||
|
||||
template<class Archive, class OStream>
|
||||
inline void basic_binary_oprimitive<Archive, OStream>::save_binary(
|
||||
template<class Archive, class Elem, class Tr>
|
||||
inline void
|
||||
basic_binary_oprimitive<Archive, Elem, Tr>::save_binary(
|
||||
const void *address,
|
||||
std::size_t count
|
||||
){
|
||||
assert(
|
||||
static_cast<std::size_t>(std::numeric_limits<std::streamsize>::max()) >= count
|
||||
);
|
||||
//assert(
|
||||
// static_cast<std::size_t>((std::numeric_limits<std::streamsize>::max)()) >= count
|
||||
//);
|
||||
// note: if the following assertions fail
|
||||
// a likely cause is that the output stream is set to "text"
|
||||
// mode where by cr characters recieve special treatment.
|
||||
// be sure that the output stream is opened with ios::binary
|
||||
if(os.fail())
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
//if(os.fail())
|
||||
// boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
// figure number of elements to output - round up
|
||||
count = ( count + sizeof(BOOST_DEDUCED_TYPENAME OStream::char_type) - 1)
|
||||
/ sizeof(BOOST_DEDUCED_TYPENAME OStream::char_type);
|
||||
os.write(
|
||||
static_cast<const BOOST_DEDUCED_TYPENAME OStream::char_type *>(address),
|
||||
count = ( count + sizeof(Elem) - 1)
|
||||
/ sizeof(Elem);
|
||||
std::streamsize scount = m_sb.sputn(
|
||||
static_cast<const Elem *>(address),
|
||||
count
|
||||
);
|
||||
assert(os.good());
|
||||
if(count != static_cast<std::size_t>(scount))
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
//os.write(
|
||||
// static_cast<const BOOST_DEDUCED_TYPENAME OStream::char_type *>(address),
|
||||
// count
|
||||
//);
|
||||
//assert(os.good());
|
||||
}
|
||||
|
||||
} //namespace boost
|
||||
} //namespace archive
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pop pragams
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP
|
||||
#define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_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
|
||||
// basic_streambuf_local_saver.hpp
|
||||
|
||||
// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// note derived from boost/io/ios_state.hpp
|
||||
// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution
|
||||
// are subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
// See <http://www.boost.org/libs/io/> for the library's home page.
|
||||
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
|
||||
#include <locale> // for std::locale
|
||||
#include <streambuf> // for std::basic_streambuf
|
||||
|
||||
namespace boost{
|
||||
namespace archive{
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_streambuf_locale_saver
|
||||
{
|
||||
public:
|
||||
typedef ::std::basic_streambuf<Ch, Tr> state_type;
|
||||
typedef ::std::locale aspect_type;
|
||||
explicit basic_streambuf_locale_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.getloc() )
|
||||
{}
|
||||
basic_streambuf_locale_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.pubimbue(a) )
|
||||
{}
|
||||
~basic_streambuf_locale_saver()
|
||||
{ this->restore(); }
|
||||
void restore()
|
||||
{ s_save_.pubimbue( a_save_ ); }
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
};
|
||||
|
||||
} // archive
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_NO_STD_LOCALE
|
||||
#endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP
|
||||
@@ -28,46 +28,57 @@
|
||||
#include <boost/pfto.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/archive/detail/interface_iarchive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
|
||||
#include <boost/serialization/string.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class basic_text_iarchive - read serialized objects from a input text stream
|
||||
template<class Archive>
|
||||
class basic_text_iarchive : public detail::common_iarchive<Archive>
|
||||
class basic_text_iarchive :
|
||||
public detail::common_iarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
#else
|
||||
friend class detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
#endif
|
||||
// intermediate level to support override of operators
|
||||
// fot templates in the absence of partial function
|
||||
// template ordering
|
||||
typedef detail::common_iarchive<Archive> detail_common_iarchive;
|
||||
template<class T>
|
||||
void load_override(T & t, BOOST_PFTO int){
|
||||
archive::load(* this->This(), t);
|
||||
void load_override(T & t, BOOST_PFTO int)
|
||||
{
|
||||
this->detail_common_iarchive::load_override(t, 0);
|
||||
}
|
||||
// text file don't include the optional information
|
||||
void load_override(class_id_optional_type & /*t*/, int){}
|
||||
void load_override(class_name_type & t, int);
|
||||
basic_text_iarchive() :
|
||||
detail::common_iarchive<Archive>()
|
||||
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(class_name_type & t, int);
|
||||
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init(void);
|
||||
|
||||
basic_text_iarchive(unsigned int flags) :
|
||||
detail::common_iarchive<Archive>(flags)
|
||||
{}
|
||||
~basic_text_iarchive(){}
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace std{
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/codecvt_null.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -65,12 +66,15 @@ protected:
|
||||
public:
|
||||
#endif
|
||||
IStream &is;
|
||||
io::ios_flags_saver flags_saver;
|
||||
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)
|
||||
@@ -113,15 +117,18 @@ public:
|
||||
t = static_cast<wchar_t>(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
basic_text_iprimitive(IStream &is, bool no_codecvt);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_text_iprimitive(IStream &is, bool no_codecvt);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
~basic_text_iprimitive();
|
||||
public:
|
||||
void load_binary(void *address, std::size_t count);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_binary(void *address, std::size_t count);
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pop pragams
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP
|
||||
|
||||
@@ -27,30 +27,32 @@
|
||||
#include <cassert>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/pfto.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
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>
|
||||
class basic_text_oarchive :
|
||||
public detail::common_oarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
|
||||
|| BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x560))
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
#else
|
||||
friend class detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
#endif
|
||||
enum {
|
||||
none,
|
||||
@@ -58,68 +60,75 @@ protected:
|
||||
space
|
||||
} delimiter;
|
||||
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
newtoken();
|
||||
|
||||
void newline(){
|
||||
delimiter = eol;
|
||||
}
|
||||
|
||||
void newtoken();
|
||||
|
||||
// default processing - invoke serialization library
|
||||
// default processing - kick back to base class. Note the
|
||||
// extra stuff to get it passed borland compilers
|
||||
typedef detail::common_oarchive<Archive> detail_common_oarchive;
|
||||
template<class T>
|
||||
void save_override(const T & t, BOOST_PFTO int)
|
||||
{
|
||||
archive::save(* this->This(), t);
|
||||
void save_override(T & t, BOOST_PFTO int){
|
||||
this->detail_common_oarchive::save_override(t, 0);
|
||||
}
|
||||
|
||||
// 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){}
|
||||
|
||||
void save_override(const class_name_type & t, int){
|
||||
this->This()->save(std::string(static_cast<const char *>(t)));
|
||||
const std::string s(t);
|
||||
* this->This() << s;
|
||||
}
|
||||
protected:
|
||||
basic_text_oarchive() :
|
||||
detail::common_oarchive<Archive>(),
|
||||
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init();
|
||||
|
||||
basic_text_oarchive(unsigned int flags) :
|
||||
detail::common_oarchive<Archive>(flags),
|
||||
delimiter(none)
|
||||
{}
|
||||
~basic_text_oarchive()
|
||||
{}
|
||||
~basic_text_oarchive(){}
|
||||
};
|
||||
|
||||
template<class Archive>
|
||||
void basic_text_oarchive<Archive>::newtoken()
|
||||
{
|
||||
switch(delimiter){
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
case eol:
|
||||
this->This()->put('\n');
|
||||
delimiter = space;
|
||||
break;
|
||||
case space:
|
||||
this->This()->put(' ');
|
||||
break;
|
||||
case none:
|
||||
delimiter = space;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP
|
||||
|
||||
@@ -24,17 +24,18 @@
|
||||
// in such cases. So we can't use basic_ostream<OStream::char_type> but rather
|
||||
// use two template parameters
|
||||
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <cstddef> // size_t
|
||||
#include <cmath> // isnan
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
#include <boost/archive/dinkumware.hpp>
|
||||
#endif
|
||||
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::size_t;
|
||||
@@ -48,9 +49,9 @@ namespace std{
|
||||
#include <boost/io/ios_state.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/codecvt_null.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -62,16 +63,21 @@ class save_access;
|
||||
template<class OStream>
|
||||
class basic_text_oprimitive
|
||||
{
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
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;
|
||||
// boost::scoped_ptr<codecvt_null<BOOST_DEDUCED_TYPENAME OStream::char_type> >
|
||||
// archive_codecvt;
|
||||
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>
|
||||
@@ -83,6 +89,14 @@ protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// fundamental types that need special treatment
|
||||
void save(const bool t){
|
||||
// trap usage of invalid uninitialized boolean which would
|
||||
// otherwise crash on load.
|
||||
assert(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
|
||||
if(os.fail())
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
os << t;
|
||||
}
|
||||
void save(const signed char t)
|
||||
{
|
||||
if(os.fail())
|
||||
@@ -111,6 +125,7 @@ protected:
|
||||
#endif
|
||||
void save(const float t)
|
||||
{
|
||||
// must be a user mistake - can't serialize un-initialized data
|
||||
if(os.fail())
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
os << std::setprecision(std::numeric_limits<float>::digits10 + 2);
|
||||
@@ -118,11 +133,16 @@ protected:
|
||||
}
|
||||
void save(const double t)
|
||||
{
|
||||
// must be a user mistake - can't serialize un-initialized data
|
||||
if(os.fail())
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
os << std::setprecision(std::numeric_limits<double>::digits10 + 2);
|
||||
os << t;
|
||||
}
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_text_oprimitive(OStream & os, bool no_codecvt);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
~basic_text_oprimitive();
|
||||
public:
|
||||
// unformatted append of one character
|
||||
void put(int c){
|
||||
@@ -130,7 +150,6 @@ public:
|
||||
boost::throw_exception(archive_exception(archive_exception::stream_error));
|
||||
os.put(c);
|
||||
}
|
||||
|
||||
// unformatted append of null terminated string
|
||||
void put(const char * s){
|
||||
if(os.fail())
|
||||
@@ -138,14 +157,13 @@ public:
|
||||
while('\0' != *s)
|
||||
os.put(*s++);
|
||||
}
|
||||
|
||||
basic_text_oprimitive(OStream & os, bool no_codecvt);
|
||||
~basic_text_oprimitive();
|
||||
public:
|
||||
void save_binary(const void *address, std::size_t count);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_binary(const void *address, std::size_t count);
|
||||
};
|
||||
|
||||
} //namespace boost
|
||||
} //namespace archive
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP
|
||||
|
||||
@@ -16,53 +16,52 @@
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
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
|
||||
} 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;
|
||||
default:
|
||||
msg = archive_exception::what();
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
// constant strings used in xml i/o
|
||||
extern const char * OBJECT_ID;
|
||||
extern const char * OBJECT_REFERENCE;
|
||||
extern const char * CLASS_ID;
|
||||
extern const char * CLASS_ID_REFERENCE;
|
||||
extern const char * CLASS_NAME;
|
||||
extern const char * TRACKING;
|
||||
extern const char * VERSION;
|
||||
extern const char * SIGNATURE;
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
OBJECT_ID();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
OBJECT_REFERENCE();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
CLASS_ID();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
CLASS_ID_REFERENCE();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
CLASS_NAME();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
TRACKING();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
VERSION();
|
||||
|
||||
extern
|
||||
BOOST_ARCHIVE_DECL(const char *)
|
||||
SIGNATURE();
|
||||
|
||||
}// namespace archive
|
||||
}// namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP
|
||||
|
||||
|
||||
@@ -9,24 +9,25 @@
|
||||
/////////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)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/pfto.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/archive/detail/interface_iarchive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/string.hpp> // makes strings prmitive
|
||||
#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 archive {
|
||||
@@ -34,24 +35,24 @@ namespace archive {
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class xml_iarchive - read serialized objects from a input text stream
|
||||
template<class Archive>
|
||||
class basic_xml_iarchive : public detail::common_iarchive<Archive>
|
||||
class basic_xml_iarchive :
|
||||
public detail::common_iarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
friend detail::interface_oarchive<Archive>;
|
||||
#else
|
||||
friend class detail::interface_iarchive<Archive>;
|
||||
protected:
|
||||
friend class detail::interface_oarchive<Archive>;
|
||||
#endif
|
||||
bool header;
|
||||
bool no_checking;
|
||||
unsigned int depth;
|
||||
void load_start(const char *name);
|
||||
void load_end(const char *name);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_start(const char *name);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_end(const char *name);
|
||||
|
||||
// Anything not an attribute and not a name-value pair is an
|
||||
// should be trapped here.
|
||||
@@ -61,16 +62,23 @@ protected:
|
||||
// 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
|
||||
// pair and be processed here
|
||||
typedef detail::common_iarchive<Archive> detail_common_iarchive;
|
||||
template<class T>
|
||||
void load_override(boost::serialization::nvp<T> & t, int)
|
||||
{
|
||||
void load_override(
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
const
|
||||
#endif
|
||||
boost::serialization::nvp<T> & t,
|
||||
int
|
||||
){
|
||||
load_start(t.name());
|
||||
archive::load(* this->This(), t.value());
|
||||
this->detail_common_iarchive::load_override(t.value(), 0);
|
||||
load_end(t.name());
|
||||
}
|
||||
|
||||
@@ -83,23 +91,28 @@ protected:
|
||||
// it otherwise it will be loaded as a normal primitive w/o tag and
|
||||
// leaving the archive in an undetermined state
|
||||
void load_override(class_id_optional_type & /* t */, int){}
|
||||
void load_override(object_id_type & t, int);
|
||||
void load_override(version_type & t, int);
|
||||
void load_override(class_id_type & t, int);
|
||||
void load_override(tracking_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(object_id_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(version_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(class_id_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
load_override(tracking_type & t, int);
|
||||
// class_name_type can't be handled here as it depends upon the
|
||||
// char type used by the stream. So require the derived implementation
|
||||
// handle this.
|
||||
// void load_override(class_name_type & t, int);
|
||||
|
||||
basic_xml_iarchive(unsigned int flags = 0) :
|
||||
header(false),
|
||||
no_checking(false),
|
||||
depth(0)
|
||||
{}
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_xml_iarchive(unsigned int flags);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
~basic_xml_iarchive();
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP
|
||||
|
||||
@@ -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)
|
||||
@@ -17,7 +17,6 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
|
||||
@@ -25,82 +24,114 @@
|
||||
#include <boost/serialization/tracking.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
|
||||
namespace boost {
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// class xml_oarchive - write serialized objects to a xml output stream
|
||||
// class basic_xml_oarchive - write serialized objects to a xml output stream
|
||||
template<class Archive>
|
||||
class basic_xml_oarchive : public detail::common_oarchive<Archive>
|
||||
class basic_xml_oarchive :
|
||||
public detail::common_oarchive<Archive>
|
||||
{
|
||||
protected:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
#elif defined(BOOST_MSVC)
|
||||
// for some inexplicable reason insertion of "class" generates compile erro
|
||||
// on msvc 7.1
|
||||
friend detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
friend class save_access;
|
||||
#else
|
||||
friend class detail::interface_oarchive<Archive>;
|
||||
protected:
|
||||
friend class save_access;
|
||||
#endif
|
||||
// special stuff for xml output
|
||||
unsigned int depth;
|
||||
bool indent_next;
|
||||
bool pending_preamble;
|
||||
bool header;
|
||||
void indent();
|
||||
void init();
|
||||
void write_attribute(
|
||||
const char *attribute_name,
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
indent();
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
init();
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
write_attribute(
|
||||
const char *attribute_name,
|
||||
int t,
|
||||
const char *conjunction = "=\""
|
||||
);
|
||||
void write_attribute(
|
||||
const char *attribute_name,
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
write_attribute(
|
||||
const char *attribute_name,
|
||||
const char *key
|
||||
);
|
||||
// helpers used below
|
||||
void save_start(const char *name);
|
||||
void save_end(const char *name);
|
||||
void end_preamble();
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_start(const char *name);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_end(const char *name);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
end_preamble();
|
||||
|
||||
// Anything not an attribute and not a name-value pair is an
|
||||
// error and should be trapped here.
|
||||
template<class T>
|
||||
void save_override(const T & t, BOOST_PFTO int)
|
||||
void save_override(T & t, BOOST_PFTO int)
|
||||
{
|
||||
// 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.
|
||||
typedef detail::common_oarchive<Archive> detail_common_oarchive;
|
||||
template<class T>
|
||||
void save_override(const ::boost::serialization::nvp<T> & t, int)
|
||||
{
|
||||
this->This()->save_start(t.name());
|
||||
archive::save(* this->This(), t.value());
|
||||
this->This()->save_end(t.name());
|
||||
void save_override(
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
const
|
||||
#endif
|
||||
::boost::serialization::nvp<T> & t,
|
||||
int
|
||||
){
|
||||
save_start(t.name());
|
||||
this->detail_common_oarchive::save_override(t.const_value(), 0);
|
||||
save_end(t.name());
|
||||
}
|
||||
|
||||
// specific overrides for attributes - not name value pairs so we
|
||||
// want to trap them before the above "fall through"
|
||||
void save_override(const object_id_type & t, int);
|
||||
void save_override(const object_reference_type & t, int);
|
||||
void save_override(const version_type & t, int);
|
||||
void save_override(const class_id_type & t, int);
|
||||
void save_override(const class_id_optional_type & t, int);
|
||||
void save_override(const class_id_reference_type & t, int);
|
||||
void save_override(const class_name_type & t, int);
|
||||
void save_override(const tracking_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const object_id_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const object_reference_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const version_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const class_id_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const class_id_optional_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const class_id_reference_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const class_name_type & t, int);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
||||
save_override(const tracking_type & t, int);
|
||||
|
||||
basic_xml_oarchive(unsigned int flags = 0);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
basic_xml_oarchive(unsigned int flags);
|
||||
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
||||
~basic_xml_oarchive();
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP
|
||||
|
||||
@@ -17,73 +17,77 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <istream>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/archive/basic_binary_iarchive.hpp>
|
||||
#include <boost/archive/basic_binary_iprimitive.hpp>
|
||||
#include <boost/archive/binary_iarchive_impl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template<class Archive>
|
||||
class binary_iarchive_impl :
|
||||
public basic_binary_iprimitive<Archive, std::istream>,
|
||||
public basic_binary_iarchive<Archive>
|
||||
{
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class detail::interface_iarchive<Archive>;
|
||||
friend class basic_binary_iarchive<Archive>;
|
||||
friend class load_access;
|
||||
protected:
|
||||
#endif
|
||||
// note: the following should not needed - but one compiler (vc 7.1)
|
||||
// fails to compile one test (test_shared_ptr) without it !!!
|
||||
// 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);
|
||||
}
|
||||
void init(){
|
||||
basic_binary_iarchive<Archive>::init();
|
||||
basic_binary_iprimitive<Archive, std::istream>::init();
|
||||
}
|
||||
binary_iarchive_impl(std::istream & is, unsigned int flags = 0) :
|
||||
basic_binary_iprimitive<Archive, std::istream>(
|
||||
is,
|
||||
0 != (flags & no_codecvt)
|
||||
)
|
||||
{
|
||||
if(0 == (flags & no_header)){
|
||||
#if ! defined(__MWERKS__)
|
||||
this->basic_binary_iarchive<Archive>::init();
|
||||
this->basic_binary_iprimitive<Archive, std::istream>::init();
|
||||
#else
|
||||
basic_binary_iarchive<Archive>::init();
|
||||
basic_binary_iprimitive<Archive, std::istream>::init();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// do not derive from this class. If you want to extend this functionality
|
||||
// via inhertance, derived from binary_iarchive_impl instead. This will
|
||||
// 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.
|
||||
class binary_iarchive :
|
||||
public binary_iarchive_impl<binary_iarchive>
|
||||
|
||||
// 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:
|
||||
binary_iarchive(std::istream & is, unsigned int flags = 0) :
|
||||
binary_iarchive_impl<binary_iarchive>(is, flags)
|
||||
{
|
||||
}
|
||||
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
|
||||
|
||||
// required by smart_cast for compilers not implementing
|
||||
// partial template specialization
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::archive::binary_iarchive)
|
||||
// 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.
|
||||
class binary_iarchive :
|
||||
public binary_iarchive_impl<
|
||||
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) :
|
||||
binary_iarchive_impl<
|
||||
binary_iarchive, std::istream::char_type, std::istream::traits_type
|
||||
>(is, flags)
|
||||
{}
|
||||
binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) :
|
||||
binary_iarchive_impl<
|
||||
binary_iarchive, std::istream::char_type, std::istream::traits_type
|
||||
>(bsb, flags)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive)
|
||||
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive)
|
||||
|
||||
#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP
|
||||
#define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_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
|
||||
// binary_iarchive_impl.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 <istream>
|
||||
#include <boost/pfto.hpp>
|
||||
#include <boost/archive/basic_binary_iprimitive.hpp>
|
||||
#include <boost/archive/basic_binary_iarchive.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template<class Archive, class Elem, class Tr>
|
||||
class binary_iarchive_impl :
|
||||
public basic_binary_iprimitive<Archive, Elem, Tr>,
|
||||
public basic_binary_iarchive<Archive>
|
||||
{
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class detail::interface_iarchive<Archive>;
|
||||
friend class basic_binary_iarchive<Archive>;
|
||||
friend class load_access;
|
||||
protected:
|
||||
#endif
|
||||
// note: the following should not needed - but one compiler (vc 7.1)
|
||||
// fails to compile one test (test_shared_ptr) without it !!!
|
||||
// make this protected so it can be called from a derived archive
|
||||
template<class T>
|
||||
void load_override(T & t, BOOST_PFTO int){
|
||||
this->basic_binary_iarchive<Archive>::load_override(t, 0L);
|
||||
}
|
||||
void init(unsigned int flags){
|
||||
if(0 != (flags & no_header))
|
||||
return;
|
||||
#if ! defined(__MWERKS__)
|
||||
this->basic_binary_iarchive<Archive>::init();
|
||||
this->basic_binary_iprimitive<Archive, Elem, Tr>::init();
|
||||
#else
|
||||
basic_binary_iarchive<Archive>::init();
|
||||
basic_binary_iprimitive<Archive, Elem, Tr>::init();
|
||||
#endif
|
||||
}
|
||||
binary_iarchive_impl(
|
||||
std::basic_streambuf<Elem, Tr> & bsb,
|
||||
unsigned int flags
|
||||
) :
|
||||
basic_binary_iprimitive<Archive, Elem, Tr>(
|
||||
bsb,
|
||||
0 != (flags & no_codecvt)
|
||||
),
|
||||
basic_binary_iarchive<Archive>(flags)
|
||||
{
|
||||
init(flags);
|
||||
}
|
||||
binary_iarchive_impl(
|
||||
std::basic_istream<Elem, Tr> & is,
|
||||
unsigned int flags
|
||||
) :
|
||||
basic_binary_iprimitive<Archive, Elem, Tr>(
|
||||
* is.rdbuf(),
|
||||
0 != (flags & no_codecvt)
|
||||
),
|
||||
basic_binary_iarchive<Archive>(flags)
|
||||
{
|
||||
init(flags);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user