Compare commits

..

56 Commits

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

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

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

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

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


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


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


[SVN r40659]
2007-11-01 20:24:02 +00:00
Robert Ramey f3732264e0 First implementation of thread safe lock free serialization
[SVN r40564]
2007-10-29 20:21:48 +00:00
Robert Ramey d92443b5ff First implementation of thread safe lock free serialization
[SVN r40562]
2007-10-29 19:49:44 +00:00
Robert Ramey 4af2f08941 First implementation of thread safe lock free serialization
[SVN r40561]
2007-10-29 19:47:00 +00:00
Robert Ramey 1208a26e01 First implementation of thread safe lock free serialization
[SVN r40560]
2007-10-29 19:37:09 +00:00
Robert Ramey 9922f32456 First implementation of thread safe lock free serialization
[SVN r40559]
2007-10-29 19:32:22 +00:00
Robert Ramey 714480207b improvements to extended type info system - unfortunately, these break the export.
[SVN r39570]
2007-09-27 04:46:21 +00:00
Robert Ramey 9b64c5cd8f improvements to extended type info system - unfortunately, these break the export.
[SVN r39569]
2007-09-27 04:44:15 +00:00
Robert Ramey ca5be78419 improvements to extended type info system - unfortunately, these break the export.
[SVN r39568]
2007-09-27 04:10:56 +00:00
Robert Ramey c3eed9577f improvements to extended type info system - unfortunately, these break the export.
[SVN r39567]
2007-09-27 04:09:17 +00:00
Robert Ramey 20bd5c3f97 improvements to extended type info system - unfortunately, these break the export.
[SVN r39566]
2007-09-27 04:05:25 +00:00
Robert Ramey 12af6786c1 improvements to extended type info system - unfortunately, these break the export.
[SVN r39565]
2007-09-27 04:03:05 +00:00
Robert Ramey bcd23ebc87 improvements to extended type info system - unfortunately, these break the export.
[SVN r39564]
2007-09-27 04:01:51 +00:00
Robert Ramey c8945462d8 improvements to extended type info system - unfortunately, these break the export.
[SVN r39562]
2007-09-27 01:53:46 +00:00
Robert Ramey c756fe1067 included helper for shared_ptr serialization
[SVN r38733]
2007-08-16 22:38:18 +00:00
Robert Ramey 13d6ea1156 initial checkin
[SVN r38701]
2007-08-15 20:09:24 +00:00
Robert Ramey aa1ba652be common jam stuff for all tests
[SVN r38700]
2007-08-15 19:33:23 +00:00
Robert Ramey 785318bf61 Cumulative changes made during release of 1.34
[SVN r38699]
2007-08-15 19:19:55 +00:00
Robert Ramey 85f769a6e8 Changes made over the course of the year while 1.34 was being worked on
[SVN r38698]
2007-08-15 18:56:04 +00:00
Robert Ramey 3e9b235481 Changes made over the course of the year while 1.34 was being worked on
[SVN r38697]
2007-08-15 18:52:50 +00:00
Robert Ramey 0fa5bef020 Changes made over the course of the year while 1.34 was being worked on
[SVN r38696]
2007-08-15 18:49:43 +00:00
Robert Ramey b1aadada54 Changes made over the course of the year while 1.34 was being worked on
[SVN r38693]
2007-08-15 18:33:11 +00:00
Robert Ramey 6af53e0732 Create branch for next serialization release
[SVN r38613]
2007-08-13 03:23:47 +00:00
667 changed files with 110188 additions and 39119 deletions
-28
View File
@@ -1,28 +0,0 @@
# 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")
-37
View File
@@ -1,37 +0,0 @@
#!/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
-651
View File
@@ -1,651 +0,0 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
merge_group:
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-7
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "11,14,17,2a"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-10-multilib
address-model: 32,64
- toolset: gcc-11
cxxstd: "11,14,17,20"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-11-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-12-multilib
address-model: 32,64
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: g++-13-multilib
address-model: 32,64
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: g++-14-multilib
address-model: 32,64
- toolset: gcc-15
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: g++-15-multilib
address-model: 32,64
- toolset: gcc-16
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: g++-16-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-20
- toolset: clang
compiler: clang++-21
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: clang-21
- toolset: clang
compiler: clang++-22
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:26.04
os: ubuntu-latest
install: clang-22
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-15
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-26
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
defaults:
run:
shell: bash
steps:
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++ curl
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- 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
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
python3 tools/boostdep/depinst/depinst.py -I benchmark --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
- name: Run examples
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
# The demos use fixed temp filenames, so run them serially (-j1)
# to avoid concurrent runs clobbering each other's archive files.
./b2 -j1 libs/$LIBRARY/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: msvc-14.5
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2025-vs2026
- toolset: clang-win
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2025
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2025
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- 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 -I benchmark --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=debug,release embed-manifest-via=linker
- name: Run examples
shell: cmd
run: |
cd ../boost-root
rem The demos use fixed temp filenames, so run them serially (-j1)
rem to avoid concurrent runs clobbering each other's archive files.
b2 -j1 libs/%LIBRARY%/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: macos-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- 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
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
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: macos-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- 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
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
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: macos-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- 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
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
python tools/boostdep/depinst/depinst.py -I benchmark -I example --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- 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%
- name: Use library with add_subdirectory (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use library with add_subdirectory (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- 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%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- name: Install (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Debug
- name: Install (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Release
- name: Use the installed library (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use the installed library (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- 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 -I benchmark -I example --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON ..
- name: Build tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Debug
- name: Run tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Debug
- name: Build tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Release
- name: Run tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Release
-103
View File
@@ -1,103 +0,0 @@
# 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
-413
View File
@@ -1,413 +0,0 @@
# 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
#####################
-124
View File
@@ -1,124 +0,0 @@
# 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::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()
-23
View File
@@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-82
View File
@@ -1,82 +0,0 @@
# 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/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%
-45
View File
@@ -1,45 +0,0 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/array//boost_array
/boost/assert//boost_assert
/boost/config//boost_config
/boost/core//boost_core
/boost/detail//boost_detail
/boost/integer//boost_integer
/boost/io//boost_io
/boost/iterator//boost_iterator
/boost/move//boost_move
/boost/mp11//boost_mp11
/boost/mpl//boost_mpl
/boost/optional//boost_optional
/boost/predef//boost_predef
/boost/preprocessor//boost_preprocessor
/boost/smart_ptr//boost_smart_ptr
/boost/spirit//boost_spirit
/boost/throw_exception//boost_throw_exception
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility
/boost/variant//boost_variant
/boost/variant2//boost_variant2 ;
project /boost/serialization
: common-requirements
<include>include
;
explicit
[ alias boost_serialization : build//boost_serialization ]
[ alias boost_wserialization : build//boost_wserialization ]
[ alias all : boost_serialization boost_wserialization example test ]
;
call-if : boost-library serialization
: install boost_serialization boost_wserialization
;
+45 -90
View File
@@ -1,71 +1,38 @@
# 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
# 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.
require-b2 5.0.1 ;
import-search /boost/config/checks ;
import config : requires ;
constant boost_dependencies_private :
/boost/function//boost_function
;
project
project boost/serialization
: source-location ../src
: common-requirements <library>$(boost_dependencies)
: requirements
<conditional>@include-spirit
<library>$(boost_dependencies_private)
: usage-requirements
<define>BOOST_SERIALIZATION_NO_LIB=1
: requirements <dependency>../../config/test//BOOST_NO_STD_LOCALE
: usage-requirements <dependency>../../config/test//BOOST_NO_STD_LOCALE
;
SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
rule include-spirit ( properties * )
{
local 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 ;
for local tset in borland { # vc iw
if ( <toolset>$(tset) in $(properties) ) {
if ( $(SPIRIT_ROOT) ) {
# note - we can't use <include>$(SPIRIT_ROOT) because
# it puts -I$(SPIRIT_ROOT) AFTER the "../../.." in the command line.
# so use these instead
result = <cxxflags>-I$(SPIRIT_ROOT) ;
}
else {
echo **** spirit 1.6x required to build library with this compiler **** ;
result = <build>no ;
}
}
}
return $(result) ;
}
SOURCES =
archive_exception
SOURCES =
basic_archive
basic_iarchive
basic_iserializer
@@ -87,58 +54,46 @@ SOURCES =
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 =
WSOURCES =
basic_text_wiprimitive
basic_text_woprimitive
binary_wiarchive
binary_woarchive
text_wiarchive
text_woarchive
polymorphic_text_wiarchive
polymorphic_text_woarchive
utf8_codecvt_facet
xml_wgrammar
xml_wiarchive
xml_woarchive
polymorphic_xml_wiarchive
polymorphic_xml_woarchive
codecvt_null
;
lib boost_serialization
: ## sources ##
$(SOURCES).cpp
: ## requirements ##
[ check-target-builds /boost/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
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
lib boost_wserialization
: $(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
# 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
;
lib boost_serialization
: $(SOURCES).cpp
:
<toolset>msvc:<cxxflags>/Gy
<toolset>msvc-6.5:<conditional>@include-spirit
<toolset>msvc-7.0:<conditional>@include-spirit
<toolset>borland:<conditional>@include-spirit
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
lib boost_wserialization
: $(WSOURCES).cpp boost_serialization
:
<toolset>msvc:<cxxflags>/Gy
<toolset>msvc-6.5:<conditional>@include-spirit
<toolset>msvc-7.0:<conditional>@include-spirit
<toolset>borland:<conditional>@include-spirit
<dependency>../../config/test//BOOST_NO_STD_WSTREAMBUF
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
;
boost-install boost_serialization boost_wserialization ;
+13 -20
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -27,36 +27,30 @@ 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 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&ouml;pflin tracked down issues with TRU64 compiler resulting in 100% passing.
<li>Markus Schöpflin tracked down issues with TRU64 compiler resulting in 100% passing.
<li><a href="mailto::troy@resophonic.com"> Troy D. Straszheim</a> made the initial version of variant serialization.
<li>Tonko Juricic helped refine and complete project files for VC 7.1 ide
<li><a href="http://www.boost.org/people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
<li><a href="../../../people/rene_rivera.htm">Rene Rivera</a> tracked down several issues related to
Code Warrior, toolset configuration and bjam and much else.
<li>Martin Ecker detected (and fixed!) a number of subtle errors regarding cyclic
<li>Martin Ecker detected (and fixed!) a number of sublte errors regarding cyclic
pointers, shared pointers. He also built the library as a DLL and raised some issues
<li>Pavel Vozenilek invested much effort in review of code and documentation
resulting in many improvements. In addition he helped a lot with porting to other
resulting in many improvements. In addition he help a lot with porting to other
platforms including VC 6.0, Intel, and especially Borland.
<li><a href="http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a> and
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> who got the boost
<li><a href="../../../people/jens_maurer.htm">Jens Maurer</a> and
<a href="../../../people/beman_dawes.html">Beman Dawes</a> who got the boost
serialization ball rolling. It was one or both of these two that invented
the much beloved <code>&amp;</code> syntax used to implement both save and
load in one function specification.
<li><a href="http://www.boost.org/people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
load in one fuction specification.
<li><a href="../../../people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
early draft and contributing the diamond inheritance example.
<li><a href="http://www.boost.org/people/william_kempf.htm">William E. Kempf</a>
<li><a href="../../../people/william_kempf.htm">William E. Kempf</a>
who made the templates for this and other boost manuals. This relieved
me of much aggravation.
<li><a href="mailto:vahan@unicad.am">Vahan Margaryan</a> and
@@ -76,11 +70,10 @@ 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 led to a re-thinking
<li>Dave Harris proposal and spirited defense of it lead 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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
+111 -130
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
(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>
@@ -26,96 +26,75 @@ http://www.boost.org/LICENSE_1_0.txt)
</table>
<hr>
<dl class="page-index">
<dt><a href="#trivial">Trivial Archive</a>
<dt><a href="#implementation">More Useful Archive Classes</a>
<dt><a href="#implementation">Implementation</a>
<dt><a href="#usage">Usage</a>
<dt><a href="#testing">Testing</a>
<dt><a href="#polymorphic">Polymorphic Archives</a>
</dl>
<h3><a name="trivial">Trivial Archive</a></h3>
<h3><a name="implementation">Implementation</a></h3>
The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
class must implement 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 &lt;cstddef&gt; // std::size_t
//////////////////////////////////////////////////////////////
// class trivial_oarchive
class trivial_oarchive {
public:
//////////////////////////////////////////////////////////
// public interface used by programs that use the
// serialization library
typedef boost::mpl::bool_&lt;true&gt; is_saving;
typedef boost::mpl::bool_&lt;false&gt; is_loading;
template&lt;class T&gt; void register_type(){}
template&lt;class T&gt; trivial_oarchive &amp; operator&lt;&lt;(const T &amp; t){
return *this;
}
template&lt;class T&gt; trivial_oarchive &amp; operator&amp;(const T &amp; t){
return *this &lt;&lt; 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.
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.
<p>
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
Our archives have been factored in to a tree of classes in order to minimize
repetition of code. This is shown in the accompanying
<a target="class_diagram" href="class_diagram.html">class diagram</a>.
All input archives should be derived from the following template:
<pre><code>
template&lt;class Archive&gt;
detail::common_iarchive;
</code></pre>
<h4>Minimum Requirments</h4>
An instance of the this template handles all the "bookkeeping" associated
with serialization. In order to be a functional only the following additional
functions <strong>must</strong> be 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>
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.
<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:
<pre><code>
<a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
#include &lt;cstddef&gt; // std::size_t
#include &lt;boost/archive/detail/common_oarchive.hpp&gt;
<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
#include &lt;boost/archive/detail/common_iarchive.hpp&gt;
</a>
/////////////////////////////////////////////////////////////////////////
// class complete_oarchive
class complete_oarchive :
public boost::archive::detail::common_oarchive&lt;complete_oarchive&gt;
{
// permit serialization system privileged access to permit
// implementation of inline templates for maximum speed.
friend class boost::archive::save_access;
// member template for saving primitive types.
// Specialize for any types/templates that require special treatment
/////////////////////////////////////////////////////////////////////////
// class trivial_iarchive - read serialized objects from a input text stream
class trivial_iarchive :
public boost::archive::detail::common_iarchive&lt;trivial_iarchive&gt;
{
// permit serialization system priviledged access to permit
// implementation of inline templates for maximum speed.
friend class boost::archive::load_access;
// member template for loading primitive types.
// Override for any types/templates that special treatment
template&lt;class T&gt;
void save(T &amp; t);
void load(T &amp; t);
public:
//////////////////////////////////////////////////////////
@@ -123,32 +102,36 @@ public:
// serialization library
// archives are expected to support this function
void save_binary(void *address, std::size_t count);
void load_binary(void *address, std::size_t count);
};
</code></pre>
Given a suitable definitions of <code style="white-space: normal">save</code>
and <code style="white-space: normal">save_binary</code>,
</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>,
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_oarchive</code> class contains
The <code style="white-space: normal">detail::common_iarchive</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 save_start(char const *)</code></h4></dt>
<dt><h4><code>void load_start()</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 "&lt;name&gt;" before data.
by XML archive to inject "&lt;name " before data.
</dd>
<p>
<dt><h4><code>void save_end(char const *)</code></h4></dt>
<dt><h4><code>void load_end()</code></h4></dt>
<dd>
<strong>Default</strong>:Does nothing.<br>
<strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
@@ -160,28 +143,33 @@ by XML archive to inject "&lt;/name&gt;" after data.
<dd>
<strong>Default</strong>:Does nothing.<br>
<strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
It's not called when archive bookkeeping data is saved. This is used by XML archives
to determine when to inject a "&gt;" character at the end of an XML header. XML output archives
Its not called when archive book keeping data is saved. This is used by XML archives
to determine when to inject a "&gt;" character at end of XML header. XML output archives
keep their own internal flag indicating that data being written is header data. This
internal flag is reset when an object start tag is written. When
<code style="white-space: normal">void end_preamble()</code> is invoked and this internal flag is set
a "&gt;" 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 thereby permitting it
implementation for <code style="white-space: normal">void end_preamble()</code> is a no-op there by permitting it
to be optimised away for archive classes that don't use it.
</dd>
<p>
<dt><h4><code>
template&lt;class T&gt;
void save_override(T &amp; t, int);
void load_override(T & t, int);
</code></h4></dt>
<dd>
<strong>Default</strong>:Invokes <code style="white-space: normal">archive::save(Archive &amp; ar, t)</code><br>
<strong>Default</strong>:Invokes <code style="white-space: normal">archive::load(Archive & ar, t)</code><br>
This is the main entry into the serialization library.<br>
<strong>Purpose</strong>:This can be specialized in cases where the data is to be written
<strong>Purpose</strong>:This can be overridden 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>
@@ -190,14 +178,14 @@ with one appropriate for XML which writes out the start of an XML tag with the c
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 save_override(T &amp; t, int);</code>.
implementation of <code style="white-space: normal">void load_override(T & t, int);</code>.
For example, in the XML archive, the override for this type renders an object_id equal to 23 as
"object_id=_23". The following table lists the types 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>serialized as</code></th>
<tr><th align=left>type</th><th align=left><code style="white-space: normal">default<br>serialed 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>
@@ -209,7 +197,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">save_override</code>
so it isn't a requirement to define <code style="white-space: normal">load_override</code>
for these types.
<p>
These are defined in
@@ -226,13 +214,18 @@ 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 &lt;name ... &gt;...&lt;/name&gt; surrounding
all data objects.
<li>Addressing any of the above may generate more issues to be addressed.
<li>The archives included with the library are all templates which use a
<li>The archives included with library are all templates which use a
<code style="white-space: normal">stream</code> or
<code style="white-space: normal">streambuf</code>
as a template parameter rather than simple classes.
@@ -250,14 +243,14 @@ 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">BOOST_CLASS_EXPORT</code> is used
is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used
to instantiate the serialization code for the included archives.
</ul>
To make this work, the following should be included after the archive
class definition.
<pre><code>
BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
</code></pre>
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
@@ -267,19 +260,21 @@ will throw an
exception.
<p>
<h4><a name="testing">Testing</h4>
Exhaustive testing of the library requires testing the different aspects of object
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).
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).
<p>
In addition, there are 28 other tests which aren't related to any particular archive class.
In addition, there are 22 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 46 archive tests * 5
standard archives + 28 general tests = 258 tests. Note that a complete test of the
the above described tests. This will result in as many as 39 archive tests * 5
standard archives + 25 general tests = 220 tests. Note that a complete test of the
library would include DLL vs static library, release vs debug so the actual total
would be closer to 1032 tests.
would be closer to 880 tests.
<p>
For each archive there is a header file in the test directory similar to the one below.
The name of this archive is passed to the test program by setting the
@@ -323,7 +318,7 @@ library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
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 circumstances, a good optimizing compiler that can expand
Under these cirumstances, a good optimizing compiler that can expand
<code>inline</code> functions to enough depth will generate fast code.
However:
<ul>
@@ -344,7 +339,7 @@ each time a new archive class is created.
</ul>
<h4>Implementation</h4>
The solution is the pair <code>polymorphic_oarchive</code>
The solution is the 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.
@@ -361,7 +356,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. This even applies to archives classes
only have to be compiled once for all archive implementations. The 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.
@@ -373,13 +368,12 @@ interface and the standard template driven implementation. This composition is
accomplished by the templates
<a target=polymorphic_iarchive_route_hpp href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp"><code style="white-space: normal">polymorphic_iarchive_route.hpp</code></a>
and
<a target=polymorphic_oarchive_route_hpp href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp"><code style="white-space: normal">polymorphic_oarchive_route.hpp</code></a>
which redirect calls to the polymorphic archives to the specific archive.
<a target=polymorphic_oarchive_route_hpp href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp"><code style="white-space: normal">polymorphic_oarchive_route.hpp</code></a>.
As these contain no code specific to the particular implementation archive, they can be used to create
a polymorphic archive implementation from any functioning templated archive implementation.
<p>
As a convenience, small header files have been included which contain
a <code style="white-space: normal">typedef</code> for a polymorphic implementation for each corresponding
<code style="white-space: normal">typedef</code> for 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
@@ -390,29 +384,16 @@ 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>
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
The main utility of polymorphic archives will be to permit the buiding of class DLLs that will
include serialization code for all present and future archives with no redundant code.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
+30 -56
View File
@@ -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><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>.
<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
corresponding to an arbitrary set of C++ data structures. Each type modeling the
correpsonding to an arbitrary set of C++ data structures. Each type modeling the
Saving Archive concept (SA) may be associated with another type modeling the
<a href="#loading_interface">Loading Archive Concept</a>(LA).
This associated type will perform the inverse operation.
That is, given a sequence of bytes generated by SA, it will generate a set of
C++ data structures that is equivalent to the original.
C++ data structures the is equivalent to the original.
The notion of equivalence is defined by the implementations of the pair of archives and the
way the data are rendered <a href="serialization.html">serializable</a>.
way the data is are rendered <a href="serialization.html">serializable</a>.
<p>
<h4>Valid Expressions</h4>
<dl>
@@ -102,7 +102,7 @@ way the data 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.get_library_version()
sa.library_version()
</code></h4></dt>
<dd>
Returns an unsigned integer containing the current version number of the serialization
@@ -112,14 +112,6 @@ way the data 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&lt;Helper&gt;(void * const helper_instance_id = 0)
</code></h4></dt>
<dd>
See <code>la.get_helper&lt;Helper&gt;(void * const helper_instance_id = 0)</code>
below.
</dd>
</dl>
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
@@ -180,7 +172,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.get_library_version()
la.library_version()
</code></h4></dt>
<dd>
Returns an unsigned integer containing the version number of the serialization
@@ -190,24 +182,6 @@ 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&lt;Helper&gt;(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&lt;Helper&gt;(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&lt;Helper&gt;(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>
@@ -216,8 +190,8 @@ equivalent to the original.
moved to address v.
<p>
When an object is loaded to a temporary variable and later moved to another location,
this function must be called in order communicate this fact. This permits the
archive to properly implement object tracking. Object tracking is required in order
This function must be called in order communicate this fact. This is permits the
the archive to properly implement object tracking. Object tracking is required in order
to correctly implement serialization of pointers to instances of derived classes.
</dd>
<dt><h4><code>
@@ -232,7 +206,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, specification of serialization is exactly the same
the same public interface, specifcation 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
@@ -241,7 +215,7 @@ archives is discussed in
<p>
The existence of the <code style="white-space: normal">&lt;&lt;</code>
and <code style="white-space: normal">&gt;&gt;</code> suggests
and <code style="white-space: normal">&gt;&gt;</code> suggest
a relationship between archives and C++ i/o streams. <strong>Archives are not
C++ i/o streams</strong>. All the archives included with this system take a stream
as an argument in the constructor and that stream is used for output or input.
@@ -250,7 +224,7 @@ archive interface. It just turns out that the archives written so far have
found it useful to base their implementation on streams.
<h3><a name="archive_models">Archive Models</a></h3>
This library includes various implementations of the Archive concept.
This library includes a various implementation of the Archive concept.
An archive is defined by two complementary classes. One is for saving data while
the other is for loading it.
@@ -292,7 +266,7 @@ included in the code module containing the serialization code.
</code></pre>
All of these archives implement the same interface. Hence, it should suffice to describe only one
All of these archives implement the same inteface. Hence, it should suffice to describe only one
of them in detail. For this purpose we will use the text archive.
@@ -303,7 +277,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 - ignored on saving
no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
};
} // archive
@@ -319,7 +293,7 @@ class text_oarchive : ...
...
public:
... // implementation of the <strong>Saving Archive</strong> concept
text_oarchive(std::ostream &amp; os, unsigned int flags = 0);
text_oarchive(std::ostream & os, unsigned int flags = 0);
~text_oarchive();
};
@@ -330,10 +304,10 @@ public:
<dl>
<dt><h4><code>
text_oarchive(std::ostream &amp; os, unsigned int flags = 0);
text_oarchive(std::ostream & os, unsigned int flags = 0);
</code></h4></dt>
<dd>
Constructs an archive given an open <code style="white-space: normal">stream</code> as
Contructs an archive given an open <code style="white-space: normal">stream</code> as
an argument and optional flags. For most applications there will be no need to use flags.
Flags are defined by <code style="white-space: normal">enum archive_flags</code> enumerator.
Multiple flags can be combined with the <code style="white-space: normal">|</code> operator.
@@ -343,7 +317,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 endianness to gracefully handle the case where it has been
sizes of native types and endianess to gracefully handle the case where it has been
erroneously assumed that such an archive is portable across platforms. In some cases,
where this extra overhead might be considered objectionable, it can be suppressed with the
<code style="white-space: normal">no_header</code> flag.
@@ -365,7 +339,7 @@ tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
<dd>
Destructor for an archive. This should be called before the stream is
closed. It restores any altered stream facets to their state before the
archive was opened.
the archive was opened.
</dd>
</dl>
@@ -379,7 +353,7 @@ class text_iarchive : ...
...
public:
... // implementation of the <strong>Loading Archive</strong> concept
text_iarchive(std::istream &amp; is, unsigned int flags = 0);
text_iarchive(std::istream & is, unsigned int flags = 0);
~text_iarchive();
};
@@ -391,10 +365,10 @@ public:
<dl>
<dt><h4><code>
text_iarchive(std::istream &amp; is, unsigned int flags = 0);
text_iarchive(std::istream & is, unsigned int flags = 0);
</code></h4></dt>
<dd>
Constructs an archive given an open <code style="white-space: normal">stream</code> as
Contructs an archive given an open <code style="white-space: normal">stream</code> as
an argument and optional flags. 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.
@@ -405,7 +379,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 their state before the
closed. It restores any altered stream facets to thier state before the
the archive was opened.
</dd>
</dl>
@@ -418,22 +392,22 @@ to the common class interface described above, they include the following
constructors:
<dl>
<dt><h4><code>
binary_oarchive(std::streambuf &amp; 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 &amp; 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 thrown can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
be throw can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
of this documentation.
<h3><a name="charactersets">Character Sets</h3>
This library includes two archive classes for XML. The wide character
version (<code style="white-space: normal">xml_w?archive</code>) renders its output as UTF-8 which can
version (<code style="white-space: normal">xml_w?archive</code>) renders it output as UTF-8 which can
handle any wide character without loss of information.
<code style="white-space: normal">std::string</code> data is converted from multi-byte format to wide
character format using the current <code style="white-space: normal">
+6 -7
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -36,23 +36,22 @@ 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 &amp; 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 Language</u>, Addison-Wesley, 1997
<li>Bjarne Stroustrup, <u>The C++ Programming Langage</u>, Addison-Wesley, 1997
<a name="7"></a>
<li>Alexandrescu, Andrei, <u>Modern C++ Design</u>, Addison-Wesley, 2001
<a name="8"></a>
<li>Jim Hyslop, and Herb Sutter, "Factory Redux, Part2",
<li>Jm 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, "Pimpls--Beauty Marks You Can Depend On",
<li>Herb Sutter, "Pimples--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",
@@ -63,7 +62,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>Vandevoorde and Josuttis, <b>C++ Templates - A Complete Guide</b>, Addison-Wesley, 2003</a>
<li>Vandervoorde and Josuttis, <b>C++ Templates - A Complete Guide</b>, Addison-Wesley, 2003</a>
</ol>
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
+39 -39
View File
@@ -1,8 +1,8 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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)
-->
<html>
@@ -29,136 +29,136 @@ http://www.boost.org/LICENSE_1_0.txt)
<pre><code>
basic_oarchive <a href="../../../boost/archive/detail/basic_oarchive.hpp">-&gt;</a>
basic_iarchive <a href="../../../boost/archive/detail/basic_iarchive.hpp">-></a>
|
|
| interface_oarchive&lt;text_oarchive&gt; <a href="../../../boost/archive/detail/interface_oarchive.hpp">-&gt;</a>
| interface_iarchive&lt;text_iarchive&gt; <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
| /
| /
| _________/
| /
| /
| /
common_oarchive&lt;text_oarchive&gt; <a href="../../../boost/archive/detail/common_oarchive.hpp">-&gt;</a>
common_iarchive&lt;text_iarchive&gt; <a href="../../../boost/archive/detail/common_iarchive.hpp">-></a>
|
|
<font color="blue">basic_text_oarchive&lt;text_oarchive&gt;</font> <a href="../../../boost/archive/basic_text_oarchive.hpp">-&gt;</a>
<font color="blue">basic_text_iarchive&lt;text_iarchive&gt;</font> <a href="../../../boost/archive/basic_text_iarchive.hpp">-></a>
|
|
| <font color="blue">basic_text_oprimitive&lt;basic_ostream&gt;</font> <a href="../../../boost/archive/basic_text_oprimitive.hpp">-&gt;</a>
| <font color="blue">basic_text_iprimitive&lt;basic_istream&gt;</font> <a href="../../../boost/archive/basic_text_iprimitive.hpp">-></a>
| /
| /
| _________/ interface_oarchive&lt;polymorphic_oarchive&gt; <a href="../../../boost/archive/detail/interface_oarchive.hpp">-&gt;</a>
| _________/ interface_iarchive&lt;polymorphic_iarchive&gt; <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
| / |
| / |
| / |
<font color="blue">text_oarchive_impl&lt;text_oarchive&gt;</font> <a href="../../../boost/archive/text_oarchive.hpp">-&gt;</a> polymorphic_oarchive_impl <a href="../../../boost/archive/polymorphic_oarchive.hpp">-&gt;</a>
<font color="blue">text_iarchive_impl&lt;text_iarchive&gt;</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_impl <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
| \ |
| \ |
| \_____________________________________ <font color="red">polymorphic_oarchive</font> <a href="../../../boost/archive/polymorphic_oarchive.hpp">-&gt;</a>
| \_____________________________________ <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
| \ /
| \ /
| \ /
<font color="red">text_oarchive</font> <a href="../../../boost/archive/text_oarchive.hpp">-&gt;</a> polymorphic_oarchive_route&lt;text_oarchive_impl&lt;text_oarchive&gt; &gt; <a href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp">-&gt;</a>
<font color="red">text_iarchive</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt; <a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">-></a>
|
|
|
<font color="red">polymorphic_text_oarchive</font> <a href="../../../boost/archive/polymorphic_text_oarchive.hpp">-&gt;</a>
<font color="red">polymorphic_text_iarchive</font> <a href="../../../boost/archive/polymorphic_text_iarchive.hpp">-></a>
</code></pre>
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
This diagram shows the relationship between the various classes that implement loading (input
serialization) for text files. The hierachy and organization is similar for saving and for
other types of archives as well. In the diagram, classes written in <font color="blue">blue</font>
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
implement loading for a given archive type. (in this case its text archives).
Users include classes in <font color="red">red</font> to load their data from a partcular
type of archive. Other classes whose names are in black 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_oarchive.hpp">basic_oarchive</a>
<a href="../../../boost/archive/detail/basic_iarchive.hpp">basic_iarchive</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_oarchive.hpp">interface_oarchive&lt;text_oarchive&gt;</a>
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive&lt;text_iarchive&gt;</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_oarchive</code>
can be used as a base class for <code style="white-space: normal">polymorphic_iarchive</code>
as well as for archive implementations.
<p><dt><code>
<a href="../../../boost/archive/detail/common_oarchive.hpp">common_oarchive&lt;text_oarchive&gt;</a>
<a href="../../../boost/archive/detail/common_iarchive.hpp">common_iarchive&lt;text_iarchive&gt;</a>
</code></dt>
<dd>
The function of this class is to make the connection between the virtual function
interface used by <code>basic_oarchive</code> and the template interface used by archive
interface used by <code>basic_iarchive</code> and the template interface used by archive
class implementations.
<p><dt><code>
<a href="../../../boost/archive/basic_text_oarchive.hpp">basic_text_oarchive&lt;text_oarchive&gt;</a>
<a href="../../../boost/archive/basic_text_iarchive.hpp">basic_text_iarchive&lt;text_iarchive&gt;</a>
</code></dt>
<dd>
Implements the basic functionality for simple text archives. The primitive save functions have been
Implements the basic functionality for simple text archives. The primitive load 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_oprimitive.hpp">basic_text_oprimitive&lt;basic_ostream&gt;</a>
<a href="../../../boost/archive/basic_text_iprimitive.hpp">basic_text_iprimitive&lt;basic_istream&gt;</a>
</code></dt>
<dd>
Implements the save oversaves for all primitive types. This is a template with a parameter
Implements the save overloads for all primitive types. This is a template with a parameter
which describes the stream.
<p><dt><code>
<a href="../../../boost/archive/text_oarchive.hpp">text_oarchive_impl&lt;text_oarchive&gt;</a>
<a href="../../../boost/archive/text_iarchive.hpp">text_iarchive_impl&lt;text_iarchive&gt;</a>
</code></dt>
<dd>
Inherits from the above two classes to implement text archives.
</dd>
<p><dt><code>
<a href="../../../boost/archive/text_oarchive.hpp">text_oarchive</a>
<a href="../../../boost/archive/text_iarchive.hpp">text_iarchive</a>
</code></dt>
<dd>
This is just a short hand for <code style="white-space: normal">text_oarchive_impl&lt;text_oarchive&gt;</code> .
This is just a short hand for <code style="white-space: normal">text_iarchive_impl&lt;text_iarchive&gt;</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_oarchive.hpp">interface_oarchive&lt;polymorphic_oarchive&gt;</a>
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive&lt;polymorphic_iarchive&gt;</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_oarchive</code> uses.
<code style="white-space: normal">common_iarchive</code> uses.
<p><dt><code>
<a href="../../../boost/archive/polymorphic_oarchive.hpp">polymorphic_oarchive</a>
<a href="../../../boost/archive/polymorphic_iarchive.hpp">polymorphic_iarchive</a>
</code></dt>
<dd>
A class with a list of virtual <code style="white-space: normal">save(T &amp;t)</code>
A class with a list of virtual <code style="white-space: normal">load(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_oarchive_route.hpp">polymorphic_oarchive_route&lt;text_oarchive_impl&lt;text_oarchive&gt; &gt;</a>
<a href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp">polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</a>
</code></dt>
<dd><p>
This class implements the <code style="white-space: normal">polymorphic_oarchive</code> in terms of a specific
This class implements the <code style="white-space: normal">polymorphic_iarchive</code> in terms of a specific
concrete class. Virtual function calls are routed to the implementing class. In this example,
that implementing class would be text_oarchive_impl.
that implementing class would be text_iarchive_impl.
<p><dt><code>
<a href="../../../boost/archive/polymorphic_text_oarchive.hpp">polymorphic_text_oarchive</a>
<a href="../../../boost/archive/polymorphic_text_iarchive.hpp">polymorphic_text_iarchive</a>
</code></dt>
<dd>
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&lt;text_oarchive_impl&lt;text_oarchive&gt; &gt;</code>
this is just a typedef so we can write polymorphic_text_archive rather than
<code style="white-space: normal">polymorphic_iarchive_route&lt;text_iarchive_impl&lt;text_iarchive&gt; &gt;</code>
</dl>
<hr>
+2 -2
View File
@@ -42,7 +42,7 @@ template&lt;
<h2>Rationale</h2>
UTF-8 is a method of encoding Unicode text in environments
UTF-8 is a method of encoding Unicode text in environments where
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&lt;
<h2>Requirements</h2>
<tt>utf8_codecvt_facet</tt> defaults to using <tt>char</tt> as
its external data type and <tt>wchar_t</tt> as its internal
it's external data type and <tt>wchar_t</tt> as it's 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>
+2 -2
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
+213 -241
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -83,261 +83,233 @@ function initialize() {
<img src="dot.gif" onclick="collapse_all()">Collapse All
-->
<p>
<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>
<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_35">Differences from version 1.35</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_34">Differences from version 1.34</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_32">Differences from version 1.32</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_33">Differences from version 1.33</a></dt>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#todo">Pending Issues</a></dt>
</dl></div></dd>
<dt><img style="display:none" src="plus.gif" id="overview"><a target="detail" href="overview.html">Overview</a></dt>
<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>
</dl></div></dd>
<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>
<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="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>
<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#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>
<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>
</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>
<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="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>
<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="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#dlls">DLLS - Serialization and Runtime Linking</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#plugins">Plugins</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#multi_threading">Multi-Threading</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#optimizations">Optimzations</a>
<dt><img style="display:none" src="plus.gif" id="exceptions"><a target="detail" href="exceptions.html">Archive Exceptions</a>
<dd><div id="exceptions_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_class"><code>unregistered_class</code></a>
<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="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>
<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="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>
<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>
</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&lt;class T&gt;</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr&lt;class T&gt;</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>
<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&lt;class T&gt;</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr&lt;class T&gt;</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="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>
<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="factory.html"><code>BOOST_SERIALIZATION_FACTORY</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html"><code>utf8_codecvt_facet</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
<dt><img style="display:none" src="plus.gif" id="singleton"><a target="detail" href="singleton.html"><code>singleton</code></a>
<dd><div id="singleton_detail"><dl class="page-index">
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#motivation">Motivation</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#features">Features</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#classinterface">Class Interface</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#requirements">Requirements</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#examples">Examples</a>
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#multithreading">Multi-Threading</a>
</dl></div></dd>
</dl></div></dd>
</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="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>
<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>
</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="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>
+26 -12
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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 use this composite as a new component somewhere else.
<li>Composable. so we can used 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 it interesting to
The fundamental feature of an Iterator Adaptor template that makes in 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&lt; // insert line breaks every 76 characters
base64_from_binary&lt; // convert binary values to base64 characters
insert_linebreaks&lt; // insert line breaks every 72 characters
base64_from_binary&lt; // convert binary values ot base64 characters
transform_width&lt; // retrieve 6 bit integers from a sequence of 8 bit bytes
const char *,
6,
8
&gt;
&gt;
,76
,72
&gt;
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 =&gt; base64 code.
<h3>Dataflow Iterators</h3>
Unfortunately, not all iterators which inherit from Iterator Adaptors are guaranteed
Unfortunately, not all iterators which inherit from Iterator Adaptors are guarenteed
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 a small set of additional requirements.
fulfills as a small set of additional requirements.
<h4>Templated Constructors</h4>
<p>
@@ -110,8 +110,22 @@ 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 using
However, I believe these are unwieldy to use compared to the above solution usiing
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&lt;char&gt;(os)
);
</code></pre>
This macro is defined in <a target="pfto" href="../../../boost/pfto.hpp">&lt;boost/pfto.hpp&gt;</a>.
For more information about this topic, check the source.
<h4>Dereferencing</h4>
Dereferencing some iterators can cause problems. For example, a natural
@@ -135,7 +149,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 namespace
Dataflow iterators for the serialization library are all defined in the hamespace
<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">
@@ -181,7 +195,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
conflicts with the standard library versions.
conflict the standard library version.
<dl class = "index">
<dt><a target="istream_iterator" href="../../../boost/archive/iterators/istream_iterator.hpp">
istream_iterator</a></dt>
+2 -2
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
+67 -56
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -26,48 +26,42 @@ 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>
<h3>Log Archive</h3>
<a name=portable_archives>
<h3>Portable Binary Archives</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_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
<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.
<ol>
<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>
<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>
As described in the comments in
<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&lt;xml_oarchive&gt;</code>. So we should derive
from <code style="white-space: normal">xml_oarchive_impl&lt;log_archive&gt;</code> rather
than <code style="white-space: normal">xml_oarchive</code>.
<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&lt;binary_oarchive&gt;</code>. So we should derive
from <code style="white-space: normal">binary_oarchive_impl&lt;portable_binary_oarchive&gt;</code> rather
than <code style="white-space: normal">binary_oarchive</code>.
<pre><code>
class log_archive :
// don't derive from xml_oarchive !!!
public xml_oarchive_impl&lt;log_archive&gt;
class portable_binary_oarchive :
// don't derive from binary_oarchive !!!
public binary_oarchive_impl&lt;portable_binary_oarchive&gt;
{
...
</code></pre>
<li><i>Note the</i> <code style="white-space: normal">log_archive</code> <i>between the</i> &lt;&gt;
<li><i>Note the</i> <code style="white-space: normal">portable_binary_oarchive</code> <i>between the</i> &lt;&gt;
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>.
@@ -76,21 +70,24 @@ 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>
friend class detail::common_oarchive&lt;log_archive&gt;;
friend class basic_xml_oarchive&lt;log_archive&gt;;
typedef portable_binary_oarchive derived_t;
friend class detail::common_oarchive&lt;derived_t&gt;;
friend class basic_binary_oarchive&lt;derived_t&gt;;
friend class basic_binary_oprimitive&lt;
derived_t,
std::ostream::char_type,
std::ostream::traits_type
&gt;;
friend class boost::serialization::save_access;
</code></pre>
<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
<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
"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 xml_oarchive_impl&lt;derived_t&gt;::save;
using binary_oarchive_impl&lt;derived_t&gt;::save;
void save(const unsigned int t);
...
</code></pre>
@@ -99,14 +96,14 @@ that the following equivalent works on more compilers.
<pre><code>
// default fall through for any types not specified here
template&lt;class T&gt;
void save(const T &amp; t){
xml_oarchive_impl&lt;derived_t&gt;::save(t);
void save(const T & t){
binary_oarchive_impl&lt;derived_t&gt;::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 explicitly instantiated.</i>
<li><i>Template definitions of base classes may have to be included.</i>
The demo includes
<pre><code>
// explicitly instantiate for this type of binary stream
@@ -114,34 +111,48 @@ 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">xml_oarchive</code>.
it would have to be reorganized along the lines of the original <code style="white-space: normal">binary_oarchive</code>.
Specifically, it would look something like:
<pre><code>
template&lt;class Archive&gt;
class log_archive_impl :
// don't derive from xml_oarchive !!!
public xml_oarchive_impl&lt;Archive&gt;
class portable_binary_oarchive_impl :
// don't derive from binary_oarchive !!!
public binary_oarchive_impl&lt;Archive&gt;
{
...
};
);
// do not derive from this class !!!
class log_archive :
public log_archive_impl&lt;log_archive&gt;
// do not derived from this class !!!
class portable_binary_oarchive :
public portable_binary_oarchive_impl&lt;portable_binary_oarchive&gt;
{
public:
log_archive(std::ostream &amp; os, unsigned int flags = 0) :
log_archive_impl&lt;xml_oarchive&gt;(os, flags)
portable_binary_oarchive(std::ostream & os, unsigned int flags = 0) :
portable_binary_oarchive_impl&lt;binary_oarchive&gt;(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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
Distributed under the Boost Software License, Version 1.0. (See
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 846 B

After

Width:  |  Height:  |  Size: 838 B

+4 -4
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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 other action, objects created in
created by the class load. Without out 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
+26 -52
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -29,15 +29,12 @@ 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="#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="#stream_error"><code style="white-space: normal">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>
@@ -57,7 +54,7 @@ class archive_exception : public std::exception
{
public:
typedef enum {
unregistered_class, // attempt to serialize a pointer of
unregistered_class, // attempt to serialize a pointer of an
// an unregistered class
invalid_signature, // first line of archive does not contain
// expected string
@@ -66,23 +63,17 @@ 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,
// the archive load would result in the creation
// of an extraneous object.
// it the archive load would result in the creation
// of 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
input_stream_error // error on stream input
stream_error // i/o error on stream
invalid_class_name, // class name greater than the maximum permitted.
// most likely a corrupted archive or an attempt
// to insert virus via buffer overrun method.
unregistered_cast, // base - derived relationship not registered with
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) {}
@@ -109,7 +100,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 whose class name has not been added to the system with the
when using a new archive how 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>
@@ -118,10 +109,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 records the current library version number to all archives created. Note that this is in
This system assigns a version number of 2 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 a previous
of this serialization system will be able to identify archives created under 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
@@ -129,35 +120,27 @@ 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&lt;class Archive&gt;
void T::save(Archive &amp;ar) const
void T::save(Archive &ar) const
{
const A * aptr = &amp;a;
ar &lt;&lt; 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 &lt;&lt; a; // save an instance of an object of class A
assert(aptr == &amp;a); // this must be true
ar << a; // save an instance of an object of class A
assert(aptr == &a); // this must be true
}
template&lt;class Archive&gt;
void T::load(Archive &amp;ar)
void T::load(Archive &ar)
{
A * aptr;
ar &gt;&gt; aptr; // create and initialize a new instance of class A
ar >> aptr; // create and initialize a new instance of class A
...
ar &gt;&gt; a; // restore state of on object of class A
assert(aptr == &amp;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
@@ -179,12 +162,8 @@ 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="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
<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
situations such as a corrupted or truncated input file, there are
several less obvious ones that sometimes occur.
<p>
@@ -225,7 +204,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 a virus via the buffer overrun method.
archive or an attempt to insert virus via 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
@@ -237,11 +216,6 @@ 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
@@ -250,8 +224,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 the XML attributes and nesting
structure are left unaltered. But any other editing is likely to render the
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
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
@@ -259,7 +233,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 an XML element doesn't match
This exception will be thrown if the start or end tag of and XML element doesn't match
the name specified for the object in the program.
<h3><a name="xml_archive_tag_name_error"><code style="white-space: normal">xml_archive_tag_name_error</code></a></h3>
+64 -160
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -49,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 perceived inefficiency.
or not enabled for reasons such as a percieved inefficiency.
<li>
<code style="white-space: normal">std::type_info</code> includes a string
containing type name. This would seem to satisfy 2) above.
@@ -57,14 +57,14 @@ 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
guarantee that class headers would be included in the same namespace accross
guarentee that class headers would be included in the same name space accross
different applications. In fact, including different headers in different
namespaces is an accepted method used to avoid namespace conflicts.
name spaces is an accepted method used to avoid name space conflicts.
Thus the namespace::class_name can't be used as a key.
<li>
There exists the possibility that different classes use different type id
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. The class header might include this information. If we want to
import class headers accross applications, its convenient that the type id
mechanism support inter-operability accross different type id systems.
</ul>
<h3>Features</h3>
@@ -95,7 +95,7 @@ corresponding type can be found. This facility is used by the serialization lib
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 {
@@ -105,18 +105,17 @@ protected:
// this class can't be used as is. It's just the
// common functionality for all type_info replacement
// systems. Hence, make these protected
extended_type_info(
const unsigned int type_info_key,
const char * key
);
const char * m_key;
extended_type_info(const unsigned int type_info_key);
~extended_type_info();
void key_register();
void key_unregister();
public:
const char * get_key() const;
bool operator&lt;(const extended_type_info &amp;rhs) const;
bool operator==(const extended_type_info &amp;rhs) const;
bool operator!=(const extended_type_info &amp;rhs) const {
void key_register(const char *key);
const char * get_key() const {
return m_key;
}
bool operator<(const extended_type_info &rhs) const;
bool operator==(const extended_type_info &rhs) const;
bool operator!=(const extended_type_info &rhs) const {
return !(operator==(rhs));
}
// for plugins
@@ -133,50 +132,37 @@ 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.
there may be more than one instance of this class correponding to a particular type.
For this reason the comparison functions below can't just compare the addresses of
this instance but rather must be programmed to compare the actual information
this instance but rather must be programmed to compare the the actual information
the instances contain.
<dl>
<dt><h4><pre><code>
extended_type_info(unsigned int type_info_key, const char *key);
extended_type_info(unsigned int type_info_key);
</code></pre></h4></dt>
<dd>
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
The argument should be the particular implementation. For
this default implementation base on typeid(), this is the
value 1. Each system must have its own integer. This value
is used to permit the inter-operability of different typeinfo
systems.
<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();
void key_register(const char *key);
</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.
Assign a unique character string identifier to this
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
instance and add it to the corresponding global trable.
This key is used to identify a type accross different instances of the program.
In this way, one instance may know what type to create when necessary.
For this purpose, it must be the same in all program instances which
refer to the same type.
<p>
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.
It may sometimes be referred to as a GUID - a <b>G</b>lobal <b>U</b>nique <b>ID</b>entifier.
</dd>
<dt><h4><pre><code>
@@ -188,19 +174,18 @@ 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 &amp; rhs) const;
bool operator==(const extended_type_info &amp; rhs) const;
bool operator!=(const extended_type_info &amp; 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
These functions are used to compare two
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
<code style="white-space: normal">
extended_type_info
</code>
</a>
objects. They impose a strict total ordering on all
<code style="white-space: normal">extended_type_info</code> records.
objects. They a strict total ordering on all instances of this class.
</dd>
<dt><h4><pre><code>
@@ -213,7 +198,7 @@ Construct a new instance of the type to which this
extended_type_info
</code>
</a>
record corresponds. This function takes a variable list of up to 4 arguments
record corresponds. This function takes variable list of up to 4 arguments
of any type. These arguments are passed to the type's constructor
at runtime. In order to use the facility,
one must declare a type sequence for the constructor arguments.
@@ -222,9 +207,9 @@ 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>.
If these types are defined in DLLS or shared libraries. When these modules
are loaded at runtime, these constructor can be called until the module
is unloaded. These modules are referred to as <b>plugin</b>.
</code>
</dd>
@@ -245,7 +230,7 @@ object.
</dl>
<h3><a name="requirements">Requirements for an Implementation</a></h3>
<h3><a name="requirements">Requirements</a></h3>
In order to be used by the serialization library, an implementation of
<code style="white-space: normal">extended_type_info</code>,
(referred to as ETI here), must be derived from
@@ -258,10 +243,24 @@ and also implement the following:
<dl>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
static extended_type_info &
ETI::get_mutable_instance();
static const extended_type_info &
ETI::get_const:instance();
</pre></code></h4></dt>
<dd>
Return a pointer to the instance of
<code style="white-space: normal">extended_type_info</code>
which corresponds to type T. Normally these instances are static objects so
this just amounts to returning the address of this static object.
</dd>
<dt><h4><code style="white-space: normal"><pre>
template&lt;class ETI&gt;
const extended_type_info *
ETI::get_derived_extended_type_info(const T &amp; t) const;
ETI::get_derived_extended_type_info(const T & t) const;
</pre></code></h4></dt>
<dd>
Return a pointer to the
@@ -269,53 +268,18 @@ 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. Implementation of this function will vary among type id systems
a static cast. Implemention of this function will vary among type id systems
and sometimes will make presumptions about the type T than can be identified
with a particular <code style="white-space: normal">extended_type_info</code> implementation.
</dd>
<dt><h4><code style="white-space: normal"><pre>
virtual bool ETI::is_less_than(const extended_type_info &amp;rhs) const;
bool ETI::less_than(const extended_type_info &rhs) const;
</pre></code></h4></dt>
<dd>
Compare this instance to another one using the same
<code style="white-space: normal">extended_type_info</code> implementation.
</dd>
<dt><h4><code style="white-space: normal"><pre>
virtual bool ETI::is_equal(const extended_type_info &amp;rhs) const;
</pre></code></h4></dt>
<dd>
Compare this instance to another one using the same
<code style="white-space: normal">extended_type_info</code> implementation.
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>
<dt><h4><code style="white-space: normal"><pre>
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>
<h3><a name="models">Models</a></h3>
@@ -330,8 +294,7 @@ by the compiler.
<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.
Instead, it requires that all polymorphic types be explicitly exported.
In addition, if the export facility is to be used to serialize types
However, if the export facility is to be used to serialize types
through base class pointers, those types are required to implement
a virtual function with the signature:
@@ -341,76 +304,17 @@ virtual const char * get_key();
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. It also demonstrates the
inter-operability between two different implementations of
This requires that non-abstract types be exported. It also demostrates the
inter-operability with between two different implementations of
<code style="white-space: normal">extended_type_info</code>.
<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&lt;T&gt;;
template
struct extended_type_info_typeid&lt;const T&gt;;
} // 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&lt;my_class&gt;
)
</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-&gt;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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005-2009.
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
+6 -40
View File
@@ -2,50 +2,16 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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 - Tips and Tricks</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 - FAQ</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>&copy; 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>
+37 -81
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -42,10 +42,10 @@ http://www.boost.org/LICENSE_1_0.txt)
</dl>
</dl>
This library includes a large number of files. They are organized and classified
according to the purposes listed in the above index.
This library includes a large number of files. The are organized and classified
according to purpose listed in the above index.
<p>
<code style="white-space: normal">namespace</code> of classes and templates is synchronized
<code style="white-space: normal">namespace</code> of a classes and templates is syncronized
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 explicitly include any other header files.
It should not be necessary to explictly 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 for loading.</dd>
<dd>wide character text input archive used forloading.</dd>
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
boost/archive/text_woarchive.hpp
@@ -161,14 +161,13 @@ boost/serialization/export.hpp
</a>
<dd>For serialization of pointers to derived classes via key export.</dd>
<dt><a target="assume_abstract" href="../../../boost/serialization/assume_abstract.hpp">
boost/serialization/assume_abstract.hpp
<dt><a target="is_abstract" href="../../../boost/serialization/is_abstract.hpp">
boost/serialization/is_abstract.hpp
</a>
<dd>This is just a thin wrapper which permits one to explicitly specify that a
particular type is an abstract base class. It is necessary to use this
for compilers which don't support the boost type traits implementation of
is_abstact.
</dd>
<dd>For serialization of pointers to abstract base classes. A generic implementation
of this is functional only on the most modern compilers. This one is just
a thin wrapper which permits one to specify "by hand" whether or not a base class
is abstract or not.</dd>
</dl>
@@ -185,7 +184,7 @@ boost/serialization/version.hpp
<dt><a target="level" href="../../../boost/serialization/level.hpp">
boost/serialization/level.hpp
</a>
<dd>To override the default implementation level trait for a type.</dd>
<dd>To override the default implementaton level trait for a type.</dd>
<dt><a target="tracking" href="../../../boost/serialization/tracking.hpp">
boost/serialization/tracking.hpp
@@ -207,7 +206,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
@@ -257,7 +256,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, they can be handled as simple primitives such as they are in simple
That is, the 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>
@@ -269,7 +268,7 @@ boost/archive/basic_text_iprimitive.hpp
</a>
</dt>
<dd>
Implementation of serialization of primitive types in terms of character
Implementation of serialization of primitive types in terms of an 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.
@@ -283,7 +282,7 @@ boost/archive/basic_binary_iprimitive.hpp
</a>
</dt>
<dd>
Implementation of serialization of primitive types in terms of character
Implementation of serialization of primitive types in terms of an character
or wide character binary streams.
</dd>
@@ -294,16 +293,16 @@ boost/archive/basic_binary_oarchive.hpp
boost/archive/basic_binary_iarchive.hpp
</a>
<dd>
Implementation of serialization of all types in terms of character
Implementation of serialization of all types in terms of an 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 symmetry with
other types of binary archives in the future. It also preserves analogy and symetry 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_te't_iarchive" href="../../../boost/archive/basic_text_iarchive.hpp">
<dt><a target="basic_text_iarchive" href="../../../boost/archive/basic_text_iarchive.hpp">
boost/archive/basic_text_iarchive.hpp
</a>
</dt>
@@ -315,12 +314,12 @@ boost/archive/basic_xml_iarchive.hpp
</a>
</dt>
<dd>
Implementation of serialization of all types in terms of character
Implementation of serialization of all types in terms of an 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 guarantee that any object not attached to a name will
includes code to guarentee 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 ignore any names attached to objects.
contains code to strip out and ingore any names attached to objects.
<p>
<dt><a target="common_iarchive" href="../../../boost/archive/detail/common_iarchive.hpp">
boost/archive/detail/common_iarchive.hpp
@@ -329,7 +328,7 @@ boost/archive/detail/common_iarchive.hpp
boost/archive/detail/common_oarchive.hpp
</a>
<dd>
All archive implementations are derived from these header files. They provide
All archive implmentations are derived from these header files. They provide
the interface to the internal implementation details of the library.
</dd>
@@ -337,54 +336,11 @@ the interface to the internal implementation details of the library.
<a name="archiveinternals">
<h4>Archive Internals</h4>
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&lt;class T&gt;
void save_override(T &amp; t, BOOST_PFTO int){
// All for otherwise unhandled types are forwarded to the base class.
// This emulates behavior for function overloading.
this-&gt;base::save_override(t, 0);
}
void save_override(const some_type &amp; t, int){
// any special handling for some type
// this will usually entail forwarding some other operation
// in the most derived class.
this-&gt;This()-&gt;...
// or in one of its parents basic_text_oprimitive
this-&gt;This()-&gt;save(static_cast&lt;int&gt;(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>
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.
<a name="codemodules">
<h4>Archive Library Code Modules</h4>
@@ -402,13 +358,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 at top speed. This is a noticeable
<li>Serialization of user and primitive types runs a top speed. This is a noticiable
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 accidentally
in the library code modules. This prevents a user program from accidently
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
@@ -417,22 +373,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 it in every
only in the library is much more convenient that having to include 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 and implementing to/from base64 conversion among
escaping and unescaping xml text, implementing to/from base64 conversion among
others.
<p>
This is a ripe topic in itself. It's touched upon by the
This is a ripe topic in itself. Its 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 it in a directory
hasn't been and probably won't be reviewed outside of this context. I've left in a directory
local to the serialization library:
<a target="archiveiterators" href="../../../boost/archive/iterators">boost/archive/iterators</a>.
These iterators are described in
+12 -12
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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 compilation on gcc
<li>improved template instantantation for type templates
serialization to permit compiliation on gcc
<li>improved template instantanciation 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 serialized
as pointers and subsequently serialized as objects
<li>improved detection of errors when objects are serializationed
as pointers and subsequently serializationed as objects
<li>permit non-portable binary archives
<li>implement workaround for systems such as MSVC 6.0 that
don't support partial ordering
<li>implement work around for systems such as MSVC 6.0 that
don'tsupport 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 an example which uses boost::shared_ptr.
<li>Included and 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 handling of the above issues.
<li>More test cases/demos to illustrate handlling 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 package compatible with two-phase lookup.
<li>Many small adjustments to accommodate quirks of various compilers.
<li>Adjustments to address make package compatible with two-phase lookup.
<li>Many small adjustments to accomdate quirks of various compilers.
<li>A few bug fixes.
</ul>
</ol>
+205 -17
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -26,13 +26,20 @@ 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="#gcc4x">44.X</a>
<dt><a href="#gcc3x">GCC 3.X, 4.X</a>
<dt><a href="#gcc295">GCC 2.95</a>
<dt><a href="#intel80">Intel 8.0</a>
<dt><a href="#vc80">Visual C++ 8.0</a>
<dt><a href="#vc71">Visual C++ 7.1</a>
<dt><a href="#vc70">Visual C++ 7.0</a>
<dt><a href="#vc6">Visual C++ 6.0</a>
<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>
@@ -42,11 +49,86 @@ 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&lt;class Archive, class T&gt;
void serialize(
Archive & ar,
T & t,
const unsigned int file_version
){
...
}
template&lt;class Archive, class T&gt;
void serialize(
Archive & ar,
my_template&lt;T&gt & 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&lt;class Archive, class T&gt;
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&lt;class Archive, class T&gt;
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,
and attempts to be portable between compiler libraries. The results of
an 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>
@@ -67,7 +149,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
locale is changed back to its original value. This action can be overridden
local 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.
@@ -93,8 +175,32 @@ 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&lt;T&gt;();
</code></pre>
for "registering" derived pointers of polymorphic classes. The actual
function prototype is:
<pre><code>
template&lt;T&gt;
void register_type(T * t = NULL);
</code></pre>
so that one may write <code style="white-space: normal">ar.register_type(static_cast&lt;T *&gt;(NULL))</code> instead of
the syntax described above.
</ul>
<h3><a name="othercompilerissues">Specific Compiler/Library Issues</a></h3>
<h4><a name="gcc4x">GCC 4.X</a></h4>
<h4><a name="gcc3x">GCC 3.X, 4.X</a></h4>
<ul>
<li>GCC versions for Cygwin and MinGW fail to support wide character I/O.
So all tests using wide char I/O fail. Note that if wide character I/O support
@@ -114,7 +220,18 @@ Naturally, the input process has to be symmetrical.
-Wno-ctor-dtor-privacy
</code></pre>
</ul>
<h4><a name="intel80">Intel C++ 8.0</a></h4>
<h4><a name="gcc295">GCC 2.95</a></h4>
All of the above plus:<br>
<ul>
<li>The serialization library depends on the templated stream
implementation to function properly.
to function properly. So STLPort must be used to build the library.
<li>Polymorphic archive tests fail.
<li>XML serialization only works with version 1.6x of spirit. In order to build
and use this library with this compiler, one must use version 1.6x rather than the
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
</ul>
<h4><a name="Intel80">Intel C++ 8.0</a></h4>
No known issues. All tests compile and run in debug and release modes.
<h4><a name="vc80">Visual C++ 8.0</a></h4>
@@ -133,12 +250,12 @@ This is due to the way that VC++ handles templated code with __decl(dllexport) a
__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 be reformulated as a library or dll
demo_portable_iarchive.cpp</code> would have to reformulated as a library or dll
similar to the pre-defined archives in order to function.
<p>
This compiler does not have RTTI or exception handling turned on by default. Although
they are not strictly necessary to use the serialization package, the example and test
programs presume that they are enabled. So be sure your command line or IDE settings
program presume that they are enabled. So be sure your command line or IDE settings
enable these features if you want to build and run these programs.
<p>
This compiler can treat <code style="white-space: normal">wchar_t</code> as either
@@ -147,21 +264,21 @@ If <code style="white-space: normal">/Zc:wchar_t</code> is specified on the
compile command line, <code style="white-space: normal">wchar_t</code> will be
considered an intrinsic type - otherwise
it will be treated as a synonym for a 16 bit integer. The library can be used
either way - <strong>BUT</strong> - both the library <strong>AND</strong> the application
either way - <strong>BUT</strong> - both the libray <strong>AND</strong> the application
must be compiled with the same switch settings. Note that <code style="white-space: normal">BJAM</code>
includes this switch by default. So if want to use the libraries that
<code style="white-space: normal">BJAM</code> builds, you should include this switch
when you compile your own applications.
<h5>Using the Visual C++ IDE</h5>
The library includes a VC++ 7.1 "Solution" - <code style="white-space: normal">BoostSerializationLibrary</code>
along with a set of project files - one for each demo and test. Consider the following if you
decide to use these configurations.
along with of a set of project files - one for each demo and test. Consider the following if you
decided to use these configurations.
<ul>
<li>The projects assume that the tests have been built with bjam using the default
locations. This will result in a <code style="white-space: normal">bin</code> subdirectory
within one's main boost directory. Below this there is a whole structure which maintains
object and library files according to the type of build. The easiest way to build this is to
invoke the runtest script which uses bjam (see below). If the libraries are not in these locations,
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..
@@ -195,6 +312,77 @@ decide 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&lt;A&gt;</code>,
invoke the macro <code style="white-space: normal">BOOST_SERIALIZATION_SHARED_PTR(A)</code>
in the header code.
<li>Lack of support for partial template specialization also creates problems for
serialization of <code style="white-space: normal">std::map</code>. In order to serialize
instances of this type include the invocation of BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
for the key type of the map.
</ul>
<h4><a name="vc6">Visual C++ 6.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 successful.
With this compiler, this message will still appear under the following conditions:
<ul>
<li>When serializing a class with multiple base classes. This problem causes two
failure in the test suite. I have been unable to devise a way to work around this.
<li>Using more than one kind of archive in the same code module. This should be easy
to work around in practice.
</ul>
<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 accessible either by making them public or by
including <code style="white-space: normal">friend</code> declarations as described in
<a href="serialization.html#member">Class Serialization - Member Function</a>, the
will compile but fail at runtime.
<li>Tests using custom extended type which doesn't use RTTI fails. (5.64 only !).
<li>Tests 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.
@@ -205,7 +393,7 @@ decide to use these configurations.
<h4><a name="codewarrior9">Code Warrior 9.x</a></h4>
<ul>
<li>Some tests and demos fail - still under investigation
<li>Some tests and demos demos fail - still under investigation
</ul>
<h4><a name="codewarrior">Code Warrior 8.3</a></h4>
@@ -225,7 +413,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
of an i/o stream unless the <code style="white-space: normal">imbue</code> function is called before the the
stream is opened. In order to use this library with this environment to generate UTF-8
files, one cannot depend on the "automatic" setting of locale that archives implement. The
stream locale must be set explicitly on the stream before an archive is opened on it. The
@@ -237,7 +425,7 @@ These platforms have several issues:
<h4><a name="stlport">STLPort 4.5.3</a></h4>
<ul>
<li>when built to use the dynamic linking versions of the C++ runtime code (<runtime-link>dynamic)
<li>when built to use dynamic linking versions of C++ runtime code (<runtime-link>dynamic)
all tests fail to link. This is due to a missing symbol in the stlport library related
to custom codecvt facets.
<li>the test_set fails to run correctly. It seems the hashed set iterator doesn't
@@ -247,7 +435,7 @@ These platforms have several issues:
<hr>
<p>Revised 1 November, 2004
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2015.
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 839 B

-91
View File
@@ -1,91 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
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)
-->
<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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+6 -3
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -28,6 +28,9 @@ 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
@@ -127,7 +130,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 guaranteed only for recent versions of GCC.
<li>Portability(1) is guarenteed 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).
-41
View File
@@ -1,41 +0,0 @@
<html>
<!--
Copyright 2008 Matthias Troyer
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)
-->
<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>
<hr>
<p><i>&copy; Copyright 2008 Matthias Troyer.
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 -19
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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,15 +41,12 @@ struct A {
// class a contains a pointer to a "hidden" declaration
B *pimpl;
template&lt;class Archive&gt;
void serialize(Archive &amp; 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. 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:
Serialization of A requires access to the definition of B in order so it
is 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>
@@ -59,8 +56,8 @@ by:
struct B {
int b;
template&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int file_version){
ar &amp; b;
void serialize(Archive & ar, const unsigned int file_version){
ar & b;
}
};
@@ -74,8 +71,8 @@ A::~A(){
// now we can define the serialization for class A
template&lt;class Archive&gt;
void A::serialize(Archive &amp; ar, const unsigned int file_version){
ar &amp; 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
@@ -88,12 +85,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 &amp; ar, const unsigned int file_version);
void A::serialize(boost::archive::text_iarchive &amp; 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 it's not "known" what types of archives
There can't be as its 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
@@ -103,11 +100,11 @@ example, including the the following code in any *.cpp file does just that:
#include &lt;boost/archive/text_oarchive.hpp&gt;
template void A::serialize&lt;boost::archive::text_iarchive&gt;(
boost::archive::text_iarchive &amp; ar,
boost::archive::text_iarchive & ar,
const unsigned int file_version
);
template void A::serialize&lt;boost::archive::text_oarchive&gt;(
boost::archive::text_oarchive &amp; ar,
boost::archive::text_oarchive & ar,
const unsigned int file_version
);
</code></pre>
@@ -115,7 +112,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 explicitly instantiation for all known templates and
driven code. One can invoke explicity instantiation for all known templates and
presume that the linker will exclude unreferenced code. This should
work but is platform dependent.
<hr>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 844 B

-170
View File
@@ -1,170 +0,0 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
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)
-->
<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 .
// 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)
#include &lt;fstream&gt;
#include &lt;boost/config.hpp&gt;
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif
#include &lt;boost/serialization/access.hpp&gt;
#include &lt;boost/serialization/base_object.hpp&gt;
#include &lt;boost/serialization/export.hpp&gt;
class Base {
friend class boost::serialization::access;
int m_i;
template&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int version){
ar &amp; BOOST_SERIALIZATION_NVP(m_i);
}
protected:
bool equals(const Base &amp;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 &amp; base_cast(){
return static_cast&lt;Base &amp;&gt;(*this);
}
template&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int version){
ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
}
public:
bool operator==(const Derived &amp;rhs) const {
return Base::equals(static_cast&lt;const Base &amp;&gt;(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 &lt;&lt; boost::serialization::make_nvp("a", a);
}
{
test_istream is(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
ia &gt;&gt; boost::serialization::make_nvp("a", a1);
}
std::remove(testfile);
if(a != a1)
return 1;
// serialize Derived and Base
Derived *ta = &amp;a;
Derived *ta1 = NULL;
{
test_ostream os(testfile);
test_oarchive oa(os);
oa &lt;&lt; boost::serialization::make_nvp("ta", ta);
}
{
test_istream is(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
ia &gt;&gt; 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&lt;Base &amp;&gt;(Derived &amp;)
</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&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int version){
//ar &amp; BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
ar &amp; boost::serialization::make_nvp(
"Base",
static_cast&lt;Base &amp;&gt;(*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>&copy; 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>
-149
View File
@@ -1,149 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 200 0.00 0.00 void accumulate<unsigned long>(unsigned int&, unsigned long const&)
0.00 0.00 0.00 150 0.00 0.00 _pei386_runtime_relocator
0.00 0.00 0.00 1 0.00 0.00 std::ostream::operator<<(void const*)
0.00 0.00 0.00 1 0.00 0.00 __divdi3
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 200/200 setvbuf [1286]
[4] 0.0 0.00 0.00 200 void accumulate<unsigned long>(unsigned int&, unsigned long const&) [4]
-----------------------------------------------
0.00 0.00 150/150 _cygwin_crt0_common@8 [1230]
[5] 0.0 0.00 0.00 150 _pei386_runtime_relocator [5]
-----------------------------------------------
0.00 0.00 1/1 _lseek64 [1234]
[6] 0.0 0.00 0.00 1 std::ostream::operator<<(void const*) [6]
-----------------------------------------------
0.00 0.00 1/1 __tcf_1 [1221]
[7] 0.0 0.00 0.00 1 __divdi3 [7]
-----------------------------------------------
2 main [1263]
[1263] 0.0 0.00 0.00 0+2 main [1263]
2 main [1263]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[4] void accumulate<unsigned long>(unsigned int&, unsigned long const&) [7] __divdi3
[6] std::ostream::operator<<(void const*) [5] _pei386_runtime_relocator
-203
View File
@@ -1,203 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
100.00 0.01 0.01 __gnu_cxx::__atomic_add(int volatile*, int)
0.00 0.01 0.00 51 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
0.00 0.01 0.00 36 0.00 0.00 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill()
0.00 0.01 0.00 30 0.00 0.00 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
0.00 0.01 0.00 11 0.00 0.00 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&)
0.00 0.01 0.00 9 0.00 0.00 void test_transform_width<6, 8>(unsigned int)
0.00 0.01 0.00 9 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain()
0.00 0.01 0.00 5 0.00 0.00 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*)
0.00 0.01 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
0.00 0.01 0.00 1 0.00 0.00 void test_xml_escape<char const>(char const*, char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 void test_xml_unescape<char const>(char const*, char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 void test_stream_iterators<char>(char const*, unsigned int)
0.00 0.01 0.00 1 0.00 0.00 test_main(int, char**)
0.00 0.01 0.00 1 0.00 0.00 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
0.00 0.01 0.00 1 0.00 0.00 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) for 100.00% of 0.01 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.01 0.00 __gnu_cxx::__atomic_add(int volatile*, int) [1]
-----------------------------------------------
0.00 0.00 51/51 void test_transform_width<6, 8>(unsigned int) [9]
[5] 0.0 0.00 0.00 51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
-----------------------------------------------
0.00 0.00 36/36 void test_transform_width<6, 8>(unsigned int) [9]
[6] 0.0 0.00 0.00 36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
-----------------------------------------------
0.00 0.00 30/30 void test_transform_width<6, 8>(unsigned int) [9]
[7] 0.0 0.00 0.00 30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
-----------------------------------------------
0.00 0.00 11/11 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
[8] 0.0 0.00 0.00 11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
-----------------------------------------------
0.00 0.00 9/9 test_main(int, char**) [16]
[9] 0.0 0.00 0.00 9 void test_transform_width<6, 8>(unsigned int) [9]
0.00 0.00 51/51 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [5]
0.00 0.00 36/36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [6]
0.00 0.00 30/30 std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&) [7]
-----------------------------------------------
0.00 0.00 9/9 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
[10] 0.0 0.00 0.00 9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
-----------------------------------------------
0.00 0.00 5/5 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
[11] 0.0 0.00 0.00 5 boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [11]
-----------------------------------------------
0.00 0.00 1/2 global constructors keyed to main [38]
0.00 0.00 1/2 global destructors keyed to main [35]
[12] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [12]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[13] 0.0 0.00 0.00 1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
0.00 0.00 11/11 boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [8]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[14] 0.0 0.00 0.00 1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
0.00 0.00 9/9 boost::archive::iterators::xml_unescape<char const*>::drain() [10]
-----------------------------------------------
0.00 0.00 1/1 test_main(int, char**) [16]
[15] 0.0 0.00 0.00 1 void test_stream_iterators<char>(char const*, unsigned int) [15]
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
-----------------------------------------------
0.00 0.00 1/1 main [1211]
[16] 0.0 0.00 0.00 1 test_main(int, char**) [16]
0.00 0.00 9/9 void test_transform_width<6, 8>(unsigned int) [9]
0.00 0.00 1/1 void test_xml_escape<char const>(char const*, char const*, unsigned int) [13]
0.00 0.00 1/1 void test_xml_unescape<char const>(char const*, char const*, unsigned int) [14]
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
-----------------------------------------------
0.00 0.00 1/1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
[17] 0.0 0.00 0.00 1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
-----------------------------------------------
0.00 0.00 1/1 void test_stream_iterators<char>(char const*, unsigned int) [15]
[18] 0.0 0.00 0.00 1 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) [18]
0.00 0.00 1/1 char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) [17]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[13] void test_xml_escape<char const>(char const*, char const*, unsigned int) [16] test_main(int, char**) [5] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
[14] void test_xml_unescape<char const>(char const*, char const*, unsigned int) [8] boost::archive::iterators::xml_escape<char const*>::fill(char const*&, char const*&) [1] __gnu_cxx::__atomic_add(int volatile*, int)
[9] void test_transform_width<6, 8>(unsigned int) [11] boost::archive::iterators::xml_unescape<char const*>::drain_residue(char const*) [17] char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)
[15] void test_stream_iterators<char>(char const*, unsigned int) [10] boost::archive::iterators::xml_unescape<char const*>::drain() [18] std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)
[12] __static_initialization_and_destruction_0(int, int) (performance_iterators.cpp) [6] boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, 8, 6, char>::fill() [7] std::vector<char, std::allocator<char> >::_M_insert_aux(__gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >, char const&)
-153
View File
@@ -1,153 +0,0 @@
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 200 0.00 0.00 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
0.00 0.00 0.00 150 0.00 0.00 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill()
0.00 0.00 0.00 2 0.00 0.00 __static_initialization_and_destruction_0(int, int)
0.00 0.00 0.00 1 0.00 0.00 void test_base64<char>()
0.00 0.00 0.00 1 0.00 0.00 std::_List_base<char, std::allocator<char> >::_M_clear()
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 200/200 void test_base64<char>() [7]
[4] 0.0 0.00 0.00 200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
-----------------------------------------------
0.00 0.00 150/150 void test_base64<char>() [7]
[5] 0.0 0.00 0.00 150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
-----------------------------------------------
0.00 0.00 1/2 global constructors keyed to main [27]
0.00 0.00 1/2 global destructors keyed to main [24]
[6] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [6]
-----------------------------------------------
0.00 0.00 1/1 main [1156]
[7] 0.0 0.00 0.00 1 void test_base64<char>() [7]
0.00 0.00 200/200 boost::archive::iterators::transform_width<char*, 6, 8, char>::fill() [4]
0.00 0.00 150/150 boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [5]
0.00 0.00 1/1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
-----------------------------------------------
0.00 0.00 1/1 void test_base64<char>() [7]
[8] 0.0 0.00 0.00 1 std::_List_base<char, std::allocator<char> >::_M_clear() [8]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Index by function name
[7] void test_base64<char>() [5] boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<boost::archive::iterators::remove_whitespace<std::_List_iterator<char> >, char>, 8, 6, char>::fill() [8] std::_List_base<char, std::allocator<char> >::_M_clear()
[6] __static_initialization_and_destruction_0(int, int) (performance_iterators_base64.cpp) [4] boost::archive::iterators::transform_width<char*, 6, 8, char>::fill()
+225 -4
View File
@@ -2,15 +2,15 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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 - Rationale</title>
<title>Seriealization - Rationale</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
@@ -31,6 +31,7 @@ http://www.boost.org/LICENSE_1_0.txt)
<dt><a href="#archives">Archives are not streams</a></dt>
<dt><a href="#strings">Strings are treated specially in text archives</a></dt>
<dt><a href="#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
<dt><a href="#trap">Compile time trap when saving a non-const value</a></dt>
<!--
<dt><a href="#footnotes">Footnotes</a></dt>
-->
@@ -49,7 +50,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 41.
distinction is addressed in <a href="bibliography.html#5">[5]</a> item number item 41 .
<li>We don't want users to insert/extract&nbsp;data
directly into/from &nbsp;the stream .&nbsp; This could
create a corrupted archive. Were archives
@@ -109,6 +110,226 @@ 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 &lt;&lt; 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 &lt;&lt; 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 &lt;&lt; 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 &lt;&lt; x;
...
x.f(); // change x in some way
...
ar &lt;&lt; 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 &lt;construct_from&gt; z;
template &lt;class Archive&gt;
void serialize(Archive & ar, const unsigned version){
ar &lt;&lt; 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&lt;construct_from&gt;</code>
is not going to have a single raw pointer shared amongst the instances. Each loaded
<code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code> is going to
have its own 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 &lt;&lt; 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 &lt;&lt; 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 &lt;&lt; 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>
+2 -2
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
+104 -244
View File
@@ -2,146 +2,42 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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 - 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="#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>
<dt><a href="#requirements">Requirements</a></dt>
<dt><a href="#differences_1_35">Differences from version 1.35</a></dt>
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
<dt><a href="#differences_1_32">Differences from version 1.32</a></dt>
<dt><a href="#todo">Pending Issues</a></dt>
</dl>
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 &lt;file name&gt;
</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 &lt;boost/archive/impl/archive_pointer_iserializer.ipp&gt;
...
template class detail::archive_pointer_iserializer&lt;naked_text_iarchive&gt; ;
...
template class detail::archive_pointer_iserializer&lt;text_iarchive&gt; ;
</pre></code>should be replaced with this new code: <code><pre>
#include &lt;boost/archive/impl/archive_serializer_map.ipp&gt;
...
template class detail::archive_serializer_map&lt;naked_text_iarchive&gt; ;
...
template class detail::archive_serializer_map&lt;text_iarchive&gt; ;
</pre></code>
As of this is written, there are no known bugs. However, due to compiler/library quirks and or
bugs, some tests fail with some combinations of compilers and libraries.
<h2><a name="requirements"></a>Requirements</h2>
This library has been tested on Boost version 1.34 and 1.35.
<!--
<p>
The serialization library uses the boost spirit package to load XML archives.
@@ -159,137 +55,101 @@ 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_39"></a>Differences from Boost 1.39</h2>
<ul>
<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.
<li>The library is now thread safe. That is, multiple archives can be open
in different threads. This has been implmented with a lock-free algorithm
to avoid any performance bottlenecks.
<li>Serialization of types defined in shared libraries is now supported.
shared libraries (DLLS) can be loaded/unloaded dynamically at runtime.
This includes the serialization of types of abstract base classes so that
a program can be written so as to be compatible with as yet undefined
and un-implemented code.
<li>The extended type info system has been enhanced to in order to implement
the above. It is now a general purpose system for creating and casting of
types about which is only known a string ID and an abstract base class.
<li>All bug reports filed as TRAK tickets have been addressed.
<li>As of this writing, the library will fail build on older compilers such
as MSVC before version 7.1 and older versions of Borland compilers. This
may or maynot change in the future.
<li>In previous versions, all types serialized through a pointer were
automatically "registered" as a side-effect. This made it unnecessary to
explicitly register or export these types if they were subsequently
serialized through a pointer to a base class. On rare occasions this
created some difficulties by instantiating undesired code and made
the requirement for registration and/or export dependent on the sequence
of operations. So any type that is to be serialized through a base
class pointer must be either explicitly registered or exported. This
might break some code and result in the throwing of "unregistered type"
exception.
</ul>
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</h2>
<ul>
<li>
Enhanced support for fast serialization for native binary archives. By Mattias
Troyer.
<li>
Improved implementation of "export" functionality. Removes header ordering
requirement and eliminates the maintenance of a pre-determined list of "known
archives" By David Abrahams.
<li>
Improved support for STLPort.
<li>Enhanced support for fast serialization for native binary archives. By Mattias Troyer.
<li>Improved implementation of "export" functionality. Removes header ordering
requirement and eliminates the maintenance of a pre-determined list of "known archives"
By David Abrahams.
<li>Improved support for STLPort.
</ul>
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
<ul>
<li>
Native Binary archives use the <code style="white-space: normal">std::streambuf</code>
interface. This should result in noticeably faster execution in many cases.
<li>Native Binary archives use the <code style="white-space: normal">std::streambuf</code> interface.
This should result in noticeably faster execution in many cases.
</ul>
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
<ul>
<li>
Dynamic Linking Library (DLLs and shared libraries) for platforms which support
them. See <a href="../../../more/getting_started/windows.html#auto-linking">Automatic
Linking on Windows</a>.
<li>
Implementation of auto-link for compilers which can support this.
<li>
Better support for <em>Argument Dependent Lookup</em>
and two-phase lookup. This results in simpler rules regarding the placing of
serialization specializations namespaces.
<li>
Enhanced documentation to help explain usage of the above.
<li>
Adjustments to improve support for less conformant compilers.
<li>
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&lt;T&gt;</code>.
This is compatible with public interface of <code style="white-space: normal">shared_ptr&lt;T&gt;</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&lt;T&gt;</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.
<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 serialization system in a way which may introduce subtle bugs in
to the program. A fuller explanation of this issue can be found
<a target="detail" href="traits.html#tracking">here</a>.
<li>A new implementation of serialization for <code style="white-space: normal">shared_ptr&lt;T&gt;</code>. This
is compatible with public interface of <code style="white-space: normal">shared_ptr&lt;T&gt;</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&lt;T&gt;</code> stored in
archives created with boost 1.32. This code is stored in the header:
<code style="white-space: normal">boost/serialization/shared_ptr_132.hpp</code>. If your application
needs to load archives created with boost 1.32 libraries, include the above header
before each inclusion of <code style="white-space: normal">boost/serialization/shared_ptr.hpp</code>.
<li>More compilers tested and supported.
<li>Miscellaneous bug fixes.
</ul>
<h2><a name="todo"></a>Pending issues</h2>
<ul>
<li>
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.
<li>Compile, and test on more platforms
<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 serializaton of <code style="white-space: normal">std::map</code>
is fixed in this version. Unfortunately, the fix breaks serialization of
<code style="white-space: normal">std::map</code> for those compilers which do not support
partial template specialization.
</ul>
<p>
Aside from the above, there are a number of issues related to specific
platforms. These are listed in <a href="implementation.html#othercompilerissues">Specific
Compiler/Library Issues</a>.
<hr>
<p>
<i>&copy; 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>
Aside from the above, there are a number of issues related to specific platforms.
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-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>
+42 -41
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -62,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="traits.html">Class Serialization Traits</a>
<dt><a href="wrappers.html">Serialization Wrappers</a>
<dt><a href="traits.html">Class Serialization Traits</a>
<dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
</dl>
@@ -71,11 +71,13 @@ 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>
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.
In this document, we use the term primitive type to mean
types whose data is simply saved/loaded to/from an archive
with no further processing. Arithmetic (including characters),
bool, enum and stl::string and stl::wstring types are primitive types. Using
<a target="detail" href="traits.html#Traits">serialization traits</a>,
any user type can also be designated as "primitive"
so that it is handled in this way.
<li>It is a class type and one of the following has been declared according
to the prototypes detailed below:
<ul>
@@ -84,7 +86,7 @@ if and only if one of the following is true:
</ul>
<li>it is a pointer to a <strong>Serializable</strong> type.
<li>it is a reference to a <strong>Serializable</strong> type.
<li>it is a native C++ Array of <strong>Serializable</strong> type.
<li>it is an native C++ Array of <strong>Serializable</strong> type.
</ul>
<h2><a name="primitiveoperators">Primitive Types</a></h2>
@@ -101,8 +103,8 @@ For class/struct types, the template operators &amp;, &lt;&lt;, and &gt;&gt;
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 serialization of a class can
be specified via either a class member function or a free function which
will result in a compile time error. The serialiation of a class can
be specified via either a class member function or a free funcation which
takes a reference to an instance of the class as an argument.
<h3><a name="member">Member Function</a></h3>
@@ -136,7 +138,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 the member function public. This will prevent serialization functions from
of making 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 +182,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 absolutely no changes to the library.
serialization with absolutly no changes to the library.
<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
For maximum portability, include any free functions templates and definitions in the
@@ -196,7 +198,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 further will find more information in
this furter will find more information in
<a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
<h3><a name="classmembers">Serialization of Class Members</a></h3>
@@ -219,7 +221,7 @@ base_object.hpp
includes the template:
<pre><code>
template&lt;class Base, class Derived&gt;
Base &amp; base_object(Derived &amp;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 +257,14 @@ Loading <code style="white-space: normal">const</code> members can be addressed
ar &amp; const_cast&lt;T &amp;&gt;(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 initialized when a class instance
keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
is constructed and not changed thereafter. However, this may
be most appropriate in many cases. Ultimately, it comes down to
the question about what <code style="white-space: normal">const</code> means in the context
of serialization.
<h4><a name="templates"></a>Templates</h4>
Implementation of serialization for templates is exactly the same process
Implementation serialization for templates is exactly the same process
as for normal classes and requires no additional considerations. Among
other things, this implies that serialization of compositions of templates
are automatically generated when required if serialization of the
@@ -273,7 +275,7 @@ class <code style="white-space: normal">my_t</code>, then serialization for
<code style="white-space: normal">std::list&lt; boost::shared_ptr&lt; my_t&gt; &gt;</code> is already available
for use.
<p>
For an example that shows how this idea might be implemented for your own
See for an example that shows how this idea might be implemented for your own
class templates, see
<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
demo_auto_ptr.cpp</a>.
@@ -434,7 +436,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">&amp;</code>
operator and <code style="white-space: normal">serialize</code>
function guarantees that this is always the case and will minimize the
occurrence of hard to find errors related to synchronization of
occurence of hard to find errors related to synchronization of
<code style="white-space: normal">save</code> and <code style="white-space: normal">load</code>
functions.
<p>
@@ -463,7 +465,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 detected when saved and restored
<li>NULL pointers must be dectected when saved and restored
to NULL when deserialized.
</ol>
@@ -482,7 +484,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 its address.
<li>if the object has already been loaded, return it's address.
<li>otherwise, create a new instance of the object
<li>read the data back in using the operators described above
<li>return the address of the newly created object.
@@ -496,7 +498,7 @@ and <code style="white-space: normal">&gt;&gt;</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 +545,7 @@ private:
ar &amp; m_state;
}
public:
// no default construct guarantees that no invalid object
// no default construct guarentees that no invalid object
// ever exists
my_class(int attribute) :
m_attribute(attribute),
@@ -591,7 +593,7 @@ class derived_one : public base {
class derived_two : public base {
...
};
int main(){
main(){
...
base *b;
...
@@ -604,7 +606,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 polymorphic or not.
(<code style="white-space: normal">base</code> in this case) is polymophic or not.
If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
virtual functions, then an object of the type <code style="white-space: normal">base</code>
will be serialized. Information in any derived classes will be lost. If this is what is desired
@@ -630,7 +632,7 @@ the same sequence. This includes "registration".
<p>
Expanding our previous example:
<pre><code>
int main(){
main(){
derived_one d1;
derived_two d2:
...
@@ -659,11 +661,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&lt;class T&gt;
register_type(T * = NULL);
register_type();
</code></pre>
So our problem could just as well be addressed by writing:
<pre><code>
int main(){
main(){
...
ar.template register_type&lt;derived_one&gt;();
ar.template register_type&lt;derived_two&gt;();
@@ -674,7 +676,7 @@ int 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 synchronization.
and corresponding load in syncronization.
<h4><a name="export">Export</a></h4>
The above will work but may be inconvenient. We don't always know which derived
@@ -690,7 +692,7 @@ So we have another method:
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
int main(){
main(){
...
base *b;
...
@@ -719,7 +721,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
explicitly by the program so normally code to serialize such classes
explictly by the program so normally code to serialize such classes
would never be instantiated. So in addition to including export key
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
instantiates the class serialization code for all archive classes used
@@ -755,7 +757,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&lt;Base&gt;(Derived &amp;)</code>
<code style="white-space: normal">boost::serialization::base_object&lt;Base&gt;(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
@@ -789,18 +791,18 @@ class derived : public base {
template&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int file_version){
// method 1 : invoke base class serialization
ar &amp; boost::serialization::base_object&lt;base&gt;(*this);
boost::serialization::base_object&lt;base&gt;(*this);
// method 2 : explicitly register base/derived relationship
boost::serialization::void_cast_register&lt;derived, base&gt;(
static_cast&lt;derived *&gt;(NULL),
static_cast&lt;base *&gt;(NULL)
static_cast&lt;base *&gt;(NULL),
static_cast&lt;derived *&gt;(NULL)
)
}
};
BOOST_CLASS_EXPORT_GUID(derived, "derived")
int main(){
main(){
//...
std::stringstream ss;
boost::archive::text_iarchive ar(ss);
@@ -907,11 +909,11 @@ rather than
<pre><code>
#include &lt;list&gt;
</code></pre>
Since the former includes the latter, this is all that is necessary.
Since the former includes the latter, this all that is necessary.
The same holds true for all STL collections as well as templates
required to support them (e.g. <code style="white-space: normal">std::pair</code>).
<p>
As of this writing, the library contains serialization of the following boost classes:
As of this writing, the library contains serialization of the following boost clases:
<ul>
<li>optional
<li>variant
@@ -919,9 +921,8 @@ 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 implementations!
new implmentations!
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
Distributed under the Boost Software License, Version 1.0. (See
+18 -18
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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&lt;class Archive, class P, class D&gt;
template&lt;class Archive, class P, class D>
inline void save_construct_data(
Archive &amp; ar,
const boost::detail::sp_counted_base_impl&lt;P, D&gt; * t,
const boost::detail::sp_counted_base_impl<P, D> * t,
const unsigned int file_version
){
// variables used for construction
ar &lt;&lt; t-&gt;ptr;
ar &lt;&lt; t->ptr;
ar &lt;&lt; *t;
}
template&lt;class Archive, class P, class D&gt;
template<class Archive, class P, class D>
inline void load_construct_data(
Archive &amp; ar,
boost::detail::sp_counted_base_impl&lt;P, D&gt; * t,
boost::detail::sp_counted_base_impl<P, D> * t,
const unsigned int file_version
){
P ptr_;
ar &gt;&gt; ptr_;
// placement new
::new(t)boost::detail::sp_counted_base_impl&lt;P, D&gt;(ptr_, D());
ar &gt;&gt; *t;
::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
ar &gt;&gt;; *t;
}
</code></pre>
The statement <code style="white-space: normal">ar &gt;&gt; ptr_</code> is key. This deserializes
the same pointer deserialized above. Default object tracking will ensure
the same pointer deserialzed 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, they will all point
corresponding to a particular object are created, the will all point
to the same object.
<p>
Since <code style="white-space: normal">sp_counted_base_impl&lt;P, D&gt;</code> is derived from
@@ -135,7 +135,7 @@ inline void serialize(
const unsigned int file_version,
int
){
ar &amp; boost::serialization::base_object&lt;
ar & boost::serialization::base_object&lt;
boost::detail::sp_counted_base
&gt;(*this);
}
@@ -150,7 +150,7 @@ inline void serialize(
){
}
</code></pre>
It would seem we're done, but running the test program,
It would seem we're done, 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&lt;P, D&gt;</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 incremented. Code must be added
count starts at 1 and is never incrememented. 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
// and its polymorphic base
// its polymorphic base
void_cast_register&lt;
boost::detail::sp_counted_base_impl&lt;P, D&gt;
boost::detail::sp_counted_base,
&gt;();
</code></pre>
and we don't have to include a trivial serializer for <code style="white-space: normal">sp_counted_base</code>.
and we don't have to include a trival 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 specialized versions of the macros used for exporting classes serialized through raw pointers.
These are specialize versions of the macros used for exporting classes serialized through raw pointers.
<p>
Clear, complete, correct and exception safe serialization of smart pointers is going to
Clearly, complete, correct and exception safe serialization of smart pointers is going to
be a challenge. I hope that this implementation provides a useful
starting point for such an effort.
<hr>
+9 -9
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -40,24 +40,24 @@ Unfortunately, this way of doing it suffered from some undesirable features
<pre><code>
template&lt;class Archive, class T&gt;
inline void save(
Archive &amp; ar,
const boost::shared_ptr&lt;T&gt; &amp;t,
Archive & ar,
const boost::shared_ptr&ltT&gt; &t,
const unsigned int /* file_version */
){
const T * t_ptr = t.get();
// just serialize the underlying raw pointer
ar &lt;&lt; boost::serialization::make_nvp("px", t_ptr);
ar &lt;&lt: boost::serialization::make_nvp("px", t_ptr);
}
template&lt;class Archive, class T&gt;
template&lt;class Archive, class T&gt
inline void load(
Archive &amp; ar,
boost::shared_ptr&lt;T&gt; &amp;t,
Archive & ar,
boost::shared_ptr&lt;T&gt; &t,
const unsigned int file_version
){
T* r;
// recover the underlying raw pointer
ar &gt;&gt; boost::serialization::make_nvp("px", r);
ar >> boost::serialization::make_nvp("px", r);
// To Do - match up with other shared pointers which
// use this same raw pointer.
-95
View File
@@ -1,95 +0,0 @@
<!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 .
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)
-->
<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 &lt;&lt; schedule;
</code></pre>
and it produces the following output
<pre><code>
schedule
count 6
item
first
driver bob
hour 6
minute 24
second -&gt;
stops
count 3
item -&gt;
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>&copy; 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>
-254
View File
@@ -1,254 +0,0 @@
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
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)
-->
<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 &lt;class T&gt;
class singleton : public boost::noncopyable
{
public:
static const T &amp; get_const_instance();
static T &amp; get_mutable_instance();
static bool is_destroyed();
};
} // namespace serialization
} // namespace boost
</code></pre>
<dl>
<dt><h4><pre><code>
static const T &amp; 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 &amp; 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&lt;T&gt;
</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&lt;T&gt;
</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&lt;const extended_type_info *, key_compare&gt; ktmap;
...
void
extended_type_info::key_register(const char *key) {
...
result = singleton&lt;ktmap&gt;::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&lt;T&gt;
</code>
</a>
as one of the base classes of the type. This is illustrated by a simplified
excerpt from
<a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
<code style="white-space: normal">
extended_type_info_typeid.hpp
</code>
</a>
<pre><code>
template&lt;class T&gt;
class extended_type_info_typeid :
public detail::extended_type_info_typeid_0,
public singleton&lt;extended_type_info_typeid&lt;const T&gt; &gt;
{
friend class singleton&lt;extended_type_info_typeid&lt;const T&gt; &gt;;
private:
// private constructor to inhibit any existence other than the
// static one. Note: not all compilers support this !!!
extended_type_info_typeid() :
detail::extended_type_info_typeid_0()
{
type_register(typeid(T));
}
~extended_type_info_typeid(){}
...
};
</code></pre>
This usage will permit a more natural syntax to be used:
<pre><code>
extended_type_info_typeid&lt;T&gt;::get_const_instance()
</code></pre>
Again, including one or more of the above statements anywhere
in the program will 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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+18 -18
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -30,23 +30,23 @@ To cast from one type to another related type, C++ provides the following
operators:
<dl>
<dt><code>static_cast&lt;T *&gt;(U *)<br>static_cast&lt;T &amp;&gt;(U &amp;)</code></dt>
<dt><code>static_cast&lt;T *<&gt;(U *)<br>static_cast&lt;T &<&gt;(U &)</code></dt>
<dd>
<ul>
<li>required if neither T nor U are polymorphic
<li>required if neither T nor U are not polymorphic
<li>permitted in other cases.
<li>fails to detect erroneous casts of polymorphic pointers/references at runtime.
<li>fails to detect erroneas casts of polymophic 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&lt;T *&gt;(U *)<br>dynamic_cast&lt;T &amp;&gt;(U &amp;)</code></dt>
<dt><code>dynamic_cast&lt;T *<&gt;(U *)<br>dynamic_cast&lt;T &<&gt;(U &)</code></dt>
<dd>
<ul>
<li>permitted if either T or U are polymorphic
<li>prohibited in other cases.
<li>throws exception on detecting erroneous casts of polymorphic pointers/references
<li>throws exception on detecting erroneas 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 &lt;boost/serialization/smart_cast.hpp&gt;
#include &lt;boost/smart_cast.hpp&gt;
struct top {
};
@@ -91,14 +91,14 @@ template&lt;class T&gt;
bool is_storable(T &amp;t){
// what type of cast to use here?
// this fails at compile time when T == base2
// this fails at compiler time when T == base2
// return static_cast&lt;base1 &amp;&gt;(t).is_storable();
// this fails at compile time when T == top
// this fails at compiler time when T == top
// otherwise it works but cannot optimize inline function call
// return dynamic_cast&lt;base1 &amp;&gt;(t).is_storable();
// this always works - and is guaranteed to generate the fastest code !
// this always works - and is guarenteed to generate the fastest code !
return (boost::smart_cast_reference&lt;base1 &amp;&gt;(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 exemplified above.
situation exmplified above.
<h3>Usage</h3>
The following syntax is supported:
<pre><code>
smart_cast&lt;Target *, Source *&gt;(Source * s);
smart_cast&lt;Target *&gt;(Source * s);
smart_cast&lt;Target &amp;, Source &amp;&gt;(Source &amp; s);
smart_cast&lt;Target *>(Source * s);
smart_cast&lt;Target &, Source &amp;&gt(Source &amp; s);
</code></pre>
Note that the above syntax doesn't include
<pre><code>
smart_cast&lt;Target &amp; &gt;(Source &amp; s)
smart_cast&lt;Target &amp; &gt(Source &amp; s)
</code></pre>
but the same functionality is supported with the following special syntax
but the same functionality is supported the the following special syntax
<pre><code>
smart_cast_reference&lt;Target &amp;&gt;(Source &amp; s)
smart_cast_reference&lt;Target &amp;&gt(Source &amp; 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 the
template specialization or on types for which have be specified with the
macro <code style="white-space: normal">
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(&lt;type&gt;)</code>
has been applied.
+67 -227
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -28,7 +28,6 @@ http://www.boost.org/LICENSE_1_0.txt)
<dl class="page-index">
<dt><a href="#objecttracking">Object Tracking</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>
@@ -37,7 +36,6 @@ http://www.boost.org/LICENSE_1_0.txt)
<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>
@@ -54,10 +52,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
programs where the copies of different objects are saved from the same address.
progams where the copies of different objects are saved from the same address.
<pre><code>
template&lt;class Archive&gt;
void save(boost::basic_oarchive &amp; ar, const unsigned int version) const
void save(boost::basic_oarchive &amp; ar, const unsigned int version) const
{
for(int i = 0; i &lt; 10; ++i){
A x = a[i];
@@ -97,11 +95,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 an address
A similar problem can occur when different objects are loaded to and address
which is different from the final location:
<pre><code>
template&lt;class Archive&gt;
void load(boost::basic_oarchive &amp; ar, const unsigned int version) const
void load(boost::basic_oarchive &amp; ar, const unsigned int version) const
{
for(int i = 0; i &lt; 10; ++i){
A x;
@@ -112,20 +110,20 @@ void load(boost::basic_oarchive &amp; 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 an object through a pointer.
this will break the features that depend on tracking such as loading object through a pointer.
Subtle bugs will be introduced into the program. This can be
addressed by altering the above code thusly:
<pre><code>
template&lt;class Archive&gt;
void load(boost::basic_iarchive &amp; ar, const unsigned int version) const
void load(boost::basic_iarchive &amp; ar, const unsigned int version) const
{
for(int i = 0; i &lt; 10; ++i){
A x;
ar &gt;&gt; x;
std::pair&lt;std::set::const_iterator, bool&gt; result;
result = std::m_set.insert(x);
ar.reset_object_address(&amp; (*result.first), &amp;x);
ar.reset_object_address(& (*result.first), &x);
}
}
</code></pre>
@@ -137,7 +135,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 the
By default, data types designated primitive by
<a target="detail" href="traits.html#level">Implementation Level</a>
class serialization trait are never tracked. If it is desired to
track a shared primitive object through a pointer (e.g. a
@@ -156,96 +154,6 @@ redundant save/load operations.
BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
</code></pre>
<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>
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>
template&lt;class T&gt;
class shared_ptr
{
...
};
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&lt;T&gt; lookup(const T *);
// insert a new shared_ptr
void insert&lt;shared_ptr&lt;T&gt; &gt;(const shared_ptr&lt;T&gt; *);
};
namespace boost {
namespace serialization {
template&lt;class Archive&gt;
void save(Archive &amp; ar, const shared_ptr &amp; x, const unsigned int /* version */)
{
// save shared ptr
...
}
template&lt;class Archive&gt;
void load(Archive &amp; ar, shared_ptr &amp; 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 &amp; hlp =
ar.template get_helper&lt;shared_ptr_serialization_helper&gt;(helper_instance_id);
// load shared pointer object
...
shared_ptr_serialization_helper &amp; hlp =
ar.template get_helper&lt;shared_ptr_serialization_helper&gt;(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&lt;T&gt; 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&lt;shared_ptr_serialization_helper&gt;();</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>
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.
This information includes version number, implementation level and tracking
@@ -267,7 +175,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 a display pixel might be
is revised. A light weight structure such as display pixel might be
declared in a header like this:
<pre><code>
@@ -295,14 +203,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 a portable binary format.
It should be possible to save such a class on one platform and load it on another.
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.
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 it's possible that a value could be written that couldn't be represented by the loading program. This is a
So its possible that a value could be written that couldn't be represented by the loading program. This is a
fairly obvious situation and easily handled by using the numeric types in
<a target="cstding" href="../../../boost/cstdint.hpp">&lt;boost/cstdint.hpp&gt;</a>
<P>
@@ -322,7 +230,7 @@ Another potential problem is illustrated by the following example:
template&lt;class T&gt;
struct my_wrapper {
template&lt;class Archive&gt;
Archive &amp; serialize ...
Archive & serialize ...
};
...
@@ -331,9 +239,9 @@ class my_class {
wchar_t a;
short unsigned b;
template&lt;class Archive&gt;
Archive &amp; serialize(Archive &amp; ar, unsigned int version){
ar &amp; my_wrapper(a);
ar &amp; my_wrapper(b);
Archive & serialize(Archive & ar, unsigned int version){
ar & my_wrapper(a);
ar & my_wrapper(b);
}
};
</code></pre>
@@ -379,7 +287,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 archived by requiring that all data serialized to an XML archive
used with any archive. This is achived 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
@@ -387,7 +295,7 @@ 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 guaranteed that all data can be serialized to all archive classes with maximum efficiency.
be guarenteed that all data can be serialized to all archive classes with maximum efficiency.
<h3><a name="export">Exporting Class Serialization</a></h3>
<a target="detail" href="traits.html#export">Elsewhere</a> in this manual, we have described
@@ -402,7 +310,7 @@ requirement.
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.
reference to it's base class.
<p>
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the same
@@ -414,7 +322,7 @@ 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
macro appear <b>after</b> and the inclusion of any archive
class headers for which code is to be instantiated.
So, code that uses <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
will look like the following:
@@ -427,22 +335,20 @@ will look like the following:
BOOST_CLASS_EXPORT(a)
... // other class headers and exports
</code></pre>
This will be true regardless of whether the code is part
This will be true regardless of whether the is part
of a stand alone executable, a static library or
a dynamic or shared library.
a dyanmic or shared library.
<p>
Including
Note that including
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
in the "a.hpp" header itself as one would do with
other serialization traits will make it difficult
or impossible to follow the rule above regarding
inclusion of archive headers before
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
is invoked. This 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.
is invoked. This is different than other serialization
traits which would normally be included in same file
as the class declaration.
<p>
This system has certain implications for placing code in static or shared
@@ -451,52 +357,45 @@ 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>.
<a href="archive_reference.html#polymorphic">Polymoprhic Archives</a>.
Also, when making shared libraries, there is currently a restriction
that only one such library can use <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
for any given type. All this will most likely make it inconvenient
to include <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
as part of the header of the class to be serialized. So, <b>the
best way to use <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
is to include it in the same module which implements the class</b>.
<p>
Strictly speaking, export should not be necessary if all pointer serialization
occurs through the most derived class. However, in order to detect
what would be a catastrophic error, the library traps ALL serializations through
a pointer to a polymorphic class which are not exported or otherwise registered.
what would be catastophic error, the library traps ALL serializations through
a pointer to a polymorphic which are not exported or otherwise registered.
So, in practice, be prepared to register or export all classes with one
or more virtual functions which are serialized through a pointer.
<p>
Note that the implementation of this functionality depends upon vendor
specific extensions to the C++ language. So, there is no guaranteed portability
specific extensions to the C++ language. So, there is no guarenteed portability
of programs which use this facility. However, all C++ compilers which
are tested with boost provide the required extensions. The library
includes the extra declarations required by each of these compilers.
It's reasonable to expect that future C++ compilers will support
these extensions or something equivalent.
<h3><a name="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
<h3><a name="dlls">DLLS - Serialization and Runtime Linking</a></h3>
Serialization code can be placed in libraries to be linked at runtime. That is,
code can be placed in DLLS(Windows) Shared Libraries(*nix), or static libraries
as well as the main executable. As long as
<a target="detail" href="serialization.html#export">
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
</a>
is not used, The serialization library imposes no special requirements
that need be taken into account when distributing code among various modules.
<p>
For static libraries, this is illustrated by
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
<code style="white-space: normal">demo_pimpl.cpp</code>
</a>,
@@ -507,87 +406,28 @@ 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 serialization is in a static library
where implementation of serializaton 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>
For runtime linked libraries this is illustrated by one of the tests:
<a href = "../test/test_dll_simple.cpp" target="test_dll_simple">
<code style="white-space: normal">test_dll_simple</code>
</a>,
and
<a href = "../test/dll_a.cpp" target="dll_a">
<code style="white-space: normal">dll_a.cpp</code>
<a 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
where implementation of serializaton is also completely separate
from the main program but the code is loaded at runtime. In this
example, this code is loaded automatically when the program which
uses it starts up, but it could just as well be loaded and unloaded
with an OS dependent API call.
<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&lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned int version);
</code></pre>
in the header, and
<pre><code>
template&lt;class Archive&gt;
void myclass::serialize(Archive &amp; ar, const unsigned int version){
...
}
BOOST_CLASS_EXPORT_IMPLEMENT(my_class)
#include &lt;boost/archive/text_oarchive&gt;
#include &lt;boost/archive/text_iarchive&gt;
template myclass::serialize(boost::archive::text_oarchive &amp; ar, const unsigned int version);
template myclass::serialize(boost::archive::text_iarchive &amp; 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
manipulation of types are runtime were required. These
are <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
for associating classes with external identifying strings (<b>GUID</b>)
and <a target="detail" href="void_cast.html"><code>void_cast</code></a>
@@ -617,33 +457,33 @@ 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.
With this in place, one can construct, serialize and destroy
about which only is know the <b>GUID</b> and a base class.
<h3><a name="multi_threading">Multi-Threading</a></h3>
The fundamental purpose of serialization would conflict with multiple
threads concurrently writing/reading from/to a single open archive instance.
The library implementation presumes that the application avoids such a situation.
thread concurrently writing/reading from/to a single open archive instance.
The library implementation presumes that the application avoids such an situtation.
<p>
However, Writing/Reading different archives simultaneously
in different tasks is permitted as each archive instance is (almost)
completely independent from any other archive instance. The only shared
information is some type tables which have been implemented using a
information are some type tables which have been implemented using a
lock-free thread-safe
<a target="detail" href="singleton.html">
<code style="white-space: normal">singleton</code>
</a>
described elsewhere in this documentation.
<p>
This singleton implementation guarantees that all of this shared
This singleton implementation guarentees that all of this shared
information is initialized when the code module which contains
it is loaded. The serialization library takes care to
them is loaded. The serialization library takes care to
ensure that these data structures are not subsequently
modified. The only time there could be a problem would
be if code is loaded/unloaded while another task is
serializing data. This could only occur for types whose
serialization is implemented in a dynamically loaded/unloaded DLL
serialization is implemented in a dynamically loaded/unload DLL
or shared library. So if the following is avoided:
<ul>
<li>Accessing the same archive instance from different tasks.
+6 -6
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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&lt;class T&gt;
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 &amp; object);
state_saver(T & object);
~state_saver();
};
</code></pre>
The complete implementation can be found
<a target="state_saver" href="../../../boost/serialization/state_saver.hpp">here</a>
<a target="state_saver" href="../../../boost/state_saver.hpp">here</a>
The following illustrates how this is expected to be used.
<pre><code>
#include &lt;boost/state_saver.hpp&gt;
void func(A &amp; a)
void func(A & a)
boost::state_saver&lt;A&gt; s(a);
... // alter state of a by calling non-const functions
... // call other functions
+3 -3
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -26,7 +26,7 @@ http://www.boost.org/LICENSE_1_0.txt)
</table>
<hr>
The header <code>&lt;boost/serialization/static_warning.hpp&gt;</code> supplies a single macro
The header <code>&lt;boost/static_warning.hpp&gt;</code> supplies a single macro
<code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>, which generates a compile time warning message if
the integral-constant-expression x is not true.
<p>
+5 -5
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -48,7 +48,7 @@ Usage of BOOST_STRONG_TYPEDEF
addresses this.
<pre></code>
<a target="strong_typedef" href="../../../boost/strong_typedef.hpp">
#include &lt;boost/serialization/strong_typedef.hpp&gt;
#include &lt;boost/strong_typedef.hpp&gt;
</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" which wraps an instance of its
which generates a class named "name" wraps and instance of its
primitive type and provides appropriate conversion operators in order
to make the new type substitutable for the one that it wraps.
-7
View File
@@ -6,10 +6,3 @@ pre{
MARGIN-LEFT: 0pt;
background-color: #EEEEEE;
}
/*
(C) Copyright 2008 Robert Ramey - http://www.rrsd.com .
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)
*/
-112
View File
@@ -1,112 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
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)
-->
<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>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</i></p>
</body>
</html>
+76 -376
View File
@@ -1,9 +1,9 @@
<!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 .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -33,12 +33,10 @@ 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 <code style="white-space: normal">int</code>, it wouldn't make sense to save
primitive types such as an <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
@@ -48,7 +46,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 explicitly assign
It is not generally necessary for the programmer to explictly 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
@@ -181,7 +179,7 @@ Default tracking traits are:
That is, addresses of addresses are not tracked by default.
<li>All current serialization wrappers such as <code style="white-space: normal">boost::serialization::nvp</code>,
<code style="white-space: normal">track_never</code>.
<li>For all other types, <code style="white-space: normal">track_selectively</code>.
<li>For all other types, <code style="white-space: normal">track_selectivly</code>.
That is addresses of serialized objects are tracked if and only if
one or more of the following is true:
<ul>
@@ -196,7 +194,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
inheritance structure with a virtual base class, object tracking
heritance 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
@@ -204,26 +202,16 @@ 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 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.
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>
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
satisfactory for our purposes for the following reasons:
statisfactory 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.
@@ -232,52 +220,45 @@ satisfactory 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 serialization.
consider equivalent for purposes of of serialization.
</ul>
<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.
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>
In a large majority of applications, the class name works just fine
for the external identifier string so the following short cut is
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>
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,
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.
When serializing an object through a pointer to its base class
and that base class is abstract (i.e. has at least one virtual function
assigned a value of 0), A compile error will be emitted. This is
addressable in one over several ways:
<ul>
<li>remove the =0 in the base classes so that the base class is no
longer abstract.
<li>implement is_abstract for your compiler. (code written according to
the C++ standard is included with this library. But it is known to fail
on several compilers.
<li>use the macro <code style="white-space: normal">BOOST_IS_ABSTRACT(my_class)</code> to indicate
that the class is an abstract base class. This will cause the compiler
to avoid generating code that causes this error.
This macro must be used in the global namespace, with full namespace
qualification of the argument class.
</ul>
<h3><a name="typeinfo">Type Information Implementation</a></h3>
This last trait is also related to the serialization of objects
through a base class pointer. The implementation of this facility
@@ -333,9 +314,10 @@ 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 differently from other types since, for example,
they usually are non-const objects while output archives require that any
Archives need to treat wrappers diffently from other types since, for example,
they usually are non-const object while output archives require that any
serialized object (with the exception of a wrapper) be const.
This header file <a href="../../../boost/serialization/wrapper.hpp">wrapper.hpp</a>
@@ -374,30 +356,7 @@ 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&lt;class T&gt;
struct is_bitwise_serializable
: public is_arithmetic&lt;T&gt;
{};
} }
</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
@@ -470,7 +429,7 @@ struct tracking_level&lt;nvp&lt;T&gt; &gt;
#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 objects will be serialized differently
portable to other platforms. It means the she 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>
@@ -512,290 +471,31 @@ 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>
<h3><a name="tracking">Bitwise serialization</a></h3>
Some simple classes could be serialized just by directly copying all bits
of the class. This is, in particular, the case for POD data types containing
no pointer members, and which are neither versioned nor tracked. Some archives,
such as non-portable binary archives can make us of this information to
substantially speed up serialization.
<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 &lt;&lt; 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 &lt;&lt; t;
</pre></code>
Likewise, the following code will trap at compile time:
<code style="white-space: normal"><pre>
T * t;
ar &gt;&gt; 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 &lt;&lt; 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 &lt;&lt; x;
...
x.f(); // change x in some way
...
ar &lt;&lt; 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 &lt;construct_from&gt; z;
template &lt;class Archive&gt;
void serialize(Archive &amp; ar, const unsigned version){
ar &lt;&lt; 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&lt;construct_from&gt;</code>
is not going to have a single raw pointer shared amongst the instances. Each loaded
<code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code> is going to
have its own 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 &lt;&lt; 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 &lt;&lt; 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 &lt;&lt; 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 &lt;= 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 &lt;&lt; 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 &gt;&gt; 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 &lt;&lt; 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>
To indicate the possibility of bitwise serialization the type trait defined
in the header
file <a href="../../../boost/serialization/is_bitwise_serializable.hpp" target="is_bitwise_serializable">is_bitwise_serializable.hpp</a>
is used:
<pre><code>
namespace boost { namespace serialization {
template<class T>
struct is_bitwise_serializable
: public is_arithmetic<T>
{};
} }
</code></pre>
is used, and can be specialized for other classes. The specialization
is made easy by the corresponding macro:
<pre><code>
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
</code></pre>
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004 and Matthias Troyer 2006.
+10 -10
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -123,7 +123,7 @@ int main() {
gps_position newg;
{
// create and open an archive for input
std::ifstream ifs("filename");
std::ifstream ifs("filename", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia &gt;&gt; newg;
@@ -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 these class members in the same sequence as they were saved.
load theese 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 occurrence. Only
class had <code style="white-space: normal">public</code> members - not a common occurence. 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 &amp; ar, const unsigned int version)
{
int i;
for(i = 0; i &lt; 10; ++i)
for(i = 0; i &lt 10; ++i)
ar &amp; 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 important that 'name' be a valid xml tag, else it
tag. It is importanted that 'name' be a valid xml tag, else it
will be impossible to restore the archive.
For more information see
<a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>.
@@ -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 implementations for the Standard Library, the serialization library
with serialization implemenations for the Standard Library, the serialization library
includes implementation of serialization for
<code style="white-space: normal">boost::shared ptr</code>. Given this, it should be
easy to alter any of these examples to eliminate the memory leak. This is left
as an exercise for the reader.
as an excercise for the reader.
<hr>
<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
+9 -9
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -29,7 +29,7 @@ http://www.boost.org/LICENSE_1_0.txt)
C++ includes the operator <code style="white-space: normal">dynamic_cast&lt;T&gt;(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 serialization of pointers to only such classes would diminish the applicability
Limiting the serializaton of pointers to only such class 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&lt;class Derived, class Base&gt;
const void_cast_detail::void_caster &amp;
const void_cast_detail::void_caster &
void_cast_register(
Derived const * derived = NULL,
Base * const base = NULL
);
)
</code></pre></h4></dt>
<dd>
This function "registers" a pair of related types. It stores the fact that
@@ -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 &amp; derived_type,
extended_type_info const &amp; 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 &amp; derived_type,
extended_type_info const &amp; base_type,
extended_type_info const & derived_type,
extended_type_info const & base_type,
void * const t
);
</code></pre></h4></dt>
+16 -16
View File
@@ -2,8 +2,8 @@
<html>
<!--
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
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>
@@ -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 a sequence of bytes stored as raw
A binary object is just an 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 a pair to the archive class.
Its sole purpose is to pass the data size and address as pair to the archive class.
<h3><a name="arrays">Arrays</a></h3>
An array is a contiguous sequence of homogeneous data types, such as a builtin
C-array, a <code>boost::array&lt;T&gt;</code> or a <code>std::vector&lt;T&gt;</code>.
C-array, a <code>boost::array&lt;T></code> or a <code>std::vector&lt;T></code>.
The purpose of this wrapper is to support archive types (such as binary
archives) that provide optimized serialization for contiguous sequences of
objects of the same type.
@@ -75,12 +75,12 @@ array.hpp
</a>
includes the function
<pre><code>
template &lt;T&gt;
template &lt;T>
boost::serialization::make_array(T* t, std::size_t size);
</code></pre>
which will construct a temporary <code>array</code> object
<pre><code>
template&lt;class T&gt;
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 serialize each array element.
Its default serialization is to use serialize each array element.
Note that it doesn't allocated any storage or create any objects.
Its sole purpose is to pass the data type, size and address to the archive class.
@@ -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 serializing the size of a C++ collection, so
</a>. This type should be used for serializaing the size of a C++ collection, so
that the archive can pick the best integral representation for the serialization
of collection sizes. This is necessary since, although <code>std::size_t</code>
is guaranteed to be an integral type large enough to represent the size of
@@ -158,27 +158,27 @@ The xml archive classes contain code similar to:
<pre><code>
// special treatment for name-value pairs.
template&lt;class T&gt;
xml_oarchive &amp; operator&amp;(const boost::serialization::nvp&lt;T&gt; &amp; 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 &amp; t.value();
*this & t.value();
// write an xml end tag
end_tag(t.name());
}
</code></pre>
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
The most obvious and convient name to assign to as the XML data item name
is - surpise! - the name of the C++ class data member. So our serialization
code will look like:
<pre><code>
ar &amp; 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 &amp; 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 &amp; 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>
+38 -30
View File
@@ -7,41 +7,49 @@
# See http://www.boost.org/libs/serialization for the library home page.
project libs/serialization/example
: id serialization_example
: id serialization_test
: requirements <library>../build//boost_serialization
;
import testing ;
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
;
# for [ requires auto_ptr ]
import-search /boost/config/checks ;
import config : requires ;
rule demo_bsl_run ( demo-name : othersources * : requirements * )
{
return [ run
# sources
$(demo-name).cpp
$(othersources).cpp
: # command
: # input files
: # requirements
# toolset suppress-warnings
<toolset>gcc:<cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy"
<toolset>msvc-8.0:<cxxflags>"-wd4996"
<toolset>borland:<cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066"
# toolset optimizations
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
<toolset>msvc:<cxxflags>"-Gy"
# toolset shared library support
<toolset>como,<runtime-link>shared:<build>no
<toolset>msvc,<stdlib>stlport,<runtime-link>shared:<build>no
<toolset>cw,<runtime-link>static:<build>no
$(requirements)
: # test name
$(demo-name)
]
;
}
test-suite "demo-suite" :
# demos
[ test-bsl-run demo ]
[ test-bsl-run demo_auto_ptr : : : [ requires auto_ptr ] ]
[ test-bsl-run demo_exception ]
[ test-bsl-run demo_fast_archive ]
[ test-bsl-run demo_log : log_archive : : <link>static ]
[ 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 : : <link>static ]
[ 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 ]
[ demo_bsl_run demo ]
[ demo_bsl_run demo_auto_ptr ]
[ demo_bsl_run demo_exception ]
[ demo_bsl_run demo_fast_archive ]
[ demo_bsl_run demo_pimpl : demo_pimpl_A ]
[ demo_bsl_run demo_polymorphic : demo_polymorphic_A ]
[ demo_bsl_run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
[ demo_bsl_run demo_shared_ptr ]
[ demo_bsl_run demo_xml ]
[ demo_bsl_run demo_xml_save ]
[ demo_bsl_run demo_xml_load : : <dependency>demo_xml_save ]
;
+24 -25
View File
@@ -2,12 +2,11 @@
// demo.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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> // NULL
#include <iomanip>
#include <iostream>
#include <fstream>
@@ -17,31 +16,31 @@
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/cstdint.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/is_abstract.hpp>
/////////////////////////////////////////////////////////////
// The intent of this program is to serve as a tutorial for
// 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 sufficiently complete to
// The intent is to create an example suffciently 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
// There are different kinds of stops. Bus stops in general will
// will appear on multiple routes. A schedule will include
// multiple trips on the same route.
// muliple trips on the same route.
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
// llustrates serialization for a simple type
//
class gps_position
{
@@ -57,13 +56,13 @@ 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)
{}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
return os << ' ' << gp.degrees << (unsigned char)176 << gp.minutes << '\'' << gp.seconds << '"';
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}
/////////////////////////////////////////////////////////////
@@ -94,7 +93,7 @@ public:
virtual ~bus_stop(){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
BOOST_IS_ABSTRACT(bus_stop)
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
@@ -147,7 +146,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
@@ -162,7 +161,7 @@ public:
//
// illustrates serialization of STL collection templates.
//
// illustrates serialization of polymorphic pointer (bus stop *);
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient. That is objects pointed to by more than one
@@ -202,7 +201,7 @@ std::ostream & operator<<(std::ostream &os, const bus_route &br)
// 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' << "0x" << std::hex << reinterpret_cast<boost::uintptr_t>(*it) << std::dec << ' ' << **it;
os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
}
return os;
}
@@ -213,7 +212,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
@@ -233,7 +232,7 @@ public:
if(file_version >= 2)
// read the drivers name
ar & driver;
// all versions have the following info
// all versions have the follwing info
ar & hour & minute;
}
@@ -265,7 +264,7 @@ public:
}
bus_schedule(){}
};
BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)
BOOST_CLASS_VERSION(bus_schedule, 2)
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
{
@@ -299,7 +298,7 @@ restore_schedule(bus_schedule &s, const char * filename)
}
int main(int argc, char *argv[])
{
{
// make the schedule
bus_schedule original_schedule;
@@ -326,7 +325,7 @@ int main(int argc, char *argv[])
"Lincoln Memorial"
);
// make a route
// make a routes
bus_route route0;
route0.append(bs0);
route0.append(bs1);
@@ -337,7 +336,7 @@ int main(int argc, char *argv[])
original_schedule.append("bob", 9, 57, &route0);
original_schedule.append("alice", 11, 02, &route0);
// make another route
// make aother routes
bus_route route1;
route1.append(bs3);
route1.append(bs2);
@@ -351,7 +350,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";
@@ -359,7 +358,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());
+10 -10
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_auto_ptr.cpp
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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 <list>
@@ -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);
-318
View File
@@ -1,318 +0,0 @@
#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 .
// 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)
// 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
-317
View File
@@ -1,317 +0,0 @@
#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 .
// 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)
// 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
-113
View File
@@ -1,113 +0,0 @@
#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 .
// 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)
// 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
-112
View File
@@ -1,112 +0,0 @@
#ifndef BOOST_SERIALIZATION_TEST_B_HPP
#define BOOST_SERIALIZATION_TEST_B_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// B.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// 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)
// 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
+10 -11
View File
@@ -1,32 +1,31 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_exception.cpp
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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
@@ -127,7 +126,7 @@ private:
// case 1:
template<class Archive>
void School::serialize(Archive & ar, const unsigned int /* file_version */){
// if an exception occurs while loading courses
// if an exeception occurs while loading courses
// the structure courses may have some courses each
// with students
ar & all_courses;
@@ -155,7 +154,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 exception occurs while loading courses
// if an exeception occurs while loading courses
// the structure courses may have some courses each
// with students
try{
@@ -167,7 +166,7 @@ void School::load(Archive & ar, const unsigned int /* file_version */){
ar >> all_students; // create students that have no courses
}
catch(std::exception){
// eliminate any dangling references
// elminate any dangling references
all_courses.clear();
all_students.clear();
throw;
+36 -39
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_fast_binary_archive.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// should pass compilation and execution
@@ -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,22 +24,25 @@
#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
@@ -48,38 +51,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){
base_t::save_override(t);
void save_override(T & t, BOOST_PFTO int){
base_t::save_override(t, 0);
// verify that this program is in fact working by making sure
// that arrays are getting passed here
BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) );
}
template<int N>
void save_override(const int (& t)[N]){
void save_override(const int (& t)[N] , int){
save_binary(t, sizeof(t));
}
template<int N>
void save_override(const unsigned int (& t)[N]){
void save_override(const unsigned int (& t)[N], int){
save_binary(t, sizeof(t));
}
template<int N>
void save_override(const long (& t)[N]){
void save_override(const long (& t)[N], int){
save_binary(t, sizeof(t));
}
template<int N>
void save_override(const unsigned long (& t)[N]){
void save_override(const unsigned long (& t)[N], int){
save_binary(t, sizeof(t));
}
public:
@@ -91,23 +94,20 @@ 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){
base_t::load_override(t);
void load_override(T & t, BOOST_PFTO int){
base_t::load_override(t, 0);
BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) );
}
template<int N>
void load_override(int (& t)[N]){
void load_override(int (& t)[N], int){
load_binary(t, sizeof(t));
}
template<int N>
void load_override(unsigned int (& t)[N]){
void load_override(unsigned int (& t)[N], int){
load_binary(t, sizeof(t));
}
template<int N>
void load_override(long (& t)[N]){
void load_override(long (& t)[N], int){
load_binary(t, sizeof(t));
}
template<int N>
void load_override(unsigned long (& t)[N]){
void load_override(unsigned long (& t)[N], int){
load_binary(t, sizeof(t));
}
public:
@@ -157,16 +157,13 @@ 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;
}
+14 -15
View File
@@ -6,32 +6,31 @@
// demo_gps.hpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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/cstdint.hpp>
#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
// There are different kinds of stops. Bus stops in general will
// will appear on multiple routes. A schedule will include
// multiple trips on the same route.
// muliple trips on the same route.
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
// llustrates serialization for a simple type
//
class gps_position
{
@@ -52,14 +51,14 @@ 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)
{}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
return os << ' ' << gp.degrees << (unsigned char)176 << gp.minutes << '\'' << gp.seconds << '"';
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}
/////////////////////////////////////////////////////////////
@@ -92,7 +91,7 @@ public:
virtual ~bus_stop(){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
BOOST_IS_ABSTRACT(bus_stop)
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
@@ -160,7 +159,7 @@ public:
//
// illustrates serialization of STL collection templates.
//
// illustrates serialization of polymorphic pointer (bus stop *);
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient. That is objects pointed to by more than one
@@ -200,7 +199,7 @@ std::ostream & operator<<(std::ostream &os, const bus_route &br)
// 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' << "0x" << std::hex << reinterpret_cast<boost::uintptr_t>(*it) << std::dec << ' ' << **it;
os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
}
return os;
}
@@ -210,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
@@ -237,7 +236,7 @@ public:
if(file_version >= 2)
// read the drivers name
ar & BOOST_SERIALIZATION_NVP(driver);
// all versions have the following info
// all versions have the follwing info
ar & BOOST_SERIALIZATION_NVP(hour)
& BOOST_SERIALIZATION_NVP(minute);
}
-76
View File
@@ -1,76 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_log.cpp
//
// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
// 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)
#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;
}
+3 -3
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_pimpl.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// should pass compilation and execution
+8 -8
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_pimpl_A.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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)
#include <boost/archive/text_iarchive.hpp>
@@ -31,15 +31,15 @@ template<class Archive>
void A::serialize(Archive & ar, const unsigned int /* file_version */){
ar & pimpl;
}
// without the explicit instantiation below, the program will
// fail to link for lack of instantiation of the above function
// without the explicit instantiations below, the program will
// fail to link for lack of instantiantiation of the above function
// note: the following failed to fix link errors for vc 7.0 !
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
);
+3 -3
View File
@@ -4,9 +4,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_pimpl_A.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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)
// class whose declaration is hidden by a pointer
+7 -7
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_polymorphic.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// should pass compilation and execution
@@ -26,10 +26,10 @@ int main(int argc, char* argv[])
// test with a text archive
std::stringstream ss;
{
// instantiate archive which inherits polymorphic interface
// instantiate archive which inhertis 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 inherits polymorphic interface
// instantiate archive which inhertis 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;
}
+16 -15
View File
@@ -1,9 +1,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_polymorphic_A.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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,15 +12,16 @@
#include "demo_polymorphic_A.hpp"
// 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
);
// 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;
}
+5 -10
View File
@@ -4,9 +4,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_polymorphic_A.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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)
namespace boost {
@@ -20,13 +20,8 @@ class polymorphic_oarchive;
struct A {
// class a contains a pointer to a "hidden" declaration
template<class Archive>
void serialize(
Archive & ar,
const unsigned int file_version
){
ar & data;
}
void serialize(boost::archive::polymorphic_iarchive & ar, const unsigned int file_version);
void serialize(boost::archive::polymorphic_oarchive & ar, const unsigned int file_version);
int data;
bool operator==(const A & rhs) const {
return data == rhs.data;
+8 -14
View File
@@ -3,15 +3,11 @@
// demo_portable_archive.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// should pass compilation and execution
// 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>
#include "portable_binary_oarchive.hpp"
@@ -27,7 +23,6 @@ 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;
@@ -43,14 +38,13 @@ public:
c == rhs.c
&& i == rhs.i
&& i2 == rhs.i2
&& ui == rhs.ui
&& l == rhs.l
&& ui == rhs.ui
&& l == rhs.l
&& ul == rhs.ul
;
}
A() :
c(0xFF & std::rand()),
pa(0),
c(std::rand()),
i(std::rand()),
i2(0x80),
ui(std::rand()),
@@ -65,7 +59,7 @@ int main( int /* argc */, char* /* argv */[] )
A a1;
std::stringstream ss;
{
{
portable_binary_oarchive pboa(ss);
pboa << a;
}
@@ -77,7 +71,7 @@ int main( int /* argc */, char* /* argv */[] )
return 1;
ss.clear();
{
{
portable_binary_oarchive pboa(ss, endian_big);
pboa << a;
}
@@ -89,7 +83,7 @@ int main( int /* argc */, char* /* argv */[] )
return 1;
ss.clear();
{
{
portable_binary_oarchive pboa(ss, endian_big);
pboa << a;
}
+8 -9
View File
@@ -3,22 +3,21 @@
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . Polymorphic
// derived pointer example by David Tonge.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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 <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
@@ -42,8 +41,8 @@ private:
}
public:
static int count;
A(){++count;} // default constructor
virtual ~A(){--count;} // default destructor
A::A(){++count;} // default constructor
virtual A::~A(){--count;} // default destructor
};
BOOST_SERIALIZATION_SHARED_PTR(A)
@@ -61,8 +60,8 @@ private:
}
public:
static int count;
B() : A() {};
virtual ~B() {};
B::B() : A() {};
virtual B::~B() {};
};
BOOST_SERIALIZATION_SHARED_PTR(B)
@@ -82,7 +81,7 @@ void display(boost::shared_ptr<A> &spa, boost::shared_ptr<A> &spa1)
std::cout << "unique element count = " << A::count << std::endl;
}
int main(int /* argc */, char * /*argv*/[])
int main(int argc, char *argv[])
{
std::string filename(boost::archive::tmpdir());
filename += "/testfile";
-75
View File
@@ -1,75 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_log.cpp
//
// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
// 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)
#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;
}
-94
View File
@@ -1,94 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
//
// demo_trivial_archive.cpp
//
// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
// 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)
#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;
}
+8 -8
View File
@@ -3,8 +3,8 @@
// demo_xml.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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 <iomanip>
@@ -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 route
// make a routes
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 another route
// make aother routes
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());
+11 -12
View File
@@ -6,8 +6,8 @@
// demo_xml.hpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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)
@@ -16,7 +16,6 @@
#include <iostream>
#include <fstream>
#include <boost/cstdint.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
@@ -24,14 +23,14 @@
// 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
// There are different kinds of stops. Bus stops in general will
// will appear on multiple routes. A schedule will include
// multiple trips on the same route.
// muliple trips on the same route.
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
// llustrates serialization for a simple type
//
class gps_position
{
@@ -52,14 +51,14 @@ 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)
{}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
return os << ' ' << gp.degrees << (unsigned char)176 << gp.minutes << '\'' << gp.seconds << '"';
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}
/////////////////////////////////////////////////////////////
@@ -160,7 +159,7 @@ public:
//
// illustrates serialization of STL collection templates.
//
// illustrates serialization of polymorphic pointer (bus stop *);
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient. That is objects pointed to by more than one
@@ -200,7 +199,7 @@ std::ostream & operator<<(std::ostream &os, const bus_route &br)
// 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' << "0x" << std::hex << reinterpret_cast<boost::uintptr_t>(*it) << std::dec << ' ' << **it;
os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
}
return os;
}
@@ -210,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
@@ -237,7 +236,7 @@ public:
if(file_version >= 2)
// read the drivers name
ar & BOOST_SERIALIZATION_NVP(driver);
// all versions have the following info
// all versions have the follwing info
ar & BOOST_SERIALIZATION_NVP(hour)
& BOOST_SERIALIZATION_NVP(minute);
}
+3 -3
View File
@@ -3,8 +3,8 @@
// demo_xml_load.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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>
@@ -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;
+6 -6
View File
@@ -3,8 +3,8 @@
// demo_xml_save.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// 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>
@@ -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 route
// make a routes
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 an other route
// make aother routes
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";
-45
View File
@@ -1,45 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// fix_six.cpp
// Copyright 2010 Robert Ramey
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
#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();
}
-32
View File
@@ -1,32 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// log_archive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// 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)
// 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
-81
View File
@@ -1,81 +0,0 @@
#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 .
// 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)
// 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
@@ -1,34 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_portable_binary_iarchive.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// 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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#define BOOST_ARCHIVE_SOURCE
#include "polymorphic_portable_binary_iarchive.hpp"
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_iarchive.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class binary_iarchive_impl<
polymorphic_portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>;
template class detail::archive_pointer_iserializer<
polymorphic_portable_binary_iarchive
> ;
} // namespace archive
} // namespace boost
@@ -1,35 +0,0 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# 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 .
// 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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/archive/detail/polymorphic_iarchive_dispatch.hpp>
#include "portable_binary_iarchive.hpp"
typedef boost::archive::detail::polymorphic_iarchive_dispatch<
portable_binary_iarchive
> polymorphic_portable_binary_iarchive;
#include <boost/version.hpp>
#if BOOST_VERSION > 103401
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
polymorphic_portable_binary_iarchive
)
#endif
#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
@@ -1,35 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_portable_binary_oarchive.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// 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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#define BOOST_ARCHIVE_SOURCE
#include "polymorphic_portable_binary_oarchive.hpp"
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_oarchive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of binary stream
template class binary_oarchive_impl<
polymorphic_portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>;
template class detail::archive_pointer_oserializer<
polymorphic_portable_binary_oarchive
> ;
} // namespace archive
} // namespace boost
@@ -1,34 +0,0 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# 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 .
// 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)
// 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
+3 -7
View File
@@ -1,18 +1,14 @@
#ifndef PORTABLE_BINARY_ARCHIVE_HPP
#define PORTABLE_BINARY_ARCHIVE_HPP
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// 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)
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/pfto.hpp>
#include <boost/static_assert.hpp>
#include <climits>
@@ -21,7 +17,7 @@
#endif
#include <boost/archive/basic_archive.hpp>
#include <boost/predef/other/endian.h>
#include <boost/detail/endian.hpp>
enum portable_binary_archive_flags {
endian_big = 0x4000,
+26 -27
View File
@@ -1,23 +1,24 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <string>
//#include <cstring> // memcpy
#include <boost/predef/other/endian.h>
#include <boost/serialization/throw_exception.hpp>
#include <boost/detail/endian.hpp>
#include <boost/throw_exception.hpp>
#include <boost/archive/archive_exception.hpp>
#include "portable_binary_iarchive.hpp"
void
void
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
char size;
l = 0;
@@ -32,36 +33,36 @@ portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
size = -size;
if(size > maxsize)
boost::serialization::throw_exception(
boost::throw_exception(
portable_binary_iarchive_exception()
);
char * cptr = reinterpret_cast<char *>(& l);
#if BOOST_ENDIAN_BIG_BYTE
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
#endif
this->primitive_base_t::load_binary(cptr, size);
#if BOOST_ENDIAN_BIG_BYTE
#ifdef BOOST_BIG_ENDIAN
if(m_flags & endian_little)
#else
if(m_flags & endian_big)
#endif
reverse_bytes(size, cptr);
reverse_bytes(size, cptr);
if(negative)
l = -l;
}
void
portable_binary_iarchive::load_override(
boost::archive::class_name_type & t
boost::archive::class_name_type & t, int
){
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
load_override(cn);
load_override(cn, 0);
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
boost::serialization::throw_exception(
boost::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_class_name)
);
@@ -70,31 +71,31 @@ portable_binary_iarchive::load_override(
t.t[cn.size()] = '\0';
}
void
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(
if(file_signature != boost::archive::ARCHIVE_SIGNATURE())
boost::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_signature
)
);
// make sure the version of the reading archive library can
// support the format of the archive being read
boost::archive::library_version_type input_library_version;
boost::archive::version_type input_library_version;
* this >> input_library_version;
// extra little .t is to get around borland quirk
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
boost::serialization::throw_exception(
if(boost::archive::ARCHIVE_VERSION() < input_library_version.t)
boost::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::unsupported_version
)
);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
this->set_library_version(input_library_version);
//#else
@@ -111,19 +112,17 @@ portable_binary_iarchive::init(unsigned int flags){
m_flags = x << CHAR_BIT;
}
#include <boost/archive/impl/archive_serializer_map.ipp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
namespace detail {
template class archive_serializer_map<portable_binary_iarchive>;
}
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
template class basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::char_type,
std::istream::traits_type
> ;
+36 -52
View File
@@ -2,7 +2,7 @@
#define PORTABLE_BINARY_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
@@ -14,19 +14,19 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.hpp
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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 <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/shared_ptr_helper.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include "portable_binary_archive.hpp"
@@ -34,50 +34,47 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_iarchive_exception :
public boost::archive::archive_exception
class portable_binary_iarchive_exception :
public virtual boost::archive::archive_exception
{
public:
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)
typedef enum {
incompatible_integer_size
} exception_code;
portable_binary_iarchive_exception(exception_code c = incompatible_integer_size )
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
switch(m_exception_code){
switch(code){
case incompatible_integer_size:
msg = "integer cannot be represented";
break;
default:
msg = boost::archive::archive_exception::what();
assert(false);
break;
boost::archive::archive_exception::what();
}
return msg;
}
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" input binary archive. It addresses integer size and endianness so
// "Portable" input binary archive. It addresses integer size and endienness so
// that binary archives can be passed across systems. Note:floating point types
// not addressed here
class portable_binary_iarchive :
public boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::char_type,
std::istream::traits_type
>,
public boost::archive::detail::common_iarchive<
portable_binary_iarchive
>
{
,
public boost::archive::detail::shared_ptr_helper
{
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::char_type,
std::istream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_iarchive<
@@ -103,26 +100,7 @@ protected:
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));
t = static_cast<T>(l);
}
void load(std::string & t){
this->primitive_base_t::load(t);
@@ -148,21 +126,27 @@ protected:
void load(unsigned char & t){
this->primitive_base_t::load(t);
}
typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
// intermediate level to support override of operators
// fot templates in the absence of partial function
// template ordering
typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
detail_common_iarchive;
template<class T>
void load_override(T & t){
this->detail_common_iarchive::load_override(t);
void load_override(T & t, BOOST_PFTO int){
this->detail_common_iarchive::load_override(t, 0);
}
void load_override(boost::archive::class_name_type & t);
// binary files don't include the optional information
void load_override(boost::archive::class_id_optional_type &){}
void load_override(boost::archive::class_name_type & t, int);
// binary files don't include the optional information
void load_override(
boost::archive::class_id_optional_type & /* t */,
int
){}
void init(unsigned int flags);
public:
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
primitive_base_t(
* is.rdbuf(),
* is.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
@@ -173,13 +157,13 @@ public:
portable_binary_iarchive(
std::basic_streambuf<
std::istream::char_type,
std::istream::char_type,
std::istream::traits_type
> & bsb,
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
+16 -18
View File
@@ -1,18 +1,18 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.cpp
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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 <boost/detail/endian.hpp>
#include "portable_binary_oarchive.hpp"
void
void
portable_binary_oarchive::save_impl(
const boost::intmax_t l,
const char maxsize
@@ -45,9 +45,9 @@ portable_binary_oarchive::save_impl(
else
ll = l;
char * cptr = reinterpret_cast<char *>(& ll);
#if BOOST_ENDIAN_BIG_BYTE
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
if(m_flags & endian_little)
if(m_flags & endian_big)
reverse_bytes(size, cptr);
#else
if(m_flags & endian_big)
@@ -56,41 +56,39 @@ portable_binary_oarchive::save_impl(
this->primitive_base_t::save_binary(cptr, size);
}
void
void
portable_binary_oarchive::init(unsigned int flags) {
if(m_flags == (endian_big | endian_little)){
boost::serialization::throw_exception(
boost::throw_exception(
portable_binary_oarchive_exception()
);
}
if(0 == (flags & boost::archive::no_header)){
// write signature in an archive version independent manner
const std::string file_signature(
boost::archive::BOOST_ARCHIVE_SIGNATURE()
boost::archive::ARCHIVE_SIGNATURE()
);
* this << file_signature;
// write library version
const boost::archive::library_version_type v(
boost::archive::BOOST_ARCHIVE_VERSION()
const boost::archive::version_type v(
boost::archive::ARCHIVE_VERSION()
);
* this << v;
}
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
}
#include <boost/archive/impl/archive_serializer_map.ipp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost {
namespace archive {
namespace detail {
template class archive_serializer_map<portable_binary_oarchive>;
}
template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
template class basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::char_type,
std::ostream::traits_type
> ;
+21 -20
View File
@@ -2,7 +2,7 @@
#define PORTABLE_BINARY_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
@@ -14,9 +14,9 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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.
@@ -33,12 +33,12 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_oarchive_exception :
public boost::archive::archive_exception
class portable_binary_oarchive_exception :
public virtual boost::archive::archive_exception
{
public:
typedef enum {
invalid_flags
invalid_flags
} exception_code;
portable_binary_oarchive_exception(exception_code c = invalid_flags )
{}
@@ -56,14 +56,14 @@ public:
};
/////////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
// "Portable" output binary archive. This is a variation of the native binary
// archive. it addresses integer size and endienness so that binary archives can
// be passed across systems. Note:floating point types not addressed here
class portable_binary_oarchive :
public boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::char_type,
std::ostream::traits_type
>,
public boost::archive::detail::common_oarchive<
@@ -72,7 +72,7 @@ class portable_binary_oarchive :
{
typedef boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_oarchive<
@@ -128,20 +128,21 @@ protected:
// 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>
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);
void save_override(T & t, BOOST_PFTO int){
this->detail_common_oarchive::save_override(t, 0);
}
// explicitly convert to char * to avoid compile ambiguities
void save_override(const boost::archive::class_name_type & t){
void save_override(const boost::archive::class_name_type & t, int){
const std::string s(t);
* this << s;
}
// binary files don't include the optional information
// binary files don't include the optional information
void save_override(
const boost::archive::class_id_optional_type & /* t */
const boost::archive::class_id_optional_type & /* t */,
int
){}
void init(unsigned int flags);
@@ -159,13 +160,13 @@ public:
portable_binary_oarchive(
std::basic_streambuf<
std::ostream::char_type,
std::ostream::char_type,
std::ostream::traits_type
> & bsb,
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
-167
View File
@@ -1,167 +0,0 @@
#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 .
// 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)
// 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
+55
View File
@@ -0,0 +1,55 @@
#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
+67 -52
View File
@@ -2,36 +2,22 @@
#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// archive/archive_exception.hpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// (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 <exception>
#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
#include <cassert>
namespace boost {
namespace archive {
@@ -39,62 +25,91 @@ namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by archives
//
class BOOST_SYMBOL_VISIBLE archive_exception :
class 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 exception not listed below
unregistered_class, // attempt to serialize a pointer of
other_exception, // any excepton not listed below
unregistered_class, // attempt to serialize a pointer of an
// 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
// 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.
// 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.
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
input_stream_error, // error on input stream
stream_error, // i/o error on stream
invalid_class_name, // class name greater than the maximum permitted.
// most likely a corrupted archive or an attempt
// to insert virus via buffer overrun method.
unregistered_cast, // base - derived relationship not registered with
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;
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;
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)
{}
};
}// namespace archive
}// namespace boost
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
+126
View File
@@ -0,0 +1,126 @@
#ifndef BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP
#define BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP
// (C) Copyright 2005 Matthias Troyer and Dave Abrahams
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
//#include <boost/archive/archive_exception.hpp>
namespace boost { namespace archive { namespace array {
// To conveniently array-optimize an input archive X:
//
// * Derive it from iarchive<X, Impl>, where Impl is an
// archive implementation base class from
// Boost.Serialization
//
// * add a member function template that implements the
// procedure for serializing arrays of T (for appropriate T)
//
// template <class T>
// load_array(serialization::array<T> &, unsigned int)
//
// * add a unary MPL lambda expression member called
// use_array_optimization whose result is convertible to
// mpl::true_ iff array elements of type T can be serialized
// with the load_array member function, and to mpl::false_ if
// the unoptimized procedure must be used.
template <class Archive>
class iarchive
: public archive::detail::common_iarchive<Archive>
{
typedef archive::detail::common_iarchive<Archive> Base;
public:
iarchive(unsigned int flags)
: archive::detail::common_iarchive<Archive>(flags)
{}
// load_override for std::vector and serialization::array dispatches to
// load_optimized with an additional argument.
//
// If that argument is of type mpl::true_, an optimized serialization is provided
// If it is false, we just forward to the default serialization in the base class
//the default version dispatches to the base class
template<class T>
void load_optimized(T &t, unsigned int version, mpl::false_)
{
Base::load_override(t, version);
}
// the optimized implementation for vector uses serialization::array
template<class ValueType, class Allocator>
void load_optimized(
std::vector<ValueType, Allocator> &t, unsigned int version, mpl::true_)
{
t.clear();
// retrieve number of elements
serialization::collection_size_type count;
*this->This() >> BOOST_SERIALIZATION_NVP(count);
t.resize(count);
if (!t.empty())
* this->This() >> serialization::make_array(serialization::detail::get_data(t),t.size());
}
// the optimized implementation for serialization::array uses save_array
template<class ValueType>
void load_optimized(
serialization::array<ValueType> &t, unsigned int version, mpl::true_)
{
this->This()->load_array(t,version);
}
// to load a vector:
// if the value type is trivially constructable or an optimized array save exists,
// then we can use the optimized version
template<class ValueType, class Allocator>
void load_override(std::vector<ValueType,Allocator> &x, unsigned int version)
{
typedef typename mpl::and_<
mpl::not_<is_same<ValueType,bool> >,
mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, ValueType>
>::type use_optimized;
load_optimized(x,version, use_optimized() );
}
// dispatch loading of arrays to the optimized version where supported
template<class ValueType>
void load_override(serialization::array<ValueType> const& x, unsigned int version)
{
typedef typename mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, ValueType
>::type use_optimized;
load_optimized(const_cast<serialization::array<ValueType>&>(x),version,use_optimized());
}
// Load everything else in the usual way, forwarding on to the base class
template<class T>
void load_override(T & x, unsigned BOOST_PFTO int version)
{
Base::load_override(x, static_cast<unsigned int>(version));
}
};
} } } // end namespace boost::archive::array
#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
+124
View File
@@ -0,0 +1,124 @@
#ifndef BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
#define BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP
// (C) Copyright 2005 Matthias Troyer and Dave Abrahams
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/pfto.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost { namespace archive { namespace array {
// To conveniently array-optimize an output archive X:
//
// * Derive it from oarchive<X, Impl>, where Impl is an
// archive implementation base class from
// Boost.Serialization
//
// * add a member function template that implements the
// procedure for serializing arrays of T (for appropriate T)
//
// template <class T>
// save_array(serialization::array<T> const &, unsigned int)
//
// * add a unary MPL lambda expression member called
// use_array_optimization whose result is convertible to
// mpl::true_ iff array elements of type T can be serialized
// with the load_array member function, and to mpl::false_ if
// the unoptimized procedure must be used.
template <class Archive>
class oarchive
: public archive::detail::common_oarchive<Archive>
{
typedef archive::detail::common_oarchive<Archive> Base;
public:
oarchive(unsigned int flags)
: archive::detail::common_oarchive<Archive>(flags)
{}
// save_override for std::vector and serialization::array dispatches to
// save_optimized with an additional argument.
//
// If that argument is of type mpl::true_, an optimized serialization is provided
// If it is false, we just forward to the default serialization in the base class
//the default version dispatches to the base class
template<class T>
void save_optimized(T const &t, unsigned int version, mpl::false_)
{
Base::save_override(t, version);
}
// the optimized implementation for vector uses serialization::array
template<class ValueType, class Allocator>
void save_optimized(
const std::vector<ValueType, Allocator> &t, unsigned int, mpl::true_)
{
const serialization::collection_size_type count(t.size());
* this->This() << BOOST_SERIALIZATION_NVP(count);
if (!t.empty())
* this->This() << serialization::make_array(serialization::detail::get_data(t),t.size());
}
// the optimized implementation for serialization::array uses save_array
template<class ValueType>
void save_optimized(
const serialization::array<ValueType> &t, unsigned int version, mpl::true_)
{
this->This()->save_array(t,version);
}
// to save a vector:
// if the value type is trivially constructable or an optimized array save exists,
// then we can use the optimized version
template<class ValueType, class Allocator>
void save_override(std::vector<ValueType,Allocator> const &x, unsigned int version)
{
typedef BOOST_DEDUCED_TYPENAME remove_const<ValueType>::type value_type;
typedef typename mpl::and_<
mpl::not_<is_same<value_type,bool> >,
mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, value_type>
>::type use_optimized;
save_optimized(x,version,use_optimized() );
}
// dispatch saving of arrays to the optimized version where supported
template<class ValueType>
void save_override(serialization::array<ValueType> const& x, unsigned int version)
{
typedef typename mpl::apply1<
BOOST_DEDUCED_TYPENAME Archive::use_array_optimization
, BOOST_DEDUCED_TYPENAME remove_const<ValueType>::type
>::type use_optimized;
save_optimized(x,version,use_optimized());
}
// Load everything else in the usual way, forwarding on to the
// Base class
template<class T>
void save_override(T const& x, unsigned BOOST_PFTO int version)
{
Base::save_override(x, static_cast<unsigned int>(version));
}
};
} } } // end namespace boost::archive::array
#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP

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