mirror of
https://github.com/boostorg/serialization.git
synced 2026-07-22 13:43:39 +00:00
Compare commits
1275 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a20c4d97c3 | |||
| 9aa208d9be | |||
| ff0a5f9f4a | |||
| e01b988e70 | |||
| e4756b71b5 | |||
| f3eaf91ca1 | |||
| a2f93247e2 | |||
| 01c26ba107 | |||
| 404e0a31ae | |||
| 90e3ce2fb9 | |||
| 897dec4c01 | |||
| f28482232d | |||
| 6388138a0c | |||
| 8d0fbb79f3 | |||
| 61a2b12076 | |||
| 5ba9e77ad6 | |||
| 74c46ec43c | |||
| 1af820b02e | |||
| cb729f5d88 | |||
| ae305113ff | |||
| c241d3485c | |||
| 9cd8257b08 | |||
| 030b627dce | |||
| 14b10185de | |||
| 0e15a5984b | |||
| dfe5c018f8 | |||
| f395fa35fa | |||
| 52bcaffa8c | |||
| 48a60a2bbb | |||
| 9a72e5407b | |||
| ab1da83f40 | |||
| 60a28371c5 | |||
| 2cda20b221 | |||
| ae69bf4ba9 | |||
| f3c564c1fd | |||
| 5e8c130c5e | |||
| bb4d07e874 | |||
| cc2d5dc850 | |||
| 7d0e15503f | |||
| d56e16b391 | |||
| 0e64d96019 | |||
| b83e440efe | |||
| 2aabad74cc | |||
| 5b08b01437 | |||
| 9bd9550ad1 | |||
| be9421f80f | |||
| cf5d908a8b | |||
| 856eb3a567 | |||
| efddba7b8f | |||
| ef7e8c4ca5 | |||
| a0d30cbb18 | |||
| a278309f29 | |||
| 85cb258dd2 | |||
| 87e657de24 | |||
| 7a70b2fca2 | |||
| b7b504829f | |||
| 3a58de12d5 | |||
| 58d722996e | |||
| a456d33e25 | |||
| c977d4e623 | |||
| a7a8704438 | |||
| 48d47e4ed6 | |||
| 3f322d4adc | |||
| df2e6703c3 | |||
| 670648f276 | |||
| 88d270543b | |||
| 2012f8c184 | |||
| 8cdb837bb9 | |||
| b87d54da86 | |||
| 473e02755f | |||
| 3f46a64ff4 | |||
| 532a1c5e26 | |||
| a8bbb11cd2 | |||
| b7ae64e95c | |||
| 08b257f927 | |||
| b4412f2867 | |||
| 358b3e0894 | |||
| 3fa5669d72 | |||
| bef84802a2 | |||
| d1390bb7b6 | |||
| e4852c641c | |||
| 0fd717cc88 | |||
| 52fa997bb8 | |||
| 45b0789b1a | |||
| 0ca603daf9 | |||
| 09e40888f5 | |||
| 78ee5d14a9 | |||
| b42c138206 | |||
| f13c963569 | |||
| ff6cc13040 | |||
| bcc0bfe073 | |||
| 337b3fbc7c | |||
| f540ab6c78 | |||
| ef69de1981 | |||
| 6ddac39d4b | |||
| a34e423069 | |||
| 9f1fc77d46 | |||
| fa6b395b54 | |||
| 63cf849d7f | |||
| 520cf46d31 | |||
| 1839f7b37e | |||
| 47119842b7 | |||
| 35ccd63f56 | |||
| 781dd9f0f2 | |||
| 7c2229df8c | |||
| cd7f64e0d7 | |||
| 4b851994d6 | |||
| 6bf961f31e | |||
| 3ab4da85f2 | |||
| 9b9e21625f | |||
| aba637361a | |||
| b7e454f52f | |||
| e4727d0c23 | |||
| 886080ef55 | |||
| 11ab51f97c | |||
| e7e5978a54 | |||
| c5d199837b | |||
| ddf65a2666 | |||
| 6296d56682 | |||
| 447445837f | |||
| 07de314975 | |||
| 8899617fba | |||
| 07c99b8649 | |||
| 6dc1b1be94 | |||
| f72b9fc8d9 | |||
| 1eb86f8c41 | |||
| e94aebed7a | |||
| bd2b756986 | |||
| 8acf32935b | |||
| ed44fcd268 | |||
| 812ef99dea | |||
| 17fb465af1 | |||
| cfed656eb0 | |||
| 4dd4895246 | |||
| 676722671e | |||
| b672e87f9d | |||
| 4fb556f9c4 | |||
| f4c6d58bb5 | |||
| 6af3783a2c | |||
| c7761f2335 | |||
| 4dc4ba018c | |||
| 753c157497 | |||
| 97f7767505 | |||
| 2bbb0577a9 | |||
| f19034cc9e | |||
| aa4b6422db | |||
| 2dbe7b8005 | |||
| 1a13d6e552 | |||
| f914a185c3 | |||
| 0eec916ab2 | |||
| 88094d44b6 | |||
| 53047f6356 | |||
| 7e0708ea5d | |||
| d0509483ed | |||
| d95a1df37a | |||
| eac306d8a6 | |||
| 998e6c3d59 | |||
| b22ffc63da | |||
| 489eef0e17 | |||
| 443dea34ab | |||
| 76df6df23f | |||
| 643cce2a9c | |||
| 098019d074 | |||
| ece3187e24 | |||
| c813db7ad7 | |||
| f04a8cbe90 | |||
| 0f0409a2ad | |||
| 6bd667a5bb | |||
| 5dd938f4f1 | |||
| 4ed898b1d3 | |||
| 7300ff02b9 | |||
| fd8186018b | |||
| c32a663c99 | |||
| 48f0844fda | |||
| 84e9ab57a7 | |||
| 0034b070bd | |||
| 1b11637b1c | |||
| 7d79dc7146 | |||
| 8d4b2136d2 | |||
| 7adafcbf01 | |||
| 669d266ec7 | |||
| 361ed95f4c | |||
| b6d26f9a58 | |||
| cd8a989be4 | |||
| ee50f8c911 | |||
| d526c0f80e | |||
| a61f5d2563 | |||
| 03c6d23ce8 | |||
| 9c770604dc | |||
| b78cd872ec | |||
| 6e3d1a89f7 | |||
| 854dd12473 | |||
| f01148e421 | |||
| cc2a996384 | |||
| 9e98df0a0d | |||
| feb53726e1 | |||
| b97bcdfeb3 | |||
| 723bd44abd | |||
| f297d80d6e | |||
| efcd46eb1b | |||
| 5778b99fd2 | |||
| c5549b2d6b | |||
| 237ff81ac6 | |||
| 65f05dc209 | |||
| 86996d0637 | |||
| 5c19264436 | |||
| af46ac2da3 | |||
| e1893dd28c | |||
| da9c3059f2 | |||
| 28c333ce65 | |||
| 5edc5acf27 | |||
| c5120dfd11 | |||
| 87c50e75fa | |||
| 738695b707 | |||
| 08455abe23 | |||
| 90e22bb58b | |||
| 449e659de3 | |||
| 4986fc2097 | |||
| 52cbea8c16 | |||
| ed435d5a31 | |||
| a362331b93 | |||
| b430b6d674 | |||
| 2792359662 | |||
| 7a078733a1 | |||
| 75c224103d | |||
| 297b7c3b52 | |||
| 8ca532a4d5 | |||
| 226af45461 | |||
| b4b8cbab00 | |||
| 3c438dfddb | |||
| 2b61be1285 | |||
| d3bb8d0e50 | |||
| 89dc4a26b1 | |||
| 6477759341 | |||
| 69d1b26937 | |||
| bc0279429b | |||
| b73329fe45 | |||
| 63b6ffa765 | |||
| 24024425f1 | |||
| 4ee479a03e | |||
| 8378c75f32 | |||
| 7d216b4761 | |||
| f94da2c724 | |||
| fea1826e06 | |||
| 8eb388fe39 | |||
| 8bbcca5341 | |||
| 0676016ce3 | |||
| be2846e2d1 | |||
| b87dc62e69 | |||
| 2c2a4a53d0 | |||
| eb35302b76 | |||
| a2a8890dfb | |||
| f4be906175 | |||
| 2e8e91a5cc | |||
| 089d57b855 | |||
| 0ba417dd1c | |||
| 9e90f233a1 | |||
| 9e7cd200e7 | |||
| d327f90bd8 | |||
| 8d0b0db5de | |||
| daf20da064 | |||
| 71851223c3 | |||
| 64dc620992 | |||
| 40314f94df | |||
| d21a064a69 | |||
| 3d179caaec | |||
| cd2f77defb | |||
| 621a3ea8a3 | |||
| 8b4e08490b | |||
| f44dc8da2c | |||
| 480a8c94b0 | |||
| 2557639490 | |||
| 932b4221ff | |||
| a5cb34ff8e | |||
| 0bccdf6da7 | |||
| ad1e1e5d5a | |||
| dd09b03d33 | |||
| 96f818ee03 | |||
| 791f1bde64 | |||
| d1ed17a656 | |||
| 8b7e756746 | |||
| eaf85795f3 | |||
| 81b44504c5 | |||
| bebea0fda9 | |||
| 0c8a1d615a | |||
| 632df7aab5 | |||
| 49f8f59da2 | |||
| 0a87904d14 | |||
| b0a794da38 | |||
| 62bf8fc1e1 | |||
| 09730b8741 | |||
| 1d86261581 | |||
| 6456a6d18f | |||
| c936a94c1a | |||
| 4dc778270a | |||
| 4bd64df332 | |||
| acbd1f88f9 | |||
| aba55e6180 | |||
| 51b1df323b | |||
| 247f223d82 | |||
| 619250c93a | |||
| 66ccdc00f1 | |||
| a8bbbea4e7 | |||
| c3552e1d03 | |||
| c518afa8ad | |||
| 29593efac2 | |||
| 5986edcfd3 | |||
| d558b6da91 | |||
| 4d11c54e60 | |||
| 1fda900179 | |||
| 0c7141fb78 | |||
| 6e24d1eb48 | |||
| fceaca0a34 | |||
| b98b458293 | |||
| 26366fecb5 | |||
| 058f1fed43 | |||
| 6b33d1cd4e | |||
| ec74c5a143 | |||
| 58b4f73c70 | |||
| 06fe1b7154 | |||
| e653bfe110 | |||
| 682c371e11 | |||
| 5b47212c01 | |||
| f09c9b197e | |||
| 3bc713367e | |||
| 7f801c3d85 | |||
| 3e0f302eee | |||
| 19e2ef234b | |||
| a1ffe9b19b | |||
| c90e97eb1e | |||
| fe8b390588 | |||
| 8e26bc59db | |||
| 9a2c1f11ab | |||
| df38b48016 | |||
| 7c97ddd99e | |||
| d1b5c47e16 | |||
| 3765166f4b | |||
| 03865e70cb | |||
| 0458a89fc3 | |||
| 49f84d7d7a | |||
| 5203ecdd65 | |||
| 1bfecdfc82 | |||
| e9ed873275 | |||
| e32c5c5e28 | |||
| e15ca7257f | |||
| 8f7b3be1d2 | |||
| c545c1fa60 | |||
| 3eb2bda80b | |||
| 42b5b6859b | |||
| fc9d311df9 | |||
| 69ecae6919 | |||
| b65e29cb5f | |||
| 9e2541b030 | |||
| 73ec60764a | |||
| e40ae62ced | |||
| d25475da16 | |||
| 1a65a19c20 | |||
| e629008d55 | |||
| 5988a816f9 | |||
| c0f17d6934 | |||
| 5fe6471b6f | |||
| 00459350f0 | |||
| ec0c2a2ba1 | |||
| 6128dfce37 | |||
| 1dcca5b67b | |||
| 150b7e8a5f | |||
| d9ad787f70 | |||
| 7ae4087c05 | |||
| 72ef8bf59a | |||
| 0040321a7c | |||
| 00ede57216 | |||
| d330deb82c | |||
| 2006c1633b | |||
| c5c233d857 | |||
| ccdb32bfe5 | |||
| 6facb61510 | |||
| eb6faaf428 | |||
| 587b081d1d | |||
| 67b16f8a9d | |||
| 9bb75492ff | |||
| 533dba12d7 | |||
| 2783e07993 | |||
| 4083f81e3c | |||
| ead783cfe8 | |||
| e4b18d9379 | |||
| e3b67eb299 | |||
| 41fd59b77b | |||
| 194ff67a05 | |||
| a76a511c95 | |||
| 494fa31e1c | |||
| edf1dffd70 | |||
| ae4c2321af | |||
| 160a3369db | |||
| a64bf6e4d5 | |||
| 53a0388fec | |||
| c05c59ca88 | |||
| 13f794d953 | |||
| e4219b35eb | |||
| d53d3159b4 | |||
| 72530c408d | |||
| 62c975820d | |||
| d1d6a4a100 | |||
| 5e6f0bd271 | |||
| 348a916a81 | |||
| 54a68ca9de | |||
| 42512bc128 | |||
| 88a4156aaa | |||
| 619f30aa8d | |||
| 153e7e635c | |||
| 40f6cfcc84 | |||
| 4d9fccbee5 | |||
| 763f204e80 | |||
| d8c26789e0 | |||
| e0b4403d61 | |||
| 45610e25e4 | |||
| ae22245b28 | |||
| 4f83fc163a | |||
| e3129464dc | |||
| 9542a9f78e | |||
| f6f040a7eb | |||
| 2d09112b24 | |||
| 599c53c5d0 | |||
| 6795c81995 | |||
| d779a5d127 | |||
| 45752f1207 | |||
| bee3377881 | |||
| f527700804 | |||
| 1fb23d124d | |||
| 18992fb13d | |||
| 794c19b2a5 | |||
| 2e2fac9291 | |||
| 423c6d8076 | |||
| b3a02cf2b1 | |||
| e25f595656 | |||
| 4a80b0f089 | |||
| 751155614c | |||
| d76884319c | |||
| 73d2494dde | |||
| ae41d09039 | |||
| f90de55927 | |||
| 50d59842c2 | |||
| 2d898f7db8 | |||
| 50ecbd1f28 | |||
| 0100558166 | |||
| 83c1373a4d | |||
| 1f94b5276b | |||
| 70206bf4ef | |||
| 23b012ef66 | |||
| 7565de4008 | |||
| 750080c20e | |||
| a32549c25f | |||
| ee3560ad83 | |||
| e525cb560f | |||
| 57da005e5f | |||
| d5aaa3801a | |||
| 0d9dd64a66 | |||
| bb6f23bd92 | |||
| 38a69e729b | |||
| e66f38a702 | |||
| 49f34b5810 | |||
| 831a6e26b4 | |||
| aedbb5da8e | |||
| 61b81fad46 | |||
| e16e3ed0dc | |||
| 92e104060d | |||
| c3fbfb3cad | |||
| 434b7c3a6d | |||
| 94d2e495ca | |||
| 8dd74ab095 | |||
| 5a94e5e4eb | |||
| 5c7e17b715 | |||
| 7067bdb263 | |||
| 1baeb11a7f | |||
| 79e73a715c | |||
| e7a7ee8018 | |||
| 4c0590737e | |||
| 94dbfcfc4f | |||
| cf0d7de91e | |||
| 768145d01d | |||
| 594541b6d7 | |||
| aa18f80439 | |||
| a838b0821f | |||
| df8dec38fc | |||
| aa6ca846a4 | |||
| 523f9baca2 | |||
| 3d8d73f0d0 | |||
| a702dcb76f | |||
| fb61aeea5c | |||
| e70a2bb9b3 | |||
| 61b8c96e23 | |||
| 567bccc026 | |||
| 6ba97066f4 | |||
| b0f63a710f | |||
| 02fff0a69e | |||
| 5712994137 | |||
| c2f9a6c3f4 | |||
| 7f80632617 | |||
| d75a4416d7 | |||
| 46ec3ad75f | |||
| c13b89c8f9 | |||
| 8ce1ff884a | |||
| c034aa1055 | |||
| 2b5f6e7a8f | |||
| 16621745f8 | |||
| 32bb9f82ae | |||
| d912153782 | |||
| 2183deba45 | |||
| 421c1f2590 | |||
| ca438959cd | |||
| 740d662757 | |||
| 3e7c5fde99 | |||
| 622a95dd81 | |||
| 521589af07 | |||
| 9e1a619324 | |||
| f5a31ae7c0 | |||
| 819f5649ad | |||
| b0e263e52a | |||
| 60b9ab6a5a | |||
| 806ed33010 | |||
| 335424ca6e | |||
| ee4b0d4d1e | |||
| 4dd2f9ce04 | |||
| c5c15b15bd | |||
| f509e1dc67 | |||
| 0f260d5d9b | |||
| 8353999a2e | |||
| a809ed7254 | |||
| 4d6f05642c | |||
| dda3b3431e | |||
| 1817cdfa4f | |||
| 68fcb21365 | |||
| 99696d9c18 | |||
| 256e8dd794 | |||
| d5d9a3a5a3 | |||
| 21ec29f991 | |||
| 7c35aa79d0 | |||
| d34508689e | |||
| c74430bbc7 | |||
| a58d835291 | |||
| 3c6c241bd7 | |||
| c957250757 | |||
| 8e4248285a | |||
| e65f25fce1 | |||
| 3fc172b3fb | |||
| 4fff20dff4 | |||
| 1d07e1dd57 | |||
| f3d5bc52bb | |||
| 673135a41e | |||
| 168671c1c3 | |||
| b8bf2de47d | |||
| a9a4f6da0b | |||
| 818333c7fd | |||
| c8cb85339d | |||
| ed0ba055c8 | |||
| fb559afd0d | |||
| 3c9fe377f3 | |||
| 57e6da40e9 | |||
| a5f7c7850b | |||
| 484874f0c2 | |||
| 7f604fa7ff | |||
| 606093112f | |||
| c9443fba24 | |||
| f5168e15a4 | |||
| f7ad9e8d07 | |||
| 679c9ee7ef | |||
| 75f09afc89 | |||
| c19a1e737e | |||
| 59e822de4a | |||
| da757049e5 | |||
| 2140063d82 | |||
| a95d415155 | |||
| e7dad5da18 | |||
| 5244401101 | |||
| 4156bd15e6 | |||
| 200cb3019c | |||
| f9c6d2a7ac | |||
| 1efe4813f8 | |||
| 6c7f48543e | |||
| f4cc516809 | |||
| b454953f27 | |||
| bda94d16d1 | |||
| 8af0e20bb0 | |||
| 7ee0f95b23 | |||
| ecaccd36a5 | |||
| e14e2de4ae | |||
| 76f231dc92 | |||
| f29bdab128 | |||
| 3812a98455 | |||
| 1fdf760fba | |||
| f8b7769f74 | |||
| 49d47f76d0 | |||
| ff6e816b98 | |||
| 61e32a782b | |||
| 1bded4af0c | |||
| 599c58825b | |||
| aad837cf20 | |||
| 127db4d189 | |||
| 77ec94abf1 | |||
| 800a233152 | |||
| 4da869a1e2 | |||
| e3fe03c675 | |||
| d57978411e | |||
| 86dcaaba03 | |||
| 875a37f915 | |||
| 33d737eb4c | |||
| 50181d8a1d | |||
| d982935ea0 | |||
| ee2284e28f | |||
| 8ced07c640 | |||
| f735d967ec | |||
| f260c15935 | |||
| f06e89cefb | |||
| ce2855e559 | |||
| 3d7ac026c6 | |||
| 3c92534d7c | |||
| 18d774a18b | |||
| 138634c667 | |||
| 01c103ab36 | |||
| a789ad849a | |||
| 096b13ef3a | |||
| ab40aa9605 | |||
| c809abe05d | |||
| 791c458e9a | |||
| 2d0c881502 | |||
| 225b1e326b | |||
| de0b48247d | |||
| 204b817694 | |||
| 4fda311951 | |||
| d7a32be2ed | |||
| 59a18411ba | |||
| 2d11a99e4d | |||
| 483301ed4e | |||
| de0d30d99c | |||
| a8f5b80422 | |||
| 1dba4d5027 | |||
| ca8cb19e53 | |||
| 6f0659a8e8 | |||
| eeda582b13 | |||
| 475ee011bd | |||
| 943ce757ed | |||
| 7755c58905 | |||
| 428a88820f | |||
| 10e65dccae | |||
| 6fb0089323 | |||
| b344e4b3c1 | |||
| b6aafd86f4 | |||
| 6382705450 | |||
| 96084a1ecc | |||
| bae58915cf | |||
| 7a2f41a221 | |||
| 5f8f8dcbc8 | |||
| 35cbf61982 | |||
| 2d17291ca8 | |||
| 46b543fd46 | |||
| 7fe90f58b7 | |||
| fbaaecd941 | |||
| 5464abd586 | |||
| c37657d102 | |||
| 354989d6a7 | |||
| 2d1b4f8721 | |||
| fe4a01eb73 | |||
| edab484451 | |||
| 0898d2157e | |||
| 55cf704082 | |||
| 42d9df67b3 | |||
| 023f0f155e | |||
| 5d6e366240 | |||
| 42275e1769 | |||
| 63f4076bbb | |||
| 980c36e6eb | |||
| ea4e72c7da | |||
| a343776194 | |||
| 20f7ac0307 | |||
| 663b1ba184 | |||
| a7bd7ef6c2 | |||
| 7c7b067dfe | |||
| 1014408275 | |||
| 995422e23a | |||
| 2b530fec86 | |||
| 797cf25d5a | |||
| b7a4b7202a | |||
| 73523aaad2 | |||
| e8a11574c7 | |||
| efa33adb99 | |||
| f210151ac0 | |||
| 46198abb47 | |||
| 6d9926c138 | |||
| 7b609deb80 | |||
| 2fe3c19dec | |||
| f568824c94 | |||
| 0f48842fa6 | |||
| 8ac1c19a7f | |||
| 01d51bf2f4 | |||
| dd26871f3e | |||
| 6ca19892be | |||
| 4f74f0a34c | |||
| a436398622 | |||
| 1edfe234c2 | |||
| 17e169b578 | |||
| 16b1306c1d | |||
| 6d27e1ef55 | |||
| 4de1aa686c | |||
| c66e364994 | |||
| 24fdc3c458 | |||
| 8ab4d7d51b | |||
| 445295b9a7 | |||
| df196d8883 | |||
| fd39ca31ae | |||
| e22fdfac68 | |||
| 5cf894db0f | |||
| b136fee2e3 | |||
| 21809d6e0d | |||
| b0342c4f11 | |||
| bc7ba5556f | |||
| 83df60972b | |||
| 285ced858f | |||
| 883d965008 | |||
| 907ca349c1 | |||
| ea526b4944 | |||
| 183e3bafcd | |||
| c0050d7558 | |||
| 51f672f8df | |||
| c0bde7203a | |||
| 1cfc69fb7c | |||
| 7109f65472 | |||
| f56194f926 | |||
| 46a0869f2d | |||
| 440f91b6e5 | |||
| 7cc8f7f20a | |||
| 2b20dfe2b7 | |||
| 51de49cd4d | |||
| cecadc1340 | |||
| cc0ad4e6c8 | |||
| c844b9e39c | |||
| bf53f0ac3a | |||
| 46512a36e8 | |||
| 1bd92a5800 | |||
| 5f7824d55a | |||
| 53f9698d21 | |||
| 889c83c34e | |||
| 2660621c3a | |||
| 7357aa1736 | |||
| e30258f8e6 | |||
| 951a5caa68 | |||
| 083011be03 | |||
| d22b7501db | |||
| e730e64b67 | |||
| 43641b792f | |||
| 17459ea306 | |||
| c7dd29d2b6 | |||
| 79b58f23f8 | |||
| 0d3a679edd | |||
| a09bd1f83a | |||
| 570e6b0dba | |||
| cf3617d933 | |||
| ebb81606ed | |||
| e3ccce340b | |||
| 0e3a44420e | |||
| b1d88d1059 | |||
| 2d4c986e88 | |||
| 9bb4b8003c | |||
| 9ed009c4e6 | |||
| 08ff4b4389 | |||
| e8ee93c383 | |||
| 32aa5a642b | |||
| 1dbe8e1777 | |||
| 038f49b18b | |||
| 7d977f68e0 | |||
| 73dc16850d | |||
| cfbbf7af09 | |||
| 9b5a6a8b81 | |||
| 6235de4ef9 | |||
| 8f459eaeae | |||
| 07e54b4077 | |||
| c6e7ac852d | |||
| 8c98a0eb8f | |||
| 696f6c0b59 | |||
| 259aacec8f | |||
| 566402275a | |||
| a6fc0ea2b2 | |||
| 95f99de1b8 | |||
| f2e6cd2002 | |||
| eaa93b8f00 | |||
| a07cb16f28 | |||
| 11cc14d1fa | |||
| d0c8cd746d | |||
| da7d81a4ec | |||
| e853dca178 | |||
| 71cddc2dd8 | |||
| 4a889a110f | |||
| 0ce29f3460 | |||
| 665fed2353 | |||
| 8abb0e5569 | |||
| 11ce59ca28 | |||
| 4184e23788 | |||
| e52fea3cd2 | |||
| 5d3200e592 | |||
| c55a87b323 | |||
| 77c54c0f18 | |||
| 508b43539d | |||
| 740211876a | |||
| dacc9b87b6 | |||
| 175058cc8d | |||
| 383e90a67b | |||
| cf5bb5eba4 | |||
| af48e0350b | |||
| 41f4a5702d | |||
| 22f86b7bf5 | |||
| 62bf9b486c | |||
| 46f4b7d7c2 | |||
| 7646d1fdc8 | |||
| 33f8836109 | |||
| 1a51354162 | |||
| 9c63cff46c | |||
| 1974409df4 | |||
| 8cd49c1007 | |||
| c39233ff52 | |||
| cf0b272984 | |||
| 699061541c | |||
| 64421c49ac | |||
| 9a72b6c928 | |||
| 61cb57079e | |||
| eb24743449 | |||
| a92769db42 | |||
| d36ca3d5d1 | |||
| ae15fe212b | |||
| bc5cd95615 | |||
| 8a9193f4a5 | |||
| 42e859eb24 | |||
| c01113966d | |||
| ddc987ca75 | |||
| 261922188d | |||
| 3205d38e82 | |||
| 584e306b3e | |||
| 43d310416b | |||
| be26dfbcf9 | |||
| 5ec245588c | |||
| 8d0aeda360 | |||
| 16aef9c78d | |||
| af094df01f | |||
| a6e82c34f9 | |||
| 14fb2f69b7 | |||
| a15282a3cc | |||
| fa93314e1b | |||
| 26490f7fa1 | |||
| 4773b7d2a2 | |||
| a94e39ed5d | |||
| 4d360d1082 | |||
| 207f3e5ffa | |||
| 5e8f1456d1 | |||
| 10d94a6c82 | |||
| 675b0b07d4 | |||
| ac989955c8 | |||
| e25add3e4c | |||
| b26df8e96b | |||
| 9c65df78a1 | |||
| 1eb3039d6e | |||
| cd79c5a02e | |||
| 787e239ba6 | |||
| 5699f26aac | |||
| c728eb8658 | |||
| 35bd0f12dc | |||
| 09bf7cb705 | |||
| 1f49950d27 | |||
| 9330f6f7ca | |||
| 9bcaba922c | |||
| c61537a7dd | |||
| a145a34048 | |||
| ec41f28599 | |||
| f422247e15 | |||
| 9f32d335a0 | |||
| 1545aeb160 | |||
| f0a7a8e6cf | |||
| 98af5f7b9e | |||
| 985ba4ac48 | |||
| ba23d735db | |||
| a60741308f | |||
| 8aaf2b217e | |||
| eed171443d | |||
| 54768d0dda | |||
| 39d054261a | |||
| 6f9eb2acf6 | |||
| 454a2e9808 | |||
| 5dda14666b | |||
| f2bd611587 | |||
| 56daebbd49 | |||
| a55637d91e | |||
| 7802ccb7b1 | |||
| 75f74bf895 | |||
| 0f6e023021 | |||
| a68aed6e1e | |||
| d5cdd7e294 | |||
| 53c2e23a29 | |||
| aee1d6591c | |||
| f5cf1ee638 | |||
| 0a4bb11b4f | |||
| dae9e76c17 | |||
| 4ca7dfddab | |||
| a2bdcadc44 | |||
| f4ad78b5e5 | |||
| c1cd63ea0e | |||
| 6c65cb5e89 | |||
| 16e1e7d8ca | |||
| a42b068bd6 | |||
| 413d3b1c40 | |||
| d4db601f5c | |||
| 8ed0a2bb54 | |||
| 9c47525123 | |||
| d2ac132266 | |||
| 1100ce5678 | |||
| 532db55bb3 | |||
| a1d25c5a56 | |||
| d9cc387f9f | |||
| 682c57e1f4 | |||
| d4f0d887bb | |||
| 690652f8ce | |||
| 0d1c34af41 | |||
| 8e6db3ac7b | |||
| dfbc408f2d | |||
| dafa8cede3 | |||
| 168d720a85 | |||
| 17cf7cd063 | |||
| 3fde9b2e80 | |||
| d104be292a | |||
| 8614ed9bcb | |||
| e8d8d44405 | |||
| 323b67cc17 | |||
| e6c2b6defa | |||
| 1203150f5e | |||
| 770f6ee7d2 | |||
| 3274bab1c9 | |||
| 8dd591e640 | |||
| d1e6d00742 | |||
| 55c334c72e | |||
| 2c01069b6a | |||
| 0332a80302 | |||
| 5d0fe132cb | |||
| dceae5e37d | |||
| 2053627f7a | |||
| 877863b27f | |||
| 21bdd6f441 | |||
| 0c254d83f8 | |||
| 3691e8eea4 | |||
| 5df107a6ae | |||
| 646c887412 | |||
| ff44a5ed88 | |||
| 22a0e3be11 | |||
| a5b5e53b8e | |||
| ae5bbe92d0 | |||
| 3923751555 | |||
| b0a32ca65f | |||
| 68879eade4 | |||
| 62d01311dc | |||
| 7e12f64e7a | |||
| ee4afb691a | |||
| c3a04751e0 | |||
| a15e0eb5b6 | |||
| 068700bd5a | |||
| f304becdeb | |||
| 34de2958f9 | |||
| 250af1cee4 | |||
| 650534788a | |||
| 767a09d95b | |||
| 436553a60d | |||
| 9ba768af1d | |||
| 7c23d146cd | |||
| e1c6005570 | |||
| 6f1d243191 | |||
| 91a1214de0 | |||
| 4ebd9d820a | |||
| 282057729e | |||
| 2c9369177e | |||
| 702cb3dbd2 | |||
| 0fbc30ac29 | |||
| 63f774a066 | |||
| 41b467d2fc | |||
| dc57e3232a | |||
| 72f5c44b60 | |||
| 05549a7299 | |||
| 555c0fdecb | |||
| e3478e277e | |||
| 3ba89eda66 | |||
| e7be2611a4 | |||
| e7039f7b67 | |||
| e381b1cf4e | |||
| 9288793f98 | |||
| 9a62d7cb7c | |||
| e0e39242b9 | |||
| 4cdf1fb779 | |||
| b2e0023850 | |||
| 54ee54aac5 | |||
| 1d2265ad7d | |||
| 073de38daf | |||
| 406df28ee7 | |||
| d0e6b436c7 | |||
| 5ee6792fcc | |||
| c541de464d | |||
| 1d6ccac54e | |||
| 6adbf03e2a | |||
| 595f59fc22 | |||
| cb88af1aaa | |||
| 6ff6313b90 | |||
| 8c471af32d | |||
| 3b747c6829 | |||
| 0bf096ad8d | |||
| ec8494e6cd | |||
| 3489b47242 | |||
| 6d14a882bc | |||
| a3f1eb6fa8 | |||
| 70ae78bee2 | |||
| 74cbdfa5da | |||
| de46678177 | |||
| 221fbce4f0 | |||
| cb772bf753 | |||
| 23240a500e | |||
| b310c34107 | |||
| a65b2675f3 | |||
| e6c5696e07 | |||
| bf9fe541c5 | |||
| f7c9d4d0c2 | |||
| 53495e8dec | |||
| c1039b5b33 | |||
| f74bd93a97 | |||
| b9982ed14d | |||
| df28702b7c | |||
| e6d6d851fd | |||
| 119c47922f | |||
| 9ac859a72c | |||
| c4424d897a | |||
| 93342f3d29 | |||
| 9deb10a819 | |||
| ed62fb8921 | |||
| 75f89c8043 | |||
| 7ae97a68c3 | |||
| 005bf3051b | |||
| a4984c40a6 | |||
| c3d762e168 | |||
| 07e02d371c | |||
| 5403c2df35 | |||
| 75efaa1fd9 | |||
| 716b6e0efc | |||
| 55fb1ab317 | |||
| 79a3ea4e3a | |||
| 32b4d852d6 | |||
| aaa702db8f | |||
| 70b9294cba | |||
| 90d9c0a064 | |||
| 3c218ee2b6 | |||
| f5e28c3bf6 | |||
| 75424b66bf | |||
| 93e0f25093 | |||
| bd53f9b877 | |||
| 13a777fa91 | |||
| 22af4055c1 | |||
| 6e32a7685f | |||
| e422c2b3d2 | |||
| 1e14fedab2 | |||
| f0bd5b26d2 | |||
| 96f14f14f5 | |||
| 4b1f3cb758 | |||
| 97ac7ebd67 | |||
| 0f45db1ea0 | |||
| a4c03eb193 | |||
| 12b1d09370 | |||
| a25837fe33 | |||
| 878707c61e | |||
| 65f03d44c2 | |||
| 3ccf67c392 | |||
| 4890facae9 | |||
| c5b396d9a9 | |||
| cc5298754b | |||
| be806a6e2c | |||
| 6e1a9716f4 | |||
| 565f275988 | |||
| 11edc76390 | |||
| d1a45cffdd | |||
| 47c2b1ff5d | |||
| b09991670d | |||
| 91a9aaf1c2 | |||
| ea545a40e3 | |||
| 4daaf2624d | |||
| eac5e7897c | |||
| e7e2f86eda | |||
| f4a24d0a95 | |||
| 0961cd43f7 | |||
| 93fb463de4 | |||
| 4a5a0ee40e | |||
| b8f55afdad | |||
| ca994c077b | |||
| b2519699af | |||
| ad1b8f4cc6 | |||
| 967934453c | |||
| 4a538b78dc | |||
| a4e304526b | |||
| 1dbac01a46 | |||
| 4ad47886f9 | |||
| 57e84bb71f | |||
| ec218d2f78 | |||
| c6b7a16fc4 | |||
| d7701256ad | |||
| be2d5eda2a | |||
| 75e899a999 | |||
| 690c5b7081 | |||
| a333600aae | |||
| de383cb6f7 | |||
| 66a7396b8a | |||
| 116a9620d2 | |||
| a980481e7c | |||
| d3c464b892 | |||
| 15ab189daf | |||
| 70557dc108 | |||
| 77760e0905 | |||
| 741f86e22f | |||
| c348e8683e | |||
| 2595e190cf | |||
| 921e0e6338 | |||
| c4dff88e3d | |||
| 4c1f453965 | |||
| 21f245cf5c | |||
| 5df5e6cf53 | |||
| 0eb2393540 | |||
| dd63c7803b | |||
| 4f8a21ecc5 | |||
| 32ff2ca0dd | |||
| 3d01e14ae1 | |||
| d8d37ecd1b | |||
| 1f7ecf69e0 | |||
| 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 | |||
| a118378af6 | |||
| cca24b471e | |||
| 42b0c2ad3e | |||
| dc153d5e7b | |||
| f6d14c80ea | |||
| 00a143fd3d | |||
| aeb7ca4619 | |||
| 5264194e67 | |||
| ce7dc653df | |||
| b3c87d2dfa | |||
| 0530d1fcaa | |||
| 66b1028d4c | |||
| cfb16a8a9d | |||
| 2d55202d2d | |||
| 480d7b2413 | |||
| 27a45b2658 | |||
| 3c09247068 | |||
| 1c90e422e6 | |||
| 02ff4b6e31 | |||
| 1efcb23869 | |||
| 5b81643b84 | |||
| e4efa8cf47 | |||
| adab69fc6e | |||
| 1681869ffa | |||
| 23b6906d8c | |||
| 4e29437a19 | |||
| 36694aec8f | |||
| e36c2be66f | |||
| ca98cc237d | |||
| 70afb78ebe | |||
| 7d71f523e8 | |||
| 7d0480231d | |||
| e954446f2a | |||
| 5088b8dd26 | |||
| 9675df04e3 | |||
| bec06ca0d4 | |||
| ea37174708 | |||
| 29ce16419f | |||
| ce1c36ea98 | |||
| b56cb9ba74 | |||
| 58e92cc397 | |||
| b37ab364a7 | |||
| 8400223437 | |||
| 2334804623 | |||
| 5d9d00bf68 | |||
| c600890b0d | |||
| 41e1b8000a | |||
| 9008ddf64a | |||
| 80a61bb579 | |||
| ea8735098e | |||
| 694a68be35 | |||
| 007bfe52b8 | |||
| 30b736df0b | |||
| aaad58be00 | |||
| 1a4e75f492 | |||
| 8cdc138fe1 | |||
| a23d2e1c45 | |||
| e15f15888e | |||
| 5787031495 | |||
| b1cbb5841a | |||
| e4ffaa0ecc | |||
| a888b6a2c6 | |||
| 3771a72827 | |||
| 75bcbe70c1 | |||
| 1c0c86407c | |||
| b271d42c4d | |||
| 73f2332552 | |||
| 0456f38813 | |||
| c45e6b53e2 | |||
| 14e7353994 | |||
| 8a4a9fe353 | |||
| 757e0319de | |||
| 8559cb7b1a | |||
| 4896421bb9 | |||
| 35184e36b3 | |||
| c785101476 | |||
| 117e7382a0 | |||
| aa4aa23be3 | |||
| ccce8f7fdd | |||
| bb8d1be57c | |||
| deac1f07fc | |||
| a484107118 | |||
| 0b9108996b | |||
| 58becb4e26 | |||
| a7bb283ddb |
+28
@@ -0,0 +1,28 @@
|
||||
# Use, modification, and distribution are
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE.txt)
|
||||
#
|
||||
# Copyright Rene Rivera 2020.
|
||||
|
||||
# For Drone CI we use the Starlark scripting language to reduce duplication.
|
||||
# As the yaml syntax for Drone CI is rather limited.
|
||||
#
|
||||
#
|
||||
globalenv={}
|
||||
linuxglobalimage="cppalliance/droneubuntu1604:1"
|
||||
windowsglobalimage="cppalliance/dronevs2019"
|
||||
|
||||
def main(ctx):
|
||||
return [
|
||||
linux_cxx("TOOLSET=gcc LINK=static,shared Job 0", "g++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv),
|
||||
linux_cxx("TOOLSET=gcc LINK=static,shared Job 1", "g++", packages="g++-5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-5', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
|
||||
linux_cxx("TOOLSET=gcc LINK=static,shared Job 2", "g++", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-6', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv),
|
||||
linux_cxx("TOOLSET=gcc LINK=static,shared Job 3", "g++", packages="g++-7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-7', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv),
|
||||
linux_cxx("TOOLSET=clang LINK=static,shared Job 4", "clang++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv),
|
||||
linux_cxx("TOOLSET=clang LINK=static,shared Job 5", "clang++", packages="libc++-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++-libc++', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv),
|
||||
osx_cxx("TOOLSET=clang LINK=static,shared Job 6", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv),
|
||||
osx_cxx("TOOLSET=clang LINK=static,shared Job 7", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="10", environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv),
|
||||
]
|
||||
|
||||
# from https://github.com/boostorg/boost-ci
|
||||
load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx")
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2020 Rene Rivera, Sam Darwin
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
set -e
|
||||
export TRAVIS_BUILD_DIR=$(pwd)
|
||||
export DRONE_BUILD_DIR=$(pwd)
|
||||
export TRAVIS_BRANCH=$DRONE_BRANCH
|
||||
export VCS_COMMIT_ID=$DRONE_COMMIT
|
||||
export GIT_COMMIT=$DRONE_COMMIT
|
||||
export REPO_NAME=$DRONE_REPO
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then
|
||||
|
||||
echo '==================================> INSTALL'
|
||||
|
||||
BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/build
|
||||
git submodule update --init libs/config
|
||||
git submodule update --init tools/boostdep
|
||||
cp -r $TRAVIS_BUILD_DIR/* libs/serialization
|
||||
python tools/boostdep/depinst/depinst.py serialization
|
||||
./bootstrap.sh
|
||||
./b2 headers
|
||||
|
||||
echo '==================================> SCRIPT'
|
||||
|
||||
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j 3 libs/serialization/test toolset=$TOOLSET link=${LINK:-shared}
|
||||
|
||||
fi
|
||||
@@ -0,0 +1,469 @@
|
||||
# Copyright 2020-2021 Peter Dimov
|
||||
# Copyright 2021 Andrey Semashev
|
||||
# Copyright 2021 Alexander Grund
|
||||
# Copyright 2022 James E. King III
|
||||
# Copyright 2023 Matt Borland
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
name: POSIX
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
LIBRARY: serialization
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
GIT_FETCH_JOBS: 8
|
||||
NET_RETRY_COUNT: 5
|
||||
DEFAULT_BUILD_VARIANT: release
|
||||
|
||||
jobs:
|
||||
CI:
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "11"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- "ppa:ubuntu-toolchain-r/test"
|
||||
- toolset: gcc-4.9
|
||||
cxxstd: "11"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- "ppa:ubuntu-toolchain-r/test"
|
||||
- toolset: gcc-5
|
||||
cxxstd: "11,14,1z"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- g++-5-multilib
|
||||
- toolset: gcc-5
|
||||
cxxstd: "11-gnu,14-gnu,1z-gnu"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- g++-5-multilib
|
||||
- toolset: gcc-6
|
||||
cxxstd: "11,14,1z"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- g++-6-multilib
|
||||
- toolset: gcc-7
|
||||
cxxstd: "11,14,17"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- g++-7-multilib
|
||||
- toolset: gcc-8
|
||||
cxxstd: "11,14,17,2a"
|
||||
address_model: 64
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- g++-8-multilib
|
||||
- toolset: gcc-9
|
||||
cxxstd: "11,14,17,2a"
|
||||
address_model: 64
|
||||
os: ubuntu-20.04
|
||||
install:
|
||||
- g++-9-multilib
|
||||
- toolset: gcc-9
|
||||
cxxstd: "11-gnu,14-gnu,17-gnu,2a-gnu"
|
||||
address_model: 64
|
||||
os: ubuntu-20.04
|
||||
install:
|
||||
- g++-9-multilib
|
||||
- toolset: gcc-10
|
||||
cxxstd: "11,14,17,20"
|
||||
address_model: 64
|
||||
os: ubuntu-20.04
|
||||
install:
|
||||
- g++-10-multilib
|
||||
- toolset: gcc-11
|
||||
cxxstd: "11,14,17,20,23"
|
||||
address_model: 64
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- g++-11-multilib
|
||||
- toolset: gcc-12
|
||||
cxxstd: "11,14,17,20,23"
|
||||
address_model: 64
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- g++-12-multilib
|
||||
- toolset: gcc-12
|
||||
cxxstd: "11-gnu,14-gnu,17-gnu,20-gnu,23-gnu"
|
||||
address_model: 64
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- g++-12-multilib
|
||||
- name: UBSAN
|
||||
toolset: gcc-12
|
||||
cxxstd: "11,20"
|
||||
address_model: 64
|
||||
ubsan: 1
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- g++-12-multilib
|
||||
|
||||
# Linux, clang
|
||||
- toolset: clang
|
||||
compiler: clang++-3.7
|
||||
cxxstd: "11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- clang-3.7
|
||||
- toolset: clang
|
||||
compiler: clang++-3.8
|
||||
cxxstd: "11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:16.04
|
||||
install:
|
||||
- clang-3.8
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "11,14,17"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "11,14,17"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-7
|
||||
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install:
|
||||
- clang-8
|
||||
- g++-7
|
||||
gcc_toolchain: 7
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install:
|
||||
- clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "11,14,17,20"
|
||||
os: ubuntu-20.04
|
||||
install:
|
||||
- clang-10
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "11,14,17,20"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-11
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-12
|
||||
- toolset: clang
|
||||
compiler: clang++-13
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-13
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-14
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-14
|
||||
- toolset: clang
|
||||
compiler: clang++-15
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-15
|
||||
sources:
|
||||
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
|
||||
source_keys:
|
||||
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
- toolset: clang
|
||||
compiler: clang++-15
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install:
|
||||
- clang-15
|
||||
- libc++-15-dev
|
||||
- libc++abi-15-dev
|
||||
sources:
|
||||
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
|
||||
source_keys:
|
||||
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
cxxflags: -stdlib=libc++
|
||||
linkflags: -stdlib=libc++
|
||||
|
||||
- toolset: clang
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: macos-11
|
||||
- toolset: clang
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: macos-12
|
||||
|
||||
timeout-minutes: 360
|
||||
runs-on: ${{matrix.os}}
|
||||
container: ${{matrix.container}}
|
||||
|
||||
steps:
|
||||
- name: Setup environment
|
||||
run: |
|
||||
if [ -f "/etc/debian_version" ]
|
||||
then
|
||||
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
fi
|
||||
if [ -n "${{matrix.container}}" ]
|
||||
then
|
||||
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
|
||||
if [ -f "/etc/debian_version" ]
|
||||
then
|
||||
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
|
||||
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
|
||||
then
|
||||
PYTHON_PACKAGE="python-is-python3"
|
||||
else
|
||||
PYTHON_PACKAGE="python"
|
||||
fi
|
||||
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
|
||||
fi
|
||||
fi
|
||||
git config --global pack.threads 0
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: |
|
||||
declare -a SOURCE_KEYS SOURCES
|
||||
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
|
||||
then
|
||||
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
|
||||
fi
|
||||
if [ -n "${{join(matrix.sources, ' ')}}" ]
|
||||
then
|
||||
SOURCES=("${{join(matrix.sources, '" "')}}")
|
||||
fi
|
||||
for key in "${SOURCE_KEYS[@]}"
|
||||
do
|
||||
for i in {1..$NET_RETRY_COUNT}
|
||||
do
|
||||
echo "Adding key: $key"
|
||||
wget -O - "$key" | sudo apt-key add - && break || sleep 2
|
||||
done
|
||||
done
|
||||
if [ ${#SOURCES[@]} -gt 0 ]
|
||||
then
|
||||
APT_ADD_REPO_COMMON_ARGS=("-y")
|
||||
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
|
||||
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
|
||||
then
|
||||
APT_ADD_REPO_COMMON_ARGS+=("-n")
|
||||
fi
|
||||
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
|
||||
for source in "${SOURCES[@]}"
|
||||
do
|
||||
for i in {1..$NET_RETRY_COUNT}
|
||||
do
|
||||
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
|
||||
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
|
||||
then
|
||||
case "$source" in
|
||||
"ppa:"*)
|
||||
APT_ADD_REPO_ARGS+=("-P")
|
||||
;;
|
||||
"deb "*)
|
||||
APT_ADD_REPO_ARGS+=("-S")
|
||||
;;
|
||||
*)
|
||||
APT_ADD_REPO_ARGS+=("-U")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
APT_ADD_REPO_ARGS+=("$source")
|
||||
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
|
||||
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
|
||||
done
|
||||
done
|
||||
fi
|
||||
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
|
||||
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
|
||||
- name: Setup GCC Toolchain
|
||||
if: matrix.gcc_toolchain
|
||||
run: |
|
||||
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
|
||||
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
|
||||
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
|
||||
mkdir -p "$GCC_TOOLCHAIN_ROOT"
|
||||
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
|
||||
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
|
||||
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
|
||||
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
|
||||
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
|
||||
DEPINST_ARGS=()
|
||||
GIT_VERSION="$(git --version | sed -e 's/git version //')"
|
||||
GIT_HAS_JOBS=1
|
||||
if [ -f "/etc/debian_version" ]
|
||||
then
|
||||
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
|
||||
then
|
||||
GIT_HAS_JOBS=0
|
||||
fi
|
||||
else
|
||||
declare -a GIT_VER=(${GIT_VERSION//./ })
|
||||
declare -a GIT_MIN_VER=(2 8 0)
|
||||
for ((i=0; i<${#GIT_VER[@]}; i++))
|
||||
do
|
||||
if [ -z "${GIT_MIN_VER[i]}" ]
|
||||
then
|
||||
GIT_MIN_VER[i]=0
|
||||
fi
|
||||
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
|
||||
then
|
||||
GIT_HAS_JOBS=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ "$GIT_HAS_JOBS" -ne 0 ]
|
||||
then
|
||||
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
|
||||
fi
|
||||
cd ..
|
||||
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
|
||||
cd boost-root
|
||||
mkdir -p libs/$LIBRARY
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
DEPINST_ARGS+=("$LIBRARY")
|
||||
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
|
||||
if [ -z "${{matrix.cmake_tests}}" ]
|
||||
then
|
||||
./bootstrap.sh
|
||||
./b2 headers
|
||||
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
|
||||
then
|
||||
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
|
||||
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
|
||||
then
|
||||
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
|
||||
fi
|
||||
echo " ;" >> ~/user-config.jam
|
||||
fi
|
||||
fi
|
||||
- name: Run tests
|
||||
if: matrix.cmake_tests == ''
|
||||
run: |
|
||||
cd ../boost-root
|
||||
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}" "link=static,shared")
|
||||
if [ -n "${{matrix.build_variant}}" ]
|
||||
then
|
||||
B2_ARGS+=("variant=${{matrix.build_variant}}")
|
||||
else
|
||||
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
|
||||
fi
|
||||
if [ -n "${{matrix.threading}}" ]
|
||||
then
|
||||
B2_ARGS+=("threading=${{matrix.threading}}")
|
||||
fi
|
||||
if [ -n "${{matrix.ubsan}}" ]
|
||||
then
|
||||
export UBSAN_OPTIONS="print_stacktrace=1"
|
||||
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
|
||||
fi
|
||||
if [ -n "${{matrix.cxxflags}}" ]
|
||||
then
|
||||
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
|
||||
fi
|
||||
if [ -n "${{matrix.linkflags}}" ]
|
||||
then
|
||||
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
|
||||
fi
|
||||
if [ -n "${{matrix.address_model}}" ]
|
||||
then
|
||||
B2_ARGS+=("address-model=${{matrix.address_model}}")
|
||||
fi
|
||||
B2_ARGS+=("libs/$LIBRARY/test")
|
||||
./b2 "${B2_ARGS[@]}"
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Windows
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
LIBRARY: serialization
|
||||
|
||||
jobs:
|
||||
CI:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.0
|
||||
cxxstd: "11,14"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
cxxstd: "11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=release
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc LINK=static,shared
|
||||
|
||||
- os: linux
|
||||
compiler: g++-5
|
||||
env: TOOLSET=gcc LINK=static,shared
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-6
|
||||
env: TOOLSET=gcc LINK=static,shared
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc LINK=static,shared
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang LINK=static,shared
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: TOOLSET=clang LINK=static,shared
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang LINK=static,shared
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang LINK=static,shared
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
- cd ..
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init tools/boostdep
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/serialization
|
||||
- python tools/boostdep/depinst/depinst.py serialization
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 -j 3 libs/serialization/test toolset=$TOOLSET link=${LINK:-shared}
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
@@ -0,0 +1,413 @@
|
||||
# CMake build control file for Serialization Library tests
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy (SET CMP0054 NEW)
|
||||
endif (POLICY CMP0054)
|
||||
|
||||
if (POLICY CMP0063)
|
||||
cmake_policy (SET CMP0063 NEW)
|
||||
endif (POLICY CMP0063)
|
||||
|
||||
project("serialization")
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
message(STATUS "C++ compiler is ${CMAKE_CXX_COMPILER_ID}" )
|
||||
add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
|
||||
message(STATUS "C compiler is ${CMAKE_C_COMPILER_ID}" )
|
||||
|
||||
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
|
||||
add_definitions( -ftemplate-depth=255 )
|
||||
# we use gcc to test for C++03 compatibility
|
||||
set(COMPILER_SUPPORTS_CXX11 FALSE)
|
||||
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
|
||||
add_definitions( /wd4996 )
|
||||
set(COMPILER_SUPPORTS_CXX11 TRUE)
|
||||
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=300")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0" )
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O3" )
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -dead_strip")
|
||||
set(COMPILER_SUPPORTS_CXX11 TRUE)
|
||||
endif()
|
||||
|
||||
add_definitions( -std=c++11 )
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
#
|
||||
# Locate Project Prerequisites
|
||||
#
|
||||
|
||||
# Boost
|
||||
|
||||
#
|
||||
# Project settings
|
||||
#
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" true)
|
||||
|
||||
find_package(Boost 1.82 REQUIRED COMPONENTS system filesystem)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
message("Boost NOT Found!")
|
||||
else()
|
||||
message(STATUS "Boost Found!")
|
||||
endif()
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(VISIBILITY_INLINES_HIDDEN YES)
|
||||
|
||||
# enable usage of CHECK_INCLUDE_FILE_CXX
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
# list of archive names for which tests should be generated
|
||||
set(archive_list text_archive text_warchive binary_archive xml_archive xml_warchive)
|
||||
# set(archive_list xml_warchive)
|
||||
|
||||
# list of tests generated by each function call
|
||||
set(test_list)
|
||||
|
||||
###########################
|
||||
# library builds
|
||||
|
||||
add_library(serialization
|
||||
../src/archive_exception.cpp
|
||||
../src/basic_archive.cpp
|
||||
../src/basic_iarchive.cpp
|
||||
../src/basic_iserializer.cpp
|
||||
../src/basic_oarchive.cpp
|
||||
../src/basic_oserializer.cpp
|
||||
../src/basic_pointer_iserializer.cpp
|
||||
../src/basic_pointer_oserializer.cpp
|
||||
../src/basic_serializer_map.cpp
|
||||
../src/basic_text_iprimitive.cpp
|
||||
../src/basic_text_oprimitive.cpp
|
||||
../src/basic_xml_archive.cpp
|
||||
../src/binary_iarchive.cpp
|
||||
../src/binary_oarchive.cpp
|
||||
../src/extended_type_info.cpp
|
||||
../src/extended_type_info_typeid.cpp
|
||||
../src/extended_type_info_no_rtti.cpp
|
||||
../src/stl_port.cpp
|
||||
../src/text_iarchive.cpp
|
||||
../src/text_oarchive.cpp
|
||||
../src/polymorphic_iarchive.cpp
|
||||
../src/polymorphic_oarchive.cpp
|
||||
../src/polymorphic_text_iarchive.cpp
|
||||
../src/polymorphic_text_oarchive.cpp
|
||||
../src/polymorphic_binary_iarchive.cpp
|
||||
../src/polymorphic_binary_oarchive.cpp
|
||||
../src/polymorphic_xml_iarchive.cpp
|
||||
../src/polymorphic_xml_oarchive.cpp
|
||||
../src/void_cast.cpp
|
||||
../src/xml_grammar.cpp
|
||||
../src/xml_iarchive.cpp
|
||||
../src/xml_oarchive.cpp
|
||||
../src/xml_archive_exception.cpp
|
||||
../src/codecvt_null.cpp
|
||||
../src/utf8_codecvt_facet.cpp
|
||||
../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"'
|
||||
)
|
||||
target_include_directories(serialization PUBLIC ${Boost_INCLUDE_DIR})
|
||||
|
||||
add_library(wserialization
|
||||
../src/basic_text_wiprimitive.cpp
|
||||
../src/basic_text_woprimitive.cpp
|
||||
../src/text_wiarchive.cpp
|
||||
../src/text_woarchive.cpp
|
||||
../src/polymorphic_text_wiarchive.cpp
|
||||
../src/polymorphic_text_woarchive.cpp
|
||||
../src/xml_wiarchive.cpp
|
||||
../src/xml_woarchive.cpp
|
||||
../src/polymorphic_xml_wiarchive.cpp
|
||||
../src/polymorphic_xml_woarchive.cpp
|
||||
../src/xml_wgrammar.cpp
|
||||
../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"'
|
||||
)
|
||||
target_include_directories(wserialization PUBLIC ${Boost_INCLUDE_DIR})
|
||||
target_link_libraries(wserialization PUBLIC serialization)
|
||||
|
||||
# end library build
|
||||
###########################
|
||||
|
||||
###########################
|
||||
# test targets
|
||||
|
||||
function( serialization_test test_name)
|
||||
set(arglist)
|
||||
foreach(a IN ITEMS ${ARGN} )
|
||||
set(arglist ${arglist} ../test/${a}.cpp)
|
||||
endforeach()
|
||||
message(STATUS ${test_name})
|
||||
add_executable( ${test_name} ../test/${test_name}.cpp ${arglist} )
|
||||
target_include_directories(${test_name} PUBLIC ${Boost_INCLUDE_DIR})
|
||||
target_link_libraries(${test_name} serialization wserialization Boost::filesystem)
|
||||
add_test( ${test_name} ${test_name} )
|
||||
endfunction(serialization_test)
|
||||
|
||||
function(archive_test test_name)
|
||||
set(test_listx)
|
||||
set(arglist)
|
||||
foreach(a IN ITEMS ${ARGN} )
|
||||
set(arglist ${arglist} ../test/${a}.cpp)
|
||||
endforeach()
|
||||
foreach(
|
||||
archive-name
|
||||
IN ITEMS ${archive_list}
|
||||
)
|
||||
set(amended_test_name ${test_name}_${archive-name})
|
||||
add_executable(${amended_test_name} ../test/${test_name}.cpp ${arglist})
|
||||
set_property(
|
||||
TARGET ${amended_test_name}
|
||||
PROPERTY COMPILE_DEFINITIONS BOOST_ARCHIVE_TEST=${archive-name}.hpp
|
||||
)
|
||||
target_include_directories(${amended_test_name} PUBLIC ${Boost_INCLUDE_DIR})
|
||||
target_link_libraries(${amended_test_name} serialization wserialization Boost::filesystem)
|
||||
add_test(${amended_test_name} ${amended_test_name})
|
||||
set(test_listx ${test_listx} ${amended_test_name})
|
||||
endforeach()
|
||||
set(test_list ${test_listx} PARENT_SCOPE)
|
||||
endfunction(archive_test)
|
||||
|
||||
function(polymorphic_archive_test test_name)
|
||||
set(test_listx)
|
||||
set(arglist)
|
||||
foreach(a IN ITEMS ${ARGN} )
|
||||
set(arglist ${arglist} ../test/${a}.cpp)
|
||||
endforeach()
|
||||
foreach(
|
||||
archive-name
|
||||
IN ITEMS ${archive_list}
|
||||
)
|
||||
set(amended_archive_name polymorphic_${archive-name})
|
||||
set(amended_test_name ${test_name}_${amended_archive_name})
|
||||
add_executable(${amended_test_name} ../test/${test_name}.cpp ${arglist})
|
||||
set_property(
|
||||
TARGET ${amended_test_name}
|
||||
PROPERTY COMPILE_DEFINITIONS BOOST_ARCHIVE_TEST=${amended_archive_name}.hpp
|
||||
)
|
||||
message(STATUS ${amended_test_name} " " ${arglist} " " ${amended_archive_name})
|
||||
target_include_directories(${amended_test_name} PUBLIC ${Boost_INCLUDE_DIR})
|
||||
target_link_libraries(${amended_test_name} serialization wserialization Boost::filesystem)
|
||||
add_test(${amended_test_name} ${amended_test_name})
|
||||
set(test_listx ${test_listx} ${amended_test_name})
|
||||
endforeach()
|
||||
set(test_list ${test_listx} PARENT_SCOPE)
|
||||
endfunction(polymorphic_archive_test)
|
||||
|
||||
enable_testing()
|
||||
|
||||
message(STATUS dll_a)
|
||||
add_library(dll_a SHARED ../test/dll_a.cpp)
|
||||
target_link_libraries(dll_a serialization)
|
||||
|
||||
message(STATUS dll_polymorphic_base)
|
||||
add_library(dll_polymorphic_base SHARED ../test/dll_polymorphic_base.cpp)
|
||||
target_link_libraries(dll_polymorphic_base serialization)
|
||||
|
||||
message(STATUS dll_polymorphic_derived2)
|
||||
add_library(dll_polymorphic_derived2 SHARED ../test/dll_polymorphic_derived2.cpp)
|
||||
target_link_libraries(dll_polymorphic_derived2 dll_polymorphic_base serialization)
|
||||
|
||||
# compile test_dll_plugin.cpp
|
||||
# Running the following test requires that the test know the directory
|
||||
# in which the dll is stored. I don't know how to extract this from bjam
|
||||
# serialization(test_dll_plugin : : dll_polymorphic_derived2_lib)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
# this test can only be made to work if we're linking with shared
|
||||
# libraries. Basically the build systems like to have all shared
|
||||
# or all static so if we're building with static C++ libraries
|
||||
# then linking with a shared one - we need multiple C++ libraries
|
||||
# and things get complex. So just run this test when we're
|
||||
# building with shared libraries (dll in windows speak)
|
||||
serialization_test(test_dll_simple)
|
||||
target_link_libraries(test_dll_simple dll_a serialization)
|
||||
endif()
|
||||
|
||||
serialization_test(test_private_ctor)
|
||||
serialization_test(test_reset_object_address A)
|
||||
serialization_test(test_void_cast)
|
||||
serialization_test(test_mult_archive_types)
|
||||
serialization_test(test_iterators)
|
||||
serialization_test(test_iterators_base64)
|
||||
serialization_test(test_inclusion)
|
||||
serialization_test(test_inclusion2)
|
||||
serialization_test(test_smart_cast)
|
||||
serialization_test(test_codecvt_null)
|
||||
serialization_test(test_strong_typedef)
|
||||
serialization_test(test_singleton)
|
||||
serialization_test(test_singleton_inherited)
|
||||
serialization_test(test_singleton_plain)
|
||||
|
||||
archive_test(test_native_array A)
|
||||
archive_test(test_boost_array A)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
archive_test(test_array A)
|
||||
endif()
|
||||
|
||||
archive_test(test_binary)
|
||||
archive_test(test_bitset)
|
||||
archive_test(test_class_info_save)
|
||||
archive_test(test_class_info_load)
|
||||
archive_test(test_complex)
|
||||
archive_test(test_contained_class A)
|
||||
archive_test(test_cyclic_ptrs A)
|
||||
archive_test(test_delete_pointer)
|
||||
archive_test(test_deque A)
|
||||
archive_test(test_derived)
|
||||
archive_test(test_derived_class A)
|
||||
archive_test(test_diamond)
|
||||
archive_test(test_diamond_complex)
|
||||
CHECK_INCLUDE_FILE_CXX(forward_list FORWARD_LIST_FOUND)
|
||||
if(FORWARD_LIST_FOUND)
|
||||
message(STATUS "forward_list header found")
|
||||
archive_test(test_forward_list A)
|
||||
archive_test(test_forward_list_ptrs A)
|
||||
else()
|
||||
message(STATUS "forward_list header NOT found")
|
||||
endif()
|
||||
|
||||
archive_test(test_helper_support)
|
||||
archive_test(test_interrupts)
|
||||
archive_test(test_list A)
|
||||
archive_test(test_list_ptrs A)
|
||||
|
||||
archive_test(test_map A)
|
||||
CHECK_INCLUDE_FILE_CXX(hash_map HASH_MAP_FOUND)
|
||||
if(HASH_MAP_FOUND)
|
||||
archive_test(test_map_hashed A)
|
||||
endif()
|
||||
archive_test(test_mi)
|
||||
archive_test(test_multiple_ptrs A)
|
||||
archive_test(test_multiple_inheritance)
|
||||
archive_test(test_new_operator A)
|
||||
archive_test(test_non_intrusive)
|
||||
archive_test(test_non_default_ctor)
|
||||
archive_test(test_non_default_ctor2)
|
||||
archive_test(test_null_ptr)
|
||||
archive_test(test_nvp A)
|
||||
archive_test(test_object)
|
||||
archive_test(test_optional)
|
||||
archive_test(test_primitive)
|
||||
archive_test(test_priority_queue A)
|
||||
archive_test(test_private_base)
|
||||
archive_test(test_private_base2)
|
||||
archive_test(test_queue A)
|
||||
archive_test(test_recursion A)
|
||||
archive_test(test_registered)
|
||||
|
||||
archive_test(test_set A)
|
||||
CHECK_INCLUDE_FILE_CXX(hash_set HASH_SET_FOUND)
|
||||
if(HASH_SET_FOUND)
|
||||
archive_test(test_set_hashed A)
|
||||
endif()
|
||||
|
||||
archive_test(test_shared_ptr)
|
||||
archive_test(test_shared_ptr_multi_base)
|
||||
archive_test(test_shared_ptr_132)
|
||||
archive_test(test_simple_class A)
|
||||
archive_test(test_simple_class_ptr A)
|
||||
CHECK_INCLUDE_FILE_CXX(slist SLIST_FOUND)
|
||||
if(SLIST_FOUND)
|
||||
message(STATUS "slist header found")
|
||||
archive_test(test_slist A)
|
||||
archive_test(test_slist_ptr A)
|
||||
endif()
|
||||
archive_test(test_stack A)
|
||||
archive_test(test_split)
|
||||
archive_test(test_tracking)
|
||||
archive_test(test_unregistered)
|
||||
archive_test(test_unique_ptr)
|
||||
archive_test(test_valarray)
|
||||
archive_test(test_variant A)
|
||||
archive_test(test_vector A)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
polymorphic_archive_test(test_dll_exported polymorphic_derived1)
|
||||
foreach(test_name IN ITEMS ${test_list} )
|
||||
target_link_libraries(${test_name} dll_polymorphic_derived2 dll_polymorphic_base serialization wserialization)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
polymorphic_archive_test(test_no_rtti polymorphic_base polymorphic_derived1 polymorphic_derived2)
|
||||
polymorphic_archive_test(test_exported polymorphic_base polymorphic_derived1 polymorphic_derived2)
|
||||
polymorphic_archive_test(test_polymorphic test_polymorphic_A A)
|
||||
polymorphic_archive_test(test_polymorphic2 test_polymorphic2imp)
|
||||
polymorphic_archive_test(test_p_helper)
|
||||
|
||||
# end test targets
|
||||
####################
|
||||
|
||||
####################
|
||||
# add headers in IDE
|
||||
|
||||
# for serialization
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/*.hpp"
|
||||
)
|
||||
add_custom_target(archive SOURCES ${x})
|
||||
set_property(TARGET archive PROPERTY FOLDER "serialization")
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/detail/*.hpp"
|
||||
)
|
||||
add_custom_target(archive-detail SOURCES ${x})
|
||||
set_property(TARGET archive-detail PROPERTY FOLDER "serialization")
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/impl/*.ipp"
|
||||
)
|
||||
add_custom_target(archive-impl SOURCES ${x})
|
||||
set_property(TARGET archive-impl PROPERTY FOLDER "serialization")
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/iterators/*.hpp"
|
||||
)
|
||||
add_custom_target(archive-iterators SOURCES ${x})
|
||||
set_property(TARGET archive-iterators PROPERTY FOLDER "serialization")
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/serialization/*.hpp"
|
||||
)
|
||||
add_custom_target(serialization-headers SOURCES ${x})
|
||||
set_property(TARGET serialization-headers PROPERTY FOLDER "serialization")
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/serialization/detail/*.hpp"
|
||||
)
|
||||
add_custom_target(serialization-detail SOURCES ${x})
|
||||
set_property(TARGET serialization-detail PROPERTY FOLDER "serialization")
|
||||
|
||||
# for wserialization
|
||||
|
||||
file(GLOB x
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/*_w*.hpp"
|
||||
)
|
||||
add_custom_target(wserialization_headers SOURCES ${x})
|
||||
set_property(TARGET wserialization_headers PROPERTY FOLDER "wserialization")
|
||||
|
||||
# end headers in IDE
|
||||
####################
|
||||
|
||||
#####################
|
||||
# add test project to run misc tests
|
||||
|
||||
add_executable( test_z ../test/test_z.cpp)
|
||||
target_link_libraries(test_z serialization wserialization ${Boost_LIBRARIES})
|
||||
|
||||
# end test project
|
||||
#####################
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
# Copyright 2020, 2021 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(boost_serialization VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_serialization
|
||||
src/archive_exception.cpp
|
||||
src/basic_archive.cpp
|
||||
src/basic_iarchive.cpp
|
||||
src/basic_iserializer.cpp
|
||||
src/basic_oarchive.cpp
|
||||
src/basic_oserializer.cpp
|
||||
src/basic_pointer_iserializer.cpp
|
||||
src/basic_pointer_oserializer.cpp
|
||||
src/basic_serializer_map.cpp
|
||||
src/basic_text_iprimitive.cpp
|
||||
src/basic_text_oprimitive.cpp
|
||||
src/basic_xml_archive.cpp
|
||||
src/binary_iarchive.cpp
|
||||
src/binary_oarchive.cpp
|
||||
src/codecvt_null.cpp
|
||||
src/extended_type_info.cpp
|
||||
src/extended_type_info_no_rtti.cpp
|
||||
src/extended_type_info_typeid.cpp
|
||||
src/polymorphic_binary_iarchive.cpp
|
||||
src/polymorphic_binary_oarchive.cpp
|
||||
src/polymorphic_iarchive.cpp
|
||||
src/polymorphic_oarchive.cpp
|
||||
src/polymorphic_text_iarchive.cpp
|
||||
src/polymorphic_text_oarchive.cpp
|
||||
src/polymorphic_xml_iarchive.cpp
|
||||
src/polymorphic_xml_oarchive.cpp
|
||||
src/stl_port.cpp
|
||||
src/text_iarchive.cpp
|
||||
src/text_oarchive.cpp
|
||||
src/utf8_codecvt_facet.cpp
|
||||
src/void_cast.cpp
|
||||
src/xml_archive_exception.cpp
|
||||
src/xml_grammar.cpp
|
||||
src/xml_iarchive.cpp
|
||||
src/xml_oarchive.cpp
|
||||
)
|
||||
|
||||
add_library(boost_wserialization
|
||||
src/basic_text_wiprimitive.cpp
|
||||
src/basic_text_woprimitive.cpp
|
||||
src/binary_wiarchive.cpp
|
||||
src/binary_woarchive.cpp
|
||||
src/polymorphic_text_wiarchive.cpp
|
||||
src/polymorphic_text_woarchive.cpp
|
||||
src/polymorphic_xml_wiarchive.cpp
|
||||
src/polymorphic_xml_woarchive.cpp
|
||||
src/text_wiarchive.cpp
|
||||
src/text_woarchive.cpp
|
||||
src/xml_wgrammar.cpp
|
||||
src/xml_wiarchive.cpp
|
||||
src/xml_woarchive.cpp
|
||||
)
|
||||
|
||||
add_library(Boost::serialization ALIAS boost_serialization)
|
||||
add_library(Boost::wserialization ALIAS boost_wserialization)
|
||||
|
||||
target_include_directories(boost_serialization PUBLIC include)
|
||||
target_include_directories(boost_wserialization PUBLIC include)
|
||||
|
||||
target_link_libraries(boost_serialization
|
||||
PUBLIC
|
||||
Boost::array
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::detail
|
||||
Boost::integer
|
||||
Boost::io
|
||||
Boost::iterator
|
||||
Boost::move
|
||||
Boost::mpl
|
||||
Boost::optional
|
||||
Boost::predef
|
||||
Boost::preprocessor
|
||||
Boost::smart_ptr
|
||||
Boost::spirit
|
||||
Boost::static_assert
|
||||
Boost::type_traits
|
||||
Boost::unordered
|
||||
Boost::utility
|
||||
Boost::variant
|
||||
PRIVATE
|
||||
Boost::function
|
||||
)
|
||||
|
||||
target_link_libraries(boost_wserialization PUBLIC boost_serialization)
|
||||
|
||||
target_compile_definitions(boost_serialization
|
||||
PUBLIC BOOST_SERIALIZATION_NO_LIB
|
||||
# Source files already define BOOST_SERIALIZATION_SOURCE
|
||||
# PRIVATE BOOST_SERIALIZATION_SOURCE
|
||||
)
|
||||
|
||||
target_compile_definitions(boost_wserialization
|
||||
PUBLIC BOOST_SERIALIZATION_NO_LIB
|
||||
# Source files already define BOOST_SERIALIZATION_SOURCE
|
||||
# PRIVATE BOOST_SERIALIZATION_SOURCE
|
||||
)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(boost_serialization PUBLIC BOOST_SERIALIZATION_DYN_LINK)
|
||||
target_compile_definitions(boost_wserialization PUBLIC BOOST_SERIALIZATION_DYN_LINK)
|
||||
else()
|
||||
target_compile_definitions(boost_serialization PUBLIC BOOST_SERIALIZATION_STATIC_LINK)
|
||||
target_compile_definitions(boost_wserialization PUBLIC BOOST_SERIALIZATION_STATIC_LINK)
|
||||
endif()
|
||||
|
||||
if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13)
|
||||
boost_install(TARGETS boost_serialization boost_wserialization VERSION ${BOOST_SUPERPROJECT_VERSION} HEADER_DIRECTORY include)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
@@ -0,0 +1,83 @@
|
||||
# Copyright 2016 Peter Dimov
|
||||
# Copyright 2016 Robert Ramey
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
# - master
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- BUILD_TOOLSET: gcc
|
||||
BUILD_LINK: static
|
||||
- BUILD_TOOLSET: gcc
|
||||
BUILD_LINK: shared
|
||||
- BUILD_TOOLSET: msvc-14.0
|
||||
BUILD_LINK: static
|
||||
- BUILD_TOOLSET: msvc-14.0
|
||||
BUILD_LINK: shared
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule init libs/align
|
||||
- git submodule init libs/array
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/bind
|
||||
- git submodule init libs/compatibility
|
||||
- git submodule init libs/concept_check
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/container
|
||||
- git submodule init libs/container_hash
|
||||
- git submodule init libs/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/filesystem
|
||||
- git submodule init libs/function
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/intrusive
|
||||
- git submodule init libs/io
|
||||
- git submodule init libs/iterator
|
||||
- git submodule init libs/lexical_cast
|
||||
- git submodule init libs/math
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/mpl
|
||||
- git submodule init libs/numeric/conversion
|
||||
- git submodule init libs/optional
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/range
|
||||
- git submodule init libs/smart_ptr
|
||||
- git submodule init libs/spirit
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/system
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/tuple
|
||||
- git submodule init libs/type_index
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init libs/unordered
|
||||
- git submodule init libs/utility
|
||||
- git submodule init libs/variant
|
||||
- git submodule init libs/winapi
|
||||
- git submodule init tools/boost_install
|
||||
- git submodule init libs/headers
|
||||
|
||||
- git submodule init tools/build
|
||||
- git submodule update
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\serialization
|
||||
- set PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%CD%;%PATH%
|
||||
- bootstrap gcc
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- cd libs/serialization/test
|
||||
- b2 -j2 toolset=%BUILD_TOOLSET% link=%BUILD_LINK%
|
||||
@@ -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.
+90
-30
@@ -8,29 +8,54 @@
|
||||
|
||||
project boost/serialization
|
||||
: source-location ../src
|
||||
;
|
||||
: requirements
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
|
||||
rule include-spirit ( properties * )
|
||||
{
|
||||
local result ;
|
||||
local SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
|
||||
for local tset in borland { # vc iw
|
||||
if ( <toolset>$(tset) in $(properties) ) {
|
||||
if ( $(SPIRIT_ROOT) ) {
|
||||
result = <cxxflags>-I$(SPIRIT_ROOT) ;
|
||||
}
|
||||
else {
|
||||
echo **** spirit 1.6x required to build library with this compiler **** ;
|
||||
result = <build>no ;
|
||||
local old-compiler ;
|
||||
if <toolset>borland in $(properties)
|
||||
{
|
||||
if ! <toolset-borland:version>6.1.0 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 =
|
||||
archive_exception
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_iserializer
|
||||
@@ -44,44 +69,79 @@ SOURCES =
|
||||
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
|
||||
polymorphic_text_iarchive
|
||||
polymorphic_text_oarchive
|
||||
polymorphic_binary_iarchive
|
||||
polymorphic_binary_oarchive
|
||||
polymorphic_xml_iarchive
|
||||
polymorphic_xml_oarchive
|
||||
void_cast
|
||||
xml_grammar
|
||||
xml_iarchive
|
||||
xml_archive_exception
|
||||
codecvt_null
|
||||
;
|
||||
|
||||
SOURCES_HAS_STD_WSTREAMBUF =
|
||||
xml_oarchive
|
||||
utf8_codecvt_facet
|
||||
;
|
||||
|
||||
|
||||
WSOURCES =
|
||||
basic_text_wiprimitive
|
||||
basic_text_woprimitive
|
||||
binary_wiarchive
|
||||
binary_woarchive
|
||||
text_wiarchive
|
||||
text_woarchive
|
||||
utf8_codecvt_facet
|
||||
polymorphic_text_wiarchive
|
||||
polymorphic_text_woarchive
|
||||
xml_wgrammar
|
||||
xml_wiarchive
|
||||
xml_woarchive
|
||||
polymorphic_xml_wiarchive
|
||||
polymorphic_xml_woarchive
|
||||
;
|
||||
|
||||
lib boost_serialization
|
||||
: $(SOURCES).cpp
|
||||
: <toolset>msvc:<cxxflags>/Gy
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
: ## sources ##
|
||||
$(SOURCES).cpp
|
||||
: ## requirements ##
|
||||
[ check-target-builds ../../config/checks//std_wstreambuf : <source>../src/$(SOURCES_HAS_STD_WSTREAMBUF).cpp ]
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
|
||||
<toolset>clang:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>darwin:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>clang:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>darwin:<cxxflags>"-ftemplate-depth-255"
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
|
||||
lib boost_wserialization
|
||||
: $(WSOURCES).cpp boost_serialization
|
||||
: <toolset>msvc:<cxxflags>/Gy
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
: $(WSOURCES).cpp boost_serialization
|
||||
:
|
||||
[ requires std_wstreambuf ]
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
|
||||
<toolset>clang:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>darwin:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>clang:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>darwin:<cxxflags>"-ftemplate-depth-255"
|
||||
# note: both serialization and wserialization are conditioned on the this
|
||||
# switch - don't change it to BOOST_WSERIALIZATION_DYN_LINK
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
|
||||
boost-install boost_serialization boost_wserialization ;
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# Boost serialization Library Build Jamfile
|
||||
# (C) Copyright Robert Ramey 2002-2004.
|
||||
# Use, modification, and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/serialization for the library home page.
|
||||
|
||||
# building this library needs a working version of spirit
|
||||
rule toolset::require-boost-spirit-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
local requires-spirit = false ;
|
||||
switch $(toolset) {
|
||||
case "borland*" :
|
||||
requires-spirit = true ;
|
||||
case "msvc*" :
|
||||
requires-spirit = true ;
|
||||
case "iw*" :
|
||||
requires-spirit = true ;
|
||||
case "vc-6*" :
|
||||
requires-spirit = true ;
|
||||
case "vc7*" :
|
||||
requires-spirit = true ;
|
||||
case "vc-7_0*" :
|
||||
requires-spirit = true ;
|
||||
case "gcc-2*" :
|
||||
requires-spirit = true ;
|
||||
}
|
||||
if $(requires-spirit) = true {
|
||||
if $(SPIRIT_ROOT) # && ( exist $(SPIRIT_ROOT) )
|
||||
{
|
||||
properties += <include>$(SPIRIT_ROOT) ;
|
||||
}
|
||||
else {
|
||||
echo **** spirit 1.6x required to build library with this compiler **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets are known apriori not to support wide char i/o
|
||||
rule toolset::require-wide-char-io-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "*cygwin" :
|
||||
echo **** wide char i/o not supported by cygwin gcc library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
|
||||
case "como*" :
|
||||
echo **** wide char i/o not supported by libcomo standard library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "mingw*" :
|
||||
if ! [ MATCH "^([5][.][0])$" : [ get-values <stlport-version> : $(properties) ] ]
|
||||
{
|
||||
echo **** wide char i/o not supported by the mingw standard library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets are known apriori not to support creation of DLLS
|
||||
rule toolset::require-shared-libraries-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "como*" :
|
||||
echo **** DLLs cannot be built with this compiler **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "msvc-stlport*" :
|
||||
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "vc-6_5-stlport*" :
|
||||
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "cw*" :
|
||||
local runtime-link = [ get-values <runtime-link> : $(properties) ] ;
|
||||
if static in $(runtime-link) {
|
||||
echo **** DLLS cannot be built with static runtime linking **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets display warnings which are not applicable to the serialization library
|
||||
rule toolset::suppress-warnings ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "vc-8*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-wd4996" ] ;
|
||||
case "*cygwin*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "gcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "mingw*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "borland*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066" ] ;
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# set optimization switches for certain toolsets. We do it here rather than in the
|
||||
# Jamfile requirements because here we can use a regex for the compiler name.
|
||||
rule toolset::optimizations ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "vc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
|
||||
case "msvc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
|
||||
case "gcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "qcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "QCC*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "mingw*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
|
||||
+19
-12
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -27,30 +27,36 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<ul>
|
||||
<li>Takatoshi Kondo found and corrected a very obscure and difficult bug in the
|
||||
serialization of virtual base classes.
|
||||
<li><a href="http://www.autoform.com">AutoForm Engineering GmbH</a> supported
|
||||
development efforts to extend correct serialization to objects stored in DLLS.
|
||||
<li><a href"http://www.cadence.com/il">Cadence Israel</a> supported enhancement
|
||||
and testing of the portable binary archive.
|
||||
<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 ehnanced the implementation of native binary archives. This includes
|
||||
<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>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
|
||||
<li>Martin Ecker detected (and fixed!) a number of subtle errors regarding cyclic
|
||||
pointers, shared pointers. He also built the library as a DLL and raised some issues
|
||||
<li>Pavel Vozenilek invested much effort in review of code and documentation
|
||||
resulting in many improvements. In addition he help a lot with porting to other
|
||||
resulting in many improvements. In addition he helped 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
|
||||
load in one function specification.
|
||||
<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
|
||||
@@ -70,10 +76,11 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
Mr. Rozenthal in particular wrote an incredibly insightful analysis
|
||||
that has driven all subsequent development that has resulted in the
|
||||
current package.
|
||||
<li>Dave Harris proposal and spirited defense of it lead to a re-thinking
|
||||
<li>Dave Harris proposal and spirited defense of it led to a re-thinking
|
||||
of the overrides for serialization of pointers. This resulted in a simpler
|
||||
and more effective method of accounting for non-default constructors
|
||||
required by serialization of pointers and STL collections.
|
||||
<li><a href="mailto:admin@thefireflyproject.us">Bryce Lelbach</a> rewrote the XML Serialization grammar using Boost.Spirit 2.x.
|
||||
</ul>
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+138
-120
@@ -1,7 +1,7 @@
|
||||
<!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 .
|
||||
(C) Copyright 2002-10 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)
|
||||
@@ -26,75 +26,96 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#implementation">Implementation</a>
|
||||
<dt><a href="#trivial">Trivial Archive</a>
|
||||
<dt><a href="#implementation">More Useful Archive Classes</a>
|
||||
<dt><a href="#usage">Usage</a>
|
||||
<dt><a href="#testing">Testing</a>
|
||||
<dt><a href="#polymorphic">Polymorphic Archives</a>
|
||||
</dl>
|
||||
<h3><a name="implementation">Implementation</a></h3>
|
||||
|
||||
<h3><a name="trivial">Trivial Archive</a></h3>
|
||||
The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
|
||||
class must implement to in order to be used to serialize
|
||||
<a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
The library implements a family of archives appropriate for different purposes.
|
||||
This section describes how they have been implemented and how one can implement his own archive class.
|
||||
Our discussion will focus on archives used for loading as the hierarchy is exactly analogous
|
||||
for archives used for saving data.
|
||||
class must implement in order to be used to serialize
|
||||
<a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
|
||||
Our discussion will focus on archives used for saving as the hierarchy is exactly analogous
|
||||
for archives used for loading data.
|
||||
|
||||
<h4>Minimum Requirements</h4>
|
||||
|
||||
The simplest class which will model the <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
|
||||
class will look like:
|
||||
|
||||
<pre><code>
|
||||
#include <cstddef> // std::size_t
|
||||
//////////////////////////////////////////////////////////////
|
||||
// class trivial_oarchive
|
||||
class trivial_oarchive {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////
|
||||
// public interface used by programs that use the
|
||||
// serialization library
|
||||
typedef boost::mpl::bool_<true> is_saving;
|
||||
typedef boost::mpl::bool_<false> is_loading;
|
||||
template<class T> void register_type(){}
|
||||
template<class T> trivial_oarchive & operator<<(const T & t){
|
||||
return *this;
|
||||
}
|
||||
template<class T> trivial_oarchive & operator&(const T & t){
|
||||
return *this << t;
|
||||
}
|
||||
void save_binary(void *address, std::size_t count){};
|
||||
};
|
||||
</code></pre>
|
||||
The simplest possible input archive class is analogous to the above.
|
||||
In the following discussion, only output archives will be addressed.
|
||||
Input archives are exactly symmetrical to output archives.
|
||||
<p>
|
||||
Our archives have been factored in to a tree of classes in order to minimize
|
||||
This archive will compile and execute with any types which implement the
|
||||
<a href="serialization.html"><strong>Serializable</strong></a> concept.
|
||||
For an example see
|
||||
<a href="../example/demo_trivial_archive.cpp" target="demo_trivial_archive">
|
||||
<code style="white-space: normal">demo_trivial_archive.cpp</code></a>.
|
||||
Of course this program won't produce any output as it is. But it provides
|
||||
the starting point for a simple class which can be used to log formatted
|
||||
output. See the implementation of a <a href="simple_log.html">simple
|
||||
log archive</a> to how this has been done.
|
||||
|
||||
<h3><a name="implementation">More Useful Archive Classes</a></h3>
|
||||
The above example is fine as far as it goes. But it doesn't implement
|
||||
useful features such as serialization of pointers, class versioning
|
||||
and others. This library implements a family of full featured archive
|
||||
classes appropriate for a variety of purposes.
|
||||
|
||||
<p>
|
||||
Our archives have been factored into 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>.
|
||||
All input archives should be derived from the following template:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
detail::common_iarchive;
|
||||
</code></pre>
|
||||
<h4>Minimum Requirments</h4>
|
||||
An instance of the this template handles all the "bookkeeping" associated
|
||||
with serialization. In order to be a functional only the following additional
|
||||
functions <strong>must</strong> be defined:
|
||||
<dl>
|
||||
<dt><h4><code>void load(T &t);</code></h4></dt>
|
||||
<dd>
|
||||
This function must be implemented for all primitive data types. This can be
|
||||
accomplished through the use of a member template or explict declarations
|
||||
for all prmititive types.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>void load_binary(void *address, std::size_t size);</code></h4></dt>
|
||||
<dd>
|
||||
This function should <code style="white-space: normal">size</code> bytes from the archive, and
|
||||
copy them in to memory starting at address <code style="white-space: normal">address</code>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>friend class boost::archive::load_access;</code></h4></dt>
|
||||
<dd>
|
||||
In addition, such a class <strong>must</strong> provide a the following
|
||||
friend declaration grant access to the core serialization library to the functions
|
||||
of this class.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
So, the most trivial implementation of an input archive would look like this:
|
||||
Any class which fulfills the following requirements will fit into
|
||||
this hierarchy and implement all the features we require. Deriving from
|
||||
the base class <a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
|
||||
common_oarchive.hpp</a> provides all features we desire which
|
||||
are missing from trivial_oarchive above.
|
||||
|
||||
<pre><code>
|
||||
<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
<a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
|
||||
#include <cstddef> // std::size_t
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
</a>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class trivial_iarchive - read serialized objects from a input text stream
|
||||
class trivial_iarchive :
|
||||
public boost::archive::detail::common_iarchive<trivial_iarchive>
|
||||
// class complete_oarchive
|
||||
class complete_oarchive :
|
||||
public boost::archive::detail::common_oarchive<complete_oarchive>
|
||||
{
|
||||
// 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;
|
||||
friend class boost::archive::save_access;
|
||||
|
||||
// member template for loading primitive types.
|
||||
// Override for any types/templates that special treatment
|
||||
// member template for saving primitive types.
|
||||
// Specialize for any types/templates that require special treatment
|
||||
template<class T>
|
||||
void load(T & t);
|
||||
void save(T & t);
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////
|
||||
@@ -102,36 +123,32 @@ public:
|
||||
// serialization library
|
||||
|
||||
// archives are expected to support this function
|
||||
void load_binary(void *address, std::size_t count);
|
||||
void save_binary(void *address, std::size_t count);
|
||||
};
|
||||
|
||||
</code></pre>
|
||||
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 definitions of <code style="white-space: normal">load</code>
|
||||
and <code style="white-space: normal">load_binary</code>,
|
||||
|
||||
Given a suitable definitions of <code style="white-space: normal">save</code>
|
||||
and <code style="white-space: normal">save_binary</code>,
|
||||
any program using serialization with a conforming C++ compiler should compile
|
||||
and run with this archive class.
|
||||
|
||||
<h4>Optional Overrides</h4>
|
||||
|
||||
The <code style="white-space: normal">detail::common_iarchive</code> class contains
|
||||
The <code style="white-space: normal">detail::common_oarchive</code> class contains
|
||||
a number of functions that are used by various parts of the serialization library
|
||||
to help render the archive in a particular form.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>void load_start()</code></h4></dt>
|
||||
<dt><h4><code>void save_start(char const *)</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Does nothing.<br>
|
||||
<strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
|
||||
by XML archive to inject "<name " before data.
|
||||
by XML archive to inject "<name>" before data.
|
||||
</dd>
|
||||
<p>
|
||||
|
||||
<dt><h4><code>void load_end()</code></h4></dt>
|
||||
<dt><h4><code>void save_end(char const *)</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Does nothing.<br>
|
||||
<strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
|
||||
@@ -143,33 +160,28 @@ by XML archive to inject "</name>" after data.
|
||||
<dd>
|
||||
<strong>Default</strong>:Does nothing.<br>
|
||||
<strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
|
||||
Its 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
|
||||
It's not called when archive bookkeeping data is saved. This is used by XML archives
|
||||
to determine when to inject a ">" character at the end of an 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
|
||||
<code style="white-space: normal">void end_preamble()</code> is invoked and this internal flag is set
|
||||
a ">" character is appended to the output and the internal flag is reset. The default
|
||||
implementation for <code style="white-space: normal">void end_preamble()</code> is a no-op there by permitting it
|
||||
implementation for <code style="white-space: normal">void end_preamble()</code> is a no-op thereby permitting it
|
||||
to be optimised away for archive classes that don't use it.
|
||||
</dd>
|
||||
<p>
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
void load_override(T & t, int);
|
||||
void save_override(T & t, int);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Invokes <code style="white-space: normal">archive::load(Archive & ar, t)</code><br>
|
||||
<strong>Default</strong>:Invokes <code style="white-space: normal">archive::save(Archive & ar, t)</code><br>
|
||||
This is the main entry into the serialization library.<br>
|
||||
<strong>Purpose</strong>:This can be overridden in cases where the data is to be written
|
||||
<strong>Purpose</strong>:This can be specialized in cases where the data is to be written
|
||||
to the archive in some special way. For example, XML archives implement special handling for
|
||||
name-value pairs by overriding this function template for name-value pairs.
|
||||
This replaces the default name-value pair handling, which is just to throw away the name,
|
||||
with one appropriate for XML which writes out the start of an XML tag with the correct object name.
|
||||
<p>
|
||||
The second argument must be part of the function signature even this it is not used.
|
||||
Its purpose is to be sure that code is portable to compilers which fail to correctly
|
||||
implement partial function template ordering. For more information see
|
||||
<a href="implementation.html#functiontemplateordering">this</a>.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
@@ -178,14 +190,14 @@ implement partial function template ordering. For more information see
|
||||
The serialization library injects bookkeeping data into the serialization archive.
|
||||
This data includes things like object ids, version numbers, class names etc. Each
|
||||
of these objects is included in a wrapper so that the archive class can override the
|
||||
implementation of <code style="white-space: normal">void load_override(T & t, int);</code>.
|
||||
implementation of <code style="white-space: normal">void save_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 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>
|
||||
<tr><th align=left>type</th><th align=left><code style="white-space: normal">default<br>serialized as</code></th>
|
||||
<tr><td><code style="white-space: normal">version_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
|
||||
<tr><td><code style="white-space: normal">object_id_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
|
||||
<tr><td><code style="white-space: normal">object_id_reference_type</code></td><td><code style="white-space: normal">unsigned int</code></td>
|
||||
@@ -197,7 +209,7 @@ used internally by the serialization library:
|
||||
</table>
|
||||
<p>
|
||||
All of these are associated with a default serialization defined in terms of primitive types
|
||||
so it isn't a requirement to define <code style="white-space: normal">load_override</code>
|
||||
so it isn't a requirement to define <code style="white-space: normal">save_override</code>
|
||||
for these types.
|
||||
<p>
|
||||
These are defined in
|
||||
@@ -214,19 +226,16 @@ explicitly provided for these types. For an example see
|
||||
In real practice, we probably won't be quite done.
|
||||
One or more of the following issues may need to be addressed:
|
||||
<ul>
|
||||
<li>Many compilers fail to implement correct partial ordering of
|
||||
function templates. The archives included with this library work around
|
||||
this using argument overloading. This technique is described in
|
||||
<a target="detail" href="implementation.html#functiontemplateordering">
|
||||
another section of this manual</a>
|
||||
<li>Even if we are using a conforming compiler, we might want our new archive class
|
||||
to be portable to non-conforming compilers.
|
||||
<li>Our archive format might require extra information inserted into it. For
|
||||
example, XML archives need <name ... >...</name> surrounding
|
||||
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.
|
||||
<li>The archives included with the library are all templates which use a
|
||||
<code style="white-space: normal">stream</code> or
|
||||
<code style="white-space: normal">streambuf</code>
|
||||
as a template parameter rather than simple classes.
|
||||
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>
|
||||
@@ -241,17 +250,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">BOOST_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
|
||||
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
|
||||
@@ -259,23 +266,20 @@ 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
|
||||
serialization with each archive. There are 36 different tests that can run with any archive. There are
|
||||
5 "standard archives" included with the system. (3 in systems which don't support wide
|
||||
charactor i/o).
|
||||
serialization with each archive. There are 46 different tests that can run with any archive.
|
||||
There are 5 "standard archives" included with the system.
|
||||
(3 in systems that don't support wide character i/o).
|
||||
<p>
|
||||
In addition, there are 22 other tests which aren't related to any particular archive
|
||||
class.
|
||||
In addition, there are 28 other tests which aren't related to any particular archive 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 39 archive tests * 5
|
||||
standard archives + 25 general tests = 220 tests. Note that a complete test of the
|
||||
the above described tests. This will result in as many as 46 archive tests * 5
|
||||
standard archives + 28 general tests = 258 tests. Note that a complete test of the
|
||||
library would include DLL vs static library, release vs debug so the actual total
|
||||
would be closer to 880 tests.
|
||||
would be closer to 1032 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
|
||||
@@ -302,16 +306,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>
|
||||
|
||||
@@ -319,7 +323,7 @@ run_archive_test <test header file> <toolset> [<boost root>] [
|
||||
|
||||
All archives described so far are implemented as templates. Code to save and load
|
||||
data to archives is regenerated for each combination of archive class and data type.
|
||||
Under these cirumstances, a good optimizing compiler that can expand
|
||||
Under these circumstances, a good optimizing compiler that can expand
|
||||
<code>inline</code> functions to enough depth will generate fast code.
|
||||
However:
|
||||
<ul>
|
||||
@@ -340,7 +344,7 @@ each time a new archive class is created.
|
||||
</ul>
|
||||
|
||||
<h4>Implementation</h4>
|
||||
The solution is the the pair <code>polymorphic_oarchive</code>
|
||||
The solution is the pair <code>polymorphic_oarchive</code>
|
||||
and <code>polymorphic_iarchive</code>. They present a common interface of virtual
|
||||
functions - no templates - that is equivalent to the standard templated one.
|
||||
|
||||
@@ -357,7 +361,7 @@ show how polymorphic archives are to be used. Note the following:
|
||||
<li><a target=demo_polymorphic_A_hpp href="../example/demo_polymorphic_A.hpp"><code style="white-space: normal">demo_polymorphic_A.hpp</code></a> and
|
||||
<a target=demo_polymorphic_A_cpp href="../example/demo_polymorphic_A.cpp"><code style="white-space: normal">demo_polymorphic_A.cpp</code></a>
|
||||
contain no templates and no reference to any specific archive implementation. That is, they will
|
||||
only have to be compiled once for all archive implementations. The even applies to archives classes
|
||||
only have to be compiled once for all archive implementations. This even applies to archives classes
|
||||
created in the future.
|
||||
<li>The main program <a target=demo_polymorphic_cp href="../example/demo_polymorphic.cpp"><code style="white-space: normal">demo_polymorphic.cpp</code></a>
|
||||
specifies a specific archive implementation.
|
||||
@@ -367,14 +371,15 @@ 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_dispatch_hpp href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_iarchive_dispatch.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_dispatch_hpp href="../../../boost/archive/detail/polymorphic_oarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_oarchive_dispatch.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>
|
||||
which redirect calls to the polymorphic archives to the specific archive.
|
||||
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>
|
||||
As a convenience, small header files have been included which contain
|
||||
<code style="white-space: normal">typedef</code> for polymorphic implementation for each corresponding
|
||||
a <code style="white-space: normal">typedef</code> for a polymorphic implementation for each corresponding
|
||||
templated one. For example, the headers
|
||||
<a target=polymorphic_text_iarchive_hpp href="../../../boost/archive/polymorphic_text_iarchive.hpp"><code style="white-space: normal">polymorphic_text_iarchive.hpp</code></a>
|
||||
and
|
||||
@@ -385,16 +390,29 @@ of the standard text archive classes
|
||||
and
|
||||
<a target=text_oarchive_hpp href="../../../boost/archive/text_oarchive.hpp"><code style="white-space: normal">text_oarchive.hpp</code></a>
|
||||
respectively. All included polymorphic archives use the same naming scheme.
|
||||
|
||||
<h4>Usage</h4>
|
||||
Polymorphic archives address the issues raised above regarding templated implementation.
|
||||
That is, there is no replicated code, and no recompilation for new archives. This will
|
||||
result in smaller executables for program which use more than one type of archive, and
|
||||
smaller DLLS. There is a
|
||||
penalty for calling archive functions through a virtual function dispatch table and there
|
||||
is no possibility for a compiler to <code style="white-space: normal">inline</code> archive functions. This will result
|
||||
in a detectable degradation in performance for saving and loading archives.
|
||||
smaller DLLS. There is a penalty for calling archive functions through a virtual function
|
||||
dispatch table and there is no possibility for a compiler to <code style="white-space: normal">inline</code>
|
||||
archive functions. This will result in a detectable degradation in performance for
|
||||
saving and loading archives.
|
||||
<p>
|
||||
The main utility of polymorphic archives will be to permit the buiding of class DLLs that will
|
||||
Note that the concept of polymorphic archives is fundamentally incompatible with the
|
||||
serialization of new types that are marked "primitive" by the user with:
|
||||
<pre><code>
|
||||
BOOST_CLASS_IMPLEMENTATION(my_primitive_type, boost::serialization::primitive_type)
|
||||
</code></pre>
|
||||
|
||||
Code to implement serialization for these types is instantiated "on the fly" in the user's program.
|
||||
But this conflicts with the whole purpose of the polymorphic archive. An attempt to
|
||||
serialize such a primitive type will result in a compilation error since the common polymorphic
|
||||
interface is static and cannot instantiate code for a new type.
|
||||
|
||||
<p>
|
||||
The main utility of polymorphic archives will be to permit the building of class DLLs that will
|
||||
include serialization code for all present and future archives with no redundant code.
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+56
-30
@@ -29,26 +29,26 @@
|
||||
<h4>Notation</h4>
|
||||
In the following descriptions
|
||||
<ul>
|
||||
<li><code>SA</code> is an type modeling the <a href="#saving_interface">Saving Archive Concept</a>
|
||||
<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 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>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><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>
|
||||
<h4><a name="saving_interface">Saving Archive Concept</a></h4>
|
||||
<h4>Associated Types</h4>
|
||||
Intuitively, a type modeling this concept will generate a sequence of bytes
|
||||
correpsonding to an arbitrary set of C++ data structures. Each type modeling the
|
||||
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 the is equivalent to the original.
|
||||
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 is are rendered <a href="serialization.html">serializable</a>.
|
||||
way the data are rendered <a href="serialization.html">serializable</a>.
|
||||
<p>
|
||||
<h4>Valid Expressions</h4>
|
||||
<dl>
|
||||
@@ -102,7 +102,7 @@ way the data is are rendered <a href="serialization.html">serializable</a>.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.library_version()
|
||||
sa.get_library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the current version number of the serialization
|
||||
@@ -112,6 +112,14 @@ way the data is are rendered <a href="serialization.html">serializable</a>.
|
||||
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>
|
||||
sa.get_helper<Helper>(void * const helper_instance_id = 0)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
See <code>la.get_helper<Helper>(void * const helper_instance_id = 0)</code>
|
||||
below.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
|
||||
@@ -172,7 +180,7 @@ equivalent to the original.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.library_version()
|
||||
la.get_library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the version number of the serialization
|
||||
@@ -182,6 +190,24 @@ equivalent to the original.
|
||||
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.get_helper<Helper>(void * const helper_instance_id)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Some otherwise unserializable types can be made serializable by inclusion of
|
||||
a helper object. The iconic example of this is shared_ptr which needs this
|
||||
helper object to keep track of previously loaded shared_ptr instances so they
|
||||
can be "matched up" with subsequently loaded ones.
|
||||
The first time <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code>
|
||||
is invoked for a given helper_instance_id, <code style="white-space: normal">Helper</code>, a default-constructed
|
||||
<code style="white-space: normal">Helper</code> object is created, attached to
|
||||
<code style="white-space: normal">la</code> and a reference to it is returned. Subsequent
|
||||
invocations of <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code> with the same id value return
|
||||
a reference to the formerly constructed object. All objects created in this manner are
|
||||
destroyed upon <code style="white-space: normal">la</code> destruction time. The purpose
|
||||
of helper objects is discussed in
|
||||
<a href="special.html#helpersupport">Special Considerations - Helper Support</a>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.reset_object_address(v, u)
|
||||
</code></h4></dt>
|
||||
@@ -190,8 +216,8 @@ equivalent to the original.
|
||||
moved to address v.
|
||||
<p>
|
||||
When an object is loaded to a temporary variable and later moved to another location,
|
||||
This function must be called in order communicate this fact. This is permits the
|
||||
the archive to properly implement object tracking. Object tracking is required in order
|
||||
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>
|
||||
@@ -206,7 +232,7 @@ equivalent to the original.
|
||||
|
||||
There are archives based on text, binary and XML file
|
||||
formats but all have the above interface. Given that all archives present
|
||||
the same public interface, specifcation of serialization is exactly the same
|
||||
the same public interface, specification of serialization is exactly the same
|
||||
for all archives. Archive classes have other members not mentioned here.
|
||||
However they are related to the internal functioning of the library and
|
||||
are not meant to be called by users of an archive. Implementation of new
|
||||
@@ -215,7 +241,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.
|
||||
@@ -224,7 +250,7 @@ archive interface. It just turns out that the archives written so far have
|
||||
found it useful to base their implementation on streams.
|
||||
|
||||
<h3><a name="archive_models">Archive Models</a></h3>
|
||||
This library includes a various implementation of the Archive concept.
|
||||
This library includes various implementations of the Archive concept.
|
||||
|
||||
An archive is defined by two complementary classes. One is for saving data while
|
||||
the other is for loading it.
|
||||
@@ -266,7 +292,7 @@ included in the code module containing the serialization code.
|
||||
|
||||
</code></pre>
|
||||
|
||||
All of these archives implement the same inteface. Hence, it should suffice to describe only one
|
||||
All of these archives implement the same interface. Hence, it should suffice to describe only one
|
||||
of them in detail. For this purpose we will use the text archive.
|
||||
|
||||
|
||||
@@ -277,7 +303,7 @@ 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
|
||||
no_xml_tag_checking = 4 // suppress checking of xml tags - ignored on saving
|
||||
};
|
||||
|
||||
} // archive
|
||||
@@ -293,7 +319,7 @@ class text_oarchive : ...
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Saving Archive</strong> concept
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
~text_oarchive();
|
||||
};
|
||||
|
||||
@@ -304,10 +330,10 @@ public:
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
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.
|
||||
@@ -317,7 +343,7 @@ output with initial data which helps identify them as archives produced by this
|
||||
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
|
||||
sizes of native types and endianness 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.
|
||||
@@ -339,7 +365,7 @@ tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to their state before the
|
||||
the archive was opened.
|
||||
archive was opened.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
@@ -353,7 +379,7 @@ class text_iarchive : ...
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Loading Archive</strong> concept
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
~text_iarchive();
|
||||
};
|
||||
|
||||
@@ -365,10 +391,10 @@ public:
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
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
|
||||
Constructs 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.
|
||||
@@ -379,7 +405,7 @@ above.
|
||||
</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
|
||||
closed. It restores any altered stream facets to their state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
</dl>
|
||||
@@ -392,22 +418,22 @@ 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);
|
||||
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);
|
||||
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 throw can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
|
||||
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">
|
||||
|
||||
@@ -36,22 +36,23 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<li>Allen Holub, "Roll Your Own Persistence", <u>Microsoft
|
||||
Systems Journal</u> vol 11, no 6 Jun 1996
|
||||
<a name="4"></a>
|
||||
<li><a href="www.codefarms.com">Code Farms, Inc.</a>
|
||||
<li>Tasos Kontogiorgos & Michael Kim, "A C++
|
||||
Template-Based Application Architecture", <u>C++ Report</u>
|
||||
<a name="5"></a>
|
||||
<li>Scott Meyers, <u>Effective C++</u>, Addison-Wesley, 1992
|
||||
<a name="6"></a>
|
||||
<li>Bjarne Stroustrup, <u>The C++ Programming Langage</u>, Addison-Wesley, 1997
|
||||
<li>Bjarne Stroustrup, <u>The C++ Programming Language</u>, Addison-Wesley, 1997
|
||||
<a name="7"></a>
|
||||
<li>Alexandrescu, Andrei, <u>Modern C++ Design</u>, Addison-Wesley, 2001
|
||||
<a name="8"></a>
|
||||
<li>Jm Hyslop, and Herb Sutter, "Factory Redux, Part2",
|
||||
<li>Jim Hyslop, and Herb Sutter, "Factory Redux, Part2",
|
||||
<u>C/C++ User's Journal</u>, vol 21, No. 8, August 2003
|
||||
<a name="9"></a>
|
||||
<li>David Vandevoorde and Nicolai M. Josuttis,
|
||||
<u>C++ Templates - The Complete Guide</u>, Addison-Wesley, 2003
|
||||
<a name="10"></a>
|
||||
<li>Herb Sutter, "Pimples--Beauty Marks You Can Depend On",
|
||||
<li>Herb Sutter, "Pimpls--Beauty Marks You Can Depend On",
|
||||
<u>C++ Report</u>, from <u>More C++ Gems</u>, Cambridge University Press, 2000
|
||||
<a name="11"></a>
|
||||
<li>James Coplien, "Curiously Recurring Template Patterns",
|
||||
@@ -62,7 +63,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<a name="13"></a>
|
||||
<li>Stephan Beal, "s11n serialization library", <a href="http://www.s11n.net">www.s11n.net</a>
|
||||
<a name="14"></a>
|
||||
<li>Vandervoorde and Josuttis, <b>C++ Templates - A Complete Guide</b>, Addison-Wesley, 2003</a>
|
||||
<li>Vandevoorde and Josuttis, <b>C++ Templates - A Complete Guide</b>, Addison-Wesley, 2003</a>
|
||||
</ol>
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+38
-38
@@ -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
|
||||
@@ -29,136 +29,136 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<pre><code>
|
||||
|
||||
|
||||
basic_iarchive <a href="../../../boost/archive/detail/basic_iarchive.hpp">-></a>
|
||||
basic_oarchive <a href="../../../boost/archive/detail/basic_oarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
| interface_iarchive<text_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| interface_oarchive<text_oarchive> <a href="../../../boost/archive/detail/interface_oarchive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| _________/
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
common_iarchive<text_iarchive> <a href="../../../boost/archive/detail/common_iarchive.hpp">-></a>
|
||||
common_oarchive<text_oarchive> <a href="../../../boost/archive/detail/common_oarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
<font color="blue">basic_text_iarchive<text_iarchive></font> <a href="../../../boost/archive/basic_text_iarchive.hpp">-></a>
|
||||
<font color="blue">basic_text_oarchive<text_oarchive></font> <a href="../../../boost/archive/basic_text_oarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
| <font color="blue">basic_text_iprimitive<basic_istream></font> <a href="../../../boost/archive/basic_text_iprimitive.hpp">-></a>
|
||||
| <font color="blue">basic_text_oprimitive<basic_ostream></font> <a href="../../../boost/archive/basic_text_oprimitive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| _________/ interface_iarchive<polymorphic_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| _________/ interface_oarchive<polymorphic_oarchive> <a href="../../../boost/archive/detail/interface_oarchive.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>
|
||||
<font color="blue">text_oarchive_impl<text_oarchive></font> <a href="../../../boost/archive/text_oarchive.hpp">-></a> polymorphic_oarchive_impl <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
| \ |
|
||||
| \ |
|
||||
| \_____________________________________ |
|
||||
| \_____________________________________ <font color="red">polymorphic_oarchive</font> <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
| \ /
|
||||
| \ /
|
||||
| \ /
|
||||
<font color="red">text_iarchive</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_dispatch<text_iarchive_impl<text_iarchive> > <a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">-></a>
|
||||
<font color="red">text_oarchive</font> <a href="../../../boost/archive/text_oarchive.hpp">-></a> polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> > <a href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp">-></a>
|
||||
|
|
||||
|
|
||||
|
|
||||
<font color="red">polymorphic_text_iarchive</font> <a href="../../../boost/archive/polymorphic_text_iarchive.hpp">-></a>
|
||||
<font color="red">polymorphic_text_oarchive</font> <a href="../../../boost/archive/polymorphic_text_oarchive.hpp">-></a>
|
||||
|
||||
|
||||
</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
|
||||
This diagram shows the relationship between the various classes that implement saving (output
|
||||
serialization) for text archives. The hierarchy and organization is similar for loading 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
|
||||
implement saving for a given archive type. (in this case it's text archives).
|
||||
Users include classes in <font color="red">red</font> to save their data from a particular
|
||||
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>
|
||||
<a href="../../../boost/archive/detail/basic_iarchive.hpp">basic_iarchive</a>
|
||||
<a href="../../../boost/archive/detail/basic_oarchive.hpp">basic_oarchive</a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
Implements the core library functions for class export, versioning, and object tracking. It is compiled
|
||||
into the library as it has no template parameters.
|
||||
</dd>
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive<text_iarchive></a>
|
||||
<a href="../../../boost/archive/detail/interface_oarchive.hpp">interface_oarchive<text_oarchive></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
A class that declares the standard archive interface. This has been factored out so that it
|
||||
can be used as a base class for <code style="white-space: normal">polymorphic_iarchive</code>
|
||||
can be used as a base class for <code style="white-space: normal">polymorphic_oarchive</code>
|
||||
as well as for archive implementations.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/detail/common_iarchive.hpp">common_iarchive<text_iarchive></a>
|
||||
<a href="../../../boost/archive/detail/common_oarchive.hpp">common_oarchive<text_oarchive></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
The function of this class is to make the connection between the virtual function
|
||||
interface used by <code>basic_iarchive</code> and the template interface used by archive
|
||||
interface used by <code>basic_oarchive</code> and the template interface used by archive
|
||||
class implementations.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/basic_text_iarchive.hpp">basic_text_iarchive<text_iarchive></a>
|
||||
<a href="../../../boost/archive/basic_text_oarchive.hpp">basic_text_oarchive<text_oarchive></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
Implements the basic functionality for simple text archives. The primitive load functions have been
|
||||
Implements the basic functionality for simple text archives. The primitive save functions have been
|
||||
factored out so it can be used in other text based archives like XML archives.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/basic_text_iprimitive.hpp">basic_text_iprimitive<basic_istream></a>
|
||||
<a href="../../../boost/archive/basic_text_oprimitive.hpp">basic_text_oprimitive<basic_ostream></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
Implements the save overloads for all primitive types. This is a template with a parameter
|
||||
Implements the save oversaves for all primitive types. This is a template with a parameter
|
||||
which describes the stream.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/text_iarchive.hpp">text_iarchive_impl<text_iarchive></a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp">text_oarchive_impl<text_oarchive></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
Inherits from the above two classes to implement text archives.
|
||||
</dd>
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/text_iarchive.hpp">text_iarchive</a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp">text_oarchive</a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
This is just a short hand for <code style="white-space: normal">text_iarchive_impl<text_iarchive></code> .
|
||||
This is just a short hand for <code style="white-space: normal">text_oarchive_impl<text_oarchive></code> .
|
||||
We can't use <code style="white-space: normal">typedef</code> because a
|
||||
<code style="white-space: normal">typedef</code> can't refer to it self in its definition.
|
||||
This is the class name that is used to serialize to a text archive.
|
||||
</dd>
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive<polymorphic_iarchive></a>
|
||||
<a href="../../../boost/archive/detail/interface_oarchive.hpp">interface_oarchive<polymorphic_oarchive></a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
Same template as above. However, this time the Archive parameter refers to the polymorphic archive
|
||||
with a virtual function interface rather than that the template interface that
|
||||
<code style="white-space: normal">common_iarchive</code> uses.
|
||||
<code style="white-space: normal">common_oarchive</code> uses.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/polymorphic_iarchive.hpp">polymorphic_iarchive</a>
|
||||
<a href="../../../boost/archive/polymorphic_oarchive.hpp">polymorphic_oarchive</a>
|
||||
</code></dt>
|
||||
<dd>
|
||||
A class with a list of virtual <code style="white-space: normal">load(T &t)</code>
|
||||
A class with a list of virtual <code style="white-space: normal">save(T &t)</code>
|
||||
for all primitive types T. This is the class that is used to do pre-compile serialization of classes
|
||||
for all archives present and future.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">polymorphic_iarchive_dispatch<text_iarchive_impl<text_iarchive> ></a>
|
||||
<a href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp">polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> ></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 implementing class would be text_iarchive_impl.
|
||||
This class implements the <code style="white-space: normal">polymorphic_oarchive</code> in terms of a specific
|
||||
concrete class. Virtual function calls are routed to the implementing class. In this example,
|
||||
that implementing class would be text_oarchive_impl.
|
||||
|
||||
<p><dt><code>
|
||||
<a href="../../../boost/archive/polymorphic_text_iarchive.hpp">polymorphic_text_iarchive</a>
|
||||
<a href="../../../boost/archive/polymorphic_text_oarchive.hpp">polymorphic_text_oarchive</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_dispatch<text_iarchive_impl<text_iarchive> ></code>
|
||||
this is just a typedef so we can write <code style="white-space: normal">polymorphic_text_archive</code> rather than
|
||||
<code style="white-space: normal">polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> ></code>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
+3
-3
@@ -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>
|
||||
@@ -42,7 +42,7 @@ template<
|
||||
<h2>Rationale</h2>
|
||||
|
||||
|
||||
UTF-8 is a method of encoding Unicode text in environments where
|
||||
UTF-8 is a method of encoding Unicode text in environments
|
||||
where data is stored as 8-bit characters and some ascii characters
|
||||
are considered special (i.e. Unix filesystem filenames) and tend
|
||||
to appear more commonly than other characters. While
|
||||
@@ -88,7 +88,7 @@ template<
|
||||
<h2>Requirements</h2>
|
||||
|
||||
<tt>utf8_codecvt_facet</tt> defaults to using <tt>char</tt> as
|
||||
it's external data type and <tt>wchar_t</tt> as it's internal
|
||||
its external data type and <tt>wchar_t</tt> as its internal
|
||||
datatype, but on some architectures <tt>wchar_t</tt> is
|
||||
not large enough to hold UCS-4 characters. In order to use
|
||||
another internal type.You must also specialize <tt>std::codecvt</tt>
|
||||
|
||||
+251
-210
@@ -83,220 +83,261 @@ function initialize() {
|
||||
<img src="dot.gif" onclick="collapse_all()">Collapse All
|
||||
-->
|
||||
<p>
|
||||
<dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="release_notes"><a target="detail" href="release.html">Release Notes</a></dt>
|
||||
<dd><div id="release_notes_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#requirements">Requirements</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_32">Differences from version 1.32</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_33">Differences from version 1.33</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_34">Differences from version 1.34</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#todo">Pending Issues</a></dt>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="overview"><a target="detail" href="overview.html">Overview</a></dt>
|
||||
<dd><div id="overview_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Requirements">Requirements</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Otherimplementations">Other Implementations</a></dt>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="tutorial"><a target="detail" href="tutorial.html">Tutorial</a></dt>
|
||||
<dd><div id="tutorial_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#simplecase">A Very Simple Case</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#nonintrusiveversion">Non Intrusive Version</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#serializablemembers">Serializable Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#derivedclasses">Derived Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#pointers">Pointers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#arrays">Arrays</a>
|
||||
<dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif" id="release_notes"><a target="detail" href="release.html">Release Notes</a></dt>
|
||||
<dt><img style="display:none" src="plus.gif" id="overview"><a target="detail" href="overview.html">Overview</a></dt>
|
||||
<dd><div id="overview_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Requirements">Requirements</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Otherimplementations">Other Implementations</a></dt>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="tutorial"><a target="detail" href="tutorial.html">Tutorial</a></dt>
|
||||
<dd><div id="tutorial_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#simplecase">A Very Simple Case</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#nonintrusiveversion">Non Intrusive Version</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#serializablemembers">Serializable Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#derivedclasses">Derived Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#pointers">Pointers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#arrays">Arrays</a>
|
||||
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#stl">STL Collections</a>
|
||||
<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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#stl">STL Collections</a>
|
||||
<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="reference.html">Reference</a></dt>
|
||||
<dd><div id="reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_concept"><a target="detail" href="archives.html">Archive 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">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#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="tutorial.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="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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#tracking">Object Tracking</a>
|
||||
<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#bitwise">Bitwise Serialization</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#templates">Template Serialization Traits</a>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="compiletimemessages"><a target="detail" href="traits.html#compiletime_messages">Compile Time Warnings and Errors</a>
|
||||
<dd><div id="compiletimemessages_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#object_level">object_level</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#object_versioning">object_versioning</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#object_tracking">object_tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#pointer_level">pointer_level</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#pointer_tracking">pointer_tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#const_loading">const_loading</a>
|
||||
</dl></div></dd>
|
||||
</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#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="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="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="dot.gif"><a target="detail" href="special.html#helpersupport">Helper Support</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
<dd><div id="portability_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#numerics">Numerics</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#traits">Traits</a>
|
||||
</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#static_libraries">Static Libraries and 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">Optimizations</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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_signature"><code>invalid_signature</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unsupported_version"><code>unsupported_version</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#pointer_conflict"><code>pointer_conflict</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#incompatible_native_format"><code>incompatible_format</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#array_size_too_short"><code>array_size_too_short</code></a>
|
||||
<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_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#trivial">Trivial Archive</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">More Useful Archive Classes</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="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#charencoding">Character Encoding</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
<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>
|
||||
<dd><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,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#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></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="headers"><a target="detail" href="headers.html">Code Structure</a>
|
||||
<dd><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>
|
||||
<dd><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>
|
||||
</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>
|
||||
<dd><div id="libraryimplementation_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archivedevelopment">Archive Development</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveinternals">Archive Internals</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#codemodules">Archive Library Code Modules</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#dataflowiterators">Dataflow Iterators</a>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<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="private_base.html">Private Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="simple_log.html">A Simple Logging Archive Class</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="otherclasses">Other Classes
|
||||
<dd><div id="otherclasses_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="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>
|
||||
<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="faq.html">Tips and Tricks</a>
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="reference.html">Reference</a></dt>
|
||||
<dd><div id="reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_concept"><a target="detail" href="archives.html">Archive 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">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#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#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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#tracking">Object Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#export">Export Key</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#Abstract">Abstract</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#typeinfo">Type Information Implementation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#wrappers">Wrappers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="traits.html#templates">Template Serialization Traits</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#models">Models - Serialization Implementations Included in the Library</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="special"><a target="detail" href="special.html">Special Considerations</a>
|
||||
<dd><div id="special_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#objecttracking">Object Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#export">Exporting Class Serialization</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#classinfo">Class Information</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
<dd><div id="portability_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#numerics">Numerics</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#traits">Traits</a>
|
||||
</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#dlls">DLLS - Serialization and Runtime Linking</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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_signature"><code>invalid_signature</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unsupported_version"><code>unsupported_version</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#pointer_conflict"><code>pointer_conflict</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#incompatible_native_format"><code>incompatible_format</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#array_size_too_short"><code>array_size_too_short</code></a>
|
||||
<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_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>
|
||||
<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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#charencoding">Character Encoding</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
<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,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#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>
|
||||
</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">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archivedevelopment">Archive Development</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveinternals">Archive Internals</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#codemodules">Archive Library Code Modules</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#dataflowiterators">Dataflow Iterators</a>
|
||||
</dl></div>
|
||||
</dl></div>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<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="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">utf-8 code_cvt</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
|
||||
</dl></div></dd>
|
||||
<!--
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="configuration.html">Configuration Information</a></dt>
|
||||
</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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="faq.html">Frequently Asked Questions (FAQs)</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="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>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="faq.html">Frequently Asked Questions (FAQs)</a></dt>
|
||||
-->
|
||||
<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>
|
||||
<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>
|
||||
</html>
|
||||
|
||||
+10
-24
@@ -35,26 +35,26 @@ We would prefer the solution that is:
|
||||
<ul>
|
||||
<li>Decomposable. so we can code, test, verify and use each (simple) stage of the conversion
|
||||
independently.
|
||||
<li>Composable. so we can used this composite as a new component somewhere else.
|
||||
<li>Composable. so we can use this composite as a new component somewhere else.
|
||||
<li>Efficient, so we're not required to re-implement it again.
|
||||
<li>Scalable, so that it works well for short and arbitrarily long sequences.
|
||||
</ul>
|
||||
The approach that comes closest to meeting these requirements is that described
|
||||
and implemented with <a href="../../iterator/doc/index.html">Iterator Adaptors</a>.
|
||||
The fundamental feature of an Iterator Adaptor template that makes in interesting to
|
||||
The fundamental feature of an Iterator Adaptor template that makes it interesting to
|
||||
us is that it takes as a parameter a base iterator from which it derives its
|
||||
input. This suggests that something like the following might be possible.
|
||||
<pre><code>
|
||||
typedef
|
||||
insert_linebreaks< // insert line breaks every 72 characters
|
||||
base64_from_binary< // convert binary values ot base64 characters
|
||||
insert_linebreaks< // insert line breaks every 76 characters
|
||||
base64_from_binary< // convert binary values to base64 characters
|
||||
transform_width< // retrieve 6 bit integers from a sequence of 8 bit bytes
|
||||
const char *,
|
||||
6,
|
||||
8
|
||||
>
|
||||
>
|
||||
,72
|
||||
,76
|
||||
>
|
||||
base64_text; // compose all the above operations in to a new iterator
|
||||
|
||||
@@ -71,12 +71,12 @@ included is <a target="transform_iterator" href="../../iterator/doc/transform_it
|
||||
transform_iterator</a>, which can be used to implement 6 bit integer => base64 code.
|
||||
|
||||
<h3>Dataflow Iterators</h3>
|
||||
Unfortunately, not all iterators which inherit from Iterator Adaptors are guarenteed
|
||||
Unfortunately, not all iterators which inherit from Iterator Adaptors are guaranteed
|
||||
to meet the composability goals stated above. To accomplish this purpose, they have
|
||||
to be written with some additional considerations in mind.
|
||||
|
||||
We define a Dataflow Iterator as an class inherited from <code style="white-space: normal">iterator_adaptor</code> which
|
||||
fulfills as a small set of additional requirements.
|
||||
fulfills a small set of additional requirements.
|
||||
|
||||
<h4>Templated Constructors</h4>
|
||||
<p>
|
||||
@@ -110,22 +110,8 @@ std::copy(
|
||||
The recursive application of this template is what automatically generates the
|
||||
constructor <code style="white-space: normal">base64_text(const char *)</code> in our example above. The original
|
||||
Iterator Adaptors include a <code style="white-space: normal">make_xxx_iterator</code> to fulfill this function.
|
||||
However, I believe these are unwieldy to use compared to the above solution usiing
|
||||
However, I believe these are unwieldy to use compared to the above solution using
|
||||
Templated constructors.
|
||||
<p>
|
||||
Unfortunately, some systems which fail to properly support partial function template
|
||||
ordering cannot support the concept of a templated constructor as implemented above.
|
||||
A special"wrapper" macro has been created to work around this problem. With this "wrapper"
|
||||
the above example is modified to:
|
||||
<pre><code>
|
||||
std::copy(
|
||||
base64_text(BOOST_MAKE_PFTO_WRAPPER(address)),
|
||||
base64_text(BOOST_MAKE_PFTO_WRAPPER(address + count)),
|
||||
ostream_iterator<char>(os)
|
||||
);
|
||||
</code></pre>
|
||||
This macro is defined in <a target="pfto" href="../../../boost/pfto.hpp"><boost/pfto.hpp></a>.
|
||||
For more information about this topic, check the source.
|
||||
|
||||
<h4>Dereferencing</h4>
|
||||
Dereferencing some iterators can cause problems. For example, a natural
|
||||
@@ -149,7 +135,7 @@ Iterators which fulfill the above requirements should be composable and the abov
|
||||
code should implement our binary to base64 conversion.
|
||||
|
||||
<h3>Iterators Included in the Library</h3>
|
||||
Dataflow iterators for the serialization library are all defined in the hamespace
|
||||
Dataflow iterators for the serialization library are all defined in the namespace
|
||||
<code style="white-space: normal">boost::archive::iterators</code> included here are:
|
||||
<dl class="index">
|
||||
<dt><a target="base64_from_binary" href="../../../boost/archive/iterators/base64_from_binary.hpp">
|
||||
@@ -195,7 +181,7 @@ The standard stream iterators don't quite work for us. On systems which impleme
|
||||
as unsigned short integers (E.G. VC 6) they didn't function as I expected. I also made some
|
||||
adjustments to be consistent with our concept of Dataflow Iterators. Like the rest of our
|
||||
iterators, they are found in the namespace <code style="white-space: normal">boost::archive::interators</code> to avoid
|
||||
conflict the standard library version.
|
||||
conflicts with the standard library versions.
|
||||
<dl class = "index">
|
||||
<dt><a target="istream_iterator" href="../../../boost/archive/iterators/istream_iterator.hpp">
|
||||
istream_iterator</a></dt>
|
||||
|
||||
+54
-65
@@ -26,42 +26,48 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a target="detail" href="#portable_archives">Portable Binary Archives</a>
|
||||
<dt><a target="detail" href="#fast_archives">Fast Binary Archives</a>
|
||||
</dl>
|
||||
|
||||
<a name=portable_archives>
|
||||
<h3>Portable Binary Archives</h3>
|
||||
<h3>Log Archive</h3>
|
||||
It may happen that one wants to create a new archive class by derivation from one
|
||||
of the included ones. Included is a sample program that shows how to derive a
|
||||
new archive from one of the ones included with the library. The first example is
|
||||
<a href="../example/demo_portable_archive.cpp" target="demo_portable_archive_cpp">demo_portable_archive.cpp</a>.
|
||||
This binary archive save/loads integers in a portable format. To this end
|
||||
it is derived from the native binary archive and the save/load functions for
|
||||
integers are overridden with special versions which convert to big endian
|
||||
format if necessary. It also implements an exception for the case where an
|
||||
integer saved on one platform is too large for the platform which is loading
|
||||
the archive. This example doesn't address floating point types.
|
||||
This examples illustrates several issues that have to be addressed when doing
|
||||
something like this. The discussion below refers to the output archive only but it
|
||||
applies equally to input archives as well.
|
||||
<a href="../example/demo_log.cpp" target="demo_log_cpp">
|
||||
demo_log.cpp</a>.
|
||||
<p>
|
||||
This derivation from the xml archive writes output in xml without the extra
|
||||
information required to read the data back into the application. It might be
|
||||
used to export one's data as simple xml for other applications or for logging
|
||||
data while debugging.
|
||||
<p>
|
||||
To this end it is derived from the included xml archive and the save functions for
|
||||
some types are specialized for this application.
|
||||
<p>
|
||||
The serialization library is
|
||||
implemented using the <b>C</b>uriously <b>R</b>ecurring <b>T</b>emplate
|
||||
<b>P</b>attern (<b>CRTP</b>). Also, all common code is factored out into
|
||||
separate modules to minimize code repetition. This makes derivation from
|
||||
an existing archive less straightforward than it would otherwise be.
|
||||
<p>
|
||||
This example illustrates several issues that have to be addressed when doing
|
||||
something like this
|
||||
<ol>
|
||||
<li><i>It is derived from</i> <code style="white-space: normal">binary_oarchive_impl<portable_binary_oarchive></code>
|
||||
<b>NOT</b> <code style="white-space: normal">binary_oarchive</code> <br>
|
||||
<li><i>It is derived from</i> <code style="white-space: normal">xml_oarchive_impl<log_archive></code>
|
||||
<b>NOT</b> <code style="white-space: normal">xml_oarchive</code> <br>
|
||||
As described in the comments in
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_hpp">binary_oarchive.hpp</a>.
|
||||
<code style="white-space: normal">binary_oarchive</code> really a shorthand name for
|
||||
<code style="white-space: normal">binary_oarchive_impl<binary_oarchive></code>. So we should derive
|
||||
from <code style="white-space: normal">binary_oarchive_impl<portable_binary_oarchive></code> rather
|
||||
than <code style="white-space: normal">binary_oarchive</code>.
|
||||
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_hpp">xml_oarchive.hpp</a>.
|
||||
<code style="white-space: normal">xml_oarchive</code> really a shorthand name for
|
||||
<code style="white-space: normal">xml_oarchive_impl<xml_oarchive></code>. So we should derive
|
||||
from <code style="white-space: normal">xml_oarchive_impl<log_archive></code> rather
|
||||
than <code style="white-space: normal">xml_oarchive</code>.
|
||||
<pre><code>
|
||||
class portable_binary_oarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<portable_binary_oarchive>
|
||||
class log_archive :
|
||||
// don't derive from xml_oarchive !!!
|
||||
public xml_oarchive_impl<log_archive>
|
||||
{
|
||||
...
|
||||
</code></pre>
|
||||
<li><i>Note the</i> <code style="white-space: normal">portable_binary_oarchive</code> <i>between the</i> <>
|
||||
<li><i>Note the</i> <code style="white-space: normal">log_archive</code> <i>between the</i> <>
|
||||
This is required so that base classes can downcast their <code style="white-space: normal">this</code> pointer
|
||||
to the most derived class. This is referred to as <b>C</b>uriously <b>R</b>ecurring
|
||||
<b>T</b>emplate <b>P</b>attern (<b>CRTP</b>) <a href="bibliography.html#11">[11]</a>.
|
||||
@@ -70,24 +76,21 @@ It is used to implement static polymorphism.
|
||||
This can be done by making members public or by including friend declarations for
|
||||
the base classes.
|
||||
<pre><code>
|
||||
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::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class detail::common_oarchive<log_archive>;
|
||||
friend class basic_xml_oarchive<log_archive>;
|
||||
friend class boost::serialization::save_access;
|
||||
</code></pre>
|
||||
<li><i>Base class functions will usually need to be explicitly invoked</i>
|
||||
We commonly overload the function name <code style="white-space: normal">save</code> for saving primitives.
|
||||
This is very convenient. Usage of a function name in a derived class
|
||||
|
||||
<li><i></i>Reread <a target="detail" href="headers.html#archiveinternals">Archive Internals</a>.
|
||||
This describes the class hierarchy so that you know what to override.
|
||||
<li><i>Base class functions will usually need to be explicitly invoked.</i>
|
||||
We commonly specialize the function name <code style="white-space: normal">save_override</code>
|
||||
for saving primitives. Usage of a function name in a derived class
|
||||
"hides" similarly named functions of the base class. That is,
|
||||
function name overloading doesn't automatically
|
||||
include base classes. To address this, we can use:
|
||||
<pre><code>
|
||||
using binary_oarchive_impl<derived_t>::save;
|
||||
using xml_oarchive_impl<derived_t>::save;
|
||||
void save(const unsigned int t);
|
||||
...
|
||||
</code></pre>
|
||||
@@ -96,14 +99,14 @@ that the following equivalent works on more compilers.
|
||||
<pre><code>
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void save(const T & t){
|
||||
binary_oarchive_impl<derived_t>::save(t);
|
||||
void save(const T & t){
|
||||
xml_oarchive_impl<derived_t>::save(t);
|
||||
}
|
||||
void save(const unsigned int t);
|
||||
...
|
||||
</code></pre>
|
||||
so it's what I use.
|
||||
<li><i>Template definitions of base classes may have to be included.</i>
|
||||
<li><i>Template definitions of base classes may have to be explicitly instantiated.</i>
|
||||
The demo includes
|
||||
<pre><code>
|
||||
// explicitly instantiate for this type of binary stream
|
||||
@@ -111,48 +114,34 @@ so it's what I use.
|
||||
</code></pre>
|
||||
for just this purpose. Failure to include required template definitions
|
||||
will result in undefined symbol errors when the program is linked.
|
||||
<li><i>Without alteration, this class cannot be further derived from</i><br>
|
||||
<li><i>Without alteration, this class cannot be further derived from.</i><br>
|
||||
Base classes using <b>CRTP</b> must be templates with a parameter corresponding to
|
||||
the most derived class. As presented here, this class doesn't qualify, so
|
||||
it cannot be used as a base class. In order to derive further from this class,
|
||||
it would have to be reorganized along the lines of the original <code style="white-space: normal">binary_oarchive</code>.
|
||||
it would have to be reorganized along the lines of the original <code style="white-space: normal">xml_oarchive</code>.
|
||||
Specifically, it would look something like:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
class portable_binary_oarchive_impl :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<Archive>
|
||||
class log_archive_impl :
|
||||
// don't derive from xml_oarchive !!!
|
||||
public xml_oarchive_impl<Archive>
|
||||
{
|
||||
...
|
||||
);
|
||||
};
|
||||
|
||||
// do not derived from this class !!!
|
||||
class portable_binary_oarchive :
|
||||
public portable_binary_oarchive_impl<portable_binary_oarchive>
|
||||
// do not derive from this class !!!
|
||||
class log_archive :
|
||||
public log_archive_impl<log_archive>
|
||||
{
|
||||
public:
|
||||
portable_binary_oarchive(std::ostream & os, unsigned int flags = 0) :
|
||||
portable_binary_oarchive_impl<binary_oarchive>(os, flags)
|
||||
log_archive(std::ostream & os, unsigned int flags = 0) :
|
||||
log_archive_impl<xml_oarchive>(os, flags)
|
||||
{}
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
</ol>
|
||||
|
||||
<a name=fast_archives>
|
||||
<h3>Fast Binary Archives</h3>
|
||||
The second example
|
||||
<a href="../example/demo_fast_archive.cpp" target="demo_fast_archive_cpp">demo_fast_archive.cpp</a>.
|
||||
is similar to the first one. The difference is that it intercepts the serialization before
|
||||
the default serialization is invoked. In this case we want to replace the default
|
||||
serialization of C arrays of integers with a faster one. The default version
|
||||
will invoke serialization of each element of the array. If its an array of
|
||||
integers, and we're not concerned with the archive being portable to another platform
|
||||
we can just save/load the whole array as a binary string of bytes. This should
|
||||
be faster than the default element by element method.
|
||||
<p>
|
||||
The same considerations that applied when overriding the the save/load of primitives
|
||||
above apply here, and the code is very similar.
|
||||
<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
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 846 B |
@@ -70,7 +70,7 @@ an invalid pointer, or creating a memory leak.
|
||||
If an exception occurs, <i>referenced</i> pointers will not need to be deleted
|
||||
so there will be no memory leaks. The destructor of this class won't attempt to
|
||||
delete these pointers so there will be no problem with dangling references.
|
||||
<i>owned</i> pointers are handled exactly as described above.
|
||||
<i>Owned</i> pointers are handled exactly as described above.
|
||||
<p>
|
||||
<li><h4>class contains <i>referenced</i> pointers which might be created by load</h4>
|
||||
If a <i>referenced</i> pointer is loaded before its corresponding <i>owned</i>
|
||||
@@ -81,7 +81,7 @@ an invalid pointer, or creating a memory leak.
|
||||
<li>Trap exceptions with a <code style="white-space: normal">try/catch</code> block.
|
||||
<li>Within the catch part, invoke the archive function
|
||||
<code style="white-space: normal">delete_created_pointers()</code> to delete any pointers
|
||||
created by the class load. Without out other action, objects created in
|
||||
created by the class load. Without other action, objects created in
|
||||
this way would end up as memory leaks as they are not considered <i>owned</i>
|
||||
pointers and hence aren't destroyed.
|
||||
<li>The object's destructor won't try
|
||||
|
||||
+53
-26
@@ -29,12 +29,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="#invalid_signature"><code style="white-space: normal">invalid_signature</code></a>
|
||||
<dt><a href="#unsupported_version"><code style="white-space: normal">unsupported_version</code></a>
|
||||
<dt><a href="#unsupported_class_version"><code style="white-space: normal">unsupported_class_version</code></a>
|
||||
<dt><a href="#pointer_conflict"><code style="white-space: normal">pointer_conflict</code></a>
|
||||
<dt><a href="#incompatible_native_format"><code style="white-space: normal">incompatible_native_format</code></a>
|
||||
<dt><a href="#array_size_too_short"><code style="white-space: normal">array_size_too_short</code></a>
|
||||
<dt><a href="#stream_error"><code style="white-space: normal">stream_error</code></a>
|
||||
<dt><a href="#input_stream_error"><code style="white-space: normal">input_stream_error</code></a>
|
||||
<dt><a href="#output_stream_error"><code style="white-space: normal">output_stream_error</code></a>
|
||||
<dt><a href="#invalid_class_name"><code style="white-space: normal">invalid_class_name</code></a>
|
||||
<dt><a href="#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
|
||||
<dt><a href="#multiple_code_instantiation"><code style="white-space: normal">multiple_code_instantiation</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>
|
||||
@@ -43,8 +46,9 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
Archive operators can throw a <code style="white-space: normal">boost::archive_exception</code>
|
||||
object which can be caught by an application program. These exceptions are defined
|
||||
in the files <a target="archive_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_exception.hpp</a> and <a target="archive_xml_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_xml_exception.hpp</a>.
|
||||
archive_exception.hpp</a>
|
||||
and <a target="basic_xml_archive_hpp" href="../../../boost/archive/basic_xml_archive.hpp">
|
||||
basic_xml_archive.hpp</a>.
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -53,7 +57,7 @@ class archive_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
unregistered_class, // attempt to serialize a pointer of an
|
||||
unregistered_class, // attempt to serialize a pointer of
|
||||
// an unregistered class
|
||||
invalid_signature, // first line of archive does not contain
|
||||
// expected string
|
||||
@@ -62,17 +66,23 @@ public:
|
||||
pointer_conflict // an attempt has been made to directly serialize
|
||||
// an object after having already serialized the same
|
||||
// object through a pointer. Were this permitted,
|
||||
// it the archive load would result in the creation
|
||||
// of extraneous object.
|
||||
// the archive load would result in the creation
|
||||
// of an extraneous object.
|
||||
incompatible_native_format, // attempt to read native binary format
|
||||
// on incompatible platform
|
||||
array_size_too_short, // array being loaded doesn't fit in array allocated
|
||||
stream_error // i/o error on stream
|
||||
input_stream_error // error on stream input
|
||||
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
|
||||
unregistered_cast, // base - derived relationship not registered with
|
||||
// void_cast_register
|
||||
unsupported_class_version, // type saved with a version # greater than the
|
||||
// one used by the program. This indicates that the program
|
||||
// needs to be rebuilt.
|
||||
multiple_code_instantiation, // code for implementing serialization for some
|
||||
// type has been instantiated in more than one module.
|
||||
output_stream_error // error on stream output
|
||||
} exception_code;
|
||||
exception_code code;
|
||||
archive_exception(exception_code c) : code(c) {}
|
||||
@@ -99,7 +109,7 @@ public:
|
||||
<h3><a name="unregistered_class"><code style="white-space: normal">unregistered_class</code></a></h3>
|
||||
An attempt has been made to serialize a polymorphic class through a pointer
|
||||
without either registering it or associating it with an export key. This can also occur
|
||||
when using a new archive how class name has not been added to the system with the
|
||||
when using a new archive whose class name has not been added to the system with the
|
||||
<code style="white-space: normal">BOOST_ARCHIVE_CUSTOM_ARCHIVE_TYPES</code> macro.
|
||||
|
||||
<h3><a name="invalid_signature"><code style="white-space: normal">invalid_signature</code></a></h3>
|
||||
@@ -108,10 +118,10 @@ the archive is opened, It is presumed that this file is not a valid archive and
|
||||
exception is thrown.
|
||||
|
||||
<h3><a name="unsupported_version"><code style="white-space: normal">unsupported_version</code></a></h3>
|
||||
This system assigns a version number of 2 to all archives created. Note that this is in
|
||||
This system records the current library version number to all archives created. Note that this is in
|
||||
no way related to version number of classes used by application programs. This refers
|
||||
to the version of the serialization system used to create the archive. Future versions
|
||||
of this serialization system will be able to identify archives created under previous
|
||||
of this serialization system will be able to identify archives created under a previous
|
||||
(i.e. this) system and alter the loading procedure accordingly. Hence, future enhancements
|
||||
to this serialization system should not obsolete any existing archive files. It is only
|
||||
necessary to increment this version number when the newer system creates archives
|
||||
@@ -119,27 +129,35 @@ incompatible in format with the current one.
|
||||
<p>Should it ever occur that an older program attempts to read newer archives whose
|
||||
format has changed, this exception is thrown.
|
||||
|
||||
<h3><a name="unsupported_class_version"><code style="white-space: normal">unsupported_class_version</code></a></h3>
|
||||
An attempt has been made to load a class whose version has been incremented since the
|
||||
program was written. Suppose that a class has been assigned version number 3 and the program
|
||||
has been built and sent to third parties. Now suppose that the definition of that class
|
||||
has been altered, the version number has been incremented to 4 and new archives have been
|
||||
built. If one attempts to load these new archives with the original program, this
|
||||
exception will be thrown.
|
||||
|
||||
<h3><a name="pointer_conflict"><code style="white-space: normal">pointer_conflict</code></a></h3>
|
||||
To understand what this exception means consider the following scenario
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void T::save(Archive &ar) const
|
||||
void T::save(Archive &ar) const
|
||||
{
|
||||
const A * aptr = &a;
|
||||
ar << aptr; // save an instance of object of class A through a pointer
|
||||
const A * aptr = &a;
|
||||
ar << aptr; // save an instance of object of class A through a pointer
|
||||
...
|
||||
ar << a; // save an instance of an object of class A
|
||||
assert(aptr == &a); // this must be true
|
||||
ar << a; // save an instance of an object of class A
|
||||
assert(aptr == &a); // this must be true
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void T::load(Archive &ar)
|
||||
void T::load(Archive &ar)
|
||||
{
|
||||
A * aptr;
|
||||
ar >> aptr; // create and initialize a new instance of class A
|
||||
ar >> aptr; // create and initialize a new instance of class A
|
||||
...
|
||||
ar >> a; // restore state of on object of class A
|
||||
assert(aptr == &a); // this won't be true
|
||||
ar >> a; // restore state of on object of class A
|
||||
assert(aptr == &a); // this won't be true
|
||||
}
|
||||
</pre></code>
|
||||
An object is saved first through a pointer then directly. Upon loading back
|
||||
@@ -161,8 +179,12 @@ An attempt has been made to read an array that is larger than the array size.
|
||||
This should only occur when the size of an array in code is reduced after an
|
||||
archive has already been created.
|
||||
|
||||
<h3><a name="stream_error"><code style="white-space: normal">stream_error</code></a></h3>
|
||||
An error has occured during stream input or ouput. Aside from the common
|
||||
<h3>
|
||||
<a name="input_stream_error"><code style="white-space: normal">input_stream_error</code></a>
|
||||
<br>
|
||||
<a name="output_stream_error"><code style="white-space: normal">output_stream_error</code></a>
|
||||
</h3>
|
||||
An error has occurred 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>
|
||||
@@ -203,7 +225,7 @@ 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
|
||||
archive or an attempt to insert virus via buffer overrun method.
|
||||
archive or an attempt to insert a virus via the buffer overrun method.
|
||||
|
||||
<h3><a name="unregistered_cast"><code style="white-space: normal">unregistered_cast</code></a></h3>
|
||||
In order to support casting between pointers of base and derived classes
|
||||
@@ -215,6 +237,11 @@ 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,
|
||||
|
||||
<h3><a name="multiple_code_instantiation"><code style="white-space: normal">multiple_code_instantiation</code></a></h3>
|
||||
This exception is thrown when it is detected that the serialization of the same type
|
||||
has been instantiated more than once. This might occur when
|
||||
serialization code is instantiated in both the mainline and one or more DLLS.
|
||||
|
||||
<h3><a name="xml_archive_parsing_error"><code style="white-space: normal">xml_archive_parsing_error</code></a></h3>
|
||||
The XML generated by the serialization process is intimately coupled to the
|
||||
C++ class structure, relationships between objects and the serialization
|
||||
@@ -223,8 +250,8 @@ to the loading serialization and this exception might be thrown. This might
|
||||
occur for one of the following reasons:
|
||||
<ul>
|
||||
<li>The archive has been edited outside the serialization system. This might
|
||||
be possible if only the data is changed and not the XML attributes and nesting
|
||||
structure is left unaltered. But any other editing is likely to render the
|
||||
be possible if only the data is changed and the XML attributes and nesting
|
||||
structure are left unaltered. But any other editing is likely to render the
|
||||
archive unreadable by the serialization library.
|
||||
<li>The serialization has been altered and an archive generated by the old
|
||||
code is being read. That is, versioning has not been properly employed to
|
||||
@@ -232,7 +259,7 @@ 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 the start or end tag of and XML element doesn't match
|
||||
This exception will be thrown if the start or end tag of an 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>
|
||||
|
||||
+237
-146
@@ -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 .
|
||||
@@ -33,7 +33,6 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#example">Example</a>
|
||||
</dl>
|
||||
|
||||
|
||||
<h3><a name="motivation">Motivation</a></h3>
|
||||
The serialization library needs a system like
|
||||
<code style="white-space: normal">type_info/typeid()</code> to perform
|
||||
@@ -50,7 +49,7 @@ the following functions
|
||||
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.
|
||||
or not enabled for reasons such as a perceived inefficiency.
|
||||
<li>
|
||||
<code style="white-space: normal">std::type_info</code> includes a string
|
||||
containing type name. This would seem to satisfy 2) above.
|
||||
@@ -58,128 +57,128 @@ the following functions
|
||||
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
|
||||
guarantee that class headers would be included in the same namespace accross
|
||||
different applications. In fact, including different headers in different
|
||||
name spaces is an accepted method used to avoid name space conflicts.
|
||||
namespaces is an accepted method used to avoid namespace conflicts.
|
||||
Thus the namespace::class_name can't be used as a key.
|
||||
<li>
|
||||
We may want the ability to serialize objects through a base class even though
|
||||
they have no <code style="white-space: normal">virtual</code> function. That
|
||||
is, objects of classes which are not polymorphic in the strict C++ sense. This
|
||||
is not supported by the standard system.
|
||||
<li>
|
||||
There exists the possibility that different classes use different type id
|
||||
mechanism. The class header might include this information. If we want to
|
||||
import class headers accross applications, its convenient that the type id
|
||||
mechanisms. The class header might include this information. If we want to
|
||||
import class headers accross applications, it's 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
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
extended_type_info</a></code> is an implementation
|
||||
of <code style="white-space: normal">std::type_info</code> functionality with the
|
||||
following features:
|
||||
<ul>
|
||||
<li>
|
||||
Maintains a global table of <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> records - one for each type known
|
||||
to the program.
|
||||
Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">extended_type_info</a></code> records - one for each type
|
||||
serialized.
|
||||
<li>
|
||||
permits association of an arbitrary key with a type. Often this key would
|
||||
permits association of an arbitrary string key with a type. Often this key would
|
||||
be the class name - but it doesn't have to be. This key is referred to as
|
||||
a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe.
|
||||
Typically this GUID would be in header files and be used to match type accross
|
||||
applications.
|
||||
applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string
|
||||
key with any known type. We'll refer to these types as "exported types"
|
||||
<li>
|
||||
permits the "mixing" of type info systems. For example, one class might use
|
||||
<code style="white-space: normal">typeid()</code> to find the external identifier
|
||||
of a class while another might not.
|
||||
</ul>
|
||||
The serialization system maintains two global tables.
|
||||
<ul>
|
||||
<li>The first is a global type table. it has an entry for each type used.
|
||||
Each entry is an instance of a class derived from
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>. This table is used
|
||||
to retrieve the unique <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
information for any given type.
|
||||
<li>The second is global key table. It has an entry for each type which has been assigned a GUID string key.
|
||||
This table is used to retrieve the unique
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> given its GUID.
|
||||
</ul>
|
||||
This library includes two different type id systems:
|
||||
<ul>
|
||||
<li>
|
||||
<code style="white-space: normal"><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">extended_type_info_typeid</a></code>
|
||||
which is implemented in terms of the standard
|
||||
<code style="white-space: normal">typeid()</code>.
|
||||
<li>
|
||||
<code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">extended_type_info_no_rtti</a></code>
|
||||
which is implemented in a way that doesn't rely on the existence
|
||||
RTTI. However, it does require that all classes for which type id is to be used
|
||||
be explictly assigned an external key - which otherwise would be optional.
|
||||
</ul>
|
||||
|
||||
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">
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
class BOOST_SERIALIZATION_DECL extended_type_info :
|
||||
private boost::noncopyable
|
||||
class extended_type_info
|
||||
{
|
||||
protected:
|
||||
extended_type_info(const char * type_info_key);
|
||||
// this class can't be used as is. It's just the
|
||||
// common functionality for all type_info replacement
|
||||
// systems. Hence, make these protected
|
||||
extended_type_info(
|
||||
const unsigned int type_info_key,
|
||||
const char * key
|
||||
);
|
||||
~extended_type_info();
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
public:
|
||||
void self_register();
|
||||
void key_register(const char *key);
|
||||
const char * get_key() const;
|
||||
|
||||
bool operator<(const extended_type_info &rhs) const;
|
||||
bool operator==(const extended_type_info &rhs) const;
|
||||
bool operator!=(const extended_type_info &rhs) const;
|
||||
|
||||
bool operator<(const extended_type_info &rhs) const;
|
||||
bool operator==(const extended_type_info &rhs) const;
|
||||
bool operator!=(const extended_type_info &rhs) const {
|
||||
return !(operator==(rhs));
|
||||
}
|
||||
// for plugins
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
virtual void destroy(void const * const p) const;
|
||||
static const extended_type_info * find(const char *key);
|
||||
static const extended_type_info * find(const extended_type_info * t);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
|
||||
There must be one and only one <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. For this reason, this class is marked is derived from
|
||||
<code style="white-space: normal">boost::noncopyable</code>.
|
||||
|
||||
<p>
|
||||
Generally, there will be one and only one
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. However, this is enforced only at the executable
|
||||
module level. That is, if a program includes some shared libraries or DLLS,
|
||||
there may be more than one instance of this class corresponding 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 actual information
|
||||
the instances contain.
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
extended_type_info(const char * type_info_key);</code></pre></h4></dt>
|
||||
<dd>
|
||||
This constructor should be called by all derived classes. It should be passed
|
||||
a pointer to a const string which identifies the type id system being used. This
|
||||
type id is used to distinguish among the various type id system that might be used
|
||||
and allow them to interoperate.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void self_register();
|
||||
extended_type_info(unsigned int type_info_key, const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This function adds entry for an entry to the global type table. It would usually be
|
||||
called from the constructor of the derived class which implements the
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> functionality.
|
||||
</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.
|
||||
This constructor should be called by all derived classes.
|
||||
The first 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.
|
||||
<p>
|
||||
The second argument is a const string which is the external
|
||||
name of the type to which this record corresponds.
|
||||
It may sometimes be referred to as a GUID - a <b>G</b>lobal <b>U</b>nique <b>ID</b>entifier.
|
||||
It is passed through archives from one program invocation to
|
||||
another to uniquely identify the types that the archive contains.
|
||||
If the "export" facility is not going to be used,
|
||||
this value may be NULL.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This system maintains a global table which relates
|
||||
external strings to
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
This table is used when loading pointers to objects serialized
|
||||
through a base class pointer. In this case, the archive
|
||||
contains a string which is looked up in this table to
|
||||
determine which <code style="white-space: normal">extended_type_info</code>
|
||||
to use for creating a new object.
|
||||
<p>
|
||||
These functions are called by constructors and
|
||||
destructors of classes which implement
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
to add and remove entries from this table.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
const char *get_key() const;
|
||||
</code></pre></h4></dt>
|
||||
@@ -189,58 +188,80 @@ instance. If no key has been associated with the instance, then a NULL is retur
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
bool operator<(const extended_type_info &rhs) const;
|
||||
bool operator==(const extended_type_info &rhs) const;
|
||||
bool operator!=(const extended_type_info &rhs) const;
|
||||
bool operator<(const extended_type_info & rhs) const;
|
||||
bool operator==(const extended_type_info & rhs) const;
|
||||
bool operator!=(const extended_type_info & rhs) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
These functions are used to compare two <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> objects.
|
||||
Among other things, these are used for lookup in the tables.
|
||||
These functions are used to compare
|
||||
<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 impose a strict total ordering on all
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
</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 a 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 loaded at runtime,
|
||||
these constructors can be called until the module is unloaded.
|
||||
Such modules are referred to as <b>plugins</b>.
|
||||
</code>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void destroy(void const * const p) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance created by the above constructor.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of the
|
||||
unique corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of a
|
||||
corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
object.
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const extended_type_info * t);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a pointer to an
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>,
|
||||
return the address of the instance of the same type in the main table.
|
||||
That is the argument t is used as a search argment to find the main
|
||||
table entry for a given type. It would be used like this:
|
||||
<code><pre>
|
||||
// return the global type entry for our type T
|
||||
return find(some_extended_type_info_implementation<T>())
|
||||
</pre></code>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="requirements">Requirements</a></h3>
|
||||
<h3><a name="requirements">Requirements for an Implementation</a></h3>
|
||||
In order to be used by the serialization library, an implementation of
|
||||
<code style="white-space: normal">extended_type_info</code>,
|
||||
(referred to as ETI here), must implement the following:
|
||||
(referred to as ETI here), must be derived from
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
and also implement the following:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
virtual bool
|
||||
ETI::less_than(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Impose a strict total ordering on all instances of the class ETI.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
static const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t);
|
||||
const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Return a pointer to the
|
||||
@@ -248,45 +269,51 @@ Return a pointer to the
|
||||
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
|
||||
a static cast. Implementation of this function will vary among type id systems
|
||||
and sometimes will make presumptions about the type T than can be identified
|
||||
with a particular <code style="white-space: normal">extended_type_info implementation</code>.
|
||||
with a particular <code style="white-space: normal">extended_type_info</code> implementation.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
static extended_type_info *
|
||||
ETI::get_instance();
|
||||
virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Return a pointer to the instance of
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
which corresponds to type T. Normally these instances are static objects so
|
||||
this just amounts to returning the address of this static object.
|
||||
Compare this instance to another one using the same
|
||||
<code style="white-space: normal">extended_type_info</code> implementation.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
static void
|
||||
template<class ETI>
|
||||
ETI::export_register(const char * key);
|
||||
virtual bool ETI::is_equal(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
The main function is to invoke key_register to add the GUID to the
|
||||
global table. Depending on the type id system being used, it might
|
||||
perform other initializaition functions as well.
|
||||
Compare this instance to another one using the same
|
||||
<code style="white-space: normal">extended_type_info</code> implementation.
|
||||
Return <code style="white-space: normal">true</code> if the types referred
|
||||
to are the same. Otherwise return
|
||||
<code style="white-space: normal">false</code>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
It must define the following
|
||||
<a href="../../mpl/doc/refmanual/integral-constant.html">
|
||||
Itegral Constant</a>
|
||||
of type
|
||||
<a href="../../mpl/doc/refmanual/bool.html">bool</a>:
|
||||
<dl>
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
ETI::is_polymorphic
|
||||
const char ETI::get_key() const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Retrieve the external key (aka GUID) for this class.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual void * construct(unsigned int count, ...) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Construct an instance of the corresponding type
|
||||
with the include argument list.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual void * destroy(void const * const ptr ) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance of this type. This calls the
|
||||
proper destructor and recovers allocated memory.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
@@ -302,24 +329,88 @@ by the compiler.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
|
||||
extended_type_info_no_rtti</a></h4></code>
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
However, it does require that all classes for which type id is to be used implement
|
||||
a virtual function of the signiture:
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
Instead, it requires that all polymorphic types be explicitly exported.
|
||||
In addition, if the export facility is to be used to serialize types
|
||||
through base class pointers, those types are required to implement
|
||||
a virtual function with the signature:
|
||||
|
||||
<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.
|
||||
as described above.
|
||||
|
||||
<h3><a name="example">Example</a></h3>
|
||||
The test program <code style="white-space: normal"><a target="test_no_rtti" href="../test/test_no_rtti.cpp">test_no_rtti</a></code>
|
||||
implements this function in terms of the <code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
|
||||
extended_type_info</a></code> API above to return the export key associated with the class.
|
||||
This requires that non-abstract types be exported.
|
||||
This requires that non-abstract types be exported. It also demonstrates the
|
||||
inter-operability between two different implementations of
|
||||
<code style="white-space: normal">extended_type_info</code>.
|
||||
|
||||
<h3><a name="type_requirements">Requirements for Each Type</a></h3>
|
||||
Each type to be managed by the system must be
|
||||
"registered" individually. This is accomplished by instantiating
|
||||
templates. For example, if the type T is to use the <code style="white-space: normal">type_info</code> system
|
||||
one would include the following code:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
template
|
||||
struct extended_type_info_typeid<T>;
|
||||
template
|
||||
struct extended_type_info_typeid<const T>;
|
||||
} // serialization
|
||||
} // boost
|
||||
</pre></code>
|
||||
|
||||
For those using the serialization library, this step can be skipped
|
||||
as it is done automatically. The serialization library includes
|
||||
the macro:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TYPE_INFO(
|
||||
my_type,
|
||||
extended_type_info_typeid<my_class>
|
||||
)
|
||||
</pre></code>
|
||||
|
||||
which is used to specify which <code>extended_type_info</code> system is to
|
||||
be used for a given type.
|
||||
<p>
|
||||
<code>extended_type_info</code> includes a facility for constructing
|
||||
instances of types without knowing what the exact types are. This is done
|
||||
with the function
|
||||
<code>
|
||||
virtual void * extended_type_info::construct(unsigned int count = 0, ...) const;
|
||||
</code>
|
||||
. For example:
|
||||
<br>
|
||||
<code><pre>
|
||||
struct base {
|
||||
...
|
||||
};
|
||||
struct derived : public base {
|
||||
...
|
||||
};
|
||||
...
|
||||
extended_type_info *eti = extended_type_info::find("my_class")
|
||||
base * b = eti->construct(...);
|
||||
</pre></code>
|
||||
<br>
|
||||
The <code>construct</code> takes an argument count and up to
|
||||
four parameters of any type. The arguments are passed to the
|
||||
constructor of "my_class".
|
||||
|
||||
|
||||
A complete example of this can be found
|
||||
<a target="test_dll_plugin.cpp" href="../test/test_dll_plugin.cpp">here</a>
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005-2009.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
|
||||
+38
-4
@@ -7,11 +7,45 @@ 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 - FAQ</title>
|
||||
<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 - Tips and Tricks</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">
|
||||
Tips and Tricks</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
This section will be used to list answers to questions raised in the mailing
|
||||
lists. Most of these are due to subtle aspects of the library which are
|
||||
overlooked even though they might be described in the documentation. Often,
|
||||
these issues are very easy to address - but can be excruciatingly difficult to
|
||||
find. Should you have such an experience, feel free to vent your frustration
|
||||
in a constructive way by adding in your own item. The best way to do this
|
||||
is to create a <a href="http://svn.boost.org/trac/boost/browser">"TRAK" item</a>
|
||||
which includes the text you want to add to this list.
|
||||
|
||||
<ul>
|
||||
<li><h4>
|
||||
</h4></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p>
|
||||
<i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2009. Distributed
|
||||
under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
or copy at http://www.boost.org/LICENSE_1_0.txt) </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+79
-35
@@ -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 .
|
||||
@@ -42,10 +42,10 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
This library includes a large number of files. The are organized and classified
|
||||
according to purpose listed in the above index.
|
||||
This library includes a large number of files. They are organized and classified
|
||||
according to the purposes listed in the above index.
|
||||
<p>
|
||||
<code style="white-space: normal">namespace</code> of a classes and templates is syncronized
|
||||
<code style="white-space: normal">namespace</code> of classes and templates is synchronized
|
||||
with the directory in which the file is found. For example, the class declaration
|
||||
<pre><code>
|
||||
boost::archive::text_oarchive
|
||||
@@ -58,7 +58,7 @@ is included with the following declaration
|
||||
<a name="userincludes">
|
||||
<h3>Files Included by User Programs</h3>
|
||||
Using this library entails including headers listed in this section.
|
||||
It should not be necessary to explictly include any other header files.
|
||||
It should not be necessary to explicitly include any other header files.
|
||||
|
||||
<a name="archiveimplementations">
|
||||
<h4>Archive Implementations</h4>
|
||||
@@ -95,7 +95,7 @@ boost/archive/text_oarchive.hpp
|
||||
<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>
|
||||
<dd>wide character text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
|
||||
boost/archive/text_woarchive.hpp
|
||||
@@ -161,13 +161,14 @@ boost/serialization/export.hpp
|
||||
</a>
|
||||
<dd>For serialization of pointers to derived classes via key export.</dd>
|
||||
|
||||
<dt><a target="is_abstract" href="../../../boost/serialization/is_abstract.hpp">
|
||||
boost/serialization/is_abstract.hpp
|
||||
<dt><a target="assume_abstract" href="../../../boost/serialization/assume_abstract.hpp">
|
||||
boost/serialization/assume_abstract.hpp
|
||||
</a>
|
||||
<dd>For serialization of pointers to abstract base classes. A generic implementation
|
||||
of this is functional only on the most modern compilers. This one is just
|
||||
a thin wrapper which permits one to specify "by hand" whether or not a base class
|
||||
is abstract or not.</dd>
|
||||
<dd>This is just a thin wrapper which permits one to explicitly specify that a
|
||||
particular type is an abstract base class. It is necessary to use this
|
||||
for compilers which don't support the boost type traits implementation of
|
||||
is_abstact.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
@@ -184,7 +185,7 @@ boost/serialization/version.hpp
|
||||
<dt><a target="level" href="../../../boost/serialization/level.hpp">
|
||||
boost/serialization/level.hpp
|
||||
</a>
|
||||
<dd>To override the default implementaton level trait for a type.</dd>
|
||||
<dd>To override the default implementation level trait for a type.</dd>
|
||||
|
||||
<dt><a target="tracking" href="../../../boost/serialization/tracking.hpp">
|
||||
boost/serialization/tracking.hpp
|
||||
@@ -206,7 +207,7 @@ This group of headers includes templates which implement serialization for Stand
|
||||
Library or Boost Library templates. Any program which uses these templates can
|
||||
invoke serialization of objects of these types just by including the corresponding header.
|
||||
<p>
|
||||
By convention, these header files are named:
|
||||
By convention these header files are named:
|
||||
|
||||
boost/serialization/xxx.hpp
|
||||
|
||||
@@ -256,7 +257,7 @@ for in all archive implementations. The serialization system relies on
|
||||
certain special types such as <code style="white-space: normal">class_id_type</code> and others to
|
||||
record information in archives that is required to reconstruct the original
|
||||
data structure. These are handled exactly as any other serializable type.
|
||||
That is, the can be handled as simple primitives such as they are in simple
|
||||
That is, they can be handled as simple primitives such as they are in simple
|
||||
text files, or with special code as they are in xml archives.
|
||||
</dd>
|
||||
|
||||
@@ -268,7 +269,7 @@ boost/archive/basic_text_iprimitive.hpp
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
Implementation of serialization of primitive types in terms of an character
|
||||
Implementation of serialization of primitive types in terms of character
|
||||
or wide character text streams. This is used in the implementation of text and
|
||||
xml archives. Presumably this would be useful for implementations of other variations
|
||||
of text archives such as user friendly text or windows ini files.
|
||||
@@ -282,7 +283,7 @@ boost/archive/basic_binary_iprimitive.hpp
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
Implementation of serialization of primitive types in terms of an character
|
||||
Implementation of serialization of primitive types in terms of character
|
||||
or wide character binary streams.
|
||||
</dd>
|
||||
|
||||
@@ -293,16 +294,16 @@ boost/archive/basic_binary_oarchive.hpp
|
||||
boost/archive/basic_binary_iarchive.hpp
|
||||
</a>
|
||||
<dd>
|
||||
Implementation of serialization of all types in terms of an character
|
||||
Implementation of serialization of all types in terms of character
|
||||
or wide character binary streams. This is factored out separately from the
|
||||
implementation of binary primitives above. This may facilitate the creation of
|
||||
other types of binary archives in the future. It also preserves analogy and symetry with
|
||||
other types of binary archives in the future. It also preserves analogy and symmetry with
|
||||
the rest of the library which aids in understanding.
|
||||
</dd>
|
||||
<dt><a target="basic_text_oarchive" href="../../../boost/archive/basic_text_oarchive.hpp">
|
||||
boost/archive/basic_text_oarchive.hpp
|
||||
</a>
|
||||
<dt><a target="basic_text_iarchive" href="../../../boost/archive/basic_text_iarchive.hpp">
|
||||
<dt><a target="basic_te't_iarchive" href="../../../boost/archive/basic_text_iarchive.hpp">
|
||||
boost/archive/basic_text_iarchive.hpp
|
||||
</a>
|
||||
</dt>
|
||||
@@ -314,12 +315,12 @@ boost/archive/basic_xml_iarchive.hpp
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
Implementation of serialization of all types in terms of an character
|
||||
Implementation of serialization of all types in terms of character
|
||||
or wide character text streams. These classes specify archive type specific
|
||||
behavior on a type by type basis. For example, <code style="white-space: normal">basic_xml_oarchive.hpp</code>
|
||||
includes code to guarentee that any object not attached to a name will
|
||||
includes code to guarantee that any object not attached to a name will
|
||||
trap during compile time. On the other hand, <code style="white-space: normal">basic_text_oarchive.hpp</code>
|
||||
contains code to strip out and ingore any names attached to objects.
|
||||
contains code to strip out and ignore any names attached to objects.
|
||||
<p>
|
||||
<dt><a target="common_iarchive" href="../../../boost/archive/detail/common_iarchive.hpp">
|
||||
boost/archive/detail/common_iarchive.hpp
|
||||
@@ -328,7 +329,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>
|
||||
|
||||
@@ -336,11 +337,54 @@ the interface to the internal implementation details of the library.
|
||||
|
||||
<a name="archiveinternals">
|
||||
<h4>Archive Internals</h4>
|
||||
The header files in the directory
|
||||
<a target="basic_xml_iarchive" href="../../../boost/archive/detail">boost/archive/detail</a>
|
||||
implement parts of the library itself. The should never need to be changed by users
|
||||
of the library in order to implement either a class serialization or a new
|
||||
archive type.
|
||||
|
||||
The interface (see <a target="detail" href="archives.html">Archive Concepts</a>)
|
||||
and implementation are factored out into separate classes to minimize code duplication.
|
||||
|
||||
These files are found in the directory
|
||||
<a target="boost_archive_detail" href="../../../boost/archive/detail">boost/archive/detail</a>.
|
||||
These are included as necessary by the archive class implementations listed above.
|
||||
This has the unfortunate side effect of making the implementation less transparent.
|
||||
Users should never find it necessary to change these files.
|
||||
<p>
|
||||
The following discussion is based on the
|
||||
<a target="class_diagram" href="class_diagram.html">class diagram</a>.
|
||||
<p>
|
||||
<dt><a target="interface_iarchive" href="../../../boost/archive/detail/interface_iarchive.hpp">
|
||||
boost/archive/detail/interface_iarchive.hpp</a>
|
||||
<dt><a target="interface_iarchive" href="../../../boost/archive/detail/interface_iarchive.hpp">
|
||||
boost/archive/detail/interface_iarchive.hpp</a>
|
||||
<dd>
|
||||
Here are the declarations and definitions for the
|
||||
<a href="archives.html">archive_concept</a>. This class redirects calls to the
|
||||
archive interface to a function named <code>save_override</code> in the most derived
|
||||
archive class.
|
||||
</dd>
|
||||
<code>save_override</code> is declared and implemented in each class in
|
||||
the archive hierarchy.
|
||||
|
||||
<pre><code>
|
||||
template<class T>
|
||||
void save_override(T & t, BOOST_PFTO int){
|
||||
// All for otherwise unhandled types are forwarded to the base class.
|
||||
// This emulates behavior for function overloading.
|
||||
this->base::save_override(t, 0);
|
||||
}
|
||||
void save_override(const some_type & t, int){
|
||||
// any special handling for some type
|
||||
// this will usually entail forwarding some other operation
|
||||
// in the most derived class.
|
||||
this->This()->...
|
||||
// or in one of its parents basic_text_oprimitive
|
||||
this->This()->save(static_cast<int>(t));
|
||||
}
|
||||
... // other special type handling
|
||||
</code></pre>
|
||||
|
||||
Note the usage of
|
||||
<a target="detail" href="implementation.html#functiontemplateordering">Partial Function Template Ordering</a>
|
||||
to permit the correct save implementation to be selected.
|
||||
</dd>
|
||||
|
||||
<a name="codemodules">
|
||||
<h4>Archive Library Code Modules</h4>
|
||||
@@ -358,13 +402,13 @@ library code for that part of the code which only depends upon the archive type.
|
||||
Building of the library generates and compiles code for all archives implemented.
|
||||
|
||||
<ul>
|
||||
<li>Serialization of user and primitive types runs a top speed. This is a noticiable
|
||||
<li>Serialization of user and primitive types runs at top speed. This is a noticeable
|
||||
difference with a previous version of the library which did not use templates for archives.
|
||||
<li>Library implementation code that never changes need only be compiled once
|
||||
rather than each time a user's program is recompiled. This can save much
|
||||
development time.
|
||||
<li>Headers which solely related to implementation need only be included
|
||||
in the library code modules. This prevents a user program from accidently
|
||||
in the library code modules. This prevents a user program from accidentally
|
||||
depending on an implementation feature of the serialization library.
|
||||
<li>In building the library I came to the conclusions that there can arise
|
||||
situations regarding static code/data instantiation that could not be
|
||||
@@ -373,22 +417,22 @@ Building of the library generates and compiles code for all archives implemented
|
||||
</ul>
|
||||
An example of this is the usage of the spirit library in the library.
|
||||
It takes a long time to compile and includes lots of other files. Having this
|
||||
only in the library is much more convenient that having to include in every
|
||||
only in the library is much more convenient that having to include it in every
|
||||
program which uses xml serialization.
|
||||
|
||||
<a name="dataflowiterators">
|
||||
<h4>Dataflow Iterators</h4>
|
||||
In the course of developing this library, it became convenient to make a set
|
||||
of composable iterator adaptors for handling archive text. Applications include
|
||||
escaping and unescaping xml text, implementing to/from base64 conversion among
|
||||
escaping and unescaping xml text and implementing to/from base64 conversion among
|
||||
others.
|
||||
<p>
|
||||
This is a ripe topic in itself. Its touched upon by the
|
||||
This is a ripe topic in itself. It's touched upon by the
|
||||
<a href="../../../libs/iterator/doc/index.html">boost iterator</a> libraries,
|
||||
<a href="http://www.zib.de/weiser/vtl/index.html">View Template Library</a>, and others.
|
||||
<p>
|
||||
The code for these iterators is really independent of this library. But since it
|
||||
hasn't been and probably won't be reviewed outside of this context. I've left in a directory
|
||||
hasn't been and probably won't be reviewed outside of this context. I've left it in a directory
|
||||
local to the serialization library:
|
||||
<a target="archiveiterators" href="../../../boost/archive/iterators">boost/archive/iterators</a>.
|
||||
These iterators are described in
|
||||
|
||||
+10
-10
@@ -30,24 +30,24 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<li>27 Feb 2002
|
||||
<ul>
|
||||
<li>divide interface from implementation for class
|
||||
serialization to permit compiliation on gcc
|
||||
<li>improved template instantanciation for type templates
|
||||
serialization to permit compilation on gcc
|
||||
<li>improved template instantantation for type templates
|
||||
</ul>
|
||||
<li>18 Mar 2002 - draft #2 uploaded to boost
|
||||
<ul>
|
||||
<li>elminated locale effects on archives
|
||||
<li>added signature and library version to archive header
|
||||
<li>improved detection of errors when objects are serializationed
|
||||
as pointers and subsequently serializationed as objects
|
||||
<li>improved detection of errors when objects are serialized
|
||||
as pointers and subsequently serialized as objects
|
||||
<li>permit non-portable binary archives
|
||||
<li>implement work around for systems such as MSVC 6.0 that
|
||||
don'tsupport partial ordering
|
||||
<li>implement workaround for systems such as MSVC 6.0 that
|
||||
don't support partial ordering
|
||||
</ul>
|
||||
<li>16 May 2002 - draft #3 uploaded to boost
|
||||
<ul>
|
||||
<li>Ability to specify serialization of other templates in a
|
||||
non-intrusive way.
|
||||
<li>Included and example which uses boost::shared_ptr.
|
||||
<li>Included an example which uses boost::shared_ptr.
|
||||
<li>improved documentation
|
||||
<li>More test cases
|
||||
<li>More testing and documentation of obscure situtations
|
||||
@@ -65,7 +65,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<li>minor corrections
|
||||
<li>Additions to documentation to explicitly address issues of
|
||||
exception safety.
|
||||
<li>More test cases/demos to illustrate handlling of the above issues.
|
||||
<li>More test cases/demos to illustrate handling of the above issues.
|
||||
<li>Additions to documentation to include rationale for not depending
|
||||
on type_id
|
||||
<li>Implementation of serialization of boost::shared_ptr.
|
||||
@@ -127,8 +127,8 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</ul>
|
||||
<li>1 November 2004 - final changes for first boost official release 1.32 .
|
||||
<ul>
|
||||
<li>Adjustments to address make package compatible with two-phase lookup.
|
||||
<li>Many small adjustments to accomdate quirks of various compilers.
|
||||
<li>Adjustments to address package compatible with two-phase lookup.
|
||||
<li>Many small adjustments to accommodate quirks of various compilers.
|
||||
<li>A few bug fixes.
|
||||
</ul>
|
||||
</ol>
|
||||
|
||||
+21
-209
@@ -26,20 +26,13 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#functiontemplateordering">Partial Function Template Ordering</a>
|
||||
<dt><a href="#charencoding">Character Encoding</a>
|
||||
<dt><a href="#tempatesyntax">Template Invocation syntax</a>
|
||||
<dt><a href="#partialtemplatespecialization">Partial Template Specialization</a>
|
||||
<dt><a href="#othercompilerissues">Specific Compiler/Library Issues</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#gcc3x">GCC 3.X, 4.X</a>
|
||||
<dt><a href="#gcc295">GCC 2.95</a>
|
||||
<dt><a href="#gcc4x">44.X</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="#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>
|
||||
@@ -49,86 +42,11 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<h3><a name="functiontemplateordering">Partial Function Template Ordering</a></h3>
|
||||
Not all C++ compilers correctly support partial function template ordering (PFTO).
|
||||
For these compilers, the following code will fail to compile:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
my_template<T> & t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
The serialization library works around this issue by using a different
|
||||
default definition of the first template:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned long int file_version // Note: change to long
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
Now, the second template is not matched with the first one so there
|
||||
is no PFTO and no compile error. When the serialization library invokes
|
||||
<pre><code>
|
||||
serialize(ar, t, 0);
|
||||
</pre></code>
|
||||
the function declaration is first matched against templates with
|
||||
an integer for the third argument. If there is a match, the matching
|
||||
template is instantiated and later invoked. If there is no match,
|
||||
an attempt is made to match other templates by converting arguments to other types.
|
||||
In this case the third argument can be converted to long to match
|
||||
the first template - which is the default. So in this case, the first
|
||||
template will be instantiated and later invoked. We have managed to
|
||||
use function overloading to achieve the same effect as PFTO
|
||||
were it correctly implemented.
|
||||
<p>
|
||||
This depends upon undefined behavior of a compiler already
|
||||
determined to be non-conforming. In other words, there is no
|
||||
guarantee that this will work on all compilers. If a compiler does not
|
||||
correctly support PFTO and this method cannot be used to workaround
|
||||
it, non-intrusive serialization cannot be supported for that compiler.
|
||||
As of this writing, such a compiler has not been encountered.
|
||||
<p>
|
||||
It turns out that using this "trick" can create problems with
|
||||
compilers that DO correctly support PFTO. For this reason we
|
||||
define a macro <code style="white-space: normal">BOOST_PTFO</code> which
|
||||
is defined to be <code style="white-space: normal">long</code>
|
||||
for non-conforming compilers and nothing for conforming ones. So
|
||||
the default definition is really:
|
||||
The serialization library works around this issue by using a different
|
||||
default definition of the first template:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned BOOST_PFTO int file_version // Note: change to BOOST_PFTO
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
<h3><a name="charencoding">Character Encoding</a></h3>
|
||||
The whole question of character encoding combined with wide characters
|
||||
is much more complicated than it would seem to be. The current library
|
||||
defines in 3 formats (text, binary, and XML), wide and narrow characters,
|
||||
an attempts to be portable between compiler libraries. The results of
|
||||
and attempts to be portable between compiler libraries. The results of
|
||||
a rather long consideration of all these factors has been to set
|
||||
default encoding according to the following rules.
|
||||
<ul>
|
||||
@@ -149,7 +67,7 @@ default encoding according to the following rules.
|
||||
</ul>
|
||||
This character encoding is implemented by changing the <code style="white-space: normal">locale</code> of the
|
||||
i/o stream used by an archive when the archive is constructed, the stream
|
||||
local is changed back to its original value. This action can be overridden
|
||||
locale is changed back to its original value. This action can be overridden
|
||||
by specifying <code style="white-space: normal">boost::archive::no_codecvt</code>
|
||||
when the archive is opened. In this case, the stream <code style="white-space: normal">locale</code> will
|
||||
not be changed by the serialization library.
|
||||
@@ -175,42 +93,18 @@ do the following.
|
||||
<li>Create the archive with the flag <code style="white-space: normal">no_codecvt</code>.
|
||||
</ul>
|
||||
Naturally, the input process has to be symmetrical.
|
||||
<h3><a name="partialtemplatespecialization">Partial Template Specialization</a></h3>
|
||||
Compilers which fail to support partial template specialization will fail to compile
|
||||
the following code. To make this compiler, the <code style="white-space: normal">const</code> has to be removed.
|
||||
<pre><code>
|
||||
void f(A const* a, text_oarchive& oa)
|
||||
{
|
||||
oa << a;
|
||||
}
|
||||
</code></pre>
|
||||
<h3><a name="tempatesyntax">Template Invocation syntax</a></h3>
|
||||
Some compilers may not recognize the syntax:
|
||||
<pre><code>
|
||||
ar.template register_type<T>();
|
||||
</code></pre>
|
||||
for "registering" derived pointers of polymorphic classes. The actual
|
||||
function prototype is:
|
||||
<pre><code>
|
||||
template<T>
|
||||
void register_type(T * t = NULL);
|
||||
</code></pre>
|
||||
so that one may write <code style="white-space: normal">ar.register_type(static_cast<T *>(NULL))</code> instead of
|
||||
the syntax described above.
|
||||
</ul>
|
||||
<h3><a name="othercompilerissues">Specific Compiler/Library Issues</a></h3>
|
||||
|
||||
<h4><a name="gcc3x">GCC 3.X, 4.X</a></h4>
|
||||
<h4><a name="gcc4x">GCC 4.X</a></h4>
|
||||
<ul>
|
||||
<li>GCC versions for Cygwin and MinGW fail to support wide character I/O.
|
||||
So all tests using wide char I/O fail. Note that if wide character I/O support
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<li>This compiler generates long warning messages related to the usage of
|
||||
non virtual destructors in polymorphic classes. These warnings have been
|
||||
carfully considered and the code that generates these warning has been
|
||||
carefully considered and the code that generates these warning has been
|
||||
unchanged. In this case the warning should should be ignored as in certain
|
||||
usages of the library, making the destructors virtual could lead to problems.
|
||||
As an alternative, base class destructors have been make "protected" to
|
||||
As an alternative, base class destructors have been made "protected" to
|
||||
address the concerns that motivate these warning messages. When building
|
||||
the serialization library and tests with bjam, these warnings are suppressed.
|
||||
When building one's own applications, these warnings can be suppressed by
|
||||
@@ -220,17 +114,7 @@ the syntax described above.
|
||||
-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
|
||||
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>
|
||||
<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>
|
||||
@@ -245,40 +129,39 @@ line by including the following switch:
|
||||
|
||||
<h4><a name="vc71">Visual C++ 7.1</a></h4>
|
||||
Derivation from an archive class defined in a DLL as described in ... will not work.
|
||||
This is due to the way that VC++ handles templeted code with __decl(dllexport) and
|
||||
This is due to the way that VC++ handles templated code with __decl(dllexport) and
|
||||
__decl(dllimport) specifications. Basically, this compiler requires that all the
|
||||
instantiations have the same specification - even though they have different
|
||||
template arguments. The example <code style="white-space: normal">
|
||||
demo_portable_iarchive.cpp</code> would have to reformulated as a library or dll
|
||||
demo_portable_iarchive.cpp</code> would have to be 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
|
||||
these switches are enabled if you want to build and run these programs.
|
||||
programs 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 libary can be used
|
||||
either way - <strong>BUT</strong> - both the libray <strong>AND</strong> the application
|
||||
it will be treated as a synonym for a 16 bit integer. The library can be used
|
||||
either way - <strong>BUT</strong> - both the library <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.
|
||||
along with a set of project files - one for each demo and test. Consider the following if you
|
||||
decide 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,
|
||||
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..
|
||||
@@ -312,77 +195,6 @@ decided to use these configurations.
|
||||
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">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.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
|
||||
error message. To function save/load/serialize member function templates must be defined
|
||||
within the class definition. This feature is essential to <code style="white-space: normal">demo_pimpl</code>. Hence,
|
||||
this program will fail to compile. In this case the problem can't be worked around and
|
||||
still demonstrate this facility.
|
||||
<li>This compiler does not support <code style="white-space: normal">wchar_t</code> as a separate type. It defines
|
||||
<code style="white-space: normal">wchar_t</code> as an alias for <code style="white-space: normal">short int</code>. In general things will still
|
||||
function. However certain customization, such as overloading archive operators for
|
||||
saving/loading wide character arrays would produce surprises in this environment.
|
||||
<li>Under certain circumstances, a program will fail to link with the message:
|
||||
LIN1179 - "invalid or corrupt file: duplicate comdat". According
|
||||
to <a href="http://groups.google.com/groups?th=8a05c82c4ffee280">
|
||||
http://groups.google.com/groups?th=8a05c82c4ffee280
|
||||
</a> (look for P78)
|
||||
A LNK1179 error occurs when:
|
||||
<ul>
|
||||
<li>The template class takes at least two arguments.
|
||||
<li>The template is used at least two times with identical first
|
||||
and different second arguments.
|
||||
<li>The static member variable is of an object type with at least one
|
||||
base class. (In another scenario it also occurred using a member
|
||||
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.
|
||||
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.
|
||||
<li>Using more than one kind of archive in the same code module. This should be easy
|
||||
to work around in practice.
|
||||
</ul>
|
||||
<li>Code modules exceeding some undetermined size that use the library will fail with
|
||||
<i>fatal error C1204: compiler limit : internal structure overflow</i>. This can be addressed
|
||||
by dividing the module into smaller ones.
|
||||
</ul>
|
||||
<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>If class serialize functions are not accessable either by making them public or by
|
||||
including <code style="white-space: normal">friend</code> declarations as described in
|
||||
<a href="serialization.html#member">Class Serialization - Member Function</a>, the
|
||||
will compile but fail at runtime.
|
||||
<li>Tests using custom extended type which doesn't use rtti fails. (5.64 only !).
|
||||
<li>Tests 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="comeau">Comeau 4.3.3</a></h4>
|
||||
<ul>
|
||||
<li>This compiler fails to make a DLL with export under windows.
|
||||
@@ -393,7 +205,7 @@ all the above issues for Visual C++ 7.0 plus:
|
||||
|
||||
<h4><a name="codewarrior9">Code Warrior 9.x</a></h4>
|
||||
<ul>
|
||||
<li>Some tests and demos demos fail - still under investigation
|
||||
<li>Some tests and demos fail - still under investigation
|
||||
</ul>
|
||||
|
||||
<h4><a name="codewarrior">Code Warrior 8.3</a></h4>
|
||||
@@ -413,7 +225,7 @@ Several compilers, including Visual C++ 6.0, use an older dinkumware library.
|
||||
These platforms have several issues:
|
||||
<ul>
|
||||
<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
|
||||
of an i/o stream unless the <code style="white-space: normal">imbue</code> function is called before the
|
||||
stream is opened. In order to use this library with this environment to generate UTF-8
|
||||
files, one cannot depend on the "automatic" setting of locale that archives implement. The
|
||||
stream locale must be set explicitly on the stream before an archive is opened on it. The
|
||||
@@ -425,17 +237,17 @@ These platforms have several issues:
|
||||
|
||||
<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)
|
||||
<li>when built to use the dynamic linking versions of the C++ runtime code (<runtime-link>dynamic)
|
||||
all tests fail to link. This is due to a missing symbol in the stlport library related
|
||||
to custom codecvt facets.
|
||||
<li>the test_set fails to run correctly. It seems the hashed set interator doesn't
|
||||
<li>the test_set fails to run correctly. It seems the hashed set iterator doesn't
|
||||
implement the ++ operator correctly. This causes the test to fail by consuming all available
|
||||
memory. Given this, this test is commented out.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2004
|
||||
<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-2015.
|
||||
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>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 839 B After Width: | Height: | Size: 849 B |
@@ -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
|
||||
techniques 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 a pointer to the object in question. Since
|
||||
the Serialization library resurrects a 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,
|
||||
then 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 functionality is implemented as an "adaptor" template
|
||||
which takes the base class as a template argument, such functionality could be
|
||||
appended to any archive for which that functionality makes sense.
|
||||
For example, an adaptor for generating an xml schema could be
|
||||
appended to both wide and 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 fulfill 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>
|
||||
+1
-4
@@ -28,9 +28,6 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dl class="index">
|
||||
<dt><a href="#Requirements">Requirements</a></dt>
|
||||
<dt><a href="#otherimplementations">Other Implementations</a></dt>
|
||||
<!--
|
||||
<dt><a href="#footnotes">Footnotes</a></dt>
|
||||
-->
|
||||
</dl>
|
||||
<p>Here, we use the term <strong>"serialization"</strong> to mean
|
||||
the reversible deconstruction of an arbitrary set of C++ data structures
|
||||
@@ -130,7 +127,7 @@ XML, or some other created by the user of this library.
|
||||
This library has similar goals to this one. Some aspects of the
|
||||
implemenation are also similar. As of this writing, it would seem that:
|
||||
<ul>
|
||||
<li>Portability(1) is guarenteed only for recent versions of GCC.
|
||||
<li>Portability(1) is guaranteed only for recent versions of GCC.
|
||||
<li>Versioning(3) of class definitions is not explicitly supported by
|
||||
the library.
|
||||
<li>it doesn't seem to automatically account for shared pointers(5).
|
||||
|
||||
@@ -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="../../../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>
|
||||
+17
-14
@@ -31,7 +31,7 @@ the "Handle Body Idiom". Included in this library is a program called
|
||||
<a href="../example/demo_pimpl.cpp" target="demo_impl_cpp">demo_pimpl.cpp</a>
|
||||
which illustrates how this is used. The file
|
||||
<a href="../example/demo_pimpl_A.cpp" target="demo_impl__Acpp">demo_pimpl_A.hpp</a>
|
||||
contains the declaration of the a class that hides its implementation
|
||||
contains the declaration of the A class that hides its implementation
|
||||
by including a pointer to struct B that is only defined as a pointer.
|
||||
<pre><code>
|
||||
// class whose declaration is hidden by a pointer
|
||||
@@ -41,12 +41,15 @@ struct A {
|
||||
// class a contains a pointer to a "hidden" declaration
|
||||
B *pimpl;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version);
|
||||
void serialize(Archive & ar, const unsigned int file_version);
|
||||
A();
|
||||
};
|
||||
</code></pre>
|
||||
Serialization of A requires access to the definition of B in order so it
|
||||
is defined in the separately compiled module:
|
||||
Serialization of A requires access to the definition of B. But that doesn't mean
|
||||
that it requires the this access from the header file. Since B is a pointer,
|
||||
a declaration of class B is sufficient. The implemenation of the serialization
|
||||
of A includes the definition of class B defined in the separately compiled module:
|
||||
|
||||
<a href="../example/demo_pimpl_A.cpp" target="demo_impl_A_cpp">demo_pimpl_A.cpp</a>
|
||||
by:
|
||||
<pre><code>
|
||||
@@ -56,8 +59,8 @@ by:
|
||||
struct B {
|
||||
int b;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & b;
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & b;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,8 +74,8 @@ A::~A(){
|
||||
|
||||
// now we can define the serialization for class A
|
||||
template<class Archive>
|
||||
void A::serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & pimpl;
|
||||
void A::serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & pimpl;
|
||||
}
|
||||
</code></pre>
|
||||
As described in <a href="bibliography.html#10">[10]</a> this brings the
|
||||
@@ -85,12 +88,12 @@ following advantages:
|
||||
So, we compile the modules and everything is fine. However when we
|
||||
link, we get an error. Two symbols are undefined:
|
||||
<pre><code>
|
||||
void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
|
||||
</code></pre>
|
||||
The problem is that when compiling the above code,
|
||||
there is no instantiation of the <code style="white-space: normal">serialize</code> template.
|
||||
There can't be as its not "known" what types of archives
|
||||
There can't be as it's not "known" what types of archives
|
||||
the serialization is going to be used with. So these functions are "missing"
|
||||
when an attempt to link is made. The solution is to explicitly instantiate
|
||||
serialization code for those archives which are going to be used. In this
|
||||
@@ -100,11 +103,11 @@ example, including the the following code in any *.cpp file does just that:
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
template void A::serialize<boost::archive::text_iarchive>(
|
||||
boost::archive::text_iarchive & ar,
|
||||
boost::archive::text_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
template void A::serialize<boost::archive::text_oarchive>(
|
||||
boost::archive::text_oarchive & ar,
|
||||
boost::archive::text_oarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
</code></pre>
|
||||
@@ -112,7 +115,7 @@ The program should now link as well as compile.
|
||||
<p>
|
||||
The downside of this is that one has to know which archives are going
|
||||
to be used with hidden serializations. This is an effect of using template
|
||||
driven code. One can invoke explicity instantiation for all known templates and
|
||||
driven code. One can invoke explicitly instantiation for all known templates and
|
||||
presume that the linker will exclude unreferenced code. This should
|
||||
work but is platform dependent.
|
||||
<hr>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 855 B |
@@ -0,0 +1,170 @@
|
||||
<!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 - Private Base 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">Private Base Classes</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
In many cases, serialization of private or protected base classes present no special problems.
|
||||
This is true for both simple classes and types as well as pointers to those
|
||||
classes and types. That is, the following program compiles and runs exactly as one would expect.
|
||||
<pre><code>
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// test_private_base.cpp
|
||||
|
||||
// (C) Copyright 2009 Eric Moyer - 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 <fstream>
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class Base {
|
||||
friend class boost::serialization::access;
|
||||
int m_i;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_NVP(m_i);
|
||||
}
|
||||
protected:
|
||||
bool equals(const Base &rhs) const {
|
||||
return m_i == rhs.m_i;
|
||||
}
|
||||
Base(int i = 0) :
|
||||
m_i(i)
|
||||
{}
|
||||
};
|
||||
|
||||
class Derived : private Base {
|
||||
friend class boost::serialization::access;
|
||||
private:
|
||||
Base & base_cast(){
|
||||
return static_cast<Base &>(*this);
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
|
||||
}
|
||||
public:
|
||||
bool operator==(const Derived &rhs) const {
|
||||
return Base::equals(static_cast<const Base &>(rhs));
|
||||
}
|
||||
Derived(int i = 0) :
|
||||
Base(i)
|
||||
{}
|
||||
};
|
||||
|
||||
int
|
||||
main( int /* argc */, char* /* argv */[] )
|
||||
{
|
||||
const char * testfile = boost::archive::tmpnam(NULL);
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived a(1), a1(2);
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("a", a);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("a", a1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
|
||||
if(a != a1)
|
||||
return 1;
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived *ta = &a;
|
||||
Derived *ta1 = NULL;
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("ta", ta);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("ta", ta1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
if(*ta != *ta1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code></pre>
|
||||
Difficulties start to occur when the base class is made polymorphic by the designation
|
||||
of one or more functions as "virtual". If a class is polymorphic, the library
|
||||
presumes that one will want the ability to serialize a derived class through
|
||||
a pointer to the base class. Included in the macro
|
||||
<code>
|
||||
BOOST_SERIALIZATION_BASE_OBJECT_NVP
|
||||
</code>
|
||||
is code which links derived and base class definitions in tables used to serialize
|
||||
derived classes through pointers to a polymorphic base class. This code requires
|
||||
the ability to invoke
|
||||
<code>
|
||||
static_cast<Base &>(Derived &)
|
||||
</code>
|
||||
which C++ will only permit from within the derived class if the base class is
|
||||
private or protected. The program will fail to compile with an error message
|
||||
indicating invalid cast.
|
||||
<p>
|
||||
In order for this
|
||||
code compiler the following alteration must be made:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
//ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
|
||||
ar & boost::serialization::make_nvp(
|
||||
"Base",
|
||||
static_cast<Base &>(*this)
|
||||
);
|
||||
}
|
||||
</code></pre>
|
||||
With this change the program will now compile.
|
||||
<p>
|
||||
If we made one of the functions of <code>Base</code> <code>virtual</code>
|
||||
in order to use the "export" functionality of the serialization library and permit serialization through
|
||||
a pointer the the base class, we'll be disappointed. Without the ability to
|
||||
cast to the base class, we can't use the functionality.
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2015.
|
||||
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,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()
|
||||
+2
-223
@@ -10,7 +10,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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>
|
||||
<title>Serialization - Rationale</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
@@ -31,7 +31,6 @@ 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>
|
||||
-->
|
||||
@@ -50,7 +49,7 @@ streams even though they have similar syntax rules.
|
||||
<ul>
|
||||
<li>Archive classes are not kinds of streams though they
|
||||
are implemented in terms of streams. This
|
||||
distinction is addressed in <a href="bibliography.html#5">[5]</a> item number item 41 .
|
||||
distinction is addressed in <a href="bibliography.html#5">[5]</a> item number 41.
|
||||
<li>We don't want users to insert/extract data
|
||||
directly into/from the stream . This could
|
||||
create a corrupted archive. Were archives
|
||||
@@ -110,226 +109,6 @@ and/or <code style="white-space: normal">export</code> facilities described in t
|
||||
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_SERIALIZATION_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_SERIALIZATION_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_SERIALIZATION_TRACKING</code> that
|
||||
was inserted. Now the second trap is avoided, But damn - the first trap is
|
||||
popping up again. Eventually, after some code restructuring, the differing
|
||||
requirements of serializating <code style="white-space: normal">construct_from</code>
|
||||
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>
|
||||
|
||||
+250
-80
@@ -9,38 +9,144 @@ 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 - Release Notes</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Release Notes</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">Release Notes</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<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">
|
||||
Release Notes</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#requirements">Requirements</a></dt>
|
||||
<dt><a href="#differences_1_32">Differences from version 1.32</a></dt>
|
||||
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
|
||||
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
|
||||
<dt><a href="#todo">Pending Issues</a></dt>
|
||||
<dt><a href="#differences_1_59">Differences from version 1.58</a></dt>
|
||||
<dt><a href="#differences_1_58">Differences from version 1.48</a></dt>
|
||||
<dt><a href="#differences_1_45">Differences from version 1.45</a></dt>
|
||||
<dt><a href="#differences_1_43">Differences from version 1.43</a></dt>
|
||||
<dt><a href="#differences_1_42">Differences from version 1.42</a></dt>
|
||||
<dt><a href="#differences_1_41">Differences from version 1.41</a></dt>
|
||||
<dt><a href="#differences_1_40">Differences from version 1.40</a></dt>
|
||||
<dt><a href="#differences_1_39">Differences from version 1.39</a></dt>
|
||||
<dt><a href="#differences_1_37">Differences from version 1.37</a></dt>
|
||||
<dt><a href="#differences_1_35">Differences from version 1.35</a></dt>
|
||||
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
|
||||
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
|
||||
<dt><a href="#differences_1_32">Differences from version 1.32</a></dt>
|
||||
<dt><a href="#todo">Pending Issues</a></dt>
|
||||
</dl>
|
||||
This is the Boost 1.33 Serialization Library.
|
||||
There are currently no known bugs. However, due to compiler/library quirks and or
|
||||
bugs, some tests fail with some combinations of compilers and libraries.
|
||||
<h2><a name="requirements"></a>Requirements</h2>
|
||||
This library requires Boost version 1.33 or later.
|
||||
As of this writing, 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="differences_1_59"></a>Differences from Boost 1.58</h2>
|
||||
<ul>
|
||||
<li>Eliminated support for Borland compilers and Microsoft compilers prior to version
|
||||
7.1.
|
||||
<li>Eliminated support for compilers which do not support Partial Function Template
|
||||
Ordering (pfto).
|
||||
<li>Added support for "visibility hidden" for GCC compilers. Shared libraries
|
||||
will only expose symbols actually needed rather than all sympols in the library. This
|
||||
should result in smaller shared libraries which are faster to load.
|
||||
</ul>
|
||||
<h2><a name="differences_1_58"></a>Differences from Boost 1.48</h2>
|
||||
<ul>
|
||||
<li>Added support for C++11 types such as std::shared_ptr, std::array, and others.
|
||||
<li>Implemented the concept of a "Helper" which can be used to implement serialization of types which are otherwise not serializable."
|
||||
<li>Made library compatible with C++11, Compatibility with C++03 has been maintained.
|
||||
</ul>
|
||||
<h2><a name="differences_1_45"></a>Differences from Boost 1.45</h2>
|
||||
Since the release of version 1.42, it has been discovered that binary
|
||||
archives created by versions 1.42-1.44 cannot always be read by the
|
||||
recent binary archive code. Work has proceeded in detecting the source
|
||||
of these anomolies and those which have been reported with test cases
|
||||
have been fixed. As of this writing, it is not known whether all
|
||||
binary archives created with these versions can be loaded.
|
||||
<h2><a name="differences_1_43"></a>Differences from Boost 1.43</h2>
|
||||
<ul>
|
||||
<li>fixed bug in the serialization of virtual base classes. Due
|
||||
to heroic efforts by Takatoshi Kondo.
|
||||
<li>Native binary archives created under versions 1.42 and 1.43
|
||||
suffer from a serious problem. It's likely they won't be readable
|
||||
by this latest version. This due to the fact that 1.42 made some
|
||||
changes in the binary format of some types. Normally this could
|
||||
be addressed by detecting the library version number written into
|
||||
the archive header. Unfortunately, this library version number
|
||||
was not incremented at 1.42 as it should have been. So now we have
|
||||
two different binary archive versions with the same library version
|
||||
number.
|
||||
<p>
|
||||
This has been addressed by including a small utility in the example
|
||||
directory named fix_six.cpp. This should be run with the command line<br>
|
||||
<code><pre>
|
||||
fix_six <file name>
|
||||
</pre></code>
|
||||
This will assign 7 to the library version number of the archive. This
|
||||
fix will need to ba applied to native binary archives created with
|
||||
boost versions 1.42 and 1.43.
|
||||
</ul>
|
||||
<h2><a name="differences_1_42"></a>Differences from Boost 1.42</h2>
|
||||
<ul>
|
||||
<li>fixed failure of shared_ptr serialization when serializing pointers
|
||||
created from enable_shared_from_this.
|
||||
<li>added example for a simple archive which can be used as a debug log.
|
||||
This example illustrates the implemenation of the archive concept to aid
|
||||
understanding required to create one's own archive classes. The resulting
|
||||
archive is useful for debugging in that it only 160 lines of code and is
|
||||
header only - that is, it doesn't required linking to the serialization library.
|
||||
<li>replaced example used to show how to derive from an existing archive.
|
||||
This example creates an XML archive class which doesn't include serialization
|
||||
traits such as class_id, class_version, etc. It might be useful for exporting
|
||||
one's class information to osme XML processor and/or debugging programs.
|
||||
<li>compile time warnings have been implemented to detect practices which
|
||||
though correct, will result in operation or side effects different than
|
||||
a user probably intends.
|
||||
<li>Some memory leaks associated with void_cast have been fixed.
|
||||
</ul>
|
||||
<h2><a name="differences_1_41"></a>Differences from Boost 1.41</h2>
|
||||
<ul>
|
||||
<li>adjustments have been made to minimize compile time warnings.
|
||||
<li>compile time warnings have been implemented to detect practices which
|
||||
though correct, will result in operation or side effects different than
|
||||
a user probably intends.
|
||||
<li>Some memory leaks associated with void_cast have been fixed.
|
||||
</ul>
|
||||
<h2><a name="differences_1_40"></a>Differences from Boost 1.40</h2>
|
||||
This library has been tested against Boost version 1.39 and 1.40.
|
||||
<p>
|
||||
Changes have been made to archive classes included with the library. Users who
|
||||
have used these a guide to making their own archive classes will find that
|
||||
these will likely no longer compile. This can be remedied by making the
|
||||
following changes in the code which instantiates these archive classes.
|
||||
</p>
|
||||
Old Code:<br>
|
||||
<code><pre>
|
||||
...
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<text_iarchive> ;
|
||||
</pre></code>should be replaced with this new code: <code><pre>
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
...
|
||||
template class detail::archive_serializer_map<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_serializer_map<text_iarchive> ;
|
||||
</pre></code>
|
||||
<!--
|
||||
<p>
|
||||
The serialization library uses the boost spirit package to load XML archives.
|
||||
We have found that all tests pass using spirit 1.6x. Spirit 1.8 and higher does not work with
|
||||
older compilers - specificallly MSVC 6, Borland and GCC < 3.0.
|
||||
older compilers - specifically MSVC 6, Borland and GCC < 3.0.
|
||||
If you are using one of these compilers, you may download a version
|
||||
of spirit 1.6 <a href="http://spirit.sourceforge.net/index.php?doc=download/index.html">here</a>.
|
||||
To use this downloaded version rather than the one included with boost,
|
||||
@@ -52,74 +158,138 @@ set SPIRIT_ROOT=c:/spirit16
|
||||
If you're not using bjam and the Jamfile to build the library, be sure that
|
||||
the directory which contains the version of spirit you plan to use is placed
|
||||
at the front of the list of include paths.
|
||||
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
|
||||
-->
|
||||
<h2><a name="differences_1_39"></a>Differences from Boost 1.39</h2>
|
||||
<ul>
|
||||
<li>Dynamic Linking Library (DLLs and shared libraries) for platforms which support them. See
|
||||
<a href="../../../more/getting_started.html#auto-link">Automatic Linking on Windows</a>.
|
||||
<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>Improved <code>const</code> correctness for save/load operators. Note that this may
|
||||
produce compile time errors in code which compiled without problem in earlier boost releases.
|
||||
In most cases the fix is trivial. In other cases, code should be scrutinized to be
|
||||
sure that it doesn't use the serializaton system in a way which may introduce subtle bugs in
|
||||
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>Miscelleanous bug fixes.
|
||||
<li>
|
||||
It is now possible to serialize an object through a pointer to a class which
|
||||
implements its own <code style="white-space: normal">new/delete</code>
|
||||
operators. This functionaly is not available on some compilers.
|
||||
<li>
|
||||
serialization of polymorphic objects has been sped up considerably.
|
||||
</ul>
|
||||
As of this writing, all bug reports filed as TRAK tickets have been addressed.
|
||||
There are some TRAK tickets pending which would best be described as feature
|
||||
requests. See <a href="#todo">Pending Issues</a>.
|
||||
<h2><a name="differences_1_37"></a>Differences from Boost 1.37</h2>
|
||||
There are no new features in this version. As of this writing, all bug reports
|
||||
filed as TRAK tickets have been addressed. There are some TRAK tickets pending
|
||||
which would best be described as feature requests. See <a href="#todo">Pending
|
||||
Issues</a>.
|
||||
<h2><a name="differences_1_36"></a>Differences from Boost 1.36</h2>
|
||||
There are no new features in this version. As of this writing, all bug reports
|
||||
filed as TRAK tickets have been addressed.
|
||||
<h2><a name="differences_1_35"></a>Differences from Boost 1.35</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The library is now thread safe. That is, multiple archives can be open in
|
||||
different threads. This has been implmented with a lock-free algorithm to avoid
|
||||
any performance bottlenecks.
|
||||
<li>
|
||||
Serialization of types defined in shared libraries is now supported. shared
|
||||
libraries (DLLS) can be loaded/unloaded dynamically at runtime. This includes
|
||||
the serialization of instances of abstract base classes so that a program can
|
||||
be written so as to be compatible with as yet undefined and un-implemented
|
||||
code.
|
||||
<li>
|
||||
The extended type info system has been enhanced to in order to implement the
|
||||
above. It is now a general purpose system for creating and casting of types
|
||||
about which is only known a string ID and an abstract base class.
|
||||
<li>
|
||||
All bug reports filed as TRAK tickets have been addressed.
|
||||
<li>
|
||||
As of this writing, the library will fail build on older compilers such as MSVC
|
||||
before version 7.1 and older versions of Borland compilers. This might or might
|
||||
not change in the future.
|
||||
</ul>
|
||||
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Enhanced support for fast serialization for native binary archives. By Mattias
|
||||
Troyer.
|
||||
<li>
|
||||
Improved implementation of "export" functionality. Removes header ordering
|
||||
requirement and eliminates the maintenance of a pre-determined list of "known
|
||||
archives" By David Abrahams.
|
||||
<li>
|
||||
Improved support for STLPort.
|
||||
</ul>
|
||||
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
|
||||
<ul>
|
||||
<li>Native Binary archives use the <code style="white-space: normal">std::streambuf</code> interface.
|
||||
This should result in noticibly faster execution in many cases.
|
||||
<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_34"></a>Differences from Boost 1.34</h2>
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
|
||||
<ul>
|
||||
<li>Ehanced support for fast serialiation for native binary archives. By Mattias Troyer.
|
||||
<li>Improved implementation of "export" functionality. Removes header ordering
|
||||
requirement and eliminates the maintainence of a pre-determined list of "known archives"
|
||||
By David Abrahams.
|
||||
<li>Improved support for STLPort.
|
||||
<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>
|
||||
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 'he 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.
|
||||
<li>Its possible that <code style="white-space: normal">std::string</code>
|
||||
and <code style="white-space: normal">std::wstring</code> contain characters such as
|
||||
'\0' which cannot be rendered in XML without an escape mechanism. Currently there is
|
||||
no such escape mechanism implemented.
|
||||
<li>A subtle error in the implementation of serialiaton of <code style="white-space: normal">std::map</code>
|
||||
is fixed in this version. Unfortunately, the fix breaks serialization of
|
||||
<code style="white-space: normal">std::map</code> for those compilers which do not support
|
||||
partial template specialization.
|
||||
<li>Floating point values which are number cannot be serialized to text base archives.
|
||||
<li>
|
||||
Rvalues cannot be serialized. It would be possible to implement this for
|
||||
untracked types, but this has not been done.
|
||||
<li>
|
||||
Pointers to pointers cannot currently be serialized
|
||||
<li>
|
||||
It's 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. Also,
|
||||
types which contain pointers or tracked types might not work correctly.
|
||||
<li>
|
||||
Serialization of virtual base classes relies upon RTTI. It will fail when used on
|
||||
systems which don't have RTTI enabled.
|
||||
</ul>
|
||||
<p>
|
||||
Aside from the above, there are a number of issus related to specific platforms.
|
||||
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
|
||||
|
||||
<hr>
|
||||
<p><i>© 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>
|
||||
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-2009.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+46
-44
@@ -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 .
|
||||
@@ -48,12 +48,13 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
</dl>
|
||||
</dl>
|
||||
<dt><a href="#pointers">Pointers</a>
|
||||
<dt><a href="#pointeroperators">Pointers</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#constructors">Non-Default Constructors</a>
|
||||
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#registration">Registration</a>
|
||||
<dt><a href="#export">Export</a>
|
||||
<dt><a href="#instantiation">Instantiation</a>
|
||||
<dt><a href="#selectivetracking">Selective Tracking</a>
|
||||
<dt><a href="#runtimecasting">Runtime Casting</a>
|
||||
@@ -61,8 +62,8 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</dl>
|
||||
<dt><a href="#references">References</a>
|
||||
<dt><a href="#arrays">Arrays</a>
|
||||
<dt><a href="wrappers.html">Serialization Wrappers</a>
|
||||
<dt><a href="traits.html">Class Serialization Traits</a>
|
||||
<dt><a href="wrappers.html">Serialization Wrappers</a>
|
||||
<dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
|
||||
</dl>
|
||||
|
||||
@@ -70,21 +71,20 @@ A type <code style="white-space: normal">T</code> is <strong>Serializable</stron
|
||||
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:
|
||||
By <i>primitive type</i> we mean a C++ built-in type and <i>ONLY</i>
|
||||
a C++ built-in type. Arithmetic (including characters), bool, enum are primitive types.
|
||||
Below in <a target="detail" href="traits.html#Traits">serialization traits</a>,
|
||||
we define a "primitive" implementation level in a different way for a
|
||||
different purpose. This can be a source of confusion.
|
||||
<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 an native C++ Array of <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>
|
||||
@@ -101,8 +101,8 @@ 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
|
||||
will result in a compile time error. The serialization of a class can
|
||||
be specified via either a class member function or a free function which
|
||||
takes a reference to an instance of the class as an argument.
|
||||
|
||||
<h3><a name="member">Member Function</a></h3>
|
||||
@@ -136,7 +136,7 @@ be made accessible to the serialization library by including:
|
||||
friend class boost::serialization::access;
|
||||
</code></pre>
|
||||
in the class definition. This latter method should be preferred over the option
|
||||
of making member function public. This will prevent serialization functions from
|
||||
of making the member function public. This will prevent serialization functions from
|
||||
being called from outside the library. This is almost certainly an error. Unfortunately,
|
||||
it may appear to function but fail in a way that is very difficult to find.
|
||||
<p>
|
||||
@@ -180,7 +180,7 @@ possible to serialize them. So in some instances, minor modifications to the
|
||||
class to be serialized will be necessary even when using this "non-intrusive"
|
||||
method. In practice this may not be such a problem as many libraries
|
||||
(E.G. STL) expose enough information to permit implementation of non-intrusive
|
||||
serialization with absolutly no changes to the library.
|
||||
serialization with absolutely 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
|
||||
@@ -196,7 +196,7 @@ templates can be in any of the following namespaces:
|
||||
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
|
||||
this further 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>
|
||||
@@ -219,7 +219,7 @@ base_object.hpp
|
||||
includes the template:
|
||||
<pre><code>
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
Base & base_object(Derived &d);
|
||||
</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 serialization operators.
|
||||
@@ -255,14 +255,14 @@ Loading <code style="white-space: normal">const</code> members can be addressed
|
||||
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
|
||||
keyword. <code style="white-space: normal">const</code> members are initialized 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
|
||||
Implementation of 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
|
||||
@@ -273,7 +273,7 @@ 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
|
||||
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>.
|
||||
@@ -434,7 +434,7 @@ is preferred. The key to the serialization implementation is that objects are s
|
||||
and loaded in exactly the same sequence. Using the <code style="white-space: normal">&</code>
|
||||
operator and <code style="white-space: normal">serialize</code>
|
||||
function guarantees that this is always the case and will minimize the
|
||||
occurence of hard to find errors related to synchronization of
|
||||
occurrence 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>
|
||||
@@ -463,7 +463,7 @@ following situations must be addressed:
|
||||
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
|
||||
<li>NULL pointers must be detected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
|
||||
@@ -482,7 +482,7 @@ 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>if the object has already been loaded, return its 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.
|
||||
@@ -496,7 +496,7 @@ and <code style="white-space: normal">>></code> operators
|
||||
<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,
|
||||
<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
|
||||
@@ -543,7 +543,7 @@ private:
|
||||
ar & m_state;
|
||||
}
|
||||
public:
|
||||
// no default construct guarentees that no invalid object
|
||||
// no default construct guarantees that no invalid object
|
||||
// ever exists
|
||||
my_class(int attribute) :
|
||||
m_attribute(attribute),
|
||||
@@ -591,7 +591,7 @@ class derived_one : public base {
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
main(){
|
||||
int main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
@@ -604,7 +604,7 @@ Should it be an object of class <code style="white-space: normal">derived_one</c
|
||||
<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.
|
||||
(<code style="white-space: normal">base</code> in this case) is polymorphic 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
|
||||
@@ -630,7 +630,7 @@ the same sequence. This includes "registration".
|
||||
<p>
|
||||
Expanding our previous example:
|
||||
<pre><code>
|
||||
main(){
|
||||
int main(){
|
||||
derived_one d1;
|
||||
derived_two d2:
|
||||
...
|
||||
@@ -659,11 +659,11 @@ This can be addressed by registering the derived class explicitly. All archives
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type();
|
||||
register_type(T * = NULL);
|
||||
</code></pre>
|
||||
So our problem could just as well be addressed by writing:
|
||||
<pre><code>
|
||||
main(){
|
||||
int main(){
|
||||
...
|
||||
ar.template register_type<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
@@ -674,9 +674,10 @@ main(){
|
||||
</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
|
||||
and corresponding load in synchronization.
|
||||
|
||||
<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
|
||||
@@ -689,7 +690,7 @@ So we have another method:
|
||||
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
|
||||
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
|
||||
|
||||
main(){
|
||||
int main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
@@ -718,7 +719,7 @@ 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
|
||||
explicitly 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
|
||||
@@ -754,7 +755,7 @@ can be used.
|
||||
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>
|
||||
<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
|
||||
@@ -788,18 +789,18 @@ class derived : public base {
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
boost::serialization::base_object<base>(*this);
|
||||
ar & boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<derived, base>(
|
||||
static_cast<base *>(NULL),
|
||||
static_cast<derived *>(NULL)
|
||||
static_cast<derived *>(NULL),
|
||||
static_cast<base *>(NULL)
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
main(){
|
||||
int main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
@@ -906,11 +907,11 @@ rather than
|
||||
<pre><code>
|
||||
#include <list>
|
||||
</code></pre>
|
||||
Since the former includes the latter, this all that is necessary.
|
||||
Since the former includes the latter, this is 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:
|
||||
As of this writing, the library contains serialization of the following boost classes:
|
||||
<ul>
|
||||
<li>optional
|
||||
<li>variant
|
||||
@@ -918,8 +919,9 @@ As of this writing, the library contains serialization of the following boost cl
|
||||
<li>shared_ptr
|
||||
<li>auto_ptr (demo)
|
||||
</ul>
|
||||
C++17 <code style="white-space: normal">std::variant is supported as well</code>.
|
||||
Others are being added to the list so check the boost files section and headers for
|
||||
new implmentations!
|
||||
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
|
||||
|
||||
+16
-16
@@ -92,36 +92,36 @@ instance of <code style="white-space: normal">sp_counted_base_impl<T, ...></code
|
||||
doesn't have a default constructor, serialization requires
|
||||
specification of the following overload:
|
||||
<pre><code>
|
||||
template<class Archive, class P, class D>
|
||||
template<class Archive, class P, class D>
|
||||
inline void save_construct_data(
|
||||
Archive & ar,
|
||||
const boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
// variables used for construction
|
||||
ar << t->ptr;
|
||||
ar << t->ptr;
|
||||
ar << *t;
|
||||
}
|
||||
|
||||
template<class Archive, class P, class D>
|
||||
template<class Archive, class P, class D>
|
||||
inline void load_construct_data(
|
||||
Archive & ar,
|
||||
boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
P ptr_;
|
||||
ar >> ptr_;
|
||||
// placement new
|
||||
::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
|
||||
ar >>; *t;
|
||||
::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
|
||||
ar >> *t;
|
||||
}
|
||||
</code></pre>
|
||||
The statement <code style="white-space: normal">ar >> ptr_</code> is key. This deserializes
|
||||
the same pointer deserialzed above. Default object tracking will ensure
|
||||
the same pointer deserialized above. Default object tracking will ensure
|
||||
that no more than one instance of the object is created and that the
|
||||
pointer returned by multiple deserializations are all the same. Hence,
|
||||
regardless of how many instances of <code style="white-space: normal">shared_ptr/shared_count</code>
|
||||
corresponding to a particular object are created, the will all point
|
||||
corresponding to a particular object are created, they will all point
|
||||
to the same object.
|
||||
<p>
|
||||
Since <code style="white-space: normal">sp_counted_base_impl<P, D></code> is derived from
|
||||
@@ -135,7 +135,7 @@ inline void serialize(
|
||||
const unsigned int file_version,
|
||||
int
|
||||
){
|
||||
ar & boost::serialization::base_object<
|
||||
ar & boost::serialization::base_object<
|
||||
boost::detail::sp_counted_base
|
||||
>(*this);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ inline void serialize(
|
||||
){
|
||||
}
|
||||
</code></pre>
|
||||
It would seem we're done, running the test program,
|
||||
It would seem we're done, but running the test program,
|
||||
<a href="../example/demo_shared_ptr.cpp" target="demo_shared_ptr_cpp">
|
||||
demo_shared_ptr.cpp
|
||||
</a>,
|
||||
@@ -170,7 +170,7 @@ This indicates that we're not quite done. Due to default object
|
||||
tracking, <code style="white-space: normal">sp_counted_base_impl<P, D></code> is only
|
||||
created once regardless of how many shared pointers point to the
|
||||
same object. Of course, it has to be this way. The reference
|
||||
count starts at 1 and is never incrememented. Code must be added
|
||||
count starts at 1 and is never incremented. Code must be added
|
||||
to the serialization functions to maintain the proper reference
|
||||
count.
|
||||
<p>
|
||||
@@ -191,13 +191,13 @@ In this case we need only the latter function so we can replace the
|
||||
base object serialization with:
|
||||
<pre><code>
|
||||
// register the relationship between each derived class
|
||||
// its polymorphic base
|
||||
// and its polymorphic base
|
||||
void_cast_register<
|
||||
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>
|
||||
and we don't have to include a trivial serializer for <code style="white-space: normal">sp_counted_base</code>.
|
||||
<p>
|
||||
Finally we need to specify name-value pair wrappers if we want to be able
|
||||
to use this serialization with XML archives.
|
||||
@@ -219,9 +219,9 @@ shared pointers:
|
||||
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.
|
||||
These are specialized 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
|
||||
Clear, 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.
|
||||
<hr>
|
||||
|
||||
+13
-13
@@ -20,7 +20,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisted</h2>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisited</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -32,7 +32,7 @@ Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<li>It was dependent on the Boost implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
The <code style="white-space: normal">shared_ptr</code> interface has been included
|
||||
in <code style="white-space: normal">std::tr1</code> and may someday be included in the standard
|
||||
C++ library. An implementation which depends only on the public interface can be guarenteed to
|
||||
C++ library. An implementation which depends only on the public interface can be guaranteed to
|
||||
function with any other future implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
<li>It required extra macros for export.
|
||||
</ul>
|
||||
@@ -40,24 +40,24 @@ Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void save(
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
const T * t_ptr = t.get();
|
||||
// just seriailize the underlying raw pointer
|
||||
ar <<: boost::serialization::make_nvp("px", t_ptr);
|
||||
// just serialize the underlying raw pointer
|
||||
ar << boost::serialization::make_nvp("px", t_ptr);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
template<class Archive, class T>
|
||||
inline void load(
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
T* r;
|
||||
// recover the underlying raw poiter
|
||||
ar >> boost::serialization::make_nvp("px", 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.
|
||||
@@ -65,13 +65,13 @@ inline void load(
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
In priniciple this is very much simpler than the original implementation. Completion of
|
||||
In principle, this is very much simpler than the original implementation. Completion of
|
||||
this code requires:
|
||||
|
||||
<ol>
|
||||
<li>Filling in the "To Do". This required making an extra map for
|
||||
<code style="white-space: normal">shared_ptr</code> instances.
|
||||
<li>A method for identifing pointers to the same objects from pointers to their base classes.
|
||||
<li>A method for identifying pointers to the same objects from pointers to their base classes.
|
||||
<li>Backward compatibility with pointers serialized by the previous method. This exploits
|
||||
the serialization class versioning.
|
||||
<li>Proper handling of <code style="white-space: normal">weak_ptr</code>.
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-10 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 - Derivation from an Existing Archive</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">A Simple Logging Archive Class</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
The purpose of this example is to help clarify the usage of the
|
||||
<a href="archives.html"><strong>Archive Concept</strong></a>
|
||||
so that one can implement his own archive classes.
|
||||
<a href="../example/simple_log_archive.hpp" target="simple_archive_hpp">
|
||||
<code>simple_log_archive.hpp</code></a> implements a simple but useful
|
||||
archive class. This class can be used to send any serializable types
|
||||
on an output text stream in a readable format. Usage of this facility
|
||||
is trivially easy:
|
||||
|
||||
<pre><code>
|
||||
#include "simple_log_archive.hpp"
|
||||
...
|
||||
// display the complete schedule
|
||||
simple_log_archive log(std::cout);
|
||||
log << schedule;
|
||||
</code></pre>
|
||||
|
||||
and it produces the following output
|
||||
|
||||
<pre><code>
|
||||
schedule
|
||||
count 6
|
||||
item
|
||||
first
|
||||
driver bob
|
||||
hour 6
|
||||
minute 24
|
||||
second ->
|
||||
stops
|
||||
count 3
|
||||
item ->
|
||||
latitude
|
||||
degrees 34
|
||||
minutes 135
|
||||
seconds 52.56
|
||||
longitude
|
||||
degrees 134
|
||||
minutes 22
|
||||
seconds 78.3
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
The complete example is <a href="../example/demo_simple_log.cpp" target="demo_simple_log_cpp">
|
||||
<code>demo_simple_log.cpp</code></a>. Look at
|
||||
<a href="archive_reference.html#trivial">Trivial Archive</a> to get a
|
||||
better understanding of how this works.
|
||||
|
||||
Also, note the following:
|
||||
<ul>
|
||||
<li>Only 160 lines of code.
|
||||
<li>Header only - linking with the serialization library not required.
|
||||
<li>Displays ALL <a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
<li>Lacks some features.
|
||||
<ul>
|
||||
<li>it will not display the data from the derived type given the pointer to a
|
||||
polymorphic base class. That is, only displays the information of the base class.
|
||||
To add that see the next example.
|
||||
<li>doesn't display information serialized as binary data
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2010.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,254 @@
|
||||
<!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 variable and constant 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 to 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 unpredictable 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 guaranteed 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 guarantees that there will be no
|
||||
race conditions during the construction of any instance. No
|
||||
thread locking is required to guarantee 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 multi-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();
|
||||
static bool is_destroyed();
|
||||
};
|
||||
|
||||
} // 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>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static bool is_destroyed();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Return <code>true</code> if the destructor on this singleton has been
|
||||
called. Otherwise, return <code>false</code>.
|
||||
</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 constructible.
|
||||
It doesn't require static variables - though it may have them.
|
||||
Since the library guarantees that only one instance of
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
exists and all access 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 an 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 guarantee 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 any other
|
||||
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 guarantee 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>
|
||||
All singletons used in the serialization library follow this rule.
|
||||
In order to help detect accidental violations of this rule there
|
||||
exist singleton lock/unlock functions.
|
||||
<pre><code>
|
||||
void boost::serialization::singleton_module::lock();
|
||||
void boost::serialization::singleton_module::unlock();
|
||||
bool boost::serialization::singleton_module::is_locked();
|
||||
</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 singleton module lock state is initialized as "unlocked" to permit
|
||||
alteration of static variables before
|
||||
<code style="white-space: normal">main</code> is called.
|
||||
The <code style="white-space: normal">lock()</code> and
|
||||
<code style="white-space: normal">unlock()</code> are "global"
|
||||
in that they affect ALL the singletons defined by this template.
|
||||
All serialization tests invoke <code style="white-space: normal">lock()</code>
|
||||
at the start of the program. 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>
|
||||
+16
-16
@@ -30,23 +30,23 @@ To cast from one type to another related type, C++ provides the following
|
||||
operators:
|
||||
|
||||
<dl>
|
||||
<dt><code>static_cast<T *<>(U *)<br>static_cast<T &<>(U &)</code></dt>
|
||||
<dt><code>static_cast<T *>(U *)<br>static_cast<T &>(U &)</code></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>required if neither T nor U are not polymorphic
|
||||
<li>required if neither T nor U are polymorphic
|
||||
<li>permitted in other cases.
|
||||
<li>fails to detect erroneas casts of polymophic pointers/references at runtime.
|
||||
<li>fails to detect erroneous casts of polymorphic pointers/references at runtime.
|
||||
<li>does not permit "cross casting"
|
||||
<li>inline function calls can be optimized away during compile time.
|
||||
</ul>
|
||||
</dd>
|
||||
<p>
|
||||
<dt><code>dynamic_cast<T *<>(U *)<br>dynamic_cast<T &<>(U &)</code></dt>
|
||||
<dt><code>dynamic_cast<T *>(U *)<br>dynamic_cast<T &>(U &)</code></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>permitted if either T or U are polymorphic
|
||||
<li>prohibited in other cases.
|
||||
<li>throws exception on detecting erroneas casts of polymorphic pointers/references
|
||||
<li>throws exception on detecting erroneous casts of polymorphic pointers/references
|
||||
at runtime.
|
||||
<li>permits "cross casting"
|
||||
<li>cannot optimise inline virtual functions at compile time.
|
||||
@@ -58,7 +58,7 @@ These rules can make it difficult to use casting with a function template argume
|
||||
Consider the following example:
|
||||
|
||||
<pre><code>
|
||||
#include <boost/smart_cast.hpp>
|
||||
#include <boost/serialization/smart_cast.hpp>
|
||||
|
||||
struct top {
|
||||
};
|
||||
@@ -91,14 +91,14 @@ template<class T>
|
||||
bool is_storable(T &t){
|
||||
// what type of cast to use here?
|
||||
|
||||
// this fails at compiler time when T == base2
|
||||
// this fails at compile time when T == base2
|
||||
// return static_cast<base1 &>(t).is_storable();
|
||||
|
||||
// this fails at compiler time when T == top
|
||||
// this fails at compile time when T == top
|
||||
// otherwise it works but cannot optimize inline function call
|
||||
// return dynamic_cast<base1 &>(t).is_storable();
|
||||
|
||||
// this always works - and is guarenteed to generate the fastest code !
|
||||
// this always works - and is guaranteed to generate the fastest code !
|
||||
return (boost::smart_cast_reference<base1 &>(t)).is_storable();
|
||||
}
|
||||
|
||||
@@ -121,27 +121,27 @@ The serialization library includes a mix of classes which use
|
||||
both static polymorphism (<strong>CRTP</strong>) and dynamic
|
||||
polymorphism via virtual functions. <code style="white-space: normal">smart_cast</code>
|
||||
was written to address the more problematic manifestations of the
|
||||
situation exmplified above.
|
||||
situation exemplified above.
|
||||
|
||||
<h3>Usage</h3>
|
||||
The following syntax is supported:
|
||||
<pre><code>
|
||||
smart_cast<Target *, Source *>(Source * s);
|
||||
smart_cast<Target *>(Source * s);
|
||||
smart_cast<Target &, Source &>(Source & s);
|
||||
smart_cast<Target *>(Source * s);
|
||||
smart_cast<Target &, Source &>(Source & s);
|
||||
</code></pre>
|
||||
Note that the above syntax doesn't include
|
||||
<pre><code>
|
||||
smart_cast<Target & >(Source & s)
|
||||
smart_cast<Target & >(Source & s)
|
||||
</code></pre>
|
||||
but the same functionality is supported the the following special syntax
|
||||
but the same functionality is supported with the following special syntax
|
||||
<pre><code>
|
||||
smart_cast_reference<Target &>(Source & s)
|
||||
smart_cast_reference<Target &>(Source & s)
|
||||
</code></pre>
|
||||
|
||||
<h3>Requirements</h3>
|
||||
<code style="white-space: normal">smart_cast</code> can be used only on compilers that support partial
|
||||
template specialization or on types for which have be specified with the
|
||||
template specialization or on types for which the
|
||||
macro <code style="white-space: normal">
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(<type>)</code>
|
||||
has been applied.
|
||||
|
||||
+355
-112
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -27,8 +27,8 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#objecttracking">Object Tracking</a>
|
||||
<dt><a href="#export">Exporting Class Serialization</a>
|
||||
<dt><a href="#classinfo">Class Information</a>
|
||||
<dt><a href="#helpersupport">Helper Support</a>
|
||||
<dt><a href="#portability">Archive Portability</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#numerics">Numerics</a>
|
||||
@@ -36,7 +36,10 @@ 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="#static_libraries">Static Libraries and 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>
|
||||
@@ -51,10 +54,10 @@ 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.
|
||||
programs 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
|
||||
void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x = a[i];
|
||||
@@ -94,11 +97,11 @@ and a likely source of very subtle bugs.
|
||||
Unfortunately, implementation issues currently prevent the detection of this kind of
|
||||
error when the data item is wrapped as a name-value pair.
|
||||
<p>
|
||||
A similar problem can occur when different objects are loaded to and address
|
||||
A similar problem can occur when different objects are loaded to an address
|
||||
which is different from the final location:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
@@ -109,20 +112,20 @@ void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
</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.
|
||||
this will break the features that depend on tracking such as loading an 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
|
||||
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);
|
||||
ar.reset_object_address(& (*result.first), &x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
@@ -134,7 +137,7 @@ values are duplicated, overhead associated with object tracking can
|
||||
be eliminated by setting the object tracking class serialization trait
|
||||
appropriately.
|
||||
<p>
|
||||
By default, data types designated primitive by
|
||||
By default, data types designated primitive by the
|
||||
<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
|
||||
@@ -153,54 +156,95 @@ redundant save/load operations.
|
||||
BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="export">Exporting Class Serialization</a></h3>
|
||||
<a target="detail" href="traits.html#export">Elsewhere</a> in this manual, we have described
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>. This is used to make the serialization library aware
|
||||
that code should be instantiated for serialization of a given class even though the
|
||||
class hasn't been otherwise referred to by the program. This functionality
|
||||
is necessary to implement serialization of pointers through a virtual base
|
||||
class pointer. That is, a polymorphic pointer.
|
||||
<h3><a name="helpersupport">Helper Support</a></h3>
|
||||
Some types, specially those with complicated lifetime behavior or limited
|
||||
access to their internal state, might need or benefit from elaborate serialization
|
||||
algorithms. The principle motivating case is that of shared_ptr. As instances
|
||||
are loaded, they have to be "matched up" with any other instances which have
|
||||
already been loaded. Thus, a table of previously loaded instances has to be
|
||||
maintained while the archive containing the shared_ptr instances is being loaded.
|
||||
Without maintaining such a table, the shared_ptr would be a serializable type.
|
||||
<p>
|
||||
This macro specifies a "<b>G</b>lobally <b>U</b>nique <b>ID</b>entifier".
|
||||
This is an string which identifies the class to be created when data is loaded.
|
||||
Generally a text representation of the class name is sufficient for this purpose,
|
||||
but in certain cases it maybe necessary to specify a different string by using
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code>
|
||||
rather than a simple
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>.
|
||||
|
||||
<p>
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> would usually
|
||||
be specified in the same header file as the class declaration to which it
|
||||
corresponds. That is, <code style="white-space: normal">BOOST_CLASS_EXPORT(T)</code>
|
||||
is a "trait" of the class T. So a program using this class will look
|
||||
something like:
|
||||
To implement this facility, one declares a <i>helper object</i>
|
||||
associated to the current archive that can be used to store contextual
|
||||
information relevant to the particular type serialization algorithm.
|
||||
|
||||
<pre><code>
|
||||
#include <boost/archive/xml_oarchive.hpp>
|
||||
.... // any other archive classes
|
||||
#include "my_class.hpp" // which contains BOOST_CLASS_EXPORT(my_class)
|
||||
</code></pre>
|
||||
template<class T>
|
||||
class shared_ptr
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
These headers can be in any order. (In boost versions 1.34
|
||||
and earlier, the archive headers had to go before any headers which
|
||||
contain <code style="white-space: normal">BOOST_CLASS_EXPORT</code>.)
|
||||
Any code required to serialize types specified
|
||||
by <code style="white-space: normal">BOOST_CLASS_EXPORT</code> will be
|
||||
instantiated for each archive whose header is included. (note that the code
|
||||
is instantiated regardless of whether or not it is actually invoked.)
|
||||
If no archive headers are included - no code should be instantiated.
|
||||
This will permit <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
to be a permanent part of the <code style="white-space: normal">my_class.hpp</code> .
|
||||
BOOST_SERIALIZATION_SPLIT_FREE(shared_ptr)
|
||||
|
||||
class shared_ptr_serialization_helper
|
||||
{
|
||||
// table of previously loaded shared_ptr
|
||||
// lookup a shared_ptr from the object address
|
||||
shared_ptr<T> lookup(const T *);
|
||||
// insert a new shared_ptr
|
||||
void insert<shared_ptr<T> >(const shared_ptr<T> *);
|
||||
};
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive & ar, const shared_ptr & x, const unsigned int /* version */)
|
||||
{
|
||||
// save shared ptr
|
||||
...
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, shared_ptr & x, const unsigned int /* version */)
|
||||
{
|
||||
// get a unique identifier. Using a constant means that all shared pointers
|
||||
// are held in the same set. Thus we detect handle multiple pointers to the
|
||||
// same value instances in the archive.
|
||||
const void * shared_ptr_helper_id = 0;
|
||||
|
||||
shared_ptr_serialization_helper & hlp =
|
||||
ar.template get_helper<shared_ptr_serialization_helper>(helper_instance_id);
|
||||
|
||||
// load shared pointer object
|
||||
...
|
||||
|
||||
shared_ptr_serialization_helper & hlp =
|
||||
ar.template get_helper<shared_ptr_serialization_helper>(shared_ptr_helper_id);
|
||||
|
||||
// look up object in helper object
|
||||
T * shared_object hlp.lookup(...);
|
||||
|
||||
// if found, return the one from the table
|
||||
|
||||
// load the shared_ptr data
|
||||
shared_ptr<T> sp = ...
|
||||
|
||||
// and add it to the table
|
||||
hlp.insert(sp);
|
||||
// implement shared_ptr_serialization_helper load algorithm with the aid of hlp
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
<code style="white-space: normal">get_helper<shared_ptr_serialization_helper>();</code>
|
||||
creates a helper object associated to the archive the first time it is invoked;
|
||||
subsequent invocations return a reference to the object created in the first
|
||||
place, so that <code style="white-space: normal">hlp</code> can effectively be
|
||||
used to store contextual information persisting through the serialization
|
||||
of different <code style="white-space: normal">complex_type</code> objects on
|
||||
the same archive.
|
||||
|
||||
<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.
|
||||
Helpers may be created for saving and loading archives.
|
||||
The same program might have several different helpers or the same helper instantiated
|
||||
separately from different parts of the program. This is what makes the helper_instance_id
|
||||
necessary. In principle it could be any unique integer. In practice it seems
|
||||
easiest to use the address of the serialization function which contains it. The
|
||||
above example uses this technique.
|
||||
|
||||
<h3><a name="classinfo">Class Information</a></h3>
|
||||
By default, for each class serialized, class information is written to the archive.
|
||||
@@ -223,7 +267,7 @@ in this manner comes at a cost. Once archives are released to users, the
|
||||
class serialization traits cannot be changed without invalidating the old
|
||||
archives. Including the class information in the archive assures us
|
||||
that they will be readable in the future even if the class definition
|
||||
is revised. A light weight structure such as display pixel might be
|
||||
is revised. A light weight structure such as a display pixel might be
|
||||
declared in a header like this:
|
||||
|
||||
<pre><code>
|
||||
@@ -251,14 +295,14 @@ BOOST_CLASS_TRACKING(pixel, boost::serialization::track_never)
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="portability">Archive Portability</a></h3>
|
||||
Several archive classes create their data in the form of text or portable a binary format.
|
||||
It should be possible to save such an of such a class on one platform and load it on another.
|
||||
Several archive classes create their data in the form of text or a portable binary format.
|
||||
It should be possible to save such a class on one platform and load it on another.
|
||||
This is subject to a couple of conditions.
|
||||
<h4><a name="numerics">Numerics</a></h4>
|
||||
The architecture of the machine reading the archive must be able hold the data
|
||||
saved. For example, the gcc compiler reserves 4 bytes to store a variable of type
|
||||
<code style="white-space: normal">wchar_t</code> while other compilers reserve only 2 bytes.
|
||||
So its possible that a value could be written that couldn't be represented by the loading program. This is a
|
||||
So it's 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>
|
||||
@@ -278,7 +322,7 @@ Another potential problem is illustrated by the following example:
|
||||
template<class T>
|
||||
struct my_wrapper {
|
||||
template<class Archive>
|
||||
Archive & serialize ...
|
||||
Archive & serialize ...
|
||||
};
|
||||
|
||||
...
|
||||
@@ -286,10 +330,10 @@ struct my_wrapper {
|
||||
class my_class {
|
||||
wchar_t a;
|
||||
short unsigned b;
|
||||
template<<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
template<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
@@ -335,7 +379,7 @@ XML format has a nested structure that maps well to the "recursive class member
|
||||
used by the serialization system. However, XML differs from other formats in that it
|
||||
requires a name for each data member. Our goal is to add this information to the
|
||||
class serialization specification while still permiting the the serialization code to be
|
||||
used with any archive. This is achived by requiring that all data serialized to an XML archive
|
||||
used with any archive. This is archived by requiring that all data serialized to an XML archive
|
||||
be serialized as a <a target="detail" href="wrappers.html#nvp">name-value pair</a>.
|
||||
The first member is the name to be used as the XML tag for the
|
||||
data item while the second is a reference to the data item itself. Any attempt to serialize data
|
||||
@@ -343,15 +387,116 @@ not wrapped in a in a <a target="detail" href="wrappers.html#nvp">name-value pai
|
||||
be trapped at compile time. The system is implemented in such a way that for other archive classes,
|
||||
just the value portion of the data is serialized. The name portion is discarded during compilation.
|
||||
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.
|
||||
be guaranteed that all data can be serialized to all archive classes with maximum efficiency.
|
||||
|
||||
<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) or Shared Libraries(*nix).
|
||||
Along with the "export" facility, this
|
||||
permits a program to written without knowledge of the actual types to be serialized.
|
||||
This package doesn't include an example of this technique - but coding would be
|
||||
very similar to the example
|
||||
<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 its 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> 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 code is part
|
||||
of a stand alone executable, a static library or
|
||||
a dynamic or shared library.
|
||||
<p>
|
||||
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 can best be addressed by using
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
|
||||
in the header declarations and
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in the class definition file.
|
||||
|
||||
<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">Polymorphic Archives</a>.
|
||||
|
||||
<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 a catastrophic error, the library traps ALL serializations through
|
||||
a pointer to a polymorphic class 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 guaranteed 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="static_libraries">Static Libraries and Serialization</a></h3>
|
||||
Code for serialization of data types can be saved in libraries
|
||||
just as it can for the rest of the type implementation.
|
||||
This works well, and can save a huge amount of compilation time.
|
||||
<ul>
|
||||
<li>Only compile serialization definitions in the library.
|
||||
<li>Explicitly instantiate serialization code for ALL
|
||||
archive classes you intend to use in the library.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
|
||||
in headers.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in definitions compiled in the library. For any particular type,
|
||||
there should be only one file which contains
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
for that type. This ensures that only one copy
|
||||
of serialization code will exist within the program. It avoids
|
||||
wasted space and the possibility of having different
|
||||
versions of the serialization code in the same program.
|
||||
Including
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in multiple files could result in a failure
|
||||
to link due to duplicated symbols or the throwing
|
||||
of a runtime exception.
|
||||
<li> Code for serialization should be only in the library,
|
||||
<li>Familiarize yourself with the <b>PIMPL</b> idiom.
|
||||
</ul>
|
||||
This is illustrated by
|
||||
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl.cpp</code>
|
||||
</a>,
|
||||
@@ -362,52 +507,150 @@ 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 completely separate
|
||||
from the main program.
|
||||
where implementation of serialization is in a static library
|
||||
completely separate from the main program.
|
||||
|
||||
<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. The best technique is the
|
||||
same as that described above for libraries. The serialization
|
||||
library test suite includes the following programs
|
||||
to illustrate how this works:
|
||||
<p>
|
||||
|
||||
<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 serialization 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.
|
||||
<p>
|
||||
Also included are
|
||||
<a href = "../test/test_dll_exported.cpp" target="test_dll_exported">
|
||||
<code style="white-space: normal">test_dll_exported.cpp</code>
|
||||
</a>,
|
||||
and
|
||||
<a href = "../test/polymorphic_derived2.cpp" target="polymorphic_derived2">
|
||||
<code style="white-space: normal">polymorphic_derived2.cpp</code>
|
||||
</a>
|
||||
which are similar to the above but include tests of the export
|
||||
and no_rtti facilities in the context of DLLS.
|
||||
<p>
|
||||
For best results, write your code to conform to the following
|
||||
guidelines:
|
||||
<ul>
|
||||
<li>Don't include <code>inline</code> code in classes used in DLLS.
|
||||
This will generate duplicate code in the DLLS and mainline. This
|
||||
needlessly duplicates code. Worse, it makes is possible for
|
||||
different versions of the same code to exist simultaneously. This
|
||||
type of error turns out to be excruciatingly difficult to debug.
|
||||
Finally, it opens the possibility that a module being referred to
|
||||
might be explicitly unloaded which would (hopefully) result in
|
||||
a runtime error. This is another bug that is not always
|
||||
reproducible or easy to find. For class member templates use something like
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version);
|
||||
</code></pre>
|
||||
in the header, and
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void myclass::serialize(Archive & ar, const unsigned int version){
|
||||
...
|
||||
}
|
||||
|
||||
BOOST_CLASS_EXPORT_IMPLEMENT(my_class)
|
||||
|
||||
#include <boost/archive/text_oarchive>
|
||||
#include <boost/archive/text_iarchive>
|
||||
template myclass::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
|
||||
template myclass::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
|
||||
... // repeat for each archive class to be used.
|
||||
</code></pre>
|
||||
in the implementation file. This will result in generation of all code
|
||||
required in only one place. The library does not detect this type of error for you.
|
||||
<li>If DLLS are to be loaded and unloaded explicitly (e.g. using <code>dlopen</code> in *nix or
|
||||
<code>LoadLibrary</code> in Windows). Try to arrange that they are unloaded in the reverse
|
||||
sequence. This should guarantee that problems are avoided even if the
|
||||
above guideline hasn't been followed.
|
||||
|
||||
</ul>
|
||||
|
||||
<h3><a name="plugins">Plugins</a></h3>
|
||||
In order to implement the library, various facilities for runtime
|
||||
manipulation of types at 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 a class
|
||||
about which is known only the <b>GUID</b> and a base class.
|
||||
|
||||
|
||||
<h3><a name="multi_threading">Multi-Threading</a></h3>
|
||||
The nature of serialization would conflict with multiple thread concurrently
|
||||
writing/reading from/to a single open archive. Since each archive is
|
||||
independent from ever other one, there should be no problem
|
||||
in having multiple open archives from one or more threads.
|
||||
The fundamental purpose of serialization would conflict with multiple
|
||||
threads concurrently writing/reading from/to a single open archive instance.
|
||||
The library implementation presumes that the application avoids such a situation.
|
||||
<p>
|
||||
Well, not quite.
|
||||
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 is 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>
|
||||
There are a couple of global data structures for holding
|
||||
information of serializable types. These structures are
|
||||
used to dispatch to correct code to handle each pair
|
||||
of serializable types and archive types. Since this
|
||||
information is shared among all archives, there is
|
||||
potential for problems. This has been addressed
|
||||
carefully implementing the library so that these
|
||||
structures are all initialized before
|
||||
<code style="white-space: normal">main(...)</code>
|
||||
is called. From then on they are never altered. So
|
||||
there SHOULD be no problem having mulitple archives
|
||||
open simultaneously - be it from the same or different
|
||||
threads.
|
||||
<p>
|
||||
Well, almost.
|
||||
<p>
|
||||
With dynamically loaded code - DLLS or Shared Libraries,
|
||||
these global data structures can be altered when a library
|
||||
is loaded or unloaded. That is, in this case, these
|
||||
globa data structures can be altered after
|
||||
<code style="white-space: normal">main(...)</code>
|
||||
is called. So if a thread is dynamically loading/unloading
|
||||
modules which contain serialization code while an
|
||||
archive is open there could be problems. Also, if
|
||||
such loading/unloading is happening concurrently
|
||||
in different threads, there could also be problems.
|
||||
<p>
|
||||
It might not be easy to control this. Is possible that
|
||||
some systems may not actually load modules until they
|
||||
are actually needed. So even though we think that
|
||||
there is not dynamic loading/unloading of such code
|
||||
it could be occurring as "help" to manage resources.
|
||||
On such systems, access to archive code would have
|
||||
to be syncronized with some multi-threading construct
|
||||
in order to be functional.
|
||||
This singleton implementation guarantees that all of this shared
|
||||
information is initialized when the code module which contains
|
||||
it 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/unloaded 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
|
||||
|
||||
@@ -32,7 +32,7 @@ and resets the object's state at destruction time, undoing any change the object
|
||||
may have gone through. Here is the interface:
|
||||
|
||||
<pre><code>
|
||||
template<class T>
|
||||
template<class T>
|
||||
// T requirements:
|
||||
// - POD or object semantic (cannot be reference, function, ...)
|
||||
// - copy constructor
|
||||
@@ -43,20 +43,20 @@ private:
|
||||
... // implementation
|
||||
|
||||
public:
|
||||
state_saver(T & object);
|
||||
state_saver(T & object);
|
||||
~state_saver();
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
The complete implementation can be found
|
||||
<a target="state_saver" href="../../../boost/state_saver.hpp">here</a>
|
||||
<a target="state_saver" href="../../../boost/serialization/state_saver.hpp">here</a>
|
||||
|
||||
The following illustrates how this is expected to be used.
|
||||
|
||||
<pre><code>
|
||||
#include <boost/state_saver.hpp>
|
||||
|
||||
void func(A & a)
|
||||
void func(A & a)
|
||||
boost::state_saver<A> s(a);
|
||||
... // alter state of a by calling non-const functions
|
||||
... // call other functions
|
||||
|
||||
+19
-1
@@ -25,7 +25,25 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
To do.
|
||||
|
||||
The header <code><boost/serialization/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
|
||||
|
||||
@@ -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 .
|
||||
@@ -48,7 +48,7 @@ Usage of BOOST_STRONG_TYPEDEF
|
||||
addresses this.
|
||||
<pre></code>
|
||||
<a target="strong_typedef" href="../../../boost/strong_typedef.hpp">
|
||||
#include <boost/strong_typedef.hpp>
|
||||
#include <boost/serialization/strong_typedef.hpp>
|
||||
</a>
|
||||
|
||||
BOOST_STRONG_TYPEDEF(int, a)
|
||||
@@ -78,7 +78,7 @@ type but still of distinct type.
|
||||
|
||||
<h3>Implemenation</h3>
|
||||
<code style="white-space: normal">BOOST_STRONG_TYPEDEF</code> is a macro
|
||||
which generates a class named "name" wraps and instance of its
|
||||
which generates a class named "name" which wraps an instance of its
|
||||
primitive type and provides appropriate conversion operators in order
|
||||
to make the new type substitutable for the one that it wraps.
|
||||
|
||||
|
||||
@@ -6,3 +6,10 @@ pre{
|
||||
MARGIN-LEFT: 0pt;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
/*
|
||||
(C) Copyright 2008 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - To Do</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">To Do</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#portablebinaryarchives">Portable Binary Archives</a></dt>
|
||||
<dt><a href="#performancetesting">Performance Testing and Profiling</a></dt>
|
||||
<dt><a href="#backversioning">Back Versioning</a></dt>
|
||||
<dt><a href="#nortti">Testing for Environments with No RTTI</a></dt>
|
||||
<dt><a href="new_case_studies.html">Additional Case Studies</a></dt>
|
||||
</dl>
|
||||
|
||||
These are enhancements that the serialization library needs but have not been done.
|
||||
Some of these projects, though tricky, are not huge and would be suitable
|
||||
for someone who has a limited time to spend on them. In particular, they
|
||||
might be of interest as student projects such as the Google Summer of Code.
|
||||
|
||||
<h2><a name="portablebinaryarchives"></a>Portable Binary Archives</h2>
|
||||
Currently there is a portable binary archive in the examples directory.
|
||||
It is not regularly submitted to the exhaustive boost testing regimen
|
||||
but it is tested occasionally and has been used in production code.
|
||||
<p>
|
||||
It's 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>Integration into the Boost testing regimen 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 immediately 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 surprised
|
||||
to find bottlenecks in totally unanticipated places and fixing those
|
||||
has always led 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 to make programs that are guaranteed
|
||||
the ability to load archives with classes of a previous version.
|
||||
But there is no way to save classes in accordance with a
|
||||
previous version. At first I dismissed this as 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>
|
||||
+377
-51
@@ -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 .
|
||||
@@ -33,10 +33,12 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#abstract">Abstract</a>
|
||||
<dt><a href="#typeinfo">Type Information Implementation</a>
|
||||
<dt><a href="#wrappers">Wrappers</a>
|
||||
<dt><a href="#bitwise">Bitwise Serialization</a>
|
||||
<dt><a href="#templates">Template Serialization Traits</a>
|
||||
<dt><a href="#compiletime_messages">Compile Time Warnings and Errors</a>
|
||||
</dl>
|
||||
Serialization of data depends on the type of the data. For example, for
|
||||
primitive types such as an <code style="white-space: normal">int</code>, it wouldn't make sense to save
|
||||
primitive types such as <code style="white-space: normal">int</code>, it wouldn't make sense to save
|
||||
a version number in the archive. Likewise, for a data type that is never
|
||||
serialized through a pointer, it would (almost) never make sense to track
|
||||
the address of objects saved to/loaded from the archive as it will never
|
||||
@@ -46,7 +48,7 @@ type, the way it is used and specifications of the programmer.
|
||||
<p>
|
||||
One can alter the manner in which a particular data type is serialized
|
||||
by specifying one or more <strong>class serialization traits</strong>.
|
||||
It is not generally necessary for the programmer to explictly assign
|
||||
It is not generally necessary for the programmer to explicitly assign
|
||||
traits to his classes as there are default values for all traits.
|
||||
If the default values are not appropriate they can be assigned by the programmer.
|
||||
A template is used to associate a typename with a constant. For example
|
||||
@@ -179,7 +181,7 @@ Default tracking traits are:
|
||||
That is, addresses of addresses are not tracked by default.
|
||||
<li>All current serialization wrappers such as <code style="white-space: normal">boost::serialization::nvp</code>,
|
||||
<code style="white-space: normal">track_never</code>.
|
||||
<li>For all other types, <code style="white-space: normal">track_selectivly</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>
|
||||
@@ -194,7 +196,7 @@ Default tracking traits are:
|
||||
The default behavior is almost always the most convenient one. However,
|
||||
there a few cases where it would be desirable to override the
|
||||
default. One case is that of a virtual base class. In a diamond
|
||||
heritance structure with a virtual base class, object tracking
|
||||
inheritance structure with a virtual base class, object tracking
|
||||
will prevent redundant save/load invocations. So here is one
|
||||
case where it might be convenient to override the default tracking
|
||||
trait. <i>(Note: in a future version the default will be reimplemented
|
||||
@@ -202,16 +204,26 @@ to automatically track classes used as virtual bases).</i> This
|
||||
situation is demonstrated by
|
||||
<a href="../test/test_diamond.cpp" target="test_diamond_cpp">test_diamond.cpp</a>
|
||||
included with the library.
|
||||
|
||||
<h3><a name="export">Export Key</a></h3>
|
||||
When serializing a derived class through a base class pointer, it
|
||||
may be convenient to define an external name by which the
|
||||
derived class can be identified.
|
||||
<i>(<a target="detail" href="special.html#derivedpointers">Elsewhere</a>
|
||||
in this manual, the
|
||||
serialization of derived classes is addressed in detail.)</i>
|
||||
|
||||
When serializing a derived class through a virtual base class pointer,
|
||||
two issues may arise.
|
||||
<ul>
|
||||
<li> The code in the derived class might never be explicitly
|
||||
referred to. Such code will never be instantiated.
|
||||
<p>
|
||||
This is addressed by invoking
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT(T)</code>
|
||||
in the file which defines (implements) the class T.
|
||||
This ensures that code for the derived class T will
|
||||
be explicitly instantiated.
|
||||
<li> There needs to be some sort of identifier which can
|
||||
be used to select the code to be invoked when the object
|
||||
is loaded.
|
||||
Standard C++ does implement <code style="white-space: normal">typeid()</code> which can be
|
||||
used to return a unique string for the class. This is not entirely
|
||||
statisfactory for our purposes for the following reasons:
|
||||
satisfactory for our purposes for the following reasons:
|
||||
<ul>
|
||||
<li>There is no guarantee that the string is the same across platforms.
|
||||
This would then fail to support portable archives.
|
||||
@@ -220,45 +232,52 @@ statisfactory for our purposes for the following reasons:
|
||||
<li>There might be classes locally defined in different code modules
|
||||
that have the same name.
|
||||
<li>There might be classes with different names that we want to
|
||||
consider equivalent for purposes of of serialization.
|
||||
consider equivalent for purposes of serialization.
|
||||
</ul>
|
||||
So the header file
|
||||
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
|
||||
includes macro definitions to specify the external string used
|
||||
to identify the class.
|
||||
<i>(<b>GUID</b> stands for <b>G</b>lobally <b>U</b>nique <b>ID</b>entfier.)</i>
|
||||
<pre><code>
|
||||
BOOST_CLASS_EXPORT_GUID(my_class, "my_class_external_identifier")
|
||||
</code></pre>
|
||||
<p>
|
||||
So in the serialization library, this is addressed by invoking
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_KEY2(my_class, "my_class_external_identifier")</code>
|
||||
in the header file which declares the class.
|
||||
In a large majority of applications, the class name works just fine
|
||||
for the external identifier string so the following short cut is
|
||||
defined
|
||||
<pre><code>
|
||||
BOOST_CLASS_EXPORT(my_class)
|
||||
</code></pre>
|
||||
which expands to:
|
||||
<pre><code>
|
||||
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.
|
||||
This macro must be used in the global namespace, with full namespace
|
||||
qualification of the argument class.
|
||||
defined -
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_KEY(my_class)</code>.
|
||||
</ul>
|
||||
For programs which consist of only one module - that is
|
||||
programs which do not use DLLS, one can specify
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT(my_class)</code>
|
||||
or
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID(my_class, "my_class_external_identifier")</code>
|
||||
in either the declaration header or definition. These macros
|
||||
expand to invocation of both of the macros described above.
|
||||
<i>(<b>GUID</b> stands for <b>G</b>lobally <b>U</b>nique <b>ID</b>entifier.)</i>
|
||||
<p>
|
||||
<i>(<a target="detail" href="special.html#export">Elsewhere</a>
|
||||
in this manual, the serialization of derived classes is addressed in detail.)</i>
|
||||
<p>
|
||||
The header file
|
||||
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
|
||||
contains all macro definitions described here.
|
||||
The library will throw a runtime exception if
|
||||
<ul>
|
||||
<li> A type not explicitly referred to is not exported.
|
||||
<li> Serialization code for the same type is instantiated
|
||||
in more than one module (or DLL).
|
||||
</ul>
|
||||
|
||||
<h3><a name="abstract">Abstract</a></h3>
|
||||
When serializing an object through a pointer to its base class,
|
||||
the library needs to determine whether or not the base 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
|
||||
@@ -314,10 +333,9 @@ 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
|
||||
Archives need to treat wrappers differently from other types since, for example,
|
||||
they usually are non-const objects 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>
|
||||
@@ -356,7 +374,30 @@ BOOST_CLASS_IS_WRAPPER(my_class)
|
||||
</code></pre>
|
||||
which expands to the code above.
|
||||
|
||||
<h3><a name="bitwise">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="templates">Template Serialization Traits</a></h3>
|
||||
In some instances it might be convenient to assign serialization traits
|
||||
@@ -429,7 +470,7 @@ struct tracking_level<nvp<T> >
|
||||
#endif
|
||||
</code></pre>
|
||||
This can be problematic when one wants to make his code <strong>and archives</strong>
|
||||
portable to other platforms. It means the she objects will be serialized differently
|
||||
portable to other platforms. It means the objects will be serialized differently
|
||||
depending on the platform used. This implies that objects saved from one platform
|
||||
won't be loaded properly on another. In other words, archives won't be portable.
|
||||
<p>
|
||||
@@ -471,6 +512,291 @@ and template parameters should be assigned according to the following table:
|
||||
<tr><td><code>IsWrapper</code></td><td><code></code>is the type a wrapper?</td><td><code>mpl::false_<br>mpl::true_</code></td><td><code>mpl::false_</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="compiletime_messages">Compile Time Warnings and Errors</a></h3>
|
||||
Some serialization traits can conflict with other ones. Sometimes these conflicts
|
||||
will result in erroneous behavior (E.G. creating of archives which could not be read)
|
||||
and other times they represent a probable misconception on the part of the
|
||||
library user which could result in surprising behavior. To the extent possible,
|
||||
these conflicts are detected at compile time and errors (BOOST_STATIC_ASSERT)
|
||||
or warnings (BOOST_STATIC_WARNING) are generated. They are generated in a
|
||||
compiler dependent manner which should show a chain of instantiation
|
||||
to the point where the error/warning is detected. Without this capability,
|
||||
it would be very hard to track down errors or unexpected behavior in library
|
||||
usage. Here is a list of the conflicts trapped:
|
||||
|
||||
<dl>
|
||||
<dt><h2><a name="object_level">object_level</a> - error</h2></dt>
|
||||
<dd>
|
||||
This error traps attempts to serialize types whose
|
||||
implementation level is set to non_serializable.
|
||||
</dd>
|
||||
<dt><h2><a name="object_versioning">object_versioning</a> - error</h2></dt>
|
||||
<dd>
|
||||
It's possible that for efficiency reasons, a type can be
|
||||
assigned a serialization level which doesn't include type information
|
||||
in the archive. This would preclude the assignment
|
||||
of a new version number to the type. This error
|
||||
traps attempts to assign a version number in this case.
|
||||
This has to be a user error.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="object_tracking">object_tracking</a> - warning</h2></dt>
|
||||
<dd>
|
||||
The following code will display a message when compiled:
|
||||
|
||||
<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>
|
||||
|
||||
The following case illustrates the function of this message.
|
||||
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 the above message is not displayed and the code is used as is.
|
||||
<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 acrimonious email exchanges,
|
||||
it's discovered
|
||||
that programmer(3) accidentally broke programmer(2)'s code .This is because by
|
||||
serializing via a pointer, the "log" object is 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 be 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 is
|
||||
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 a difficult to find and fix program bug, but we have a bunch of
|
||||
invalid archives and lost data.
|
||||
</ol>
|
||||
|
||||
<p>Now consider what happens when the message is displayed:
|
||||
|
||||
<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). 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 programmer (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 presumably that shifts the const
|
||||
error to somewhere else. And he 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 maybe 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 messages 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 messages are useful and that any such annoyance is a small price to
|
||||
pay to avoid particularly vexing programming errors.
|
||||
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="pointer_level">pointer_level</a> - warning</h2></dt>
|
||||
<dd>
|
||||
This trap addresses the following situation when serializing
|
||||
a pointer:
|
||||
<ul>
|
||||
<li>A type doesn't save class information in the
|
||||
archive. That is, the serialization trait implementation
|
||||
level <= object_serializable.
|
||||
<li>Tracking for this type is set to "track selectively"
|
||||
in this case, indication that an object is tracked is
|
||||
not stored in the archive itself - see level == object_serializable.
|
||||
Since class information is not saved in the archive, the existence
|
||||
or absence of the operation <code style="white-space: normal">ar << T *</code> anywhere else in the
|
||||
program is used to infer that an object of this type should be tracked.
|
||||
<p>
|
||||
A problem arises when a program which reads an archive
|
||||
includes the operation <code style="white-space: normal">ar >> T *</code> so that tracking information
|
||||
will be included in the archive. When a program which
|
||||
creates the archive doesn't include <code style="white-space: normal">ar << T</code> it is presumed
|
||||
that the archive doesn't include tracking information and
|
||||
the archive will fail to load. Also the reverse situation could
|
||||
trigger a similar problem.
|
||||
<p>
|
||||
Though this situation is unlikely for several reasons,
|
||||
it is possible - hence this warning.
|
||||
</ul>
|
||||
So if your program traps here, consider changing the
|
||||
tracking or implementation level traits - or not
|
||||
serializing via a pointer.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="pointer_tracking">pointer_tracking</a> - warning</h2></dt>
|
||||
<dd>
|
||||
Serializing an object of a type marked "track_never" through a pointer
|
||||
could result in creating more objects than were saved! There are cases
|
||||
in which a user might really want to do this so we leave it as a warning.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="const_loading">const_loading</a> - error</h2></dt>
|
||||
<dd>
|
||||
One cannot load data into a "const" object unless it's a
|
||||
wrapper around some other non-const object.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<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
|
||||
|
||||
+8
-8
@@ -123,7 +123,7 @@ int main() {
|
||||
gps_position newg;
|
||||
{
|
||||
// create and open an archive for input
|
||||
std::ifstream ifs("filename", std::ios::binary);
|
||||
std::ifstream ifs("filename");
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
// read class state from archive
|
||||
ia >> newg;
|
||||
@@ -136,7 +136,7 @@ int main() {
|
||||
<p>For each class to be saved via serialization, there must exist a function to
|
||||
save all the class members which define the state of the class.
|
||||
For each class to be loaded via serialization, there must exist a function to
|
||||
load theese class members in the same sequence as they were saved.
|
||||
load these class members in the same sequence as they were saved.
|
||||
In the above example, these functions are generated by the
|
||||
template member function <code style="white-space: normal">serialize</code>.
|
||||
|
||||
@@ -185,7 +185,7 @@ The main application of non-intrusive serialization is to permit serialization
|
||||
to be implemented for classes without changing the class definition.
|
||||
In order for this to be possible, the class must expose enough information
|
||||
to reconstruct the class state. In this example, we presumed that the
|
||||
class had <code style="white-space: normal">public</code> members - not a common occurence. Only
|
||||
class had <code style="white-space: normal">public</code> members - not a common occurrence. Only
|
||||
classes which expose enough information to save and restore the class
|
||||
state will be serializable without changing the class definition.
|
||||
<h3><a name="serializablemembers">Serializable Members</a></h3>
|
||||
@@ -290,7 +290,7 @@ class bus_route
|
||||
void serialize(Archive & ar, const unsigned int version)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 10; ++i)
|
||||
for(i = 0; i < 10; ++i)
|
||||
ar & stops[i];
|
||||
}
|
||||
public:
|
||||
@@ -327,7 +327,7 @@ 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>
|
||||
<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
|
||||
@@ -541,7 +541,7 @@ This is described later in the manual.
|
||||
<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
|
||||
tag. It is important 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>.
|
||||
@@ -569,11 +569,11 @@ anywhere in the program - a memory leak.
|
||||
There are couple of ways of fixing this. One way is to explicitly manage the bus stops.
|
||||
However, a more robust and transparent is to use
|
||||
<code style="white-space: normal">shared_ptr</code> rather than raw pointers. Along
|
||||
with serialization implemenations for the Standard Library, the serialization library
|
||||
with serialization implementations 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.
|
||||
as an exercise for the reader.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+9
-9
@@ -29,7 +29,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
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
|
||||
Limiting the serialization of pointers to only such classes would diminish the applicability
|
||||
of the library.
|
||||
|
||||
<h3>Usage</h3>
|
||||
@@ -42,11 +42,11 @@ They are declared in the namespace
|
||||
<dl>
|
||||
<dt><h4><pre><code>
|
||||
template<class Derived, class Base>
|
||||
const void_cast_detail::void_caster &
|
||||
const void_cast_detail::void_caster &
|
||||
void_cast_register(
|
||||
const Derived * derived = NULL,
|
||||
const Base * base = NULL
|
||||
)
|
||||
Derived const * derived = NULL,
|
||||
Base * const base = NULL
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This function "registers" a pair of related types. It stores the fact that
|
||||
@@ -67,8 +67,8 @@ This function "registers" a pair of related types. It stores the fact that
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_upcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
@@ -76,8 +76,8 @@ void_upcast(
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_downcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
|
||||
+14
-14
@@ -43,7 +43,7 @@ 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
|
||||
A binary object is just a sequence of bytes stored as raw
|
||||
binary data. This would most likely be used for a large amount
|
||||
of "light weight" data such as a pixel map or embedded binary file.
|
||||
The header file
|
||||
@@ -59,12 +59,12 @@ which will construct a temporary binary object that can be serialized just like
|
||||
Its default serialization is to use archive class primitives
|
||||
<code style="white-space: normal">save_binary</code> and <code>load_binary</code>.
|
||||
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.
|
||||
Its sole purpose is to pass the data size and address as a 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>.
|
||||
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.
|
||||
@@ -75,12 +75,12 @@ array.hpp
|
||||
</a>
|
||||
includes the function
|
||||
<pre><code>
|
||||
template <T>
|
||||
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>
|
||||
template<class T>
|
||||
class array
|
||||
{
|
||||
public:
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
};
|
||||
</code></pre>
|
||||
that can be serialized just like any other object.
|
||||
Its default serialization is to use serialize each array element.
|
||||
Its default serialization is to 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.
|
||||
|
||||
@@ -118,7 +118,7 @@ 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
|
||||
</a>. This type should be used for serializing 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
|
||||
@@ -158,27 +158,27 @@ The xml archive classes contain code similar to:
|
||||
<pre><code>
|
||||
// special treatment for name-value pairs.
|
||||
template<class T>
|
||||
xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
{
|
||||
// write an xml start tag
|
||||
start_tag(t.name());
|
||||
|
||||
// serialize the data as usual
|
||||
*this & t.value();
|
||||
*this & t.value();
|
||||
|
||||
// write an xml end tag
|
||||
end_tag(t.name());
|
||||
}
|
||||
</code></pre>
|
||||
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
|
||||
The most obvious and convenient name to assign to as the XML data item name
|
||||
is - surprise! - the name of the C++ class data member. So our serialization
|
||||
code will look like:
|
||||
<pre><code>
|
||||
ar & make_nvp("my_variable", my_variable);
|
||||
ar & make_nvp("my_variable", my_variable);
|
||||
</code></pre>
|
||||
To simplify typing and enhance readability a macro is defined so we can write:
|
||||
<pre><code>
|
||||
ar & BOOST_SERIALIZATION_NVP(my_variable);
|
||||
ar & BOOST_SERIALIZATION_NVP(my_variable);
|
||||
</code></pre>
|
||||
Similarly there exists a macro definition that permits us to write:
|
||||
<pre><code>
|
||||
@@ -200,7 +200,7 @@ is example of the XML Archive corresponding to our tutorial example.
|
||||
Wrappers should be designed so that they can be composed as necessary.
|
||||
For example, to pass binary data as a name value pair use:
|
||||
<pre><code>
|
||||
ar & make_nvp("named_binary_object", make_binary_object(address, size));
|
||||
ar & make_nvp("named_binary_object", make_binary_object(address, size));
|
||||
</code></pre>
|
||||
</html>
|
||||
<hr>
|
||||
|
||||
@@ -1,41 +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/example ;
|
||||
|
||||
rule demo-bsl-build ( demo-name )
|
||||
{
|
||||
exe $(demo-name)
|
||||
: # sources
|
||||
$(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
|
||||
<vc-7_0><release><cxxflags>-Gy
|
||||
<vc-7_1><release><cxxflags>-Gy
|
||||
: # default build
|
||||
debug
|
||||
;
|
||||
}
|
||||
|
||||
demo-bsl-build demo ;
|
||||
demo-bsl-build demo_auto_ptr ;
|
||||
demo-bsl-build demo_exception ;
|
||||
demo-bsl-build demo_fast_archive ;
|
||||
demo-bsl-build demo_pimpl ;
|
||||
demo-bsl-build demo_portable_archive ;
|
||||
demo-bsl-build demo_shared_ptr ;
|
||||
demo-bsl-build demo_xml ;
|
||||
demo-bsl-build demo_xml_save ;
|
||||
demo-bsl-build demo_xml_load ;
|
||||
@@ -0,0 +1,42 @@
|
||||
# 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_example
|
||||
: requirements <library>../build//boost_serialization
|
||||
;
|
||||
|
||||
import ../util/test :
|
||||
run-template
|
||||
run-invoke
|
||||
run-winvoke
|
||||
test-bsl-run-no-lib
|
||||
test-bsl-run
|
||||
test-bsl-run_archive
|
||||
test-bsl-run_files
|
||||
test-bsl-run_polymorphic_archive
|
||||
;
|
||||
|
||||
test-suite "demo-suite" :
|
||||
# demos
|
||||
[ test-bsl-run demo ]
|
||||
[ test-bsl-run demo_auto_ptr ]
|
||||
[ test-bsl-run demo_exception ]
|
||||
[ test-bsl-run demo_fast_archive ]
|
||||
[ test-bsl-run demo_log : log_archive ]
|
||||
[ test-bsl-run demo_pimpl : demo_pimpl_A ]
|
||||
[ test-bsl-run demo_polymorphic : demo_polymorphic_A ]
|
||||
[ test-bsl-run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
|
||||
[ test-bsl-run demo_shared_ptr ]
|
||||
[ test-bsl-run demo_simple_log ]
|
||||
[ test-bsl-run demo_trivial_archive ]
|
||||
[ test-bsl-run demo_xml ]
|
||||
[ test-bsl-run demo_xml_save ]
|
||||
[ test-bsl-run demo_xml_load : : : <dependency>demo_xml_save ]
|
||||
;
|
||||
|
||||
+20
-19
@@ -7,6 +7,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#include <cstddef> // NULL
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -20,27 +21,27 @@
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/is_abstract.hpp>
|
||||
#include <boost/serialization/assume_abstract.hpp>
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// The intent of this program is to serve as a tutorial for
|
||||
// users of the serialization package. An attempt has been made
|
||||
// to illustrate most of the facilities of the package.
|
||||
// to illustrate most of the facilities of the package.
|
||||
//
|
||||
// The intent is to create an example suffciently complete to
|
||||
// The intent is to create an example sufficiently complete to
|
||||
// illustrate the usage and utility of the package while
|
||||
// including a minimum of other code.
|
||||
// including a minimum of other code.
|
||||
//
|
||||
// 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
|
||||
// There are different kinds of stops. Bus stops in general
|
||||
// will appear on multiple routes. A schedule will include
|
||||
// muliple trips on the same route.
|
||||
// multiple trips on the same route.
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// gps coordinate
|
||||
//
|
||||
// llustrates serialization for a simple type
|
||||
// illustrates serialization for a simple type
|
||||
//
|
||||
class gps_position
|
||||
{
|
||||
@@ -56,7 +57,7 @@ class gps_position
|
||||
public:
|
||||
// every serializable class needs a constructor
|
||||
gps_position(){};
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
degrees(_d), minutes(_m), seconds(_s)
|
||||
{}
|
||||
};
|
||||
@@ -93,7 +94,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)
|
||||
{
|
||||
@@ -146,7 +147,7 @@ class bus_stop_destination : public bus_stop
|
||||
ar & boost::serialization::base_object<bus_stop>(*this) & name;
|
||||
}
|
||||
public:
|
||||
|
||||
|
||||
bus_stop_destination(){}
|
||||
bus_stop_destination(
|
||||
const gps_position & _lat, const gps_position & _long, const std::string & _name
|
||||
@@ -161,7 +162,7 @@ public:
|
||||
//
|
||||
// illustrates serialization of STL collection templates.
|
||||
//
|
||||
// illustrates serialzation of polymorphic pointer (bus stop *);
|
||||
// illustrates serialization 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
|
||||
@@ -212,7 +213,7 @@ std::ostream & operator<<(std::ostream &os, const bus_route &br)
|
||||
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
|
||||
// See definition of operator<< <pair<F, S> >(ar, pair) and others in
|
||||
// serialization.hpp
|
||||
//
|
||||
//
|
||||
// illustrates nesting of serializable classes
|
||||
//
|
||||
// illustrates use of version number to automatically grandfather older
|
||||
@@ -232,7 +233,7 @@ public:
|
||||
if(file_version >= 2)
|
||||
// read the drivers name
|
||||
ar & driver;
|
||||
// all versions have the follwing info
|
||||
// all versions have the following info
|
||||
ar & hour & minute;
|
||||
}
|
||||
|
||||
@@ -264,7 +265,7 @@ public:
|
||||
}
|
||||
bus_schedule(){}
|
||||
};
|
||||
BOOST_CLASS_VERSION(bus_schedule, 2)
|
||||
BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
|
||||
{
|
||||
@@ -298,7 +299,7 @@ restore_schedule(bus_schedule &s, const char * filename)
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
// make the schedule
|
||||
bus_schedule original_schedule;
|
||||
|
||||
@@ -325,7 +326,7 @@ int main(int argc, char *argv[])
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a routes
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
@@ -336,7 +337,7 @@ int main(int argc, char *argv[])
|
||||
original_schedule.append("bob", 9, 57, &route0);
|
||||
original_schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make aother routes
|
||||
// make another route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
@@ -350,7 +351,7 @@ int main(int argc, char *argv[])
|
||||
// display the complete schedule
|
||||
std::cout << "original schedule";
|
||||
std::cout << original_schedule;
|
||||
|
||||
|
||||
std::string filename(boost::archive::tmpdir());
|
||||
filename += "/demofile.txt";
|
||||
|
||||
@@ -358,7 +359,7 @@ int main(int argc, char *argv[])
|
||||
save_schedule(original_schedule, filename.c_str());
|
||||
|
||||
// ... some time later
|
||||
// make a new schedule
|
||||
// make a new schedule
|
||||
bus_schedule new_schedule;
|
||||
|
||||
restore_schedule(new_schedule, filename.c_str());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_auto_ptr.cpp
|
||||
|
||||
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
// (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)
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <cstdio> // remove, std::autoptr inteface wrong in dinkumware
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
@@ -25,17 +25,17 @@ namespace std{
|
||||
|
||||
#include <boost/serialization/split_free.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// implement serialization for auto_ptr<T>
|
||||
// implement serialization for auto_ptr< T >
|
||||
// note: this must be added to the boost namespace in order to
|
||||
// be called by the library
|
||||
template<class Archive, class T>
|
||||
inline void save(
|
||||
Archive & ar,
|
||||
const std::auto_ptr<T> &t,
|
||||
const std::auto_ptr< T > &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
// only the raw pointer has to be saved
|
||||
@@ -47,7 +47,7 @@ inline void save(
|
||||
template<class Archive, class T>
|
||||
inline void load(
|
||||
Archive & ar,
|
||||
std::auto_ptr<T> &t,
|
||||
std::auto_ptr< T > &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
T *pTarget;
|
||||
@@ -55,7 +55,7 @@ inline void load(
|
||||
// note that the reset automagically maintains the reference count
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
t.release();
|
||||
t = std::auto_ptr<T>(pTarget);
|
||||
t = std::auto_ptr< T >(pTarget);
|
||||
#else
|
||||
t.reset(pTarget);
|
||||
#endif
|
||||
@@ -66,7 +66,7 @@ inline void load(
|
||||
template<class Archive, class T>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
std::auto_ptr<T> &t,
|
||||
std::auto_ptr< T > &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
boost::serialization::split_free(ar, t, file_version);
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_A_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# 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/math/special_functions/next.hpp>
|
||||
|
||||
#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(BOOST_BORLANDC, <= 0x551 )
|
||||
int i;
|
||||
if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){
|
||||
i = l;
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
}
|
||||
else{
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
l = i;
|
||||
}
|
||||
#else
|
||||
ar & BOOST_SERIALIZATION_NVP(l);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(m);
|
||||
ar & BOOST_SERIALIZATION_NVP(n);
|
||||
ar & BOOST_SERIALIZATION_NVP(o);
|
||||
ar & BOOST_SERIALIZATION_NVP(p);
|
||||
ar & BOOST_SERIALIZATION_NVP(q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
ar & BOOST_SERIALIZATION_NVP(r);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(c);
|
||||
ar & BOOST_SERIALIZATION_NVP(s);
|
||||
ar & BOOST_SERIALIZATION_NVP(t);
|
||||
ar & BOOST_SERIALIZATION_NVP(u);
|
||||
ar & BOOST_SERIALIZATION_NVP(v);
|
||||
ar & BOOST_SERIALIZATION_NVP(w);
|
||||
ar & BOOST_SERIALIZATION_NVP(x);
|
||||
ar & BOOST_SERIALIZATION_NVP(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
ar & BOOST_SERIALIZATION_NVP(z);
|
||||
#endif
|
||||
}
|
||||
bool b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
boost::int64_t f;
|
||||
boost::uint64_t g;
|
||||
#endif
|
||||
enum h {
|
||||
i = 0,
|
||||
j,
|
||||
k
|
||||
} l;
|
||||
std::size_t m;
|
||||
signed long n;
|
||||
unsigned long o;
|
||||
signed short p;
|
||||
unsigned short q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
wchar_t r;
|
||||
#endif
|
||||
char c;
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
std::string y;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
std::wstring z;
|
||||
#endif
|
||||
public:
|
||||
A();
|
||||
bool operator==(const A &rhs) const;
|
||||
bool operator!=(const A &rhs) const;
|
||||
bool operator<(const A &rhs) const; // used by less
|
||||
// hash function for class A
|
||||
operator std::size_t () const;
|
||||
friend std::ostream & operator<<(std::ostream & os, A const & a);
|
||||
friend std::istream & operator>>(std::istream & is, A & a);
|
||||
};
|
||||
|
||||
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
|
||||
|
||||
template<class S>
|
||||
void randomize(S &x)
|
||||
{
|
||||
assert(0 == x.size());
|
||||
for(;;){
|
||||
unsigned int i = std::rand() % 27;
|
||||
if(0 == i)
|
||||
break;
|
||||
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void accumulate(std::size_t & s, const T & t){
|
||||
const char * tptr = (const char *)(& t);
|
||||
unsigned int count = sizeof(t);
|
||||
while(count-- > 0){
|
||||
s += *tptr++;
|
||||
}
|
||||
}
|
||||
|
||||
A::operator std::size_t () const {
|
||||
std::size_t retval = 0;
|
||||
accumulate(retval, b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
accumulate(retval, f);
|
||||
accumulate(retval, g);
|
||||
#endif
|
||||
accumulate(retval, l);
|
||||
accumulate(retval, m);
|
||||
accumulate(retval, n);
|
||||
accumulate(retval, o);
|
||||
accumulate(retval, p);
|
||||
accumulate(retval, q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
accumulate(retval, r);
|
||||
#endif
|
||||
accumulate(retval, c);
|
||||
accumulate(retval, s);
|
||||
accumulate(retval, t);
|
||||
accumulate(retval, u);
|
||||
accumulate(retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline A::A() :
|
||||
b(true),
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
f(std::rand() * std::rand()),
|
||||
g(std::rand() * std::rand()),
|
||||
#endif
|
||||
l(static_cast<enum h>(std::rand() % 3)),
|
||||
m(std::rand()),
|
||||
n(std::rand()),
|
||||
o(std::rand()),
|
||||
p(std::rand()),
|
||||
q(std::rand()),
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
r(std::rand()),
|
||||
#endif
|
||||
c(std::rand()),
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand()),
|
||||
x((double)std::rand())
|
||||
{
|
||||
randomize(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
randomize(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool A::operator==(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return false;
|
||||
if(l != rhs.l)
|
||||
return false;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return false;
|
||||
if(g != rhs.g)
|
||||
return false;
|
||||
#endif
|
||||
if(m != rhs.m)
|
||||
return false;
|
||||
if(n != rhs.n)
|
||||
return false;
|
||||
if(o != rhs.o)
|
||||
return false;
|
||||
if(p != rhs.p)
|
||||
return false;
|
||||
if(q != rhs.q)
|
||||
return false;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r)
|
||||
return false;
|
||||
#endif
|
||||
if(c != rhs.c)
|
||||
return false;
|
||||
if(s != rhs.s)
|
||||
return false;
|
||||
if(t != rhs.t)
|
||||
return false;
|
||||
if(u != rhs.u)
|
||||
return false;
|
||||
if(v != rhs.v)
|
||||
return false;
|
||||
if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
|
||||
return false;
|
||||
if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
|
||||
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,317 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_A_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_A_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# 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(BOOST_BORLANDC, <= 0x551 )
|
||||
int i;
|
||||
if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){
|
||||
i = l;
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
}
|
||||
else{
|
||||
ar & BOOST_SERIALIZATION_NVP(i);
|
||||
l = i;
|
||||
}
|
||||
#else
|
||||
ar & BOOST_SERIALIZATION_NVP(l);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(m);
|
||||
ar & BOOST_SERIALIZATION_NVP(n);
|
||||
ar & BOOST_SERIALIZATION_NVP(o);
|
||||
ar & BOOST_SERIALIZATION_NVP(p);
|
||||
ar & BOOST_SERIALIZATION_NVP(q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
ar & BOOST_SERIALIZATION_NVP(r);
|
||||
#endif
|
||||
ar & BOOST_SERIALIZATION_NVP(c);
|
||||
ar & BOOST_SERIALIZATION_NVP(s);
|
||||
ar & BOOST_SERIALIZATION_NVP(t);
|
||||
ar & BOOST_SERIALIZATION_NVP(u);
|
||||
ar & BOOST_SERIALIZATION_NVP(v);
|
||||
ar & BOOST_SERIALIZATION_NVP(w);
|
||||
ar & BOOST_SERIALIZATION_NVP(x);
|
||||
ar & BOOST_SERIALIZATION_NVP(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
ar & BOOST_SERIALIZATION_NVP(z);
|
||||
#endif
|
||||
}
|
||||
bool b;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
boost::int64_t f;
|
||||
boost::uint64_t g;
|
||||
#endif
|
||||
enum h {
|
||||
i = 0,
|
||||
j,
|
||||
k
|
||||
} l;
|
||||
std::size_t m;
|
||||
signed long n;
|
||||
unsigned long o;
|
||||
signed short p;
|
||||
unsigned short q;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
wchar_t r;
|
||||
#endif
|
||||
char c;
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
std::string y;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
std::wstring z;
|
||||
#endif
|
||||
public:
|
||||
A();
|
||||
bool operator==(const A &rhs) const;
|
||||
bool operator!=(const A &rhs) const;
|
||||
bool operator<(const A &rhs) const; // used by less
|
||||
// hash function for class A
|
||||
operator std::size_t () const;
|
||||
friend std::ostream & operator<<(std::ostream & os, A const & a);
|
||||
friend std::istream & operator>>(std::istream & is, A & a);
|
||||
};
|
||||
|
||||
//BOOST_TEST_DONT_PRINT_LOG_VALUE(A);
|
||||
|
||||
template<class S>
|
||||
void randomize(S &x)
|
||||
{
|
||||
assert(0 == x.size());
|
||||
for(;;){
|
||||
unsigned int i = std::rand() % 27;
|
||||
if(0 == i)
|
||||
break;
|
||||
x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void accumulate(std::size_t & s, const T & t){
|
||||
const char * tptr = (const char *)(& t);
|
||||
unsigned int count = sizeof(t);
|
||||
while(count-- > 0){
|
||||
s += *tptr++;
|
||||
}
|
||||
}
|
||||
|
||||
A::operator std::size_t () const {
|
||||
std::size_t retval = 0;
|
||||
accumulate(retval, b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
accumulate(retval, f);
|
||||
accumulate(retval, g);
|
||||
#endif
|
||||
accumulate(retval, l);
|
||||
accumulate(retval, m);
|
||||
accumulate(retval, n);
|
||||
accumulate(retval, o);
|
||||
accumulate(retval, p);
|
||||
accumulate(retval, q);
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
accumulate(retval, r);
|
||||
#endif
|
||||
accumulate(retval, c);
|
||||
accumulate(retval, s);
|
||||
accumulate(retval, t);
|
||||
accumulate(retval, u);
|
||||
accumulate(retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline A::A() :
|
||||
b(true),
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
f(std::rand() * std::rand()),
|
||||
g(std::rand() * std::rand()),
|
||||
#endif
|
||||
l(static_cast<enum h>(std::rand() % 3)),
|
||||
m(std::rand()),
|
||||
n(std::rand()),
|
||||
o(std::rand()),
|
||||
p(std::rand()),
|
||||
q(std::rand()),
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
r(std::rand()),
|
||||
#endif
|
||||
c(std::rand()),
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand()),
|
||||
x((double)std::rand())
|
||||
{
|
||||
randomize(y);
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
randomize(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool A::operator==(const A &rhs) const
|
||||
{
|
||||
if(b != rhs.b)
|
||||
return false;
|
||||
if(l != rhs.l)
|
||||
return false;
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
if(f != rhs.f)
|
||||
return false;
|
||||
if(g != rhs.g)
|
||||
return false;
|
||||
#endif
|
||||
if(m != rhs.m)
|
||||
return false;
|
||||
if(n != rhs.n)
|
||||
return false;
|
||||
if(o != rhs.o)
|
||||
return false;
|
||||
if(p != rhs.p)
|
||||
return false;
|
||||
if(q != rhs.q)
|
||||
return false;
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
if(r != rhs.r)
|
||||
return false;
|
||||
#endif
|
||||
if(c != rhs.c)
|
||||
return false;
|
||||
if(s != rhs.s)
|
||||
return false;
|
||||
if(t != rhs.t)
|
||||
return false;
|
||||
if(u != rhs.u)
|
||||
return false;
|
||||
if(v != rhs.v)
|
||||
return false;
|
||||
if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
|
||||
return false;
|
||||
if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
|
||||
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,113 @@
|
||||
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
|
||||
#define BOOST_SERIALIZATION_TEST_B_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# 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/math/special_functions/next.hpp>
|
||||
|
||||
#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::abs( boost::math::float_distance(w, rhs.w)) < 2
|
||||
&& std::abs( boost::math::float_distance(x, rhs.x)) < 2
|
||||
;
|
||||
}
|
||||
|
||||
#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)
|
||||
# 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::abs( boost::math::float_distance(w, rhs.w)) < 2
|
||||
&& std::abs( boost::math::float_distance(x, rhs.x)) < 2
|
||||
;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_B_HPP
|
||||
@@ -1,31 +1,32 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_exception.cpp
|
||||
|
||||
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
// (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)
|
||||
|
||||
// Example of safe exception handling for pointer de-serialization
|
||||
//
|
||||
// This example was prepared by Robert Ramey to demonstrate and test
|
||||
//
|
||||
// This example was prepared by Robert Ramey to demonstrate and test
|
||||
// safe exception handling during the de-serialization of pointers in
|
||||
// a non-trivial example.
|
||||
//
|
||||
// Hopefully, this addresses exception issues raised by
|
||||
// Vahan Margaryan who spent considerable time and effort
|
||||
// in the analysis and testing of issues of exception safety
|
||||
// in the analysis and testing of issues of exception safety
|
||||
// of the serialization library.
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <cstddef> // NULL
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <cstdio> // remove
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
@@ -126,7 +127,7 @@ private:
|
||||
// case 1:
|
||||
template<class Archive>
|
||||
void School::serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
// if an exeception occurs while loading courses
|
||||
// if an exception occurs while loading courses
|
||||
// the structure courses may have some courses each
|
||||
// with students
|
||||
ar & all_courses;
|
||||
@@ -154,7 +155,7 @@ void School::save(Archive & ar, const unsigned int /* file_version */) const {
|
||||
|
||||
template<class Archive>
|
||||
void School::load(Archive & ar, const unsigned int /* file_version */){
|
||||
// if an exeception occurs while loading courses
|
||||
// if an exception occurs while loading courses
|
||||
// the structure courses may have some courses each
|
||||
// with students
|
||||
try{
|
||||
@@ -166,7 +167,7 @@ void School::load(Archive & ar, const unsigned int /* file_version */){
|
||||
ar >> all_students; // create students that have no courses
|
||||
}
|
||||
catch(std::exception){
|
||||
// elminate any dangling references
|
||||
// eliminate any dangling references
|
||||
all_courses.clear();
|
||||
all_students.clear();
|
||||
throw;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_fast_binary_archive.cpp
|
||||
|
||||
// (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)
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/pfto.hpp>
|
||||
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include <boost/archive/binary_oarchive_impl.hpp>
|
||||
#include <boost/archive/binary_iarchive_impl.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
// include template definitions for base classes used. Otherwise
|
||||
// you'll get link failure with undefined symbols
|
||||
@@ -24,25 +24,22 @@
|
||||
#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
|
||||
// "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,
|
||||
std::ostream::char_type,
|
||||
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,
|
||||
fast_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -51,38 +48,38 @@ public:
|
||||
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::char_type,
|
||||
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
|
||||
// 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(T & t, BOOST_PFTO int){
|
||||
base_t::save_override(t, 0);
|
||||
void save_override(T & t){
|
||||
base_t::save_override(t);
|
||||
// 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) );
|
||||
}
|
||||
template<int N>
|
||||
void save_override(const int (& t)[N] , int){
|
||||
void save_override(const int (& t)[N]){
|
||||
save_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void save_override(const unsigned int (& t)[N], int){
|
||||
void save_override(const unsigned int (& t)[N]){
|
||||
save_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void save_override(const long (& t)[N], int){
|
||||
void save_override(const long (& t)[N]){
|
||||
save_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void save_override(const unsigned long (& t)[N], int){
|
||||
void save_override(const unsigned long (& t)[N]){
|
||||
save_binary(t, sizeof(t));
|
||||
}
|
||||
public:
|
||||
@@ -94,20 +91,23 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_oarchive)
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// "Fast" input binary archive. This is a variation of the native binary
|
||||
// "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,
|
||||
std::istream::char_type,
|
||||
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,
|
||||
fast_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -116,36 +116,36 @@ public:
|
||||
friend class boost::archive::detail::interface_iarchive<derived_t>;
|
||||
friend class basic_binary_iarchive<derived_t>;
|
||||
friend class basic_binary_iprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
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
|
||||
// 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){
|
||||
base_t::load_override(t, 0);
|
||||
void load_override(T & t){
|
||||
base_t::load_override(t);
|
||||
BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) );
|
||||
}
|
||||
template<int N>
|
||||
void load_override(int (& t)[N], int){
|
||||
void load_override(int (& t)[N]){
|
||||
load_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void load_override(unsigned int (& t)[N], int){
|
||||
void load_override(unsigned int (& t)[N]){
|
||||
load_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void load_override(long (& t)[N], int){
|
||||
void load_override(long (& t)[N]){
|
||||
load_binary(t, sizeof(t));
|
||||
}
|
||||
template<int N>
|
||||
void load_override(unsigned long (& t)[N], int){
|
||||
void load_override(unsigned long (& t)[N]){
|
||||
load_binary(t, sizeof(t));
|
||||
}
|
||||
public:
|
||||
@@ -157,13 +157,16 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_iarchive)
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
const int a[3] = {1, 2, 3};
|
||||
int a1[3] = {4, 5, 6};
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
{
|
||||
fast_binary_oarchive pboa(ss);
|
||||
pboa << a;
|
||||
}
|
||||
|
||||
+10
-10
@@ -10,27 +10,27 @@
|
||||
// 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/string.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/assume_abstract.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
|
||||
// There are different kinds of stops. Bus stops in general
|
||||
// will appear on multiple routes. A schedule will include
|
||||
// muliple trips on the same route.
|
||||
// multiple trips on the same route.
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// gps coordinate
|
||||
//
|
||||
// llustrates serialization for a simple type
|
||||
// illustrates serialization for a simple type
|
||||
//
|
||||
class gps_position
|
||||
{
|
||||
@@ -51,7 +51,7 @@ class gps_position
|
||||
public:
|
||||
// every serializable class needs a constructor
|
||||
gps_position(){};
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
degrees(_d), minutes(_m), seconds(_s)
|
||||
{}
|
||||
};
|
||||
@@ -91,7 +91,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)
|
||||
{
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
//
|
||||
// illustrates serialization of STL collection templates.
|
||||
//
|
||||
// illustrates serialzation of polymorphic pointer (bus stop *);
|
||||
// illustrates serialization 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
|
||||
@@ -209,7 +209,7 @@ std::ostream & operator<<(std::ostream &os, const bus_route &br)
|
||||
//
|
||||
// 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
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
if(file_version >= 2)
|
||||
// read the drivers name
|
||||
ar & BOOST_SERIALIZATION_NVP(driver);
|
||||
// all versions have the follwing info
|
||||
// all versions have the following info
|
||||
ar & BOOST_SERIALIZATION_NVP(hour)
|
||||
& BOOST_SERIALIZATION_NVP(minute);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_log.cpp
|
||||
//
|
||||
// (C) Copyright 2009 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 <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include "demo_gps.hpp"
|
||||
#include "log_archive.hpp"
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
// make the schedule
|
||||
bus_schedule schedule;
|
||||
|
||||
// fill in the data
|
||||
// make a few stops
|
||||
bus_stop *bs0 = new bus_stop_corner(
|
||||
gps_position(34, 135, 52.560f),
|
||||
gps_position(134, 22, 78.30f),
|
||||
"24th Street", "10th Avenue"
|
||||
);
|
||||
bus_stop *bs1 = new bus_stop_corner(
|
||||
gps_position(35, 137, 23.456f),
|
||||
gps_position(133, 35, 54.12f),
|
||||
"State street", "Cathedral Vista Lane"
|
||||
);
|
||||
bus_stop *bs2 = new bus_stop_destination(
|
||||
gps_position(35, 136, 15.456f),
|
||||
gps_position(133, 32, 15.300f),
|
||||
"White House"
|
||||
);
|
||||
bus_stop *bs3 = new bus_stop_destination(
|
||||
gps_position(35, 134, 48.789f),
|
||||
gps_position(133, 32, 16.230f),
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
route0.append(bs2);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("bob", 6, 24, &route0);
|
||||
schedule.append("bob", 9, 57, &route0);
|
||||
schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make another route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
route1.append(bs1);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("ted", 7, 17, &route1);
|
||||
schedule.append("ted", 9, 38, &route1);
|
||||
schedule.append("alice", 11, 47, &route1);
|
||||
|
||||
// display the complete schedule
|
||||
log_archive oa(std::cout);
|
||||
oa << BOOST_SERIALIZATION_NVP(schedule);
|
||||
oa << schedule;
|
||||
|
||||
delete bs0;
|
||||
delete bs1;
|
||||
delete bs2;
|
||||
delete bs3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_pimpl.cpp
|
||||
|
||||
// (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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_pimpl_A.cpp
|
||||
|
||||
// (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)
|
||||
@@ -31,15 +31,15 @@ template<class Archive>
|
||||
void A::serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
ar & pimpl;
|
||||
}
|
||||
|
||||
// without the explicit instantiations below, the program will
|
||||
// fail to link for lack of instantiantiation of the above function
|
||||
|
||||
// without the explicit instantiation below, the program will
|
||||
// fail to link for lack of instantiation of the above function
|
||||
// note: the following failed to fix link errors for vc 7.0 !
|
||||
template void A::serialize<boost::archive::text_iarchive>(
|
||||
boost::archive::text_iarchive & ar,
|
||||
boost::archive::text_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
template void A::serialize<boost::archive::text_oarchive>(
|
||||
boost::archive::text_oarchive & ar,
|
||||
boost::archive::text_oarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_pimpl_A.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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_polymorphic.cpp
|
||||
|
||||
// (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)
|
||||
@@ -26,10 +26,10 @@ int main(int argc, char* argv[])
|
||||
// test with a text archive
|
||||
std::stringstream ss;
|
||||
{
|
||||
// instantiate archive which inhertis polymorphic interface
|
||||
// instantiate archive which inherits polymorphic interface
|
||||
// and the normal text archive implementation
|
||||
boost::archive::polymorphic_text_oarchive oa(ss);
|
||||
boost::archive::polymorphic_oarchive & oa_interface = oa;
|
||||
boost::archive::polymorphic_oarchive & oa_interface = oa;
|
||||
// we can just just the interface for saving
|
||||
oa_interface << a;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ int main(int argc, char* argv[])
|
||||
//test with a binary archive
|
||||
std::stringstream ss;
|
||||
{
|
||||
// instantiate archive which inhertis polymorphic interface
|
||||
// instantiate archive which inherits polymorphic interface
|
||||
// and the normal binary archive implementation
|
||||
boost::archive::polymorphic_binary_oarchive oa(ss);
|
||||
oa << a;
|
||||
@@ -53,7 +53,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
// see above
|
||||
boost::archive::polymorphic_binary_iarchive ia(ss);
|
||||
boost::archive::polymorphic_iarchive & ia_interface = ia;
|
||||
boost::archive::polymorphic_iarchive & ia_interface = ia;
|
||||
// use just the polymorphic interface for loading.
|
||||
ia_interface >> a1;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_polymorphic_A.cpp
|
||||
|
||||
// (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)
|
||||
@@ -12,16 +12,15 @@
|
||||
|
||||
#include "demo_polymorphic_A.hpp"
|
||||
|
||||
// now we can define the serialization for class A
|
||||
void A::serialize(
|
||||
boost::archive::polymorphic_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
){
|
||||
ar & data;
|
||||
}
|
||||
void A::serialize(
|
||||
boost::archive::polymorphic_oarchive & ar,
|
||||
const unsigned int file_version
|
||||
){
|
||||
ar & data;
|
||||
}
|
||||
// explicitly instantiate templates for polymorphic archives
|
||||
// used by this demo.
|
||||
template
|
||||
void A::serialize<boost::archive::polymorphic_iarchive>(
|
||||
boost::archive::polymorphic_iarchive &,
|
||||
const unsigned int
|
||||
);
|
||||
template
|
||||
void A::serialize<boost::archive::polymorphic_oarchive>(
|
||||
boost::archive::polymorphic_oarchive &,
|
||||
const unsigned int
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// demo_polymorphic_A.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)
|
||||
@@ -20,8 +20,13 @@ class polymorphic_oarchive;
|
||||
|
||||
struct A {
|
||||
// class a contains a pointer to a "hidden" declaration
|
||||
void serialize(boost::archive::polymorphic_iarchive & ar, const unsigned int file_version);
|
||||
void serialize(boost::archive::polymorphic_oarchive & ar, const unsigned int file_version);
|
||||
template<class Archive>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
const unsigned int file_version
|
||||
){
|
||||
ar & data;
|
||||
}
|
||||
int data;
|
||||
bool operator==(const A & rhs) const {
|
||||
return data == rhs.data;
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// should pass compilation and execution
|
||||
|
||||
// note:: this example can only be built with the static library
|
||||
// (at least with MSVC - due to conflicts related to import of library
|
||||
// code and instantiation of templates.
|
||||
#include <sstream>
|
||||
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include "portable_binary_oarchive.hpp"
|
||||
#include "portable_binary_iarchive.hpp"
|
||||
|
||||
@@ -20,30 +23,38 @@
|
||||
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;
|
||||
A *pa;
|
||||
int i;
|
||||
int i2; // special tricky case to check sign extension
|
||||
unsigned int ui;
|
||||
long l;
|
||||
unsigned long ul;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* version */){
|
||||
ar & i & ui & l & ul ;
|
||||
ar & c & i & i2 & ui & l & ul ;
|
||||
}
|
||||
public:
|
||||
bool operator==(const A & rhs) const {
|
||||
return
|
||||
i == rhs.i && ui == rhs.ui && l == rhs.l && ul == rhs.ul
|
||||
c == rhs.c
|
||||
&& i == rhs.i
|
||||
&& i2 == rhs.i2
|
||||
&& ui == rhs.ui
|
||||
&& l == rhs.l
|
||||
&& ul == rhs.ul
|
||||
;
|
||||
}
|
||||
A() :
|
||||
c(0xFF & std::rand()),
|
||||
pa(0),
|
||||
i(std::rand()),
|
||||
i2(0x80),
|
||||
ui(std::rand()),
|
||||
l(std::rand()),
|
||||
l(std::rand() * std::rand()),
|
||||
ul(std::rand())
|
||||
{}
|
||||
};
|
||||
@@ -54,7 +65,7 @@ int main( int /* argc */, char* /* argv */[] )
|
||||
A a1;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
{
|
||||
portable_binary_oarchive pboa(ss);
|
||||
pboa << a;
|
||||
}
|
||||
@@ -62,6 +73,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cstddef> // NULL
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <cstdio> // remove
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
@@ -41,8 +42,8 @@ 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)
|
||||
@@ -60,8 +61,8 @@ private:
|
||||
}
|
||||
public:
|
||||
static int count;
|
||||
B::B() : A() {};
|
||||
virtual B::~B() {};
|
||||
B() : A() {};
|
||||
virtual ~B() {};
|
||||
};
|
||||
|
||||
BOOST_SERIALIZATION_SHARED_PTR(B)
|
||||
@@ -81,7 +82,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";
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_log.cpp
|
||||
//
|
||||
// (C) Copyright 2009 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 <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include "demo_gps.hpp"
|
||||
#include "simple_log_archive.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// make the schedule
|
||||
bus_schedule schedule;
|
||||
|
||||
// fill in the data
|
||||
// make a few stops
|
||||
bus_stop *bs0 = new bus_stop_corner(
|
||||
gps_position(34, 135, 52.560f),
|
||||
gps_position(134, 22, 78.30f),
|
||||
"24th Street", "10th Avenue"
|
||||
);
|
||||
bus_stop *bs1 = new bus_stop_corner(
|
||||
gps_position(35, 137, 23.456f),
|
||||
gps_position(133, 35, 54.12f),
|
||||
"State street", "Cathedral Vista Lane"
|
||||
);
|
||||
bus_stop *bs2 = new bus_stop_destination(
|
||||
gps_position(35, 136, 15.456f),
|
||||
gps_position(133, 32, 15.300f),
|
||||
"White House"
|
||||
);
|
||||
bus_stop *bs3 = new bus_stop_destination(
|
||||
gps_position(35, 134, 48.789f),
|
||||
gps_position(133, 32, 16.230f),
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
route0.append(bs2);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("bob", 6, 24, &route0);
|
||||
schedule.append("bob", 9, 57, &route0);
|
||||
schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make another route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
route1.append(bs1);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("ted", 7, 17, &route1);
|
||||
schedule.append("ted", 9, 38, &route1);
|
||||
schedule.append("alice", 11, 47, &route1);
|
||||
|
||||
// display the complete schedule
|
||||
simple_log_archive log(std::cout);
|
||||
log << schedule;
|
||||
|
||||
delete bs0;
|
||||
delete bs1;
|
||||
delete bs2;
|
||||
delete bs3;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_trivial_archive.cpp
|
||||
//
|
||||
// (C) Copyright 2009 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 <cstddef> // std::size_t
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class trivial_oarchive
|
||||
class trivial_oarchive {
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////
|
||||
// public interface used by programs that use the
|
||||
// serialization library
|
||||
typedef boost::mpl::bool_<true> is_saving;
|
||||
typedef boost::mpl::bool_<false> is_loading;
|
||||
template<class T> void register_type(){}
|
||||
template<class T> trivial_oarchive & operator<<(const T & t){
|
||||
return *this;
|
||||
}
|
||||
template<class T> trivial_oarchive & operator&(const T & t){
|
||||
return *this << t;
|
||||
}
|
||||
void save_binary(void *address, std::size_t count){};
|
||||
};
|
||||
|
||||
#include "demo_gps.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// make the schedule
|
||||
bus_schedule schedule;
|
||||
|
||||
// fill in the data
|
||||
// make a few stops
|
||||
bus_stop *bs0 = new bus_stop_corner(
|
||||
gps_position(34, 135, 52.560f),
|
||||
gps_position(134, 22, 78.30f),
|
||||
"24th Street", "10th Avenue"
|
||||
);
|
||||
bus_stop *bs1 = new bus_stop_corner(
|
||||
gps_position(35, 137, 23.456f),
|
||||
gps_position(133, 35, 54.12f),
|
||||
"State street", "Cathedral Vista Lane"
|
||||
);
|
||||
bus_stop *bs2 = new bus_stop_destination(
|
||||
gps_position(35, 136, 15.456f),
|
||||
gps_position(133, 32, 15.300f),
|
||||
"White House"
|
||||
);
|
||||
bus_stop *bs3 = new bus_stop_destination(
|
||||
gps_position(35, 134, 48.789f),
|
||||
gps_position(133, 32, 16.230f),
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
route0.append(bs2);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("bob", 6, 24, &route0);
|
||||
schedule.append("bob", 9, 57, &route0);
|
||||
schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make another route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
route1.append(bs1);
|
||||
|
||||
// add trips to schedule
|
||||
schedule.append("ted", 7, 17, &route1);
|
||||
schedule.append("ted", 9, 38, &route1);
|
||||
schedule.append("alice", 11, 47, &route1);
|
||||
|
||||
// display the complete schedule
|
||||
trivial_oarchive ta;
|
||||
ta << schedule;
|
||||
|
||||
delete bs0;
|
||||
delete bs1;
|
||||
delete bs2;
|
||||
delete bs3;
|
||||
return 0;
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <cstdio> // remove
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
@@ -47,7 +47,7 @@ restore_schedule(bus_schedule &s, const char * filename)
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
// make the schedule
|
||||
bus_schedule original_schedule;
|
||||
|
||||
@@ -74,7 +74,7 @@ int main(int argc, char *argv[])
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a routes
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
@@ -85,7 +85,7 @@ int main(int argc, char *argv[])
|
||||
original_schedule.append("bob", 9, 57, &route0);
|
||||
original_schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make aother routes
|
||||
// make another route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
|
||||
// display the complete schedule
|
||||
std::cout << "original schedule";
|
||||
std::cout << original_schedule;
|
||||
|
||||
|
||||
std::string filename(boost::archive::tmpdir());
|
||||
filename += "/demo.xml";
|
||||
|
||||
@@ -107,7 +107,7 @@ int main(int argc, char *argv[])
|
||||
save_schedule(original_schedule, filename.c_str());
|
||||
|
||||
// ... some time later
|
||||
// make a new schedule
|
||||
// make a new schedule
|
||||
bus_schedule new_schedule;
|
||||
|
||||
restore_schedule(new_schedule, filename.c_str());
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_xml.hpp
|
||||
//
|
||||
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
// This illustration models the bus system of a small city.
|
||||
// This includes, multiple bus stops, bus routes and schedules.
|
||||
// There are different kinds of stops. Bus stops in general
|
||||
// will appear on multiple routes. A schedule will include
|
||||
// multiple trips on the same route.
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// gps coordinate
|
||||
//
|
||||
// illustrates serialization for a simple type
|
||||
//
|
||||
class gps_position
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
|
||||
|
||||
int degrees;
|
||||
int minutes;
|
||||
float seconds;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
ar & BOOST_SERIALIZATION_NVP(degrees)
|
||||
& BOOST_SERIALIZATION_NVP(minutes)
|
||||
& BOOST_SERIALIZATION_NVP(seconds);
|
||||
}
|
||||
|
||||
public:
|
||||
// every serializable class needs a constructor
|
||||
gps_position(){};
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
degrees(_d), minutes(_m), seconds(_s)
|
||||
{}
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
|
||||
{
|
||||
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// One bus stop
|
||||
//
|
||||
// illustrates serialization of serializable members
|
||||
//
|
||||
|
||||
class bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
virtual std::string description() const = 0;
|
||||
gps_position latitude;
|
||||
gps_position longitude;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(latitude);
|
||||
ar & BOOST_SERIALIZATION_NVP(longitude);
|
||||
}
|
||||
|
||||
protected:
|
||||
bus_stop(const gps_position & _lat, const gps_position & _long) :
|
||||
latitude(_lat), longitude(_long)
|
||||
{}
|
||||
public:
|
||||
bus_stop(){}
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
|
||||
virtual ~bus_stop(){}
|
||||
};
|
||||
|
||||
BOOST_IS_ABSTRACT(bus_stop)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
|
||||
{
|
||||
return os << bs.latitude << bs.longitude << ' ' << bs.description();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Several kinds of bus stops
|
||||
//
|
||||
// illustrates serialization of derived types
|
||||
//
|
||||
class bus_stop_corner : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string street1;
|
||||
std::string street2;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return street1 + " and " + street2;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
// save/load base class information
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
|
||||
ar & BOOST_SERIALIZATION_NVP(street1);
|
||||
ar & BOOST_SERIALIZATION_NVP(street2);
|
||||
}
|
||||
public:
|
||||
bus_stop_corner(){}
|
||||
bus_stop_corner(const gps_position & _lat, const gps_position & _long,
|
||||
const std::string & _s1, const std::string & _s2
|
||||
) :
|
||||
bus_stop(_lat, _long), street1(_s1), street2(_s2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class bus_stop_destination : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string name;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
|
||||
& BOOST_SERIALIZATION_NVP(name);
|
||||
}
|
||||
public:
|
||||
bus_stop_destination(){}
|
||||
bus_stop_destination(
|
||||
const gps_position & _lat, const gps_position & _long, const std::string & _name
|
||||
) :
|
||||
bus_stop(_lat, _long), name(_name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// a bus route is a collection of bus stops
|
||||
//
|
||||
// illustrates serialization of STL collection templates.
|
||||
//
|
||||
// illustrates serialization 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 following info
|
||||
ar & BOOST_SERIALIZATION_NVP(hour)
|
||||
& BOOST_SERIALIZATION_NVP(minute);
|
||||
}
|
||||
|
||||
// starting time
|
||||
int hour;
|
||||
int minute;
|
||||
// only after system shipped was the driver's name added to the class
|
||||
std::string driver;
|
||||
|
||||
trip_info(){}
|
||||
trip_info(int _h, int _m, const std::string &_d) :
|
||||
hour(_h), minute(_m), driver(_d)
|
||||
{}
|
||||
~trip_info(){
|
||||
}
|
||||
};
|
||||
// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
|
||||
private:
|
||||
std::list<std::pair<trip_info, bus_route *> > schedule;
|
||||
public:
|
||||
void append(const std::string &_d, int _h, int _m, bus_route *_br)
|
||||
{
|
||||
schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
|
||||
}
|
||||
bus_schedule(){}
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
|
||||
BOOST_CLASS_VERSION(bus_schedule, 2)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
|
||||
{
|
||||
return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
|
||||
}
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
|
||||
{
|
||||
std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
|
||||
for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
|
||||
os << it->first << *(it->second);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
@@ -28,7 +28,7 @@ restore_schedule(bus_schedule &s, const char * filename)
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
// make a new schedule
|
||||
bus_schedule new_schedule;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ void save_schedule(const bus_schedule &s, const char * filename){
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
// make the schedule
|
||||
bus_schedule original_schedule;
|
||||
|
||||
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a routes
|
||||
// make a route
|
||||
bus_route route0;
|
||||
route0.append(bs0);
|
||||
route0.append(bs1);
|
||||
@@ -62,7 +62,7 @@ int main(int argc, char *argv[])
|
||||
original_schedule.append("bob", 9, 57, &route0);
|
||||
original_schedule.append("alice", 11, 02, &route0);
|
||||
|
||||
// make aother routes
|
||||
// make an other route
|
||||
bus_route route1;
|
||||
route1.append(bs3);
|
||||
route1.append(bs2);
|
||||
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
|
||||
// display the complete schedule
|
||||
std::cout << "original schedule";
|
||||
std::cout << original_schedule;
|
||||
|
||||
|
||||
std::string filename(boost::archive::tmpdir());
|
||||
filename += "/demo_save.xml";
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
|
||||
void usage(const char * program_name){
|
||||
std::cout << "usage:";
|
||||
std::cout << program_name << " filename" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
if(argc != 2){
|
||||
std::cout << "invalid number of arguments" << std::endl;
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
std::filebuf fb;
|
||||
fb.open(
|
||||
argv[1],
|
||||
std::ios_base::binary | std::ios_base::in | std::ios_base::out
|
||||
);
|
||||
if(!fb.is_open()){
|
||||
std::cout << argv[1] << " failed to open" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
boost::archive::binary_iarchive ia(fb);
|
||||
boost::archive::library_version_type lvt = ia.get_library_version();
|
||||
if(boost::archive::library_version_type(6) != lvt){
|
||||
std::cout << "library version not equal to six" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
lvt = boost::archive::library_version_type(7);
|
||||
fb.pubseekpos(26, std::ios_base::out);
|
||||
fb.sputn(reinterpret_cast<const char *>(& lvt), sizeof(lvt));
|
||||
fb.close();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// log_archive.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.
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER == 1200)
|
||||
# pragma warning (disable : 4786) // too long name, harmless warning
|
||||
#endif
|
||||
|
||||
//#define BOOST_ARCHIVE_SOURCE
|
||||
#include "log_archive.hpp"
|
||||
#include <boost/archive/detail/archive_serializer_map.hpp>
|
||||
|
||||
// explicitly instantiate for this type of xml stream
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
#include <boost/archive/impl/basic_xml_oarchive.ipp>
|
||||
#include <boost/archive/impl/xml_oarchive_impl.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template class detail::archive_serializer_map<log_archive>;
|
||||
template class basic_xml_oarchive<log_archive> ;
|
||||
template class xml_oarchive_impl<log_archive> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef LOG_ARCHIVE_HPP
|
||||
#define LOG_ARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// log_archive.hpp
|
||||
|
||||
// (C) Copyright 2010 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/xml_oarchive.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
namespace detail {
|
||||
template<class Archive> class interface_oarchive;
|
||||
} // namespace detail
|
||||
} // namespace archive
|
||||
} // boost
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// log data to an output stream. This illustrates a simpler implementation
|
||||
// of text output which is useful for getting a formatted display of
|
||||
// any serializable class. Intended to be useful as a debugging aid.
|
||||
class log_archive :
|
||||
/* protected ? */
|
||||
public boost::archive::xml_oarchive_impl<log_archive>
|
||||
{
|
||||
typedef boost::archive::xml_oarchive_impl<log_archive> base;
|
||||
// give serialization implementation access to this class
|
||||
friend class boost::archive::detail::interface_oarchive<log_archive>;
|
||||
friend class boost::archive::basic_xml_oarchive<log_archive>;
|
||||
friend class boost::archive::save_access;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Override functions defined in basic_xml_oarchive
|
||||
|
||||
// Anything not an attribute and not a name-value pair is an
|
||||
// error and should be trapped here.
|
||||
template<class T>
|
||||
void save_override(T & t){
|
||||
// make it a name-value pair and pass it on.
|
||||
// this permits this to be used even with data types which
|
||||
// are not wrapped with the name
|
||||
base::save_override(boost::serialization::make_nvp(NULL, t));
|
||||
}
|
||||
template<class T>
|
||||
void save_override(const boost::serialization::nvp< T > & t){
|
||||
// this is here to remove the "const" requirement. Since
|
||||
// this class is to be used only for output, it's not required.
|
||||
base::save_override(t);
|
||||
}
|
||||
// specific overrides for attributes - not name value pairs so we
|
||||
// want to trap them before the above "fall through"
|
||||
// since we don't want to see these in the output - make them no-ops.
|
||||
void save_override(const boost::archive::object_id_type & t){}
|
||||
void save_override(const boost::archive::object_reference_type & t){}
|
||||
void save_override(const boost::archive::version_type & t){}
|
||||
void save_override(const boost::archive::class_id_type & t){}
|
||||
void save_override(const boost::archive::class_id_optional_type & t){}
|
||||
void save_override(const boost::archive::class_id_reference_type & t){}
|
||||
void save_override(const boost::archive::class_name_type & t){}
|
||||
void save_override(const boost::archive::tracking_type & t){}
|
||||
public:
|
||||
log_archive(std::ostream & os, unsigned int flags = 0) :
|
||||
boost::archive::xml_oarchive_impl<log_archive>(
|
||||
os,
|
||||
flags | boost::archive::no_header
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // LOG_ARCHIVE_HPP
|
||||
@@ -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)
|
||||
# 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)
|
||||
# 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,46 @@
|
||||
#ifndef PORTABLE_BINARY_ARCHIVE_HPP
|
||||
#define PORTABLE_BINARY_ARCHIVE_HPP
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.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/predef/other/endian.h>
|
||||
|
||||
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,131 @@
|
||||
/////////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 <boost/predef/other/endian.h>
|
||||
#include <boost/serialization/throw_exception.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
|
||||
#include "portable_binary_iarchive.hpp"
|
||||
|
||||
void
|
||||
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
|
||||
char size;
|
||||
l = 0;
|
||||
this->primitive_base_t::load(size);
|
||||
|
||||
if(0 == size){
|
||||
return;
|
||||
}
|
||||
|
||||
bool negative = (size < 0);
|
||||
if(negative)
|
||||
size = -size;
|
||||
|
||||
if(size > maxsize)
|
||||
boost::serialization::throw_exception(
|
||||
portable_binary_iarchive_exception()
|
||||
);
|
||||
|
||||
char * cptr = reinterpret_cast<char *>(& l);
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
cptr += (sizeof(boost::intmax_t) - size);
|
||||
#endif
|
||||
this->primitive_base_t::load_binary(cptr, size);
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
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
|
||||
){
|
||||
std::string cn;
|
||||
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
|
||||
load_override(cn);
|
||||
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::invalid_class_name)
|
||||
);
|
||||
std::memcpy(t, cn.data(), cn.size());
|
||||
// borland tweak
|
||||
t.t[cn.size()] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_iarchive::init(unsigned int flags){
|
||||
if(0 == (flags & boost::archive::no_header)){
|
||||
// read signature in an archive version independent manner
|
||||
std::string file_signature;
|
||||
* this >> file_signature;
|
||||
if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::invalid_signature
|
||||
)
|
||||
);
|
||||
// make sure the version of the reading archive library can
|
||||
// support the format of the archive being read
|
||||
boost::archive::library_version_type input_library_version;
|
||||
* this >> input_library_version;
|
||||
|
||||
// extra little .t is to get around borland quirk
|
||||
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::unsupported_version
|
||||
)
|
||||
);
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
|
||||
this->set_library_version(input_library_version);
|
||||
//#else
|
||||
//#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
//detail::
|
||||
//#endif
|
||||
boost::archive::detail::basic_iarchive::set_library_version(
|
||||
input_library_version
|
||||
);
|
||||
#endif
|
||||
}
|
||||
unsigned char x;
|
||||
load(x);
|
||||
m_flags = x << CHAR_BIT;
|
||||
}
|
||||
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
namespace detail {
|
||||
template class archive_serializer_map<portable_binary_iarchive>;
|
||||
}
|
||||
|
||||
template class basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -2,172 +2,203 @@
|
||||
#define PORTABLE_BINARY_IARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4244 )
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// portable_binary_iarchive.hpp
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <ostream>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <istream>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/item_version_type.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/basic_binary_iprimitive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.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 :
|
||||
public virtual boost::archive::archive_exception
|
||||
class portable_binary_iarchive_exception :
|
||||
public boost::archive::archive_exception
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
incompatible_integer_size
|
||||
} exception_code;
|
||||
portable_binary_archive_exception(exception_code c = incompatible_integer_size )
|
||||
enum exception_code {
|
||||
incompatible_integer_size
|
||||
} m_exception_code ;
|
||||
portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) :
|
||||
boost::archive::archive_exception(boost::archive::archive_exception::other_exception),
|
||||
m_exception_code(c)
|
||||
{}
|
||||
virtual const char *what( ) const throw( )
|
||||
{
|
||||
const char *msg = "programmer error";
|
||||
switch(code){
|
||||
switch(m_exception_code){
|
||||
case incompatible_integer_size:
|
||||
msg = "integer cannot be represented";
|
||||
break;
|
||||
default:
|
||||
boost::archive::archive_exception::what();
|
||||
msg = boost::archive::archive_exception::what();
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
/////////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 endianness so
|
||||
// that binary archives can be passed across systems. Note:floating point types
|
||||
// not addressed here
|
||||
class portable_binary_iarchive :
|
||||
// don't derive from binary_iarchive !!!
|
||||
public boost::archive::binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
public boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>,
|
||||
public boost::archive::detail::shared_ptr_helper
|
||||
{
|
||||
typedef boost::archive::binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> archive_base_t;
|
||||
public boost::archive::detail::common_iarchive<
|
||||
portable_binary_iarchive
|
||||
>
|
||||
{
|
||||
typedef boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
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 archive_base_t;
|
||||
friend primitive_base_t; // since with override load below
|
||||
friend class boost::archive::basic_binary_iarchive<portable_binary_iarchive>;
|
||||
friend class boost::archive::detail::interface_iarchive<
|
||||
portable_binary_iarchive
|
||||
>;
|
||||
friend class boost::archive::load_access;
|
||||
protected:
|
||||
#endif
|
||||
void load_impl(long & l, char maxsize){
|
||||
char size;
|
||||
this->archive_base_t::load(size);
|
||||
if(size > maxsize)
|
||||
throw portable_binary_archive_exception() ;
|
||||
l = 0;
|
||||
load_binary(& l, size);
|
||||
// we choose to use litle endian
|
||||
#ifdef BOOST_BIG_ENDIAN
|
||||
char * first = static_cast<char *>(static_cast<void *>(& l));
|
||||
char * last = first + sizeof(l) - 1;
|
||||
for(;first < last;++first, --last){
|
||||
char x = *last;
|
||||
*last = *first;
|
||||
*first = x;
|
||||
}
|
||||
#endif
|
||||
unsigned int m_flags;
|
||||
void load_impl(boost::intmax_t & l, char maxsize);
|
||||
|
||||
// extend sign if necessary
|
||||
if((l >> (size - 1) * 8) & 0x80){
|
||||
l |= (-1 << (size * 8));
|
||||
}
|
||||
}
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void load(T & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(T));
|
||||
// use cast to avoid compile time warning
|
||||
//t = static_cast< T >(l);
|
||||
t = T(l);
|
||||
}
|
||||
void load(boost::serialization::item_version_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::serialization::item_version_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::serialization::item_version_type(l);
|
||||
}
|
||||
void load(boost::archive::version_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::archive::version_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::archive::version_type(l);
|
||||
}
|
||||
void load(boost::archive::class_id_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::archive::class_id_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::archive::class_id_type(static_cast<int>(l));
|
||||
}
|
||||
void load(std::string & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(unsigned short & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned short));
|
||||
t = l;
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void load(std::wstring & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(short & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(short));
|
||||
t = l;
|
||||
#endif
|
||||
void load(float & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// floats not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
}
|
||||
void load(unsigned int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned int));
|
||||
t = l;
|
||||
void load(double & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// doubles not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
}
|
||||
void load(int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(int));
|
||||
t = l;
|
||||
void load(char & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(unsigned long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned long));
|
||||
t = l;
|
||||
void load(unsigned char & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
void load(long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(long));
|
||||
t = l;
|
||||
typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
|
||||
detail_common_iarchive;
|
||||
template<class T>
|
||||
void load_override(T & t){
|
||||
this->detail_common_iarchive::load_override(t);
|
||||
}
|
||||
void load_override(boost::archive::class_name_type & t);
|
||||
// binary files don't include the optional information
|
||||
void load_override(boost::archive::class_id_optional_type &){}
|
||||
|
||||
void init(unsigned int flags);
|
||||
public:
|
||||
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
|
||||
archive_base_t(
|
||||
is,
|
||||
flags | boost::archive::no_header // skip default header checking
|
||||
)
|
||||
primitive_base_t(
|
||||
* is.rdbuf(),
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(0)
|
||||
{
|
||||
// use our own header checking
|
||||
if(0 != (flags & boost::archive::no_header)){
|
||||
this->archive_base_t::init(flags);
|
||||
// skip the following for "portable" binary archives
|
||||
// boost::archive::basic_binary_oprimitive<derived_t, std::ostream>::init();
|
||||
}
|
||||
init(flags);
|
||||
}
|
||||
|
||||
portable_binary_iarchive(
|
||||
std::basic_streambuf<
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> & bsb,
|
||||
unsigned int flags
|
||||
) :
|
||||
primitive_base_t(
|
||||
bsb,
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(0)
|
||||
{
|
||||
init(flags);
|
||||
}
|
||||
};
|
||||
|
||||
// explicitly instantiate for this type of text stream
|
||||
#include <boost/archive/impl/basic_binary_iarchive.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template class binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>;
|
||||
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
// required by export in boost version > 1.34
|
||||
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
|
||||
#endif
|
||||
|
||||
// required by export in boost <= 1.34
|
||||
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif // PORTABLE_BINARY_IARCHIVE_HPP
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/////////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/predef/other/endian.h>
|
||||
#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);
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
cptr += (sizeof(boost::intmax_t) - size);
|
||||
if(m_flags & endian_little)
|
||||
reverse_bytes(size, cptr);
|
||||
#else
|
||||
if(m_flags & endian_big)
|
||||
reverse_bytes(size, cptr);
|
||||
#endif
|
||||
this->primitive_base_t::save_binary(cptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_oarchive::init(unsigned int flags) {
|
||||
if(m_flags == (endian_big | endian_little)){
|
||||
boost::serialization::throw_exception(
|
||||
portable_binary_oarchive_exception()
|
||||
);
|
||||
}
|
||||
if(0 == (flags & boost::archive::no_header)){
|
||||
// write signature in an archive version independent manner
|
||||
const std::string file_signature(
|
||||
boost::archive::BOOST_ARCHIVE_SIGNATURE()
|
||||
);
|
||||
* this << file_signature;
|
||||
// write library version
|
||||
const boost::archive::library_version_type v(
|
||||
boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
);
|
||||
* this << v;
|
||||
}
|
||||
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
|
||||
}
|
||||
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
namespace detail {
|
||||
template class archive_serializer_map<portable_binary_oarchive>;
|
||||
}
|
||||
|
||||
template class basic_binary_oprimitive<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -2,14 +2,19 @@
|
||||
#define PORTABLE_BINARY_OARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#if defined(_MSC_VER)
|
||||
# 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
|
||||
|
||||
// (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,75 +22,75 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <ostream>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <boost/archive/basic_binary_oprimitive.hpp>
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
#include "portable_binary_archive.hpp"
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// "Portable" output binary archive. This is a variation of the native binary
|
||||
// archive. it addresses integer size and endienness so that binary archives can
|
||||
// exception to be thrown if integer read from archive doesn't fit
|
||||
// variable being loaded
|
||||
class portable_binary_oarchive_exception :
|
||||
public 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
|
||||
// archive. it addresses integer size and endianness so that binary archives can
|
||||
// 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,
|
||||
std::ostream::char_type,
|
||||
public boost::archive::basic_binary_oprimitive<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>,
|
||||
public boost::archive::detail::common_oarchive<
|
||||
portable_binary_oarchive
|
||||
>
|
||||
{
|
||||
typedef boost::archive::binary_oarchive_impl<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> archive_base_t;
|
||||
typedef boost::archive::basic_binary_oprimitive<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> primitive_base_t;
|
||||
typedef boost::archive::detail::common_oarchive<
|
||||
portable_binary_oarchive
|
||||
> archive_base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend archive_base_t;
|
||||
friend primitive_base_t; // since with override save below
|
||||
friend class boost::archive::basic_binary_oarchive<portable_binary_oarchive>;
|
||||
friend class boost::archive::detail::interface_oarchive<
|
||||
portable_binary_oarchive
|
||||
>;
|
||||
friend class boost::archive::save_access;
|
||||
protected:
|
||||
#endif
|
||||
void save_impl(const long l){
|
||||
long ll = l;
|
||||
char size = 0;
|
||||
if(l < 0){
|
||||
// make sure that enough of data is output
|
||||
// to include a high order bit indicating the sign
|
||||
char x;
|
||||
do{
|
||||
x = ll;
|
||||
ll >>= 8;
|
||||
++size;
|
||||
}while(ll != -1 && x < 0);
|
||||
}
|
||||
else{
|
||||
do{
|
||||
ll >>= 8;
|
||||
++size;
|
||||
}while(ll != 0);
|
||||
}
|
||||
|
||||
this->archive_base_t::save(size);
|
||||
|
||||
// we choose to use litle endian
|
||||
#ifdef BOOST_BIG_ENDIAN
|
||||
char * first = static_cast<char *>(static_cast<void *>(& l));
|
||||
char * last = first + sizeof(l) - 1;
|
||||
for(;first < last;++first, --last){
|
||||
char x = *last;
|
||||
*last = *first;
|
||||
*first = x;
|
||||
}
|
||||
#endif
|
||||
save_binary(& l, size);
|
||||
}
|
||||
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
|
||||
@@ -94,60 +99,93 @@ public:
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void save(const T & t){
|
||||
save_impl(t, sizeof(T));
|
||||
}
|
||||
void save(const std::string & t){
|
||||
this->primitive_base_t::save(t);
|
||||
}
|
||||
void save(const short 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 short t){
|
||||
save_impl(t);
|
||||
#endif
|
||||
void save(const float & t){
|
||||
this->primitive_base_t::save(t);
|
||||
// floats not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
}
|
||||
void save(const unsigned int 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 int t){
|
||||
save_impl(t);
|
||||
void save(const char & t){
|
||||
this->primitive_base_t::save(t);
|
||||
}
|
||||
void save(const unsigned long t){
|
||||
save_impl(t);
|
||||
void save(const unsigned char & t){
|
||||
this->primitive_base_t::save(t);
|
||||
}
|
||||
void save(const long t){
|
||||
save_impl(t);
|
||||
|
||||
// default processing - kick back to base class. Note the
|
||||
// extra stuff to get it passed borland compilers
|
||||
typedef boost::archive::detail::common_oarchive<portable_binary_oarchive>
|
||||
detail_common_oarchive;
|
||||
template<class T>
|
||||
void save_override(T & t){
|
||||
this->detail_common_oarchive::save_override(t);
|
||||
}
|
||||
// explicitly convert to char * to avoid compile ambiguities
|
||||
void save_override(const boost::archive::class_name_type & t){
|
||||
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 */
|
||||
){}
|
||||
|
||||
void init(unsigned int flags);
|
||||
public:
|
||||
portable_binary_oarchive(std::ostream & os, unsigned flags = 0) :
|
||||
archive_base_t(
|
||||
os,
|
||||
flags | boost::archive::no_header // skip default header checking
|
||||
)
|
||||
primitive_base_t(
|
||||
* os.rdbuf(),
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(flags & (endian_big | endian_little))
|
||||
{
|
||||
// use our own header checking
|
||||
if(0 != (flags & boost::archive::no_header)){
|
||||
this->archive_base_t::init(flags);
|
||||
// skip the following for "portable" binary archives
|
||||
// boost::archive::basic_binary_iprimitive<derived_t, std::ostream>::init();
|
||||
}
|
||||
init(flags);
|
||||
}
|
||||
|
||||
portable_binary_oarchive(
|
||||
std::basic_streambuf<
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> & bsb,
|
||||
unsigned int flags
|
||||
) :
|
||||
primitive_base_t(
|
||||
bsb,
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(0)
|
||||
{
|
||||
init(flags);
|
||||
}
|
||||
};
|
||||
|
||||
#include <boost/archive/impl/basic_binary_oarchive.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
// explicitly instantiate for this type of binary stream
|
||||
template class binary_oarchive_impl<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
// required by export in boost version > 1.34
|
||||
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive)
|
||||
#endif
|
||||
|
||||
// required by export in boost <= 1.34
|
||||
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif // PORTABLE_BINARY_OARCHIVE_HPP
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
#ifndef BOOST_SIMPLE_LOG_ARCHIVE_HPP
|
||||
#define BOOST_SIMPLE_LOG_ARCHIVE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// simple_log_archive.hpp
|
||||
|
||||
// (C) Copyright 2010 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 <cstddef> // std::size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::size_t;
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// log data to an output stream. This illustrates a simpler implementation
|
||||
// of text output which is useful for getting a formatted display of
|
||||
// any serializable class. Intended to be useful as a debugging aid.
|
||||
class simple_log_archive {
|
||||
std::ostream & m_os;
|
||||
unsigned int m_depth;
|
||||
|
||||
template<class Archive>
|
||||
struct save_enum_type {
|
||||
template<class T>
|
||||
static void invoke(Archive &ar, const T &t){
|
||||
ar.m_os << static_cast<int>(t);
|
||||
}
|
||||
};
|
||||
template<class Archive>
|
||||
struct save_primitive {
|
||||
template<class T>
|
||||
static void invoke(Archive & ar, const T & t){
|
||||
ar.m_os << t;
|
||||
}
|
||||
};
|
||||
template<class Archive>
|
||||
struct save_only {
|
||||
template<class T>
|
||||
static void invoke(Archive & ar, const T & t){
|
||||
// make sure call is routed through the highest interface that might
|
||||
// be specialized by the user.
|
||||
boost::serialization::serialize_adl(
|
||||
ar,
|
||||
const_cast<T &>(t),
|
||||
::boost::serialization::version< T >::value
|
||||
);
|
||||
}
|
||||
};
|
||||
template<class T>
|
||||
void save(const T &t){
|
||||
typedef
|
||||
BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<boost::is_enum< T >,
|
||||
boost::mpl::identity<save_enum_type<simple_log_archive> >,
|
||||
//else
|
||||
BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
|
||||
// if its primitive
|
||||
boost::mpl::equal_to<
|
||||
boost::serialization::implementation_level< T >,
|
||||
boost::mpl::int_<boost::serialization::primitive_type>
|
||||
>,
|
||||
boost::mpl::identity<save_primitive<simple_log_archive> >,
|
||||
// else
|
||||
boost::mpl::identity<save_only<simple_log_archive> >
|
||||
> >::type typex;
|
||||
typex::invoke(*this, t);
|
||||
}
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void save(const std::wstring &ws){
|
||||
m_os << "wide string types not supported in log archive";
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
///////////////////////////////////////////////////
|
||||
// Implement requirements for archive concept
|
||||
|
||||
typedef boost::mpl::bool_<false> is_loading;
|
||||
typedef boost::mpl::bool_<true> is_saving;
|
||||
|
||||
// this can be a no-op since we ignore pointer polymorphism
|
||||
template<class T>
|
||||
void register_type(const T * = NULL){}
|
||||
|
||||
unsigned int get_library_version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
save_binary(const void *address, std::size_t count){
|
||||
m_os << "save_binary not implemented";
|
||||
}
|
||||
|
||||
// the << operators
|
||||
template<class T>
|
||||
simple_log_archive & operator<<(T const & t){
|
||||
m_os << ' ';
|
||||
save(t);
|
||||
return * this;
|
||||
}
|
||||
template<class T>
|
||||
simple_log_archive & operator<<(T * const t){
|
||||
m_os << " ->";
|
||||
if(NULL == t)
|
||||
m_os << " null";
|
||||
else
|
||||
*this << * t;
|
||||
return * this;
|
||||
}
|
||||
template<class T, int N>
|
||||
simple_log_archive & operator<<(const T (&t)[N]){
|
||||
return *this << boost::serialization::make_array(
|
||||
static_cast<const T *>(&t[0]),
|
||||
N
|
||||
);
|
||||
}
|
||||
template<class T>
|
||||
simple_log_archive & operator<<(const boost::serialization::nvp< T > & t){
|
||||
m_os << '\n'; // start line with each named object
|
||||
// indent according to object depth
|
||||
for(unsigned int i = 0; i < m_depth; ++i)
|
||||
m_os << ' ';
|
||||
++m_depth;
|
||||
m_os << t.name(); // output the name of the object
|
||||
* this << t.const_value();
|
||||
--m_depth;
|
||||
return * this;
|
||||
}
|
||||
|
||||
// the & operator
|
||||
template<class T>
|
||||
simple_log_archive & operator&(const T & t){
|
||||
return * this << t;
|
||||
}
|
||||
///////////////////////////////////////////////
|
||||
|
||||
simple_log_archive(std::ostream & os) :
|
||||
m_os(os),
|
||||
m_depth(0)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // BOOST_SIMPLE_LOG_ARCHIVE_HPP
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef BOOST_ARCHIVE_ADD_FACET_HPP
|
||||
#define BOOST_ARCHIVE_ADD_FACET_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
|
||||
// add_facet.hpp
|
||||
|
||||
// (C) Copyright 2003 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 <locale>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// does STLport uses native STL for locales?
|
||||
#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)
|
||||
# define BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template<class Facet>
|
||||
inline std::locale *
|
||||
add_facet(const std::locale &l, Facet * f){
|
||||
return
|
||||
#if defined BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT
|
||||
// std namespace used for native locale
|
||||
new std::locale(std::_Addfac(l, f));
|
||||
#elif BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) // old Dinkumwar
|
||||
// std namespace used for native locale
|
||||
new std::locale(std::_Addfac(l, f));
|
||||
#else
|
||||
// standard compatible
|
||||
new std::locale(l, f);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT
|
||||
|
||||
#endif // BOOST_ARCHIVE_ADD_FACET_HPP
|
||||
@@ -2,14 +2,14 @@
|
||||
#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// archive/archive_exception.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,21 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <exception>
|
||||
#include <cassert>
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/archive/detail/decl.hpp>
|
||||
|
||||
// note: the only reason this is in here is that windows header
|
||||
// includes #define exception_code _exception_code (arrrgghhhh!).
|
||||
// the most expedient way to address this is be sure that this
|
||||
// header is always included whenever this header file is included.
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#include <excpt.h>
|
||||
#endif
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -25,91 +39,62 @@ namespace archive {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// exceptions thrown by archives
|
||||
//
|
||||
class archive_exception :
|
||||
class BOOST_SYMBOL_VISIBLE archive_exception :
|
||||
public virtual std::exception
|
||||
{
|
||||
private:
|
||||
char m_buffer[128];
|
||||
protected:
|
||||
BOOST_ARCHIVE_DECL unsigned int
|
||||
append(unsigned int l, const char * a);
|
||||
BOOST_ARCHIVE_DECL
|
||||
archive_exception() BOOST_NOEXCEPT;
|
||||
public:
|
||||
typedef enum {
|
||||
no_exception, // initialized without code
|
||||
other_exception, // any excepton not listed below
|
||||
unregistered_class, // attempt to serialize a pointer of an
|
||||
other_exception, // any exception not listed below
|
||||
unregistered_class, // attempt to serialize a pointer of
|
||||
// an unregistered class
|
||||
invalid_signature, // first line of archive does not contain
|
||||
// expected string
|
||||
unsupported_version,// archive created with library version
|
||||
// subsequent to this one
|
||||
pointer_conflict, // an attempt has been made to directly
|
||||
// serialization::detail an object
|
||||
// after having already serialzed the same
|
||||
// object through a pointer. Were this permited,
|
||||
// it the archive load would result in the
|
||||
// creation of an extra copy of the obect.
|
||||
// serialize an object which has
|
||||
// already been serialized through a pointer.
|
||||
// Were this permitted, the archive load would result
|
||||
// in the creation of an extra copy of the object.
|
||||
incompatible_native_format, // attempt to read native binary format
|
||||
// on incompatible platform
|
||||
array_size_too_short,// array being loaded doesn't fit in array allocated
|
||||
stream_error, // i/o error on stream
|
||||
input_stream_error, // error on input 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
|
||||
unregistered_cast, // base - derived relationship not registered with
|
||||
// void_cast_register
|
||||
unsupported_class_version, // type saved with a version # greater than the
|
||||
// one used by the program. This indicates that the program
|
||||
// needs to be rebuilt.
|
||||
multiple_code_instantiation, // code for implementing serialization for some
|
||||
// type has been instantiated in more than one module.
|
||||
output_stream_error // error on input stream
|
||||
} exception_code;
|
||||
exception_code code;
|
||||
archive_exception(exception_code c) :
|
||||
code(c)
|
||||
{}
|
||||
virtual const char *what( ) const throw( )
|
||||
{
|
||||
const char *msg = "programming error";
|
||||
switch(code){
|
||||
case no_exception:
|
||||
msg = "uninitialized exception";
|
||||
break;
|
||||
case unregistered_class:
|
||||
msg = "unregistered class";
|
||||
break;
|
||||
case invalid_signature:
|
||||
msg = "invalid signature";
|
||||
break;
|
||||
case unsupported_version:
|
||||
msg = "unsupported version";
|
||||
break;
|
||||
case pointer_conflict:
|
||||
msg = "pointer conflict";
|
||||
break;
|
||||
case incompatible_native_format:
|
||||
msg = "incompatible native format";
|
||||
break;
|
||||
case array_size_too_short:
|
||||
msg = "array size too short";
|
||||
break;
|
||||
case stream_error:
|
||||
msg = "stream error";
|
||||
break;
|
||||
case invalid_class_name:
|
||||
msg = "class name too long";
|
||||
break;
|
||||
case unregistered_cast:
|
||||
msg = "unregistered void cast";
|
||||
break;
|
||||
case other_exception:
|
||||
// if get here - it indicates a derived exception
|
||||
// was sliced by passing by value in catch
|
||||
msg = "unknown derived exception";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
protected:
|
||||
archive_exception() :
|
||||
code(no_exception)
|
||||
{}
|
||||
|
||||
BOOST_ARCHIVE_DECL archive_exception(
|
||||
exception_code c,
|
||||
const char * e1 = NULL,
|
||||
const char * e2 = NULL
|
||||
) BOOST_NOEXCEPT;
|
||||
BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT;
|
||||
BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE;
|
||||
BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE;
|
||||
};
|
||||
|
||||
}// namespace archive
|
||||
}// namespace boost
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user