mirror of
https://github.com/boostorg/serialization.git
synced 2026-07-22 13:43:39 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96fe06322f |
-28
@@ -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")
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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()
|
||||
@@ -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.
|
||||
@@ -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%
|
||||
@@ -0,0 +1,3 @@
|
||||
This file is used by the project manager only and should be treated like the project file
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!-- C++Builder XML Project -->
|
||||
<PROJECT>
|
||||
<MACROS>
|
||||
<VERSION value="BCB.06.00"/>
|
||||
<PROJECT value="test_simple_class.exe"/>
|
||||
<OBJFILES value="..\test\test_simple_class.obj"/>
|
||||
<RESFILES value="test_simple_class.res"/>
|
||||
<IDLFILES value=""/>
|
||||
<IDLGENFILES value=""/>
|
||||
<DEFFILE value=""/>
|
||||
<RESDEPEN value="$(RESFILES)"/>
|
||||
<LIBFILES value="..\..\..\bin\boost\libs\serialization\build\libboost_serialization.lib\borland\debug\runtime-link-static\libboost_serialization.lib
|
||||
..\..\..\bin\boost\libs\serialization\build\libboost_wserialization.lib\borland\debug\runtime-link-static\libboost_wserialization.lib
|
||||
..\..\..\bin\boost\libs\test\build\libboost_test_exec_monitor.lib\borland\debug\runtime-link-static\libboost_test_exec_monitor.lib"/>
|
||||
<LIBRARIES value=""/>
|
||||
<SPARELIBS value=""/>
|
||||
<PACKAGES value="vcl.bpi rtl.bpi dbrtl.bpi adortl.bpi vcldb.bpi vclx.bpi bdertl.bpi
|
||||
vcldbx.bpi ibxpress.bpi dsnap.bpi cds.bpi bdecds.bpi qrpt.bpi teeui.bpi
|
||||
teedb.bpi tee.bpi dss.bpi teeqr.bpi visualclx.bpi visualdbclx.bpi
|
||||
dsnapcrba.bpi dsnapcon.bpi bcbsmp.bpi vclie.bpi xmlrtl.bpi inet.bpi
|
||||
inetdbbde.bpi inetdbxpress.bpi inetdb.bpi nmfast.bpi webdsnap.bpi
|
||||
bcbie.bpi websnap.bpi soaprtl.bpi dclocx.bpi dbexpress.bpi dbxcds.bpi
|
||||
indy.bpi bcb2kaxserver.bpi"/>
|
||||
<PATHCPP value=".;..\test"/>
|
||||
<PATHPAS value=".;"/>
|
||||
<PATHRC value=".;"/>
|
||||
<PATHASM value=".;"/>
|
||||
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
|
||||
<RELEASELIBPATH value="$(BCB)\lib\release"/>
|
||||
<LINKER value="ilink32"/>
|
||||
<USERDEFINES value="_DEBUG;BOOST_ARCHIVE_TEST=xml_warchive.hpp"/>
|
||||
<SYSDEFINES value="NO_STRICT;_NO_VCL;USEPACKAGES"/>
|
||||
<MAINSOURCE value="test_simple_class.bpf"/>
|
||||
<INCLUDEPATH value="..\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl"/>
|
||||
<LIBPATH value="..\test;$(BCB)\lib\obj;$(BCB)\lib"/>
|
||||
<WARNINGS value="-w-par"/>
|
||||
<OTHERFILES value=""/>
|
||||
</MACROS>
|
||||
<OPTIONS>
|
||||
<IDLCFLAGS value="-I..\test -IC:\boost_1_31_0 -I$(BCB)\include -I$(BCB)\include\vcl
|
||||
-src_suffix cpp -D_DEBUG -DBOOST_ARCHIVE_TEST=xml_warchive.hpp -boa"/>
|
||||
<CFLAG1 value="-Od -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi- -tWC -tWM -c"/>
|
||||
<PFLAGS value="-$YD -$W -$O- -$A8 -v -JPHNE -M"/>
|
||||
<RFLAGS value=""/>
|
||||
<AFLAGS value="/mx /w2 /zd"/>
|
||||
<LFLAGS value="-D"" -ap -Tpe -x -Gn -v"/>
|
||||
<OTHERFILES value=""/>
|
||||
</OPTIONS>
|
||||
<LINKER>
|
||||
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
|
||||
<ALLRES value="$(RESFILES)"/>
|
||||
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mt.lib"/>
|
||||
<OTHERFILES value=""/>
|
||||
</LINKER>
|
||||
<FILELIST>
|
||||
<FILE FILENAME="test_simple_class.res" FORMNAME="" UNITNAME="test_simple_class.res" CONTAINERID="ResTool" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
<FILE FILENAME="test_simple_class.bpf" FORMNAME="" UNITNAME="test_simple_class" CONTAINERID="BPF" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
<FILE FILENAME="..\test\test_simple_class.cpp" FORMNAME="" UNITNAME="test_simple_class" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
<FILE FILENAME="..\..\..\bin\boost\libs\serialization\build\libboost_serialization.lib\borland\debug\runtime-link-static\libboost_serialization.lib" FORMNAME="" UNITNAME="libboost_serialization.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
<FILE FILENAME="..\..\..\bin\boost\libs\serialization\build\libboost_wserialization.lib\borland\debug\runtime-link-static\libboost_wserialization.lib" FORMNAME="" UNITNAME="libboost_wserialization.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
<FILE FILENAME="..\..\..\bin\boost\libs\test\build\libboost_test_exec_monitor.lib\borland\debug\runtime-link-static\libboost_test_exec_monitor.lib" FORMNAME="" UNITNAME="libboost_test_exec_monitor.lib" CONTAINERID="LibTool" DESIGNCLASS="" LOCALCOMMAND=""/>
|
||||
</FILELIST>
|
||||
<BUILDTOOLS>
|
||||
</BUILDTOOLS>
|
||||
|
||||
<IDEOPTIONS>
|
||||
[Version Info]
|
||||
IncludeVerInfo=0
|
||||
AutoIncBuild=0
|
||||
MajorVer=1
|
||||
MinorVer=0
|
||||
Release=0
|
||||
Build=0
|
||||
Debug=0
|
||||
PreRelease=0
|
||||
Special=0
|
||||
Private=0
|
||||
DLL=0
|
||||
Locale=1033
|
||||
CodePage=1252
|
||||
|
||||
[Version Info Keys]
|
||||
CompanyName=
|
||||
FileDescription=
|
||||
FileVersion=1.0.0.0
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=1.0.0.0
|
||||
Comments=
|
||||
|
||||
[HistoryLists\hlIncludePath]
|
||||
Count=5
|
||||
Item0=..\test;C:\boost_1_31_0\libs\serialization\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl
|
||||
Item1=C:\boost_1_31_0\libs\serialization\test;C:\boost_1_31_0;$(BCB)\include;$(BCB)\include\vcl
|
||||
Item2=C:\boost_1_31_0\libs;C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
|
||||
Item3=C:\boost_1_31_0\libs\;C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
|
||||
Item4=C:\boost_1_31_0\libs\serialization\test;$(BCB)\include;$(BCB)\include\vcl
|
||||
|
||||
[HistoryLists\hlLibraryPath]
|
||||
Count=2
|
||||
Item0=..\test;C:\boost_1_31_0\libs\serialization\test;$(BCB)\lib\obj;$(BCB)\lib
|
||||
Item1=C:\boost_1_31_0\libs\serialization\test;$(BCB)\lib\obj;$(BCB)\lib
|
||||
|
||||
[HistoryLists\hlDebugSourcePath]
|
||||
Count=1
|
||||
Item0=$(BCB)\source\vcl
|
||||
|
||||
[HistoryLists\hlConditionals]
|
||||
Count=2
|
||||
Item0=_DEBUG;BOOST_ARCHIVE_TEST=xml_warchive.hpp
|
||||
Item1=_DEBUG
|
||||
|
||||
[Debugging]
|
||||
DebugSourceDirs=$(BCB)\source\vcl
|
||||
|
||||
[Parameters]
|
||||
RunParams=
|
||||
Launcher=
|
||||
UseLauncher=0
|
||||
DebugCWD=
|
||||
HostApplication=
|
||||
RemoteHost=
|
||||
RemotePath=
|
||||
RemoteLauncher=
|
||||
RemoteCWD=
|
||||
RemoteDebug=0
|
||||
|
||||
[Compiler]
|
||||
ShowInfoMsgs=0
|
||||
LinkDebugVcl=1
|
||||
LinkCGLIB=0
|
||||
|
||||
[CORBA]
|
||||
AddServerUnit=1
|
||||
AddClientUnit=1
|
||||
PrecompiledHeaders=1
|
||||
|
||||
[Language]
|
||||
ActiveLang=
|
||||
ProjectLang=
|
||||
RootDir=
|
||||
</IDEOPTIONS>
|
||||
</PROJECT>
|
||||
Binary file not shown.
@@ -1,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
|
||||
;
|
||||
|
||||
+36
-93
@@ -1,71 +1,36 @@
|
||||
# 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 boost/serialization
|
||||
: source-location ../src
|
||||
;
|
||||
|
||||
project
|
||||
: source-location ../src
|
||||
: common-requirements <library>$(boost_dependencies)
|
||||
: requirements
|
||||
<conditional>@include-spirit
|
||||
<library>$(boost_dependencies_private)
|
||||
: usage-requirements
|
||||
<define>BOOST_SERIALIZATION_NO_LIB=1
|
||||
;
|
||||
|
||||
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 ;
|
||||
local SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ;
|
||||
for local tset in borland { # vc iw
|
||||
if ( <toolset>$(tset) in $(properties) ) {
|
||||
if ( $(SPIRIT_ROOT) ) {
|
||||
result = <cxxflags>-I$(SPIRIT_ROOT) ;
|
||||
}
|
||||
else {
|
||||
echo **** spirit 1.6x required to build library with this compiler **** ;
|
||||
result = <build>no ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
SOURCES =
|
||||
archive_exception
|
||||
|
||||
SOURCES =
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_iserializer
|
||||
@@ -79,66 +44,44 @@ SOURCES =
|
||||
basic_xml_archive
|
||||
binary_iarchive
|
||||
binary_oarchive
|
||||
codecvt_null
|
||||
extended_type_info
|
||||
extended_type_info_typeid
|
||||
extended_type_info_no_rtti
|
||||
extended_type_info_typeid
|
||||
polymorphic_iarchive
|
||||
polymorphic_oarchive
|
||||
stl_port
|
||||
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_serialization
|
||||
: $(SOURCES).cpp
|
||||
: <toolset>msvc:<cxxflags>/Gy
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
|
||||
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_wserialization
|
||||
: $(WSOURCES).cpp boost_serialization
|
||||
: <toolset>msvc:<cxxflags>/Gy
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
# Boost serialization Library Build Jamfile
|
||||
# (C) Copyright Robert Ramey 2002-2004.
|
||||
# Use, modification, and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/serialization for the library home page.
|
||||
|
||||
# building this library needs a working version of spirit
|
||||
rule toolset::require-boost-spirit-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
local requires-spirit = false ;
|
||||
switch $(toolset) {
|
||||
case "borland*" :
|
||||
requires-spirit = true ;
|
||||
case "msvc*" :
|
||||
requires-spirit = true ;
|
||||
case "iw*" :
|
||||
requires-spirit = true ;
|
||||
case "vc-6*" :
|
||||
requires-spirit = true ;
|
||||
case "vc7*" :
|
||||
requires-spirit = true ;
|
||||
case "vc-7_0*" :
|
||||
requires-spirit = true ;
|
||||
case "gcc-2*" :
|
||||
requires-spirit = true ;
|
||||
}
|
||||
if $(requires-spirit) = true {
|
||||
if $(SPIRIT_ROOT) # && ( exist $(SPIRIT_ROOT) )
|
||||
{
|
||||
properties += <include>$(SPIRIT_ROOT) ;
|
||||
}
|
||||
else {
|
||||
echo **** spirit 1.6x required to build library with this compiler **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets are known apriori not to support wide char i/o
|
||||
rule toolset::require-wide-char-io-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "*cygwin" :
|
||||
echo **** wide char i/o not supported by cygwin gcc library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
|
||||
case "como*" :
|
||||
echo **** wide char i/o not supported by libcomo standard library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "mingw*" :
|
||||
if ! [ MATCH "^([5][.][0])$" : [ get-values <stlport-version> : $(properties) ] ]
|
||||
{
|
||||
echo **** wide char i/o not supported by the mingw standard library **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets are known apriori not to support creation of DLLS
|
||||
rule toolset::require-shared-libraries-support ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "como*" :
|
||||
echo **** DLLs cannot be built with this compiler **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "msvc-stlport*" :
|
||||
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "vc-6_5-stlport*" :
|
||||
echo **** DLLs cannot be built with this compiler and stlport 4.x **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
case "cw*" :
|
||||
local runtime-link = [ get-values <runtime-link> : $(properties) ] ;
|
||||
if static in $(runtime-link) {
|
||||
echo **** DLLS cannot be built with static runtime linking **** ;
|
||||
properties = [ impose-requirements $(properties) : <build>no ] ;
|
||||
}
|
||||
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# certain tool sets display warnings which are not applicable to the serialization library
|
||||
rule toolset::suppress-warnings ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "vc-8*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-wd4996" ] ;
|
||||
case "*cygwin*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "gcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "mingw*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy" ] ;
|
||||
case "borland*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066" ] ;
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
# set optimization switches for certain toolsets. We do it here rather than in the
|
||||
# Jamfile requirements because here we can use a regex for the compiler name.
|
||||
rule toolset::optimizations ( toolset variant : subvariant-path properties * )
|
||||
{
|
||||
switch $(toolset) {
|
||||
case "vc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
|
||||
case "msvc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-Gy" ] ;
|
||||
case "gcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "qcc*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "QCC*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
case "mingw*" :
|
||||
properties = [ impose-requirements $(properties) : <cxxflags>"-ftemplate-depth-255" ] ;
|
||||
}
|
||||
return $(subvariant-path) $(properties) ;
|
||||
}
|
||||
|
||||
|
||||
+14
-21
@@ -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
|
||||
<li>Mattias Troyer ehnanced the implementation of native binary archives. This includes
|
||||
enhancement and generalization of the library itself including generalization of
|
||||
the wrapper concept.
|
||||
<li>Markus Schö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>&</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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+125
-143
@@ -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 <cstddef> // std::size_t
|
||||
//////////////////////////////////////////////////////////////
|
||||
// class trivial_oarchive
|
||||
class trivial_oarchive {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////
|
||||
// public interface used by programs that use the
|
||||
// serialization library
|
||||
typedef boost::mpl::bool_<true> is_saving;
|
||||
typedef boost::mpl::bool_<false> is_loading;
|
||||
template<class T> void register_type(){}
|
||||
template<class T> trivial_oarchive & operator<<(const T & t){
|
||||
return *this;
|
||||
}
|
||||
template<class T> trivial_oarchive & operator&(const T & t){
|
||||
return *this << t;
|
||||
}
|
||||
void save_binary(void *address, std::size_t count){};
|
||||
};
|
||||
</code></pre>
|
||||
The simplest possible input archive class is analogous to the above.
|
||||
In the following discussion, only output archives will be addressed.
|
||||
Input archives are exactly symmetrical to output archives.
|
||||
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<class Archive>
|
||||
detail::common_iarchive;
|
||||
</code></pre>
|
||||
<h4>Minimum Requirments</h4>
|
||||
An instance of the this template handles all the "bookkeeping" associated
|
||||
with serialization. In order to be a functional only the following additional
|
||||
functions <strong>must</strong> be defined:
|
||||
<dl>
|
||||
<dt><h4><code>void load(T &t);</code></h4></dt>
|
||||
<dd>
|
||||
This function must be implemented for all primitive data types. This can be
|
||||
accomplished through the use of a member template or explict declarations
|
||||
for all prmititive types.
|
||||
</dd>
|
||||
|
||||
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 <cstddef> // std::size_t
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
</a>
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class complete_oarchive
|
||||
class complete_oarchive :
|
||||
public boost::archive::detail::common_oarchive<complete_oarchive>
|
||||
{
|
||||
// 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<trivial_iarchive>
|
||||
{
|
||||
// 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<class T>
|
||||
void save(T & t);
|
||||
void load(T & 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 "<name>" before data.
|
||||
by XML archive to inject "<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 "</name>" 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 ">" 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 ">" 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 ">" 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<class T>
|
||||
void save_override(T & t, int);
|
||||
void load_override(T & t, int);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Invokes <code style="white-space: normal">archive::save(Archive & 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 & 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,16 +214,19 @@ explicitly provided for these types. For an example see
|
||||
In real practice, we probably won't be quite done.
|
||||
One or more of the following issues may need to be addressed:
|
||||
<ul>
|
||||
<li>Many compilers fail to implement correct partial ordering of
|
||||
function templates. The archives included with this library work around
|
||||
this using argument overloading. This technique is described in
|
||||
<a target="detail" href="implementation.html#functiontemplateordering">
|
||||
another section of this manual</a>
|
||||
<li>Even if we are using a conforming compiler, we might want our new archive class
|
||||
to be portable to non-conforming compilers.
|
||||
<li>Our archive format might require extra information inserted into it. For
|
||||
example, XML archives need <name ... >...</name> surrounding
|
||||
all data objects.
|
||||
<li>Addressing any of the above may generate more issues to be addressed.
|
||||
<li>The archives included with the library are all templates which use a
|
||||
<code style="white-space: normal">stream</code> or
|
||||
<code style="white-space: normal">streambuf</code>
|
||||
as a template parameter rather than simple classes.
|
||||
<li>The archives included with library are all templates which use a
|
||||
<code style="white-space: normal">stream</code> as a template parameter rather than simple classes.
|
||||
Combined with the above, even more issues arise with non-conforming compilers.
|
||||
</ul>
|
||||
The attached <a target="class_diagram" href="class_diagram.html">class diagram</a>
|
||||
@@ -250,15 +241,17 @@ EXCEPT for one special case.
|
||||
<ul>
|
||||
<li>Instances of a derived class are serialized through a base class pointer.
|
||||
<li>Such instances are not "registered" neither implicitly nor explicitly. That
|
||||
is, the macro <code style="white-space: normal">BOOST_CLASS_EXPORT</code> is used
|
||||
to instantiate the serialization code for the included archives.
|
||||
is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used to instantiate the serialization
|
||||
code for the included archives.
|
||||
</ul>
|
||||
|
||||
To make this work, the following should be included after the archive
|
||||
class definition.
|
||||
The problem here is that BOOT_CLASS_EXPORT only generates code for those archives
|
||||
included with the library - not those added subsequently. To generate code for
|
||||
newly created archive classes, the following should be used.
|
||||
<pre><code>
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
|
||||
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES trivial_oarchive
|
||||
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES trivial_iarchive
|
||||
</code></pre>
|
||||
before <code style="white-space: normal">BOOST_CLASS_EXPORT</code> is invoked for any serializable class.
|
||||
Failure to do this will not inhibit the program from compiling, linking
|
||||
and executing properly - except in one case. If an instance of a derived
|
||||
class is serialized through a pointer to its base class, the program
|
||||
@@ -266,20 +259,23 @@ will throw an
|
||||
<a href="exceptions.html#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
|
||||
exception.
|
||||
<p>
|
||||
Only one of the above statements is permitted, However, any number of new archive
|
||||
classes can be specified as list separated by commas.
|
||||
|
||||
<h4><a name="testing">Testing</h4>
|
||||
Exhaustive testing of the library requires testing the different aspects of object
|
||||
serialization with each archive. There are 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
|
||||
@@ -306,16 +302,16 @@ typedef std::ifstream test_istream;
|
||||
#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
|
||||
</code></pre>
|
||||
|
||||
To test a new archive, for example, portable binary archives, with the gcc compiler,
|
||||
make a header file <code style="white-space: normal">portable_binary_archive.hpp</code>
|
||||
To test a new archive, for example, portable binary archives, make a
|
||||
header file <code style="white-space: normal">portable_binary_archive.hpp</code>
|
||||
and invoke <code style="white-space: normal">bjam</code> with
|
||||
<pre><code>
|
||||
-sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
|
||||
</code></pre>
|
||||
This process in encapsulated in the shell or cmd script
|
||||
<code style="white-space: normal">library_test</code> whose command line is
|
||||
This process in encapsulated in the shell script
|
||||
<code style="white-space: normal">run_archive_test</code> whose command line is
|
||||
<pre><code>
|
||||
library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
|
||||
run_archive_test <test header file> <toolset> [<boost root>] [<target directory>]
|
||||
</code></pre>
|
||||
<h3><a name="polymorphic">Polymorphic Archives</a></h3>
|
||||
|
||||
@@ -323,7 +319,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 +340,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 +357,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.
|
||||
@@ -371,15 +367,14 @@ As can be seen in the
|
||||
and the header files, this implementation is just a composition of the polymorphic
|
||||
interface and the standard template driven implementation. This composition is
|
||||
accomplished by the templates
|
||||
<a target=polymorphic_iarchive_route_hpp href="../../../boost/archive/detail/polymorphic_iarchive_route.hpp"><code style="white-space: normal">polymorphic_iarchive_route.hpp</code></a>
|
||||
<a target=polymorphic_iarchive_dispatch_hpp href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_iarchive_dispatch.hpp</code></a>
|
||||
and
|
||||
<a target=polymorphic_oarchive_route_hpp href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp"><code style="white-space: normal">polymorphic_oarchive_route.hpp</code></a>
|
||||
which redirect calls to the polymorphic archives to the specific archive.
|
||||
<a target=polymorphic_oarchive_dispatch_hpp href="../../../boost/archive/detail/polymorphic_oarchive_dispatch.hpp"><code style="white-space: normal">polymorphic_oarchive_dispatch.hpp</code></a>.
|
||||
As these contain no code specific to the particular implementation archive, they can be used to create
|
||||
a polymorphic archive implementation from any functioning templated archive implementation.
|
||||
<p>
|
||||
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 +385,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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+30
-56
@@ -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<Helper>(void * const helper_instance_id = 0)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
See <code>la.get_helper<Helper>(void * const helper_instance_id = 0)</code>
|
||||
below.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
|
||||
@@ -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<Helper>(void * const helper_instance_id)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Some otherwise unserializable types can be made serializable by inclusion of
|
||||
a helper object. The iconic example of this is shared_ptr which needs this
|
||||
helper object to keep track of previously loaded shared_ptr instances so they
|
||||
can be "matched up" with subsequently loaded ones.
|
||||
The first time <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code>
|
||||
is invoked for a given helper_instance_id, <code style="white-space: normal">Helper</code>, a default-constructed
|
||||
<code style="white-space: normal">Helper</code> object is created, attached to
|
||||
<code style="white-space: normal">la</code> and a reference to it is returned. Subsequent
|
||||
invocations of <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code> with the same id value return
|
||||
a reference to the formerly constructed object. All objects created in this manner are
|
||||
destroyed upon <code style="white-space: normal">la</code> destruction time. The purpose
|
||||
of helper objects is discussed in
|
||||
<a href="special.html#helpersupport">Special Considerations - Helper Support</a>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.reset_object_address(v, u)
|
||||
</code></h4></dt>
|
||||
@@ -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"><<</code>
|
||||
and <code style="white-space: normal">>></code> suggests
|
||||
and <code style="white-space: normal">>></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 & 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 & 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 & 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 & 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 & bsb, unsigned int flags = 0);
|
||||
binary_oarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
and
|
||||
<dt><h4><code>
|
||||
binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
</dl>
|
||||
|
||||
<h3><a name="exceptions">Exceptions</h3>
|
||||
All of the archive classes included may throw exceptions. The list of exceptions that might
|
||||
be 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">
|
||||
|
||||
@@ -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 & 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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+40
-40
@@ -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">-></a>
|
||||
basic_iarchive <a href="../../../boost/archive/detail/basic_iarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
| interface_oarchive<text_oarchive> <a href="../../../boost/archive/detail/interface_oarchive.hpp">-></a>
|
||||
| interface_iarchive<text_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| _________/
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
common_oarchive<text_oarchive> <a href="../../../boost/archive/detail/common_oarchive.hpp">-></a>
|
||||
common_iarchive<text_iarchive> <a href="../../../boost/archive/detail/common_iarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
<font color="blue">basic_text_oarchive<text_oarchive></font> <a href="../../../boost/archive/basic_text_oarchive.hpp">-></a>
|
||||
<font color="blue">basic_text_iarchive<text_iarchive></font> <a href="../../../boost/archive/basic_text_iarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
| <font color="blue">basic_text_oprimitive<basic_ostream></font> <a href="../../../boost/archive/basic_text_oprimitive.hpp">-></a>
|
||||
| <font color="blue">basic_text_iprimitive<basic_istream></font> <a href="../../../boost/archive/basic_text_iprimitive.hpp">-></a>
|
||||
| /
|
||||
| /
|
||||
| _________/ interface_oarchive<polymorphic_oarchive> <a href="../../../boost/archive/detail/interface_oarchive.hpp">-></a>
|
||||
| _________/ interface_iarchive<polymorphic_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| / |
|
||||
| / |
|
||||
| / |
|
||||
<font color="blue">text_oarchive_impl<text_oarchive></font> <a href="../../../boost/archive/text_oarchive.hpp">-></a> polymorphic_oarchive_impl <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
<font color="blue">text_iarchive_impl<text_iarchive></font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
|
||||
| \ |
|
||||
| \ |
|
||||
| \_____________________________________ <font color="red">polymorphic_oarchive</font> <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
| \_____________________________________ |
|
||||
| \ /
|
||||
| \ /
|
||||
| \ /
|
||||
<font color="red">text_oarchive</font> <a href="../../../boost/archive/text_oarchive.hpp">-></a> polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> > <a href="../../../boost/archive/detail/polymorphic_oarchive_route.hpp">-></a>
|
||||
<font color="red">text_iarchive</font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> polymorphic_iarchive_dispatch<text_iarchive_impl<text_iarchive> > <a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">-></a>
|
||||
|
|
||||
|
|
||||
|
|
||||
<font color="red">polymorphic_text_oarchive</font> <a href="../../../boost/archive/polymorphic_text_oarchive.hpp">-></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 identical 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<text_oarchive></a>
|
||||
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive<text_iarchive></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<text_oarchive></a>
|
||||
<a href="../../../boost/archive/detail/common_iarchive.hpp">common_iarchive<text_iarchive></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<text_oarchive></a>
|
||||
<a href="../../../boost/archive/basic_text_iarchive.hpp">basic_text_iarchive<text_iarchive></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<basic_ostream></a>
|
||||
<a href="../../../boost/archive/basic_text_iprimitive.hpp">basic_text_iprimitive<basic_istream></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<text_oarchive></a>
|
||||
<a href="../../../boost/archive/text_iarchive.hpp">text_iarchive_impl<text_iarchive></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<text_oarchive></code> .
|
||||
This is just a short hand for <code style="white-space: normal">text_iarchive_impl<text_iarchive></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<polymorphic_oarchive></a>
|
||||
<a href="../../../boost/archive/detail/interface_iarchive.hpp">interface_iarchive<polymorphic_iarchive></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 &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<text_oarchive_impl<text_oarchive> ></a>
|
||||
<a href="../../../boost/archive/detail/polymorphic_iarchive_dispatch.hpp">polymorphic_iarchive_dispatch<text_iarchive_impl<text_iarchive> ></a>
|
||||
</code></dt>
|
||||
<dd><p>
|
||||
This class implements the <code style="white-space: normal">polymorphic_oarchive</code> in terms of a specific
|
||||
concrete class. Virtual function calls are routed to the implementing class. In this example,
|
||||
that implementing class would be text_oarchive_impl.
|
||||
This class implements the <code style="white-space: normal">polymorphic_iarchive</code> in terms of a specific
|
||||
concrete class. Virtual function calls are forwarded to the implementing class. In this example,
|
||||
that implementing class would be text_iarchive_impl.
|
||||
|
||||
<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<text_oarchive_impl<text_oarchive> ></code>
|
||||
this is just a typedef so we can write polymorphic_text_archive rather than
|
||||
<code style="white-space: normal">polymorphic_iarchive_dispatch<text_iarchive_impl<text_iarchive> ></code>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@ width="277" height="86"> <br clear="all">
|
||||
<a name="sec:utf8-codecvt-facet-class"></a>
|
||||
|
||||
|
||||
<h1><code>utf8_codecvt_facet</code></h1>
|
||||
<h1>UTF-8 Codecvt Facet</h1>
|
||||
|
||||
|
||||
<pre>
|
||||
@@ -42,7 +42,7 @@ template<
|
||||
<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<
|
||||
<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,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>
|
||||
|
||||
+200
-241
@@ -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,220 @@ 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_32">Differences from version 1.32</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_33">Differences from version 1.33</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#difference_1_34">Differences from version 1.34</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#todo">Pending Issues</a></dt>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="overview"><a target="detail" href="overview.html">Overview</a></dt>
|
||||
<dd><div id="overview_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Requirements">Requirements</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="overview.html#Otherimplementations">Other Implementations</a></dt>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="tutorial"><a target="detail" href="tutorial.html">Tutorial</a></dt>
|
||||
<dd><div id="tutorial_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#simplecase">A Very Simple Case</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#nonintrusiveversion">Non Intrusive Version</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#serializablemembers">Serializable Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#derivedclasses">Derived Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#pointers">Pointers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="tutorial.html#arrays">Arrays</a>
|
||||
|
||||
<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#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#export">Exporting Class Serialization</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#classinfo">Class Information</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
<dd><div id="portability_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#numerics">Numerics</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#traits">Traits</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#binary_archives">Binary Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#xml_archives">XML Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#dlls">DLLS - Serialization and Runtime Linking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#multi_threading">Multi-Threading</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#optimizations">Optimzations</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="exceptions"><a target="detail" href="exceptions.html">Archive Exceptions</a>
|
||||
<dd><div id="exceptions_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_class"><code>unregistered_class</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_signature"><code>invalid_signature</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unsupported_version"><code>unsupported_version</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#pointer_conflict"><code>pointer_conflict</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#incompatible_native_format"><code>incompatible_format</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#array_size_too_short"><code>array_size_too_short</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#stream_error"><code>stream_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_class_name"><code>invalid_class_name</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_cast"><code>unregistered_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parsing_error"><code>xml_archive_parsing_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_mismatch"><code>xml_archive_tag_mismatch</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_name_error"><code>xml_archive_tag_name_error</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exception_safety.html">Exception Safety</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="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<class T></code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr<class T></code>Revisited</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="pimpl.html">PIMPL</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="private_base.html">Private Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="simple_log.html">A Simple Logging Archive Class</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="otherclasses">Other Classes
|
||||
<dd><div id="otherclasses_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="extended_type_info"><a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
<dd><div id="extended_type_info_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#motivation">Motivation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#runtime">Runtime Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#requirements">Requirements</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="case_studies">Case Studies
|
||||
<dd><div id="case_studies_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr.html">Template serialization - <code>shared_ptr<class T></code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr<class T></code>Revisited</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="pimpl.html">PIMPL</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="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="miscellaneous">Miscellaneous
|
||||
<dd><div id="miscellaneous_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="extended_type_info"><a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
<dd><div id="extended_type_info_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#motivation">Motivation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#runtime">Runtime Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#requirements">Requirements</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="void_cast.html"><code>void_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html">utf-8 code_cvt</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
|
||||
</dl></div></dd>
|
||||
</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
@@ -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< // insert line breaks every 76 characters
|
||||
base64_from_binary< // convert binary values to base64 characters
|
||||
insert_linebreaks< // insert line breaks every 72 characters
|
||||
base64_from_binary< // convert binary values ot base64 characters
|
||||
transform_width< // retrieve 6 bit integers from a sequence of 8 bit bytes
|
||||
const char *,
|
||||
6,
|
||||
8
|
||||
>
|
||||
>
|
||||
,76
|
||||
,72
|
||||
>
|
||||
base64_text; // compose all the above operations in to a new iterator
|
||||
|
||||
@@ -71,12 +71,12 @@ included is <a target="transform_iterator" href="../../iterator/doc/transform_it
|
||||
transform_iterator</a>, which can be used to implement 6 bit integer => base64 code.
|
||||
|
||||
<h3>Dataflow Iterators</h3>
|
||||
Unfortunately, not all iterators which inherit from Iterator Adaptors are 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<char>(os)
|
||||
);
|
||||
</code></pre>
|
||||
This macro is defined in <a target="pfto" href="../../../boost/pfto.hpp"><boost/pfto.hpp></a>.
|
||||
For more information about this topic, check the source.
|
||||
|
||||
<h4>Dereferencing</h4>
|
||||
Dereferencing some iterators can cause problems. For example, a natural
|
||||
@@ -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,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
@@ -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<xml_oarchive></code>. So we should derive
|
||||
from <code style="white-space: normal">xml_oarchive_impl<log_archive></code> rather
|
||||
than <code style="white-space: normal">xml_oarchive</code>.
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_hpp">binary_oarchive.hpp</a>.
|
||||
<code style="white-space: normal">binary_oarchive</code> really a shorthand name for
|
||||
<code style="white-space: normal">binary_oarchive_impl<binary_oarchive></code>. So we should derive
|
||||
from <code style="white-space: normal">binary_oarchive_impl<portable_binary_oarchive></code> rather
|
||||
than <code style="white-space: normal">binary_oarchive</code>.
|
||||
<pre><code>
|
||||
class log_archive :
|
||||
// don't derive from xml_oarchive !!!
|
||||
public xml_oarchive_impl<log_archive>
|
||||
class portable_binary_oarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<portable_binary_oarchive>
|
||||
{
|
||||
...
|
||||
</code></pre>
|
||||
<li><i>Note the</i> <code style="white-space: normal">log_archive</code> <i>between the</i> <>
|
||||
<li><i>Note the</i> <code style="white-space: normal">portable_binary_oarchive</code> <i>between the</i> <>
|
||||
This is required so that base classes can downcast their <code style="white-space: normal">this</code> pointer
|
||||
to the most derived class. This is referred to as <b>C</b>uriously <b>R</b>ecurring
|
||||
<b>T</b>emplate <b>P</b>attern (<b>CRTP</b>) <a href="bibliography.html#11">[11]</a>.
|
||||
@@ -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<log_archive>;
|
||||
friend class basic_xml_oarchive<log_archive>;
|
||||
typedef portable_binary_oarchive derived_t;
|
||||
friend class detail::common_oarchive<derived_t>;
|
||||
friend class basic_binary_oarchive<derived_t>;
|
||||
friend class basic_binary_oprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class 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<derived_t>::save;
|
||||
using binary_oarchive_impl<derived_t>::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<class T>
|
||||
void save(const T & t){
|
||||
xml_oarchive_impl<derived_t>::save(t);
|
||||
void save(const T & t){
|
||||
binary_oarchive_impl<derived_t>::save(t);
|
||||
}
|
||||
void save(const unsigned int t);
|
||||
...
|
||||
</code></pre>
|
||||
so it's what I use.
|
||||
<li><i>Template definitions of base classes may have to be 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<class Archive>
|
||||
class log_archive_impl :
|
||||
// don't derive from xml_oarchive !!!
|
||||
public xml_oarchive_impl<Archive>
|
||||
class portable_binary_oarchive_impl :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<Archive>
|
||||
{
|
||||
...
|
||||
};
|
||||
);
|
||||
|
||||
// do not derive from this class !!!
|
||||
class log_archive :
|
||||
public log_archive_impl<log_archive>
|
||||
// do not derived from this class !!!
|
||||
class portable_binary_oarchive :
|
||||
public portable_binary_oarchive_impl<portable_binary_oarchive>
|
||||
{
|
||||
public:
|
||||
log_archive(std::ostream & os, unsigned int flags = 0) :
|
||||
log_archive_impl<xml_oarchive>(os, flags)
|
||||
portable_binary_oarchive(std::ostream & os, unsigned int flags = 0) :
|
||||
portable_binary_oarchive_impl<binary_oarchive>(os, flags)
|
||||
{}
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
</ol>
|
||||
|
||||
<a name=fast_archives>
|
||||
<h3>Fast Binary Archives</h3>
|
||||
The second example
|
||||
<a href="../example/demo_fast_archive.cpp" target="demo_fast_archive_cpp">demo_fast_archive.cpp</a>.
|
||||
is similar to the first one. The difference is that it intercepts the serialization before
|
||||
the default serialization is invoked. In this case we want to replace the default
|
||||
serialization of C arrays of integers with a faster one. The default version
|
||||
will invoke serialization of each element of the array. If its an array of
|
||||
integers, and we're not concerned with the archive being portable to another platform
|
||||
we can just save/load the whole array as a binary string of bytes. This should
|
||||
be faster than the default element by element method.
|
||||
<p>
|
||||
The same considerations that applied when overriding the the save/load of primitives
|
||||
above apply here, and the code is very similar.
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 846 B After Width: | Height: | Size: 838 B |
@@ -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
|
||||
|
||||
+28
-55
@@ -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>
|
||||
@@ -46,9 +43,8 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
Archive operators can throw a <code style="white-space: normal">boost::archive_exception</code>
|
||||
object which can be caught by an application program. These exceptions are defined
|
||||
in the files <a target="archive_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
|
||||
archive_exception.hpp</a>
|
||||
and <a target="basic_xml_archive_hpp" href="../../../boost/archive/basic_xml_archive.hpp">
|
||||
basic_xml_archive.hpp</a>.
|
||||
boost/archive/archive_exception.hpp</a> and <a target="archive_xml_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_xml_exception.hpp</a>.
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -57,7 +53,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 +62,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 +99,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 +108,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 +119,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<class Archive>
|
||||
void T::save(Archive &ar) const
|
||||
void T::save(Archive &ar) const
|
||||
{
|
||||
const A * aptr = &a;
|
||||
ar << aptr; // save an instance of object of class A through a pointer
|
||||
const A * aptr = &a;
|
||||
ar << aptr; // save an instance of object of class A through a pointer
|
||||
...
|
||||
ar << a; // save an instance of an object of class A
|
||||
assert(aptr == &a); // this must be true
|
||||
ar << a; // save an instance of an object of class A
|
||||
assert(aptr == &a); // this must be true
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void T::load(Archive &ar)
|
||||
void T::load(Archive &ar)
|
||||
{
|
||||
A * aptr;
|
||||
ar >> aptr; // create and initialize a new instance of class A
|
||||
ar >> aptr; // create and initialize a new instance of class A
|
||||
...
|
||||
ar >> a; // restore state of on object of class A
|
||||
assert(aptr == &a); // this won't be true
|
||||
ar >> a; // restore state of on object of class A
|
||||
assert(aptr == &a); // this won't be true
|
||||
}
|
||||
</pre></code>
|
||||
An object is saved first through a pointer then directly. Upon loading back
|
||||
@@ -179,12 +161,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 +203,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 +215,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 +223,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 +232,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>
|
||||
|
||||
+144
-235
@@ -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,6 +33,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#example">Example</a>
|
||||
</dl>
|
||||
|
||||
|
||||
<h3><a name="motivation">Motivation</a></h3>
|
||||
The serialization library needs a system like
|
||||
<code style="white-space: normal">type_info/typeid()</code> to perform
|
||||
@@ -49,7 +50,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,128 +58,128 @@ the following functions
|
||||
and operating systems. This makes it unusable for support of portable archives.
|
||||
<li>
|
||||
Even if the type name string could somehow be made portable, there is no
|
||||
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>
|
||||
We may want the ability to serialize objects through a base class even though
|
||||
they have no <code style="white-space: normal">virtual</code> function. That
|
||||
is, objects of classes which are not polymorphic in the strict C++ sense. This
|
||||
is not supported by the standard system.
|
||||
<li>
|
||||
There exists the possibility that different classes use different type id
|
||||
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>
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
extended_type_info</a></code> is an implementation
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> is an implementation
|
||||
of <code style="white-space: normal">std::type_info</code> functionality with the
|
||||
following features:
|
||||
<ul>
|
||||
<li>
|
||||
Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">extended_type_info</a></code> records - one for each type
|
||||
serialized.
|
||||
Maintains a global table of <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> records - one for each type known
|
||||
to the program.
|
||||
<li>
|
||||
permits association of an arbitrary string key with a type. Often this key would
|
||||
permits association of an arbitrary key with a type. Often this key would
|
||||
be the class name - but it doesn't have to be. This key is referred to as
|
||||
a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe.
|
||||
Typically this GUID would be in header files and be used to match type accross
|
||||
applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string
|
||||
key with any known type. We'll refer to these types as "exported types"
|
||||
applications.
|
||||
<li>
|
||||
permits the "mixing" of type info systems. For example, one class might use
|
||||
<code style="white-space: normal">typeid()</code> to find the external identifier
|
||||
of a class while another might not.
|
||||
</ul>
|
||||
|
||||
Exported types are maintained in a global table so that given a string key, the
|
||||
corresponding type can be found. This facility is used by the serialization library
|
||||
in order to construct types serialized through a base class pointer.
|
||||
The serialization system maintains two global tables.
|
||||
<ul>
|
||||
<li>The first is a global type table. it has an entry for each type used.
|
||||
Each entry is an instance of a class derived from
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>. This table is used
|
||||
to retrieve the unique <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
information for any given type.
|
||||
<li>The second is global key table. It has an entry for each type which has been assigned a GUID string key.
|
||||
This table is used to retrieve the unique
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> given its GUID.
|
||||
</ul>
|
||||
This library includes two different type id systems:
|
||||
<ul>
|
||||
<li>
|
||||
<code style="white-space: normal"><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">extended_type_info_typeid</a></code>
|
||||
which is implemented in terms of the standard
|
||||
<code style="white-space: normal">typeid()</code>.
|
||||
<li>
|
||||
<code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">extended_type_info_no_rtti</a></code>
|
||||
which is implemented in a way that doesn't rely on the existence
|
||||
RTTI. However, it does require that all classes for which type id is to be used
|
||||
be explictly assigned an external key - which otherwise would be optional.
|
||||
</ul>
|
||||
|
||||
<h3><a name="runtime">Runtime Interface</a></h3>
|
||||
<pre><code>
|
||||
<pre><code">
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
class extended_type_info
|
||||
class BOOST_SERIALIZATION_DECL extended_type_info :
|
||||
private boost::noncopyable
|
||||
{
|
||||
protected:
|
||||
// this class can't be used as is. It's just the
|
||||
// common functionality for all type_info replacement
|
||||
// systems. Hence, make these protected
|
||||
extended_type_info(
|
||||
const unsigned int type_info_key,
|
||||
const char * key
|
||||
);
|
||||
~extended_type_info();
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
extended_type_info(const char * type_info_key);
|
||||
public:
|
||||
void self_register();
|
||||
void key_register(const char *key);
|
||||
const char * get_key() const;
|
||||
bool operator<(const extended_type_info &rhs) const;
|
||||
bool operator==(const extended_type_info &rhs) const;
|
||||
bool operator!=(const extended_type_info &rhs) const {
|
||||
return !(operator==(rhs));
|
||||
}
|
||||
// for plugins
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
virtual void destroy(void const * const p) const;
|
||||
|
||||
bool operator<(const extended_type_info &rhs) const;
|
||||
bool operator==(const extended_type_info &rhs) const;
|
||||
bool operator!=(const extended_type_info &rhs) const;
|
||||
|
||||
static const extended_type_info * find(const char *key);
|
||||
static const extended_type_info * find(const extended_type_info * t);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
<p>
|
||||
Generally, there will be one and only one
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. However, this is enforced only at the executable
|
||||
module level. That is, if a program includes some shared libraries or DLLS,
|
||||
there may be more than one instance of this class corresponding to a particular type.
|
||||
For this reason the comparison functions below can't just compare the addresses of
|
||||
this instance but rather must be programmed to compare the actual information
|
||||
the instances contain.
|
||||
|
||||
There must be one and only one <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. For this reason, this class is marked is derived from
|
||||
<code style="white-space: normal">boost::noncopyable</code>.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
extended_type_info(unsigned int type_info_key, const char *key);
|
||||
</code></pre></h4></dt>
|
||||
extended_type_info(const char * 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
|
||||
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.
|
||||
This constructor should be called by all derived classes. It should be passed
|
||||
a pointer to a const string which identifies the type id system being used. This
|
||||
type id is used to distinguish among the various type id system that might be used
|
||||
and allow them to interoperate.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
void self_register();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This system maintains a global table which relates
|
||||
external strings to
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
This table is used when loading pointers to objects serialized
|
||||
through a base class pointer. In this case, the archive
|
||||
contains a string which is looked up in this table to
|
||||
determine which <code style="white-space: normal">extended_type_info</code>
|
||||
to use for creating a new object.
|
||||
<p>
|
||||
These functions are called by constructors and
|
||||
destructors of classes which implement
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
to add and remove entries from this table.
|
||||
This function adds entry for an entry to the global type table. It would usually be
|
||||
called from the constructor of the derived class which implements the
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> functionality.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void key_register(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Assign a unique character string identifier to this
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance and add it to the corresponding global trable.
|
||||
This key is used to identify a type accross different instances of the program.
|
||||
In this way, one instance may know what type to create when necessary.
|
||||
For this purpose, it must be the same in all program instances which
|
||||
refer to the same type.
|
||||
<p>
|
||||
It may sometimes be referred to as a GUID - a <b>G</b>lobal <b>U</b>nique <b>ID</b>entifier.
|
||||
<dt><h4><pre><code>
|
||||
const char *get_key() const;
|
||||
</code></pre></h4></dt>
|
||||
@@ -188,80 +189,58 @@ instance. If no key has been associated with the instance, then a NULL is retur
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
bool operator<(const extended_type_info & rhs) const;
|
||||
bool operator==(const extended_type_info & rhs) const;
|
||||
bool operator!=(const extended_type_info & rhs) const;
|
||||
bool operator<(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
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
objects. They impose a strict total ordering on all
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Construct a new instance of the type to which this
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
record corresponds. This function takes a variable list of up to 4 arguments
|
||||
of any type. These arguments are passed to the type's constructor
|
||||
at runtime. In order to use the facility,
|
||||
one must declare a type sequence for the constructor arguments.
|
||||
Arguments for this function must match in number and type
|
||||
with those specified when the type was exported.
|
||||
This function permits one to create instances of
|
||||
any exported type given only the exported <strong>GUID</strong> assigned
|
||||
with BOOST_CLASS_EXPORT.
|
||||
If these types are defined in DLLS or shared libraries loaded at runtime,
|
||||
these constructors can be called until the module is unloaded.
|
||||
Such modules are referred to as <b>plugins</b>.
|
||||
</code>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void destroy(void const * const p) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance created by the above constructor.
|
||||
</dd>
|
||||
These functions are used to compare two <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code> objects.
|
||||
Among other things, these are used for lookup in the tables.
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of a
|
||||
corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of the
|
||||
unique corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
object.
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const extended_type_info * t);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a pointer to an
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>,
|
||||
return the address of the instance of the same type in the main table.
|
||||
That is the argument t is used as a search argment to find the main
|
||||
table entry for a given type. It would be used like this:
|
||||
<code><pre>
|
||||
// return the global type entry for our type T
|
||||
return find(some_extended_type_info_implementation<T>())
|
||||
</pre></code>
|
||||
|
||||
</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
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
and also implement the following:
|
||||
(referred to as ETI here), must implement the following:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t) const;
|
||||
virtual bool
|
||||
ETI::less_than(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Impose a strict total ordering on all instances of the class ETI.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
static const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t);
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Return a pointer to the
|
||||
@@ -269,51 +248,45 @@ 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.
|
||||
with a particular <code style="white-space: normal">extended_type_info implementation</code>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
|
||||
template<class ETI>
|
||||
static extended_type_info *
|
||||
ETI::get_instance();
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Compare this instance to another one using the same
|
||||
<code style="white-space: normal">extended_type_info</code> implementation.
|
||||
Return a pointer to the instance of
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
which corresponds to type T. Normally these instances are static objects so
|
||||
this just amounts to returning the address of this static object.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual bool ETI::is_equal(const extended_type_info &rhs) const;
|
||||
static void
|
||||
template<class ETI>
|
||||
ETI::export_register(const char * key);
|
||||
</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>
|
||||
The main function is to invoke key_register to add the GUID to the
|
||||
global table. Depending on the type id system being used, it might
|
||||
perform other initializaition functions as well.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
It must define the following
|
||||
<a href="../../mpl/doc/refmanual/integral-constant.html">
|
||||
Itegral Constant</a>
|
||||
of type
|
||||
<a href="../../mpl/doc/refmanual/bool.html">bool</a>:
|
||||
<dl>
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
const char ETI::get_key() const;
|
||||
ETI::is_polymorphic
|
||||
</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>
|
||||
@@ -329,88 +302,24 @@ by the compiler.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
|
||||
extended_type_info_no_rtti</a></h4></code>
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
Instead, it requires that all polymorphic types be explicitly exported.
|
||||
In addition, if the export facility is to be used to serialize types
|
||||
through base class pointers, those types are required to implement
|
||||
a virtual function with the signature:
|
||||
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
However, it does require that all classes for which type id is to be used implement
|
||||
a virtual function of the signiture:
|
||||
<code><pre>
|
||||
virtual const char * get_key();
|
||||
</pre></code>
|
||||
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
|
||||
<code style="white-space: normal">extended_type_info</code>.
|
||||
This requires that non-abstract types be exported.
|
||||
|
||||
<h3><a name="type_requirements">Requirements for Each Type</a></h3>
|
||||
Each type to be managed by the system must be
|
||||
"registered" individually. This is accomplished by instantiating
|
||||
templates. For example, if the type T is to use the <code style="white-space: normal">type_info</code> system
|
||||
one would include the following code:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
template
|
||||
struct extended_type_info_typeid<T>;
|
||||
template
|
||||
struct extended_type_info_typeid<const T>;
|
||||
} // serialization
|
||||
} // boost
|
||||
</pre></code>
|
||||
|
||||
For those using the serialization library, this step can be skipped
|
||||
as it is done automatically. The serialization library includes
|
||||
the macro:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TYPE_INFO(
|
||||
my_type,
|
||||
extended_type_info_typeid<my_class>
|
||||
)
|
||||
</pre></code>
|
||||
|
||||
which is used to specify which <code>extended_type_info</code> system is to
|
||||
be used for a given type.
|
||||
<p>
|
||||
<code>extended_type_info</code> includes a facility for constructing
|
||||
instances of types without knowing what the exact types are. This is done
|
||||
with the function
|
||||
<code>
|
||||
virtual void * extended_type_info::construct(unsigned int count = 0, ...) const;
|
||||
</code>
|
||||
. For example:
|
||||
<br>
|
||||
<code><pre>
|
||||
struct base {
|
||||
...
|
||||
};
|
||||
struct derived : public base {
|
||||
...
|
||||
};
|
||||
...
|
||||
extended_type_info *eti = extended_type_info::find("my_class")
|
||||
base * b = eti->construct(...);
|
||||
</pre></code>
|
||||
<br>
|
||||
The <code>construct</code> takes an argument count and up to
|
||||
four parameters of any type. The arguments are passed to the
|
||||
constructor of "my_class".
|
||||
|
||||
|
||||
A complete example of this can be found
|
||||
<a target="test_dll_plugin.cpp" href="../test/test_dll_plugin.cpp">here</a>
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005-2009.
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
|
||||
+6
-40
@@ -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>© 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
@@ -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<class T>
|
||||
void save_override(T & t, BOOST_PFTO int){
|
||||
// All for otherwise unhandled types are forwarded to the base class.
|
||||
// This emulates behavior for function overloading.
|
||||
this->base::save_override(t, 0);
|
||||
}
|
||||
void save_override(const some_type & t, int){
|
||||
// any special handling for some type
|
||||
// this will usually entail forwarding some other operation
|
||||
// in the most derived class.
|
||||
this->This()->...
|
||||
// or in one of its parents basic_text_oprimitive
|
||||
this->This()->save(static_cast<int>(t));
|
||||
}
|
||||
... // other special type handling
|
||||
</code></pre>
|
||||
|
||||
Note the usage of
|
||||
<a target="detail" href="implementation.html#functiontemplateordering">Partial Function Template Ordering</a>
|
||||
to permit the correct save implementation to be selected.
|
||||
</dd>
|
||||
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
@@ -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>
|
||||
|
||||
+211
-23
@@ -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<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
my_template<T> & t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
The serialization library works around this issue by using a different
|
||||
default definition of the first template:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned long int file_version // Note: change to long
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
Now, the second template is not matched with the first one so there
|
||||
is no PFTO and no compile error. When the serialization library invokes
|
||||
<pre><code>
|
||||
serialize(ar, t, 0);
|
||||
</pre></code>
|
||||
the function declaration is first matched against templates with
|
||||
an integer for the third argument. If there is a match, the matching
|
||||
template is instantiated and later invoked. If there is no match,
|
||||
an attempt is made to match other templates by converting arguments to other types.
|
||||
In this case the third argument can be converted to long to match
|
||||
the first template - which is the default. So in this case, the first
|
||||
template will be instantiated and later invoked. We have managed to
|
||||
use function overloading to achieve the same effect as PFTO
|
||||
were it correctly implemented.
|
||||
<p>
|
||||
This depends upon undefined behavior of a compiler already
|
||||
determined to be non-conforming. In other words, there is no
|
||||
guarantee that this will work on all compilers. If a compiler does not
|
||||
correctly support PFTO and this method cannot be used to workaround
|
||||
it, non-intrusive serialization cannot be supported for that compiler.
|
||||
As of this writing, such a compiler has not been encountered.
|
||||
<p>
|
||||
It turns out that using this "trick" can create problems with
|
||||
compilers that DO correctly support PFTO. For this reason we
|
||||
define a macro <code style="white-space: normal">BOOST_PTFO</code> which
|
||||
is defined to be <code style="white-space: normal">long</code>
|
||||
for non-conforming compilers and nothing for conforming ones. So
|
||||
the default definition is really:
|
||||
The serialization library works around this issue by using a different
|
||||
default definition of the first template:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned BOOST_PFTO int file_version // Note: change to BOOST_PFTO
|
||||
){
|
||||
...
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
<h3><a name="charencoding">Character Encoding</a></h3>
|
||||
The whole question of character encoding combined with wide characters
|
||||
is much more complicated than it would seem to be. The current library
|
||||
defines in 3 formats (text, binary, and XML), wide and narrow characters,
|
||||
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,18 +175,42 @@ do the following.
|
||||
<li>Create the archive with the flag <code style="white-space: normal">no_codecvt</code>.
|
||||
</ul>
|
||||
Naturally, the input process has to be symmetrical.
|
||||
<h3><a name="partialtemplatespecialization">Partial Template Specialization</a></h3>
|
||||
Compilers which fail to support partial template specialization will fail to compile
|
||||
the following code. To make this compiler, the <code style="white-space: normal">const</code> has to be removed.
|
||||
<pre><code>
|
||||
void f(A const* a, text_oarchive& oa)
|
||||
{
|
||||
oa << a;
|
||||
}
|
||||
</code></pre>
|
||||
<h3><a name="tempatesyntax">Template Invocation syntax</a></h3>
|
||||
Some compilers may not recognize the syntax:
|
||||
<pre><code>
|
||||
ar.template register_type<T>();
|
||||
</code></pre>
|
||||
for "registering" derived pointers of polymorphic classes. The actual
|
||||
function prototype is:
|
||||
<pre><code>
|
||||
template<T>
|
||||
void register_type(T * t = NULL);
|
||||
</code></pre>
|
||||
so that one may write <code style="white-space: normal">ar.register_type(static_cast<T *>(NULL))</code> instead of
|
||||
the syntax described above.
|
||||
</ul>
|
||||
<h3><a name="othercompilerissues">Specific Compiler/Library Issues</a></h3>
|
||||
<h4><a name="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
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<li>This compiler generates long warning messages related to the usage of
|
||||
non virtual destructors in polymorphic classes. These warnings have been
|
||||
carefully considered and the code that generates these warning has been
|
||||
carfully considered and the code that generates these warning has been
|
||||
unchanged. In this case the warning should should be ignored as in certain
|
||||
usages of the library, making the destructors virtual could lead to problems.
|
||||
As an alternative, base class destructors have been made "protected" to
|
||||
As an alternative, base class destructors have been make "protected" to
|
||||
address the concerns that motivate these warning messages. When building
|
||||
the serialization library and tests with bjam, these warnings are suppressed.
|
||||
When building one's own applications, these warnings can be suppressed by
|
||||
@@ -114,7 +220,17 @@ 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 templeted stream implemention
|
||||
to function properly. So STLPort must be used to build the library.
|
||||
<li>Polymorphic archive tests fail.
|
||||
<li>XML serialization only works with version 1.6x of spirit. In order to build
|
||||
and use this library with this compiler, one must use version 1.6x rather than the
|
||||
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
|
||||
</ul>
|
||||
<h4><a name="Intel80">Intel C++ 8.0</a></h4>
|
||||
No known issues. All tests compile and run in debug and release modes.
|
||||
|
||||
<h4><a name="vc80">Visual C++ 8.0</a></h4>
|
||||
@@ -129,39 +245,40 @@ line by including the following switch:
|
||||
|
||||
<h4><a name="vc71">Visual C++ 7.1</a></h4>
|
||||
Derivation from an archive class defined in a DLL as described in ... will not work.
|
||||
This is due to the way that VC++ handles templated code with __decl(dllexport) and
|
||||
This is due to the way that VC++ handles templeted code with __decl(dllexport) and
|
||||
__decl(dllimport) specifications. Basically, this compiler requires that all the
|
||||
instantiations have the same specification - even though they have different
|
||||
template arguments. The example <code style="white-space: normal">
|
||||
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
|
||||
enable these features if you want to build and run these programs.
|
||||
program presume that they are enabled. So be sure your command line or IDE settings
|
||||
enable these features if you want
|
||||
these switches are enabled if you want to build and run these programs.
|
||||
<p>
|
||||
This compiler can treat <code style="white-space: normal">wchar_t</code> as either
|
||||
a short integer or an intrinsic type.
|
||||
If <code style="white-space: normal">/Zc:wchar_t</code> is specified on the
|
||||
compile command line, <code style="white-space: normal">wchar_t</code> will be
|
||||
considered an intrinsic type - otherwise
|
||||
it will be treated as a synonym for a 16 bit integer. The library can be used
|
||||
either way - <strong>BUT</strong> - both the library <strong>AND</strong> the application
|
||||
it will be treated as a synonym for a 16 bit integer. The libary can be used
|
||||
either way - <strong>BUT</strong> - both the libray <strong>AND</strong> the application
|
||||
must be compiled with the same switch settings. Note that <code style="white-space: normal">BJAM</code>
|
||||
includes this switch by default. So if want to use the libraries that
|
||||
<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<A></code>,
|
||||
invoke the macro <code style="white-space: normal">BOOST_SERIALIZATION_SHARED_PTR(A)</code>
|
||||
in the header code.
|
||||
<li>Lack of support for partial template specialization also creates problems for
|
||||
serialization of <code style="white-space: normal">std::map</code>. In order to serialize
|
||||
instances of this type include the invocation of BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
|
||||
for the key type of the map.
|
||||
</ul>
|
||||
<h4><a name="vc6">Visual C++ 6.5</a></h4>
|
||||
all the above issues for Visual C++ 7.0 plus:
|
||||
<ul>
|
||||
<li>Out of line template definitions are not recognized and fail with a confusing
|
||||
error message. To function save/load/serialize member function templates must be defined
|
||||
within the class definition. This feature is essential to <code style="white-space: normal">demo_pimpl</code>. Hence,
|
||||
this program will fail to compile. In this case the problem can't be worked around and
|
||||
still demonstrate this facility.
|
||||
<li>This compiler does not support <code style="white-space: normal">wchar_t</code> as a separate type. It defines
|
||||
<code style="white-space: normal">wchar_t</code> as an alias for <code style="white-space: normal">short int</code>. In general things will still
|
||||
function. However certain customization, such as overloading archive operators for
|
||||
saving/loading wide character arrays would produce surprises in this environment.
|
||||
<li>Under certain circumstances, a program will fail to link with the message:
|
||||
LIN1179 - "invalid or corrupt file: duplicate comdat". According
|
||||
to <a href="http://groups.google.com/groups?th=8a05c82c4ffee280">
|
||||
http://groups.google.com/groups?th=8a05c82c4ffee280
|
||||
</a> (look for P78)
|
||||
A LNK1179 error occurs when:
|
||||
<ul>
|
||||
<li>The template class takes at least two arguments.
|
||||
<li>The template is used at least two times with identical first
|
||||
and different second arguments.
|
||||
<li>The static member variable is of an object type with at least one
|
||||
base class. (In another scenario it also occurred using a member
|
||||
without a base class.)
|
||||
</ul>
|
||||
Working around this in the implementation of the library for this compiler
|
||||
entailed a ridiculous amount of effort. Even so, the effort wasn't entirely succesful.
|
||||
With this compiler, this message will still appear under the following conditions:
|
||||
<ul>
|
||||
<li>When serializing a class with multiple base classes. This problem causes two
|
||||
failure in the test suite. I have been unable to divise a way to work around this.
|
||||
<li>Using more than one kind of archive in the same code module. This should be easy
|
||||
to work around in practice.
|
||||
</ul>
|
||||
<li>Code modules exceeding some undetermined size that use the library will fail with
|
||||
<i>fatal error C1204: compiler limit : internal structure overflow</i>. This can be addressed
|
||||
by dividing the module into smaller ones.
|
||||
</ul>
|
||||
<h4><a name="borland">Borland 5.64 and 5.51</a></h4>
|
||||
<ul>
|
||||
<li><code style="white-space: normal">enum</code> data members cannot be serialized.
|
||||
Conversion to/from integers will work around the problem.
|
||||
<li>If class serialize functions are not accessable either by making them public or by
|
||||
including <code style="white-space: normal">friend</code> declarations as described in
|
||||
<a href="serialization.html#member">Class Serialization - Member Function</a>, the
|
||||
will compile but fail at runtime.
|
||||
<li>Tests using custom extended type which doesn't use rtti fails. (5.64 only !).
|
||||
<li>Tests built in release mode fail. This seems to be an issue with the boost test system
|
||||
with this compiler.
|
||||
<li>XML serialization only works with version 1.6x of spirit. In order to build
|
||||
and use this library with this compiler, one must use version 1.6x rather than the
|
||||
latest version shipped with boost. See <a href="release.html">Release Notes</a>.
|
||||
</ul>
|
||||
<h4><a name="comeau">Comeau 4.3.3</a></h4>
|
||||
<ul>
|
||||
<li>This compiler fails to make a DLL with export under windows.
|
||||
@@ -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,17 +425,17 @@ 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
|
||||
<li>the test_set fails to run correctly. It seems the hashed set interator doesn't
|
||||
implement the ++ operator correctly. This causes the test to fail by consuming all available
|
||||
memory. Given this, this test is commented out.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2004
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2015.
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 849 B After Width: | Height: | Size: 839 B |
@@ -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>© 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
@@ -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).
|
||||
|
||||
@@ -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>© 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
@@ -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<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version);
|
||||
void serialize(Archive & ar, const unsigned int file_version);
|
||||
A();
|
||||
};
|
||||
</code></pre>
|
||||
Serialization of A requires access to the definition of B. 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<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & 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<class Archive>
|
||||
void A::serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & pimpl;
|
||||
void A::serialize(Archive & ar, const unsigned int file_version){
|
||||
ar & pimpl;
|
||||
}
|
||||
</code></pre>
|
||||
As described in <a href="bibliography.html#10">[10]</a> this brings the
|
||||
@@ -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 & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
|
||||
void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
|
||||
</code></pre>
|
||||
The problem is that when compiling the above code,
|
||||
there is no instantiation of the <code style="white-space: normal">serialize</code> template.
|
||||
There can't be as 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 <boost/archive/text_oarchive.hpp>
|
||||
|
||||
template void A::serialize<boost::archive::text_iarchive>(
|
||||
boost::archive::text_iarchive & ar,
|
||||
boost::archive::text_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
template void A::serialize<boost::archive::text_oarchive>(
|
||||
boost::archive::text_oarchive & ar,
|
||||
boost::archive::text_oarchive & ar,
|
||||
const unsigned int file_version
|
||||
);
|
||||
</code></pre>
|
||||
@@ -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>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 855 B After Width: | Height: | Size: 844 B |
@@ -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 <fstream>
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class Base {
|
||||
friend class boost::serialization::access;
|
||||
int m_i;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_NVP(m_i);
|
||||
}
|
||||
protected:
|
||||
bool equals(const Base &rhs) const {
|
||||
return m_i == rhs.m_i;
|
||||
}
|
||||
Base(int i = 0) :
|
||||
m_i(i)
|
||||
{}
|
||||
};
|
||||
|
||||
class Derived : private Base {
|
||||
friend class boost::serialization::access;
|
||||
private:
|
||||
Base & base_cast(){
|
||||
return static_cast<Base &>(*this);
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
|
||||
}
|
||||
public:
|
||||
bool operator==(const Derived &rhs) const {
|
||||
return Base::equals(static_cast<const Base &>(rhs));
|
||||
}
|
||||
Derived(int i = 0) :
|
||||
Base(i)
|
||||
{}
|
||||
};
|
||||
|
||||
int
|
||||
main( int /* argc */, char* /* argv */[] )
|
||||
{
|
||||
const char * testfile = boost::archive::tmpnam(NULL);
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived a(1), a1(2);
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("a", a);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("a", a1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
|
||||
if(a != a1)
|
||||
return 1;
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived *ta = &a;
|
||||
Derived *ta1 = NULL;
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("ta", ta);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("ta", ta1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
if(*ta != *ta1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code></pre>
|
||||
Difficulties start to occur when the base class is made polymorphic by the designation
|
||||
of one or more functions as "virtual". If a class is polymorphic, the library
|
||||
presumes that one will want the ability to serialize a derived class through
|
||||
a pointer to the base class. Included in the macro
|
||||
<code>
|
||||
BOOST_SERIALIZATION_BASE_OBJECT_NVP
|
||||
</code>
|
||||
is code which links derived and base class definitions in tables used to serialize
|
||||
derived classes through pointers to a polymorphic base class. This code requires
|
||||
the ability to invoke
|
||||
<code>
|
||||
static_cast<Base &>(Derived &)
|
||||
</code>
|
||||
which C++ will only permit from within the derived class if the base class is
|
||||
private or protected. The program will fail to compile with an error message
|
||||
indicating invalid cast.
|
||||
<p>
|
||||
In order for this
|
||||
code compiler the following alteration must be made:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
//ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
|
||||
ar & boost::serialization::make_nvp(
|
||||
"Base",
|
||||
static_cast<Base &>(*this)
|
||||
);
|
||||
}
|
||||
</code></pre>
|
||||
With this change the program will now compile.
|
||||
<p>
|
||||
If we made one of the functions of <code>Base</code> <code>virtual</code>
|
||||
in order to use the "export" functionality of the serialization library and permit serialization through
|
||||
a pointer the the base class, we'll be disappointed. Without the ability to
|
||||
cast to the base class, we can't use the functionality.
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2015.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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
|
||||
@@ -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&)
|
||||
@@ -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
@@ -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 data
|
||||
directly into/from the stream . 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 << t;
|
||||
</pre></code>
|
||||
|
||||
unless the tracking_level serialization trait is set to "track_never". The following
|
||||
will compile without problem:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
const T t
|
||||
ar << t;
|
||||
</pre></code>
|
||||
|
||||
Likewise, the following code will trap at compile time:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
T * t;
|
||||
ar >> t;
|
||||
</pre></code>
|
||||
|
||||
if the tracking_level serialization trait is set to "track_never".
|
||||
<p>
|
||||
|
||||
This behavior has been contraversial and may be revised in the future. The criticism
|
||||
is that it will flag code that is in fact correct and force users to insert
|
||||
<code style="white-space: normal">const_cast</code>. My view is that:
|
||||
<ul>
|
||||
<li>The trap is useful in detecting a certain class of programming errors.
|
||||
<li>Such errors would otherwise be difficult to detect.
|
||||
<li>The incovenience caused by including this trap is very small in relation
|
||||
to its benefits.
|
||||
</ul>
|
||||
|
||||
The following case illustrates my position. It was originally used as an example in the
|
||||
mailing list by Peter Dimov.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class construct_from
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
Suppose that there is no trap as described above.
|
||||
<ol>
|
||||
<li>this example compiles and executes fine. No tracking is done because
|
||||
construct_from has never been serialized through a pointer. Now some time
|
||||
later, the next programmer(2) comes along and makes an enhancement. He
|
||||
wants the archive to be sort of a log.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
...
|
||||
x.f(); // change x in some way
|
||||
...
|
||||
ar << x
|
||||
}
|
||||
</pre></code>
|
||||
<p>
|
||||
Again no problem. He gets two different of copies in the archive, each one is different.
|
||||
That is he gets exactly what he expects and is naturally delighted.
|
||||
<p>
|
||||
<li>Now sometime later, a third programmer(3) sees construct_from and says -
|
||||
oh cool, just what I need. He writes a function in a totally disjoint
|
||||
module. (The project is so big, he doesn't even realize the existence of
|
||||
the original usage) and writes something like:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class K {
|
||||
shared_ptr <construct_from> z;
|
||||
template <class Archive>
|
||||
void serialize(Archive & ar, const unsigned version){
|
||||
ar << z;
|
||||
}
|
||||
};
|
||||
</pre></code>
|
||||
|
||||
<p>
|
||||
He builds and runs the program and tests his new functionality. It works
|
||||
great and he's delighted.
|
||||
<p>
|
||||
<li>Things continue smoothly as before. A month goes by and it's
|
||||
discovered that when loading the archives made in the last month (reading the
|
||||
log). Things don't work. The second log entry is always the same as the
|
||||
first. After a series of very long and increasingly acrimonius email exchanges,
|
||||
its discovered
|
||||
that programmer (3) accidently broke programmer(2)'s code .This is because by
|
||||
serializing via a pointer, the "log" object now being tracked. This is because
|
||||
the default tracking behavior is "track_selectively". This means that class
|
||||
instances are tracked only if they are serialized through pointers anywhere in
|
||||
the program. Now multiple saves from the same address result in only the first one
|
||||
being written to the archive. Subsequent saves only add the address - even though the
|
||||
data might have been changed. When it comes time to load the data, all instances of the log record show the same data.
|
||||
In this way, the behavior of a functioning piece of code is changed due the side
|
||||
effect of a change in an otherwise disjoint module.
|
||||
Worse yet, the data has been lost and cannot not be now recovered from the archives.
|
||||
People are really upset and disappointed with boost (at least the serialization system).
|
||||
<p>
|
||||
<li>
|
||||
After a lot of investigation, it's discovered what the source of the problem
|
||||
and class construct_from is marked "track_never" by including:
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_SERIALIZATION_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
<li>Now everything works again. Or - so it seems.
|
||||
<p>
|
||||
<li><code style="white-space: normal">shared_ptr<construct_from></code>
|
||||
is not going to have a single raw pointer shared amongst the instances. Each loaded
|
||||
<code style="white-space: normal">shared_ptr<construct_from></code> is going to
|
||||
have its own distinct raw pointer. This will break
|
||||
<code style="white-space: normal">shared_ptr</code> and cause a memory leak. Again,
|
||||
The cause of this problem is very far removed from the point of discovery. It could
|
||||
well be that the problem is not even discovered until after the archives are loaded.
|
||||
Now we not only have difficult to find and fix program bug, but we have a bunch of
|
||||
invalid archives and lost data.
|
||||
</ol>
|
||||
|
||||
Now consider what happens when the trap is enabled:.
|
||||
|
||||
<ol>
|
||||
<p>
|
||||
<li>Right away, the program traps at
|
||||
<code style="white-space: normal"><pre>
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
<li>The programmer curses (another %^&*&* hoop to jump through). If he's in a
|
||||
hurry (and who isn't) and would prefer not to <code style="white-space: normal">const_cast</code>
|
||||
- because it looks bad. So he'll just make the following change an move on.
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
Things work fine and he moves on.
|
||||
<p>
|
||||
<li>Now programer (2) wants to make his change - and again another
|
||||
annoying const issue;
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
...
|
||||
x.f(); // change x in some way ; compile error f() is not const
|
||||
...
|
||||
ar << x
|
||||
</pre></code>
|
||||
<p>
|
||||
He's mildly annoyed now he tries the following:
|
||||
<ul>
|
||||
<li>He considers making f() a const - but presumable that shifts the const
|
||||
error to somewhere else. And his doesn't want to fiddle with "his" code to
|
||||
work around a quirk in the serializaition system
|
||||
<p>
|
||||
<li>He removes the <code style="white-space: normal">const</code>
|
||||
from <code style="white-space: normal">const construct_from</code> above - damn now he
|
||||
gets the trap. If he looks at the comment code where the
|
||||
<code style="white-space: normal">BOOST_STATIC_ASSERT</code>
|
||||
occurs, he'll do one of two things
|
||||
<ol>
|
||||
<p>
|
||||
<li>This is just crazy. Its making my life needlessly difficult and flagging
|
||||
code that is just fine. So I'll fix this with a <code style="white-space: normal">const_cast</code>
|
||||
and fire off a complaint to the list and mabe they will fix it.
|
||||
In this case, the story branches off to the previous scenario.
|
||||
<p>
|
||||
<li>Oh, this trap is suggesting that the default serialization isn't really
|
||||
what I want. Of course in this particular program it doesn't matter. But
|
||||
then the code in the trap can't really evaluate code in other modules (which
|
||||
might not even be written yet). OK, I'll add the following to my
|
||||
construct_from.hpp to solve the problem.
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_SERIALIZATION_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
</ol>
|
||||
</ul>
|
||||
<p>
|
||||
<li>Now programmer (3) comes along and make his change. The behavior of the
|
||||
original (and distant module) remains unchanged because the
|
||||
<code style="white-space: normal">construct_from</code> trait has been set to
|
||||
"track_never" so he should always get copies and the log should be what we expect.
|
||||
<p>
|
||||
<li>But now he gets another trap - trying to save an object of a
|
||||
class marked "track_never" through a pointer. So he goes back to
|
||||
construct_from.hpp and comments out the
|
||||
<code style="white-space: normal">BOOST_SERIALIZATION_TRACKING</code> that
|
||||
was inserted. Now the second trap is avoided, But damn - the first trap is
|
||||
popping up again. Eventually, after some code restructuring, the differing
|
||||
requirements of serializating <code style="white-space: normal">construct_from</code>
|
||||
are reconciled.
|
||||
</ol>
|
||||
Note that in this second scenario
|
||||
<ul>
|
||||
<li>all errors are trapped at compile time.
|
||||
<li>no invalid archives are created.
|
||||
<li>no data is lost.
|
||||
<li>no runtime errors occur.
|
||||
</ul>
|
||||
|
||||
It's true that these traps may sometimes flag code that is currently correct and
|
||||
that this may be annoying to some programmers. However, this example illustrates
|
||||
my view that these traps are useful and that any such annoyance is small price to
|
||||
pay to avoid particularly vexing programming errors.
|
||||
|
||||
<!--
|
||||
<h2><a name="footnotes"></a>Footnotes</h2>
|
||||
<dl>
|
||||
|
||||
+2
-2
@@ -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>
|
||||
|
||||
+82
-252
@@ -2,151 +2,45 @@
|
||||
<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_32">Differences from version 1.32</a></dt>
|
||||
<dt><a href="#differences_1_33">Differences from version 1.33</a></dt>
|
||||
<dt><a href="#differences_1_34">Differences from version 1.34</a></dt>
|
||||
<dt><a href="#todo">Pending Issues</a></dt>
|
||||
</dl>
|
||||
As of this writing, there are no known bugs. However, due to compiler/library
|
||||
quirks and or bugs, some tests fail with some combinations of compilers and
|
||||
libraries.
|
||||
<h2><a name="differences_1_59"></a>Differences from Boost 1.58</h2>
|
||||
<ul>
|
||||
<li>Eliminated support for Borland compilers and Microsoft compilers prior to version
|
||||
7.1.
|
||||
<li>Eliminated support for compilers which do not support Partial Function Template
|
||||
Ordering (pfto).
|
||||
<li>Added support for "visibility hidden" for GCC compilers. Shared libraries
|
||||
will only expose symbols actually needed rather than all sympols in the library. This
|
||||
should result in smaller shared libraries which are faster to load.
|
||||
</ul>
|
||||
<h2><a name="differences_1_58"></a>Differences from Boost 1.48</h2>
|
||||
<ul>
|
||||
<li>Added support for C++11 types such as std::shared_ptr, std::array, and others.
|
||||
<li>Implemented the concept of a "Helper" which can be used to implement serialization of types which are otherwise not serializable."
|
||||
<li>Made library compatible with C++11, Compatibility with C++03 has been maintained.
|
||||
</ul>
|
||||
<h2><a name="differences_1_45"></a>Differences from Boost 1.45</h2>
|
||||
Since the release of version 1.42, it has been discovered that binary
|
||||
archives created by versions 1.42-1.44 cannot always be read by the
|
||||
recent binary archive code. Work has proceeded in detecting the source
|
||||
of these anomolies and those which have been reported with test cases
|
||||
have been fixed. As of this writing, it is not known whether all
|
||||
binary archives created with these versions can be loaded.
|
||||
<h2><a name="differences_1_43"></a>Differences from Boost 1.43</h2>
|
||||
<ul>
|
||||
<li>fixed bug in the serialization of virtual base classes. Due
|
||||
to heroic efforts by Takatoshi Kondo.
|
||||
<li>Native binary archives created under versions 1.42 and 1.43
|
||||
suffer from a serious problem. It's likely they won't be readable
|
||||
by this latest version. This due to the fact that 1.42 made some
|
||||
changes in the binary format of some types. Normally this could
|
||||
be addressed by detecting the library version number written into
|
||||
the archive header. Unfortunately, this library version number
|
||||
was not incremented at 1.42 as it should have been. So now we have
|
||||
two different binary archive versions with the same library version
|
||||
number.
|
||||
<p>
|
||||
This has been addressed by including a small utility in the example
|
||||
directory named fix_six.cpp. This should be run with the command line<br>
|
||||
<code><pre>
|
||||
fix_six <file name>
|
||||
</pre></code>
|
||||
This will assign 7 to the library version number of the archive. This
|
||||
fix will need to ba applied to native binary archives created with
|
||||
boost versions 1.42 and 1.43.
|
||||
</ul>
|
||||
<h2><a name="differences_1_42"></a>Differences from Boost 1.42</h2>
|
||||
<ul>
|
||||
<li>fixed failure of shared_ptr serialization when serializing pointers
|
||||
created from enable_shared_from_this.
|
||||
<li>added example for a simple archive which can be used as a debug log.
|
||||
This example illustrates the implemenation of the archive concept to aid
|
||||
understanding required to create one's own archive classes. The resulting
|
||||
archive is useful for debugging in that it only 160 lines of code and is
|
||||
header only - that is, it doesn't required linking to the serialization library.
|
||||
<li>replaced example used to show how to derive from an existing archive.
|
||||
This example creates an XML archive class which doesn't include serialization
|
||||
traits such as class_id, class_version, etc. It might be useful for exporting
|
||||
one's class information to osme XML processor and/or debugging programs.
|
||||
<li>compile time warnings have been implemented to detect practices which
|
||||
though correct, will result in operation or side effects different than
|
||||
a user probably intends.
|
||||
<li>Some memory leaks associated with void_cast have been fixed.
|
||||
</ul>
|
||||
<h2><a name="differences_1_41"></a>Differences from Boost 1.41</h2>
|
||||
<ul>
|
||||
<li>adjustments have been made to minimize compile time warnings.
|
||||
<li>compile time warnings have been implemented to detect practices which
|
||||
though correct, will result in operation or side effects different than
|
||||
a user probably intends.
|
||||
<li>Some memory leaks associated with void_cast have been fixed.
|
||||
</ul>
|
||||
<h2><a name="differences_1_40"></a>Differences from Boost 1.40</h2>
|
||||
This library has been tested against Boost version 1.39 and 1.40.
|
||||
<p>
|
||||
Changes have been made to archive classes included with the library. Users who
|
||||
have used these a guide to making their own archive classes will find that
|
||||
these will likely no longer compile. This can be remedied by making the
|
||||
following changes in the code which instantiates these archive classes.
|
||||
</p>
|
||||
Old Code:<br>
|
||||
<code><pre>
|
||||
...
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<text_iarchive> ;
|
||||
</pre></code>should be replaced with this new code: <code><pre>
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
...
|
||||
template class detail::archive_serializer_map<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_serializer_map<text_iarchive> ;
|
||||
</pre></code>
|
||||
<!--
|
||||
This is the Boost 1.33 Serialization Library.
|
||||
There are currently no known bugs. However, due to compiler/library quirks and or
|
||||
bugs, some tests fail with some combinations of compilers and libraries.
|
||||
<h2><a name="requirements"></a>Requirements</h2>
|
||||
This library requires Boost version 1.33 or later.
|
||||
<p>
|
||||
The serialization library uses the boost spirit package to load XML archives.
|
||||
We have found that all tests pass using spirit 1.6x. Spirit 1.8 and higher does not work with
|
||||
older compilers - specifically MSVC 6, Borland and GCC < 3.0.
|
||||
older compilers - specificallly MSVC 6, Borland and GCC < 3.0.
|
||||
If you are using one of these compilers, you may download a version
|
||||
of spirit 1.6 <a href="http://spirit.sourceforge.net/index.php?doc=download/index.html">here</a>.
|
||||
To use this downloaded version rather than the one included with boost,
|
||||
@@ -158,138 +52,74 @@ set SPIRIT_ROOT=c:/spirit16
|
||||
If you're not using bjam and the Jamfile to build the library, be sure that
|
||||
the directory which contains the version of spirit you plan to use is placed
|
||||
at the front of the list of include paths.
|
||||
-->
|
||||
<h2><a name="differences_1_39"></a>Differences from Boost 1.39</h2>
|
||||
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</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.
|
||||
</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>Dynamic Linking Library (DLLs and shared libraries) for platforms which support them. See
|
||||
<a href="../../../more/getting_started.html#auto-link">Automatic Linking on Windows</a>.
|
||||
<li>Implementation of auto-link for compilers which can support this.
|
||||
<li>Better support for <em>Argument Dependent Lookup</em> and two-phase lookup.
|
||||
This results in simpler rules regarding the placing of serialization specializations
|
||||
namespaces.
|
||||
<li>Enhanced documentation to help explain usage of the above.
|
||||
<li>Adjustments to improve support for less conformant compilers.
|
||||
<li>Improved <code>const</code> correctness for save/load operators. Note that this may
|
||||
produce compile time errors in code which compiled without problem in earlier boost releases.
|
||||
In most cases the fix is trivial. In other cases, code should be scrutinized to be
|
||||
sure that it doesn't use the serializaton system in a way which may introduce subtle bugs in
|
||||
to the program. A fuller explanation of this issue can be found
|
||||
<a target="detail" href="traits.html#tracking">here</a>.
|
||||
<li>A new implementation of serialization for <code style="white-space: normal">shared_ptr<T></code>. This
|
||||
is compatible with public interface of <code style="white-space: normal">shared_ptr<T></code>
|
||||
so it should be more robust and not have to change in the future. The implementation optionally
|
||||
includes code to load <code style="white-space: normal">shared_ptr<T></code> stored in
|
||||
archives created with boost 1.32. This code is stored in the header:
|
||||
<code style="white-space: normal">boost/serialization/shared_ptr_132.hpp</code>. If your application
|
||||
needs to load archives created with boost 1.32 libraries, include the above header
|
||||
before each inclusion of <code style="white-space: normal">boost/serialization/shared_ptr.hpp</code>.
|
||||
<li>More compilers tested and supported.
|
||||
<li>Miscelleanous bug fixes.
|
||||
</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 noticibly faster execution in many cases.
|
||||
</ul>
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
|
||||
|
||||
<h2><a name="differences_1_34"></a>Differences from Boost 1.34</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<T></code>.
|
||||
This is compatible with public interface of <code style="white-space: normal">shared_ptr<T></code>
|
||||
so it should be more robust and not have to change in the future. The
|
||||
implementation optionally includes code to load <code style="white-space: normal">shared_ptr<T></code>
|
||||
stored in archives created with boost 1.32. This code is stored in 'he header: <code style="white-space: normal">
|
||||
boost/serialization/shared_ptr_132.hpp</code>. If your application needs to
|
||||
load archives created with boost 1.32 libraries, include the above header
|
||||
before each inclusion of <code style="white-space: normal">boost/serialization/shared_ptr.hpp</code>.
|
||||
<li>
|
||||
More compilers tested and supported.
|
||||
<li>
|
||||
Miscellaneous bug fixes.
|
||||
<li>Ehanced support for fast serialiation for native binary archives. By Mattias Troyer.
|
||||
<li>Improved implementation of "export" functionality. Removes header ordering
|
||||
requirement and eliminates the maintainence of a pre-determined list of "known archives"
|
||||
By David Abrahams.
|
||||
<li>Improved support for STLPort.
|
||||
</ul>
|
||||
|
||||
<h2><a name="todo"></a>Pending issues</h2>
|
||||
<ul>
|
||||
<li>
|
||||
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>implement <code>is_virtual_base<T></code> to automatically
|
||||
eliminate redundancy in virtual base class serialization.
|
||||
<li>currently can't serialize through a pointer an object a of class
|
||||
that implements its own <code style="white-space: normal">new/delete</code> operators.
|
||||
<li>Its possible that <code style="white-space: normal">std::string</code>
|
||||
and <code style="white-space: normal">std::wstring</code> contain characters such as
|
||||
'\0' which cannot be rendered in XML without an escape mechanism. Currently there is
|
||||
no such escape mechanism implemented.
|
||||
<li>A subtle error in the implementation of serialiaton of <code style="white-space: normal">std::map</code>
|
||||
is fixed in this version. Unfortunately, the fix breaks serialization of
|
||||
<code style="white-space: normal">std::map</code> for those compilers which do not support
|
||||
partial template specialization.
|
||||
<li>Floating point values which are number cannot be serialized to text base archives.
|
||||
</ul>
|
||||
<p>
|
||||
Aside from the above, there are a number of issues related to specific
|
||||
platforms. These are listed in <a href="implementation.html#othercompilerissues">Specific
|
||||
Compiler/Library Issues</a>.
|
||||
<hr>
|
||||
<p>
|
||||
<i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-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 issus related to specific platforms.
|
||||
These are listed in <a href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2007.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+46
-48
@@ -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,13 +48,12 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
</dl>
|
||||
</dl>
|
||||
<dt><a href="#pointeroperators">Pointers</a>
|
||||
<dt><a href="#pointers">Pointers</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#constructors">Non-Default Constructors</a>
|
||||
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#registration">Registration</a>
|
||||
<dt><a href="#export">Export</a>
|
||||
<dt><a href="#instantiation">Instantiation</a>
|
||||
<dt><a href="#selectivetracking">Selective Tracking</a>
|
||||
<dt><a href="#runtimecasting">Runtime Casting</a>
|
||||
@@ -62,8 +61,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,20 +70,21 @@ 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.
|
||||
<li>It is a class type and one of the following has been declared according
|
||||
to the prototypes detailed below:
|
||||
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:
|
||||
<ul>
|
||||
<li>a class member function <code style="white-space: normal">serialize</code>
|
||||
<li>a global function <code style="white-space: normal">serialize</code>
|
||||
</ul>
|
||||
<li>it is a pointer to a <strong>Serializable</strong> type.
|
||||
<li>it is a reference to a <strong>Serializable</strong> type.
|
||||
<li>it is a native C++ Array of <strong>Serializable</strong> type.
|
||||
<li>it is an native C++ Array of <strong>Serializable</strong> type.
|
||||
</ul>
|
||||
|
||||
<h2><a name="primitiveoperators">Primitive Types</a></h2>
|
||||
@@ -101,8 +101,8 @@ For class/struct types, the template operators &, <<, and >>
|
||||
will generate code that invokes the programmer's serialization code for the
|
||||
particular data type. There is no default. An attempt to serialize a
|
||||
class/struct for which no serialization has been explicitly specified
|
||||
will result in a compile time error. The 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 +136,7 @@ be made accessible to the serialization library by including:
|
||||
friend class boost::serialization::access;
|
||||
</code></pre>
|
||||
in the class definition. This latter method should be preferred over the option
|
||||
of making 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 +180,7 @@ possible to serialize them. So in some instances, minor modifications to the
|
||||
class to be serialized will be necessary even when using this "non-intrusive"
|
||||
method. In practice this may not be such a problem as many libraries
|
||||
(E.G. STL) expose enough information to permit implementation of non-intrusive
|
||||
serialization with 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 +196,7 @@ templates can be in any of the following namespaces:
|
||||
Note that, at first glance, this suggestion may seem to be wrong for compilers which implement
|
||||
two phase lookup. In fact, the serialization library used a perhaps overly clever
|
||||
method to support this rule even for such compilers. Those with an interest in studying
|
||||
this 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 +219,7 @@ base_object.hpp
|
||||
includes the template:
|
||||
<pre><code>
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
Base & base_object(Derived &d);
|
||||
</code></pre>
|
||||
which should be used to create a reference to an object of the base
|
||||
which can be used as an argument to the archive serialization operators.
|
||||
@@ -255,14 +255,14 @@ Loading <code style="white-space: normal">const</code> members can be addressed
|
||||
ar & const_cast<T &>(t);
|
||||
</code></pre>
|
||||
Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
|
||||
keyword. <code style="white-space: normal">const</code> members are 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 +273,7 @@ class <code style="white-space: normal">my_t</code>, then serialization for
|
||||
<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
|
||||
for use.
|
||||
<p>
|
||||
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 +434,7 @@ is preferred. The key to the serialization implementation is that objects are s
|
||||
and loaded in exactly the same sequence. Using the <code style="white-space: normal">&</code>
|
||||
operator and <code style="white-space: normal">serialize</code>
|
||||
function guarantees that this is always the case and will minimize the
|
||||
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 +463,7 @@ following situations must be addressed:
|
||||
be determined and saved. Upon restoration the correct type
|
||||
must be created and its address correctly cast to the base
|
||||
class. That is, polymorphic pointers have to be considered.
|
||||
<li>NULL pointers must be detected when saved and restored
|
||||
<li>NULL pointers must be dectected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
|
||||
@@ -482,7 +482,7 @@ Loading a pointer:
|
||||
<ol>
|
||||
<li>read a tag from the archive.
|
||||
<li>determine the type of object to be created
|
||||
<li>if the object has already been loaded, return 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 +496,7 @@ and <code style="white-space: normal">>></code> operators
|
||||
<li>Loading the same pointer object multiple times
|
||||
results in only one object being created, thereby replicating
|
||||
the original pointer configuration.
|
||||
<li>Structures, such as collections of polymorphic pointers,
|
||||
<li>Structures such as collections of polymorphic pointers,
|
||||
are handled with no special effort on the part of users of this library.
|
||||
</ul>
|
||||
Serialization of pointers of derived types through a pointer to the
|
||||
@@ -543,7 +543,7 @@ private:
|
||||
ar & m_state;
|
||||
}
|
||||
public:
|
||||
// no default construct guarantees that no invalid object
|
||||
// no default construct guarentees that no invalid object
|
||||
// ever exists
|
||||
my_class(int attribute) :
|
||||
m_attribute(attribute),
|
||||
@@ -591,7 +591,7 @@ class derived_one : public base {
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
int main(){
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
@@ -604,7 +604,7 @@ Should it be an object of class <code style="white-space: normal">derived_one</c
|
||||
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
|
||||
<p>
|
||||
It turns out that the kind of object serialized depends upon whether the base class
|
||||
(<code style="white-space: normal">base</code> in this case) is 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 +630,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 +659,11 @@ This can be addressed by registering the derived class explicitly. All archives
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type(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<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
@@ -674,10 +674,9 @@ 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.
|
||||
|
||||
<h4><a name="export">Export</a></h4>
|
||||
The above will work but may be inconvenient. We don't always know which derived
|
||||
and corresponding load in syncronization.
|
||||
<p>
|
||||
This will work but may be inconvenient. We don't always know which derived
|
||||
classes we are going to serialize when we write the code to serialize through
|
||||
a base class pointer. Every time a new derived class is written we have to
|
||||
go back to all the places where the base class is serialized and update the
|
||||
@@ -690,7 +689,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 +718,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 +754,7 @@ can be used.
|
||||
In order to properly translate between base and derived pointers
|
||||
at runtime, the system requires each base/derived pair be found
|
||||
in a table. A side effect of serializing a base object with
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
is to ensure that the base/derived pair is added to the table
|
||||
before the <code style="white-space: normal">main</code> function is entered.
|
||||
This is very convenient and results in a clean syntax. The only
|
||||
@@ -789,18 +788,18 @@ class derived : public base {
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
ar & boost::serialization::base_object<base>(*this);
|
||||
boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<derived, base>(
|
||||
static_cast<derived *>(NULL),
|
||||
static_cast<base *>(NULL)
|
||||
static_cast<base *>(NULL),
|
||||
static_cast<derived *>(NULL)
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
int main(){
|
||||
main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
@@ -907,11 +906,11 @@ rather than
|
||||
<pre><code>
|
||||
#include <list>
|
||||
</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 +918,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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
+18
-18
@@ -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<class Archive, class P, class D>
|
||||
template<class Archive, class P, class D>
|
||||
inline void save_construct_data(
|
||||
Archive & ar,
|
||||
const boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
// variables used for construction
|
||||
ar << t->ptr;
|
||||
ar << t->ptr;
|
||||
ar << *t;
|
||||
}
|
||||
|
||||
template<class Archive, class P, class D>
|
||||
template<class Archive, class P, class D>
|
||||
inline void load_construct_data(
|
||||
Archive & ar,
|
||||
boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
boost::detail::sp_counted_base_impl<P, D> * t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
P ptr_;
|
||||
ar >> ptr_;
|
||||
// placement new
|
||||
::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
|
||||
ar >> *t;
|
||||
::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_, D());
|
||||
ar >>; *t;
|
||||
}
|
||||
</code></pre>
|
||||
The statement <code style="white-space: normal">ar >> ptr_</code> is key. This deserializes
|
||||
the same pointer 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<P, D></code> is derived from
|
||||
@@ -135,7 +135,7 @@ inline void serialize(
|
||||
const unsigned int file_version,
|
||||
int
|
||||
){
|
||||
ar & boost::serialization::base_object<
|
||||
ar & boost::serialization::base_object<
|
||||
boost::detail::sp_counted_base
|
||||
>(*this);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ inline void serialize(
|
||||
){
|
||||
}
|
||||
</code></pre>
|
||||
It would seem we're done, 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<P, D></code> is only
|
||||
created once regardless of how many shared pointers point to the
|
||||
same object. Of course, it has to be this way. The reference
|
||||
count starts at 1 and is never 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<
|
||||
boost::detail::sp_counted_base_impl<P, D>
|
||||
boost::detail::sp_counted_base,
|
||||
>();
|
||||
</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>
|
||||
|
||||
+15
-15
@@ -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>
|
||||
@@ -20,7 +20,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisited</h2>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisted</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -32,7 +32,7 @@ Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<li>It was dependent on the Boost implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
The <code style="white-space: normal">shared_ptr</code> interface has been included
|
||||
in <code style="white-space: normal">std::tr1</code> and may someday be included in the standard
|
||||
C++ library. An implementation which depends only on the public interface can be guaranteed to
|
||||
C++ library. An implementation which depends only on the public interface can be guarenteed to
|
||||
function with any other future implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
<li>It required extra macros for export.
|
||||
</ul>
|
||||
@@ -40,24 +40,24 @@ Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void save(
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
const T * t_ptr = t.get();
|
||||
// just serialize the underlying raw pointer
|
||||
ar << boost::serialization::make_nvp("px", t_ptr);
|
||||
// just seriailize the underlying raw pointer
|
||||
ar <<: boost::serialization::make_nvp("px", t_ptr);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
template<class Archive, class T>
|
||||
inline void load(
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
T* r;
|
||||
// recover the underlying raw pointer
|
||||
ar >> boost::serialization::make_nvp("px", r);
|
||||
// recover the underlying raw poiter
|
||||
ar >> boost::serialization::make_nvp("px", r);
|
||||
|
||||
// To Do - match up with other shared pointers which
|
||||
// use this same raw pointer.
|
||||
@@ -65,13 +65,13 @@ inline void load(
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
In principle, this is very much simpler than the original implementation. Completion of
|
||||
In priniciple this is very much simpler than the original implementation. Completion of
|
||||
this code requires:
|
||||
|
||||
<ol>
|
||||
<li>Filling in the "To Do". This required making an extra map for
|
||||
<code style="white-space: normal">shared_ptr</code> instances.
|
||||
<li>A method for identifying pointers to the same objects from pointers to their base classes.
|
||||
<li>A method for identifing pointers to the same objects from pointers to their base classes.
|
||||
<li>Backward compatibility with pointers serialized by the previous method. This exploits
|
||||
the serialization class versioning.
|
||||
<li>Proper handling of <code style="white-space: normal">weak_ptr</code>.
|
||||
|
||||
@@ -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 << schedule;
|
||||
</code></pre>
|
||||
|
||||
and it produces the following output
|
||||
|
||||
<pre><code>
|
||||
schedule
|
||||
count 6
|
||||
item
|
||||
first
|
||||
driver bob
|
||||
hour 6
|
||||
minute 24
|
||||
second ->
|
||||
stops
|
||||
count 3
|
||||
item ->
|
||||
latitude
|
||||
degrees 34
|
||||
minutes 135
|
||||
seconds 52.56
|
||||
longitude
|
||||
degrees 134
|
||||
minutes 22
|
||||
seconds 78.3
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
The complete example is <a href="../example/demo_simple_log.cpp" target="demo_simple_log_cpp">
|
||||
<code>demo_simple_log.cpp</code></a>. Look at
|
||||
<a href="archive_reference.html#trivial">Trivial Archive</a> to get a
|
||||
better understanding of how this works.
|
||||
|
||||
Also, note the following:
|
||||
<ul>
|
||||
<li>Only 160 lines of code.
|
||||
<li>Header only - linking with the serialization library not required.
|
||||
<li>Displays ALL <a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
<li>Lacks some features.
|
||||
<ul>
|
||||
<li>it will not display the data from the derived type given the pointer to a
|
||||
polymorphic base class. That is, only displays the information of the base class.
|
||||
To add that see the next example.
|
||||
<li>doesn't display information serialized as binary data
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2010.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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 <class T>
|
||||
class singleton : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
static const T & get_const_instance();
|
||||
static T & get_mutable_instance();
|
||||
static bool is_destroyed();
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const T & get_const_instance();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Retrieve a constant reference to the singleton for this type.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static T & get_mutable_instance();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Retrieve a mutable reference to the singleton for this type.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static bool is_destroyed();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Return <code>true</code> if the destructor on this singleton has been
|
||||
called. Otherwise, return <code>false</code>.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="requirements">Requirements</a></h3>
|
||||
In order to be used as
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>, the type T must be default constructible.
|
||||
It doesn't require static variables - though it may have them.
|
||||
Since the library guarantees that only one instance of
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
exists and all access is through the above static interface
|
||||
functions, common member functions of T become
|
||||
the functional equivalent of
|
||||
<code style="white-space: normal">static</code> functions.
|
||||
|
||||
<h3><a name="example">Examples</a></h3>
|
||||
There are at least two different ways to use this class template.
|
||||
Both are used in the serialization library.
|
||||
<p>
|
||||
The first way is illustrated by an excerpt from the file
|
||||
<code style="white-space: normal"><a target="extended_type_info" href="../src/extended_type_info.cpp">extended_type_info.cpp</a></code>.
|
||||
which contains the following code:
|
||||
|
||||
<pre><code>
|
||||
typedef std::set<const extended_type_info *, key_compare> ktmap;
|
||||
...
|
||||
void
|
||||
extended_type_info::key_register(const char *key) {
|
||||
...
|
||||
result = singleton<ktmap>::get_mutable_instance().insert(this);
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
Just by referring to the singleton instance anywhere in the program
|
||||
will guarantee that one and only one instance for the specified
|
||||
type (<code style="white-space: normal">ktmap</code> in this example)
|
||||
will exist throughout the program. There is no need for any other
|
||||
declaration or definition.
|
||||
<p>
|
||||
A second way is to use
|
||||
<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
|
||||
<code style="white-space: normal">
|
||||
singleton<T>
|
||||
</code>
|
||||
</a>
|
||||
as one of the base classes of the type. This is illustrated by a simplified
|
||||
excerpt from
|
||||
<a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info_typeid.hpp
|
||||
</code>
|
||||
</a>
|
||||
|
||||
<pre><code>
|
||||
template<class T>
|
||||
class extended_type_info_typeid :
|
||||
public detail::extended_type_info_typeid_0,
|
||||
public singleton<extended_type_info_typeid<const T> >
|
||||
{
|
||||
friend class singleton<extended_type_info_typeid<const T> >;
|
||||
private:
|
||||
// private constructor to inhibit any existence other than the
|
||||
// static one. Note: not all compilers support this !!!
|
||||
extended_type_info_typeid() :
|
||||
detail::extended_type_info_typeid_0()
|
||||
{
|
||||
type_register(typeid(T));
|
||||
}
|
||||
~extended_type_info_typeid(){}
|
||||
...
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
This usage will permit a more natural syntax to be used:
|
||||
<pre><code>
|
||||
extended_type_info_typeid<T>::get_const_instance()
|
||||
</code></pre>
|
||||
|
||||
Again, including one or more of the above statements anywhere
|
||||
in the program will guarantee that one and only one instance
|
||||
is created and referred to.
|
||||
|
||||
<h3><a name="multithreading">Multi-Threading</a></h3>
|
||||
This singleton CAN be safely used in multi-threading applications if one
|
||||
is careful follow a simple rule:
|
||||
<p>
|
||||
<b>Do not call get_mutable_instance when more than one thread is running!</b>
|
||||
All singletons used in the serialization library follow this rule.
|
||||
In order to help detect accidental violations of this rule there
|
||||
exist singleton lock/unlock functions.
|
||||
<pre><code>
|
||||
void boost::serialization::singleton_module::lock();
|
||||
void boost::serialization::singleton_module::unlock();
|
||||
bool boost::serialization::singleton_module::is_locked();
|
||||
</code></pre>
|
||||
In a program compiled for debug, any invocation of
|
||||
<code style="white-space: normal">get_mutable_instance()</code>
|
||||
while the library is in a "locked" state will trap in an assertion.
|
||||
The singleton module lock state is initialized as "unlocked" to permit
|
||||
alteration of static variables before
|
||||
<code style="white-space: normal">main</code> is called.
|
||||
The <code style="white-space: normal">lock()</code> and
|
||||
<code style="white-space: normal">unlock()</code> are "global"
|
||||
in that they affect ALL the singletons defined by this template.
|
||||
All serialization tests invoke <code style="white-space: normal">lock()</code>
|
||||
at the start of the program. For programs compiled in release
|
||||
mode these functions have no effect.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
+18
-18
@@ -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<T *>(U *)<br>static_cast<T &>(U &)</code></dt>
|
||||
<dt><code>static_cast<T *<>(U *)<br>static_cast<T &<>(U &)</code></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>required if neither T nor U are 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<T *>(U *)<br>dynamic_cast<T &>(U &)</code></dt>
|
||||
<dt><code>dynamic_cast<T *<>(U *)<br>dynamic_cast<T &<>(U &)</code></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>permitted if either T or U are polymorphic
|
||||
<li>prohibited in other cases.
|
||||
<li>throws exception on detecting 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 <boost/serialization/smart_cast.hpp>
|
||||
#include <boost/smart_cast.hpp>
|
||||
|
||||
struct top {
|
||||
};
|
||||
@@ -91,14 +91,14 @@ template<class T>
|
||||
bool is_storable(T &t){
|
||||
// what type of cast to use here?
|
||||
|
||||
// this fails at compile time when T == base2
|
||||
// this fails at compiler time when T == base2
|
||||
// return static_cast<base1 &>(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<base1 &>(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<base1 &>(t)).is_storable();
|
||||
}
|
||||
|
||||
@@ -121,27 +121,27 @@ The serialization library includes a mix of classes which use
|
||||
both static polymorphism (<strong>CRTP</strong>) and dynamic
|
||||
polymorphism via virtual functions. <code style="white-space: normal">smart_cast</code>
|
||||
was written to address the more problematic manifestations of the
|
||||
situation exemplified above.
|
||||
situation exmplified above.
|
||||
|
||||
<h3>Usage</h3>
|
||||
The following syntax is supported:
|
||||
<pre><code>
|
||||
smart_cast<Target *, Source *>(Source * s);
|
||||
smart_cast<Target *>(Source * s);
|
||||
smart_cast<Target &, Source &>(Source & s);
|
||||
smart_cast<Target *>(Source * s);
|
||||
smart_cast<Target &, Source &>(Source & s);
|
||||
</code></pre>
|
||||
Note that the above syntax doesn't include
|
||||
<pre><code>
|
||||
smart_cast<Target & >(Source & s)
|
||||
smart_cast<Target & >(Source & s)
|
||||
</code></pre>
|
||||
but the same functionality is supported with the following special syntax
|
||||
but the same functionality is supported the the following special syntax
|
||||
<pre><code>
|
||||
smart_cast_reference<Target &>(Source & s)
|
||||
smart_cast_reference<Target &>(Source & s)
|
||||
</code></pre>
|
||||
|
||||
<h3>Requirements</h3>
|
||||
<code style="white-space: normal">smart_cast</code> can be used only on compilers that support partial
|
||||
template specialization or on types for which 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(<type>)</code>
|
||||
has been applied.
|
||||
|
||||
+114
-357
@@ -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,8 +27,8 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#objecttracking">Object Tracking</a>
|
||||
<dt><a href="#export">Exporting Class Serialization</a>
|
||||
<dt><a href="#classinfo">Class Information</a>
|
||||
<dt><a href="#helpersupport">Helper Support</a>
|
||||
<dt><a href="#portability">Archive Portability</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#numerics">Numerics</a>
|
||||
@@ -36,10 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</dl>
|
||||
<dt><a href="#binary_archives">Binary Archives</a>
|
||||
<dt><a href="#xml_archives">XML Archives</a>
|
||||
<dt><a href="#export">Exporting Class Serialization</a>
|
||||
<dt><a href="#static_libraries">Static Libraries and Serialization</a>
|
||||
<dt><a href="#dlls">DLLS - Serialization and Runtime Linking</a>
|
||||
<dt><a href="#plugins">Plugins</a>
|
||||
<dt><a href="#multi_threading">Multi-Threading</a>
|
||||
<dt><a href="#optimizations">Optimizations</a>
|
||||
<dt><a href="exceptions.html">Archive Exceptions</a>
|
||||
@@ -54,10 +51,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<class Archive>
|
||||
void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x = a[i];
|
||||
@@ -97,11 +94,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<class Archive>
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
@@ -112,20 +109,20 @@ void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
</code></pre>
|
||||
In this case, the address of <code>x</code> is the one that is tracked rather than
|
||||
the address of the new item added to the set. Left unaddressed
|
||||
this will break the features that depend on tracking such as loading 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<class Archive>
|
||||
void load(boost::basic_iarchive & ar, const unsigned int version) const
|
||||
void load(boost::basic_iarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
ar >> x;
|
||||
std::pair<std::set::const_iterator, bool> result;
|
||||
result = std::m_set.insert(x);
|
||||
ar.reset_object_address(& (*result.first), &x);
|
||||
ar.reset_object_address(& (*result.first), &x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
@@ -137,7 +134,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,95 +153,54 @@ 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.
|
||||
<h3><a name="export">Exporting Class Serialization</a></h3>
|
||||
<a target="detail" href="traits.html#export">Elsewhere</a> in this manual, we have described
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>. This is used to make the serialization library aware
|
||||
that code should be instantiated for serialization of a given class even though the
|
||||
class hasn't been otherwise referred to by the program. This functionality
|
||||
is necessary to implement serialization of pointers through a virtual base
|
||||
class pointer. That is, a polymorphic pointer.
|
||||
<p>
|
||||
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.
|
||||
This macro specifies a "<b>G</b>lobally <b>U</b>nique <b>ID</b>entifier".
|
||||
This is an string which identifies the class to be created when data is loaded.
|
||||
Generally a text representation of the class name is sufficient for this purpose,
|
||||
but in certain cases it maybe necessary to specify a different string by using
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code>
|
||||
rather than a simple
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>.
|
||||
|
||||
<p>
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> would usually
|
||||
be specified in the same header file as the class declaration to which it
|
||||
corresponds. That is, <code style="white-space: normal">BOOST_CLASS_EXPORT(T)</code>
|
||||
is a "trait" of the class T. So a program using this class will look
|
||||
something like:
|
||||
|
||||
<pre><code>
|
||||
template<class T>
|
||||
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<T> lookup(const T *);
|
||||
// insert a new shared_ptr
|
||||
void insert<shared_ptr<T> >(const shared_ptr<T> *);
|
||||
};
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive & ar, const shared_ptr & x, const unsigned int /* version */)
|
||||
{
|
||||
// save shared ptr
|
||||
...
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, shared_ptr & x, const unsigned int /* version */)
|
||||
{
|
||||
// get a unique identifier. Using a constant means that all shared pointers
|
||||
// are held in the same set. Thus we detect handle multiple pointers to the
|
||||
// same value instances in the archive.
|
||||
const void * shared_ptr_helper_id = 0;
|
||||
|
||||
shared_ptr_serialization_helper & hlp =
|
||||
ar.template get_helper<shared_ptr_serialization_helper>(helper_instance_id);
|
||||
|
||||
// load shared pointer object
|
||||
...
|
||||
|
||||
shared_ptr_serialization_helper & hlp =
|
||||
ar.template get_helper<shared_ptr_serialization_helper>(shared_ptr_helper_id);
|
||||
|
||||
// look up object in helper object
|
||||
T * shared_object hlp.lookup(...);
|
||||
|
||||
// if found, return the one from the table
|
||||
|
||||
// load the shared_ptr data
|
||||
shared_ptr<T> sp = ...
|
||||
|
||||
// and add it to the table
|
||||
hlp.insert(sp);
|
||||
// implement shared_ptr_serialization_helper load algorithm with the aid of hlp
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
#include <boost/archive/xml_oarchive.hpp>
|
||||
.... // any other archive classes
|
||||
#include "my_class.hpp" // which contains BOOST_CLASS_EXPORT(my_class)
|
||||
</code></pre>
|
||||
<code style="white-space: normal">get_helper<shared_ptr_serialization_helper>();</code>
|
||||
creates a helper object associated to the archive the first time it is invoked;
|
||||
subsequent invocations return a reference to the object created in the first
|
||||
place, so that <code style="white-space: normal">hlp</code> can effectively be
|
||||
used to store contextual information persisting through the serialization
|
||||
of different <code style="white-space: normal">complex_type</code> objects on
|
||||
the same archive.
|
||||
|
||||
These headers can be in any order. (In boost versions 1.34
|
||||
and earlier, the archive headers had to go before any headers which
|
||||
contain <code style="white-space: normal">BOOST_CLASS_EXPORT</code>.)
|
||||
Any code required to serialize types specified
|
||||
by <code style="white-space: normal">BOOST_CLASS_EXPORT</code> will be
|
||||
instantiated for each archive whose header is included. (note that the code
|
||||
is instantiated regardless of whether or not it is actually invoked.)
|
||||
If no archive headers are included - no code should be instantiated.
|
||||
This will permit <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
to be a permanent part of the <code style="white-space: normal">my_class.hpp</code> .
|
||||
|
||||
<p>
|
||||
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.
|
||||
Note that the implementation of this functionality depends upon vendor
|
||||
specific extensions to the C++ language. So, there is no guarenteed portability
|
||||
of programs which use this facility. However, all C++ compilers which
|
||||
are tested with boost provide the required extensions. The library
|
||||
includes the extra declarations required by each of these compilers.
|
||||
It's reasonable to expect that future C++ compilers will support
|
||||
these extensions or something equivalent.
|
||||
|
||||
<h3><a name="classinfo">Class Information</a></h3>
|
||||
By default, for each class serialized, class information is written to the archive.
|
||||
@@ -267,7 +223,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 +251,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"><boost/cstdint.hpp></a>
|
||||
<P>
|
||||
@@ -322,7 +278,7 @@ Another potential problem is illustrated by the following example:
|
||||
template<class T>
|
||||
struct my_wrapper {
|
||||
template<class Archive>
|
||||
Archive & serialize ...
|
||||
Archive & serialize ...
|
||||
};
|
||||
|
||||
...
|
||||
@@ -330,10 +286,10 @@ struct my_wrapper {
|
||||
class my_class {
|
||||
wchar_t a;
|
||||
short unsigned b;
|
||||
template<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
template<<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
@@ -379,7 +335,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,116 +343,15 @@ 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
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>.
|
||||
Export implies two things:
|
||||
<ul>
|
||||
<li>Instantiates code which is not otherwise referred to.
|
||||
<li>Associates an external identifier with the class to be serialized.
|
||||
The fact that the class isn't explicitly referred to implies this
|
||||
requirement.
|
||||
</ul>
|
||||
In C++, usage of code not explicitly referred to is implemented via
|
||||
virtual functions. Hence, the need for export is implied by the
|
||||
usage of a derived class that is manipulated via a pointer or
|
||||
reference to its base class.
|
||||
|
||||
<p>
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the same
|
||||
source module that includes any of the archive class headers will
|
||||
instantiate code required to serialize polymorphic pointers of
|
||||
the indicated type to the all those archive classes. If no
|
||||
archive class headers are included, then no code will be instantiated.
|
||||
|
||||
<p>
|
||||
Note that the implemenation of this functionality requires
|
||||
that the <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
macro appear <b>after</b> the inclusion of any archive
|
||||
class headers for which code is to be instantiated.
|
||||
So, code that uses <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
will look like the following:
|
||||
<pre><code>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
... // other archives
|
||||
|
||||
#include "a.hpp" // header declaration for class a
|
||||
BOOST_CLASS_EXPORT(a)
|
||||
... // other class headers and exports
|
||||
</code></pre>
|
||||
This will be true regardless of whether the code is part
|
||||
of a stand alone executable, a static library or
|
||||
a dynamic or shared library.
|
||||
<p>
|
||||
Including
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
in the "a.hpp" header itself as one would do with
|
||||
other serialization traits will make it difficult
|
||||
or impossible to follow the rule above regarding
|
||||
inclusion of archive headers before
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
is invoked. This can best be addressed by using
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
|
||||
in the header declarations and
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in the class definition file.
|
||||
|
||||
<p>
|
||||
This system has certain implications for placing code in static or shared
|
||||
libraries. Placing <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
|
||||
in library code will have no effect unless archive class headers are
|
||||
also included. So when building a library, one should include all headers
|
||||
for all the archive classes which he anticipates using. Alternatively,
|
||||
one can include headers for just the
|
||||
<a href="archive_reference.html#polymorphic">Polymorphic Archives</a>.
|
||||
|
||||
<p>
|
||||
Strictly speaking, export should not be necessary if all pointer serialization
|
||||
occurs through the most derived class. However, in order to detect
|
||||
what would be a catastrophic error, the library traps ALL serializations through
|
||||
a pointer to a polymorphic class which are not exported or otherwise registered.
|
||||
So, in practice, be prepared to register or export all classes with one
|
||||
or more virtual functions which are serialized through a pointer.
|
||||
|
||||
<p>
|
||||
Note that the implementation of this functionality depends upon vendor
|
||||
specific extensions to the C++ language. So, there is no guaranteed portability
|
||||
of programs which use this facility. However, all C++ compilers which
|
||||
are tested with boost provide the required extensions. The library
|
||||
includes the extra declarations required by each of these compilers.
|
||||
It's reasonable to expect that future C++ compilers will support
|
||||
these extensions or something equivalent.
|
||||
|
||||
<h3><a name="static_libraries">Static Libraries and Serialization</a></h3>
|
||||
Code for serialization of data types can be saved in libraries
|
||||
just as it can for the rest of the type implementation.
|
||||
This works well, and can save a huge amount of compilation time.
|
||||
<ul>
|
||||
<li>Only compile serialization definitions in the library.
|
||||
<li>Explicitly instantiate serialization code for ALL
|
||||
archive classes you intend to use in the library.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
|
||||
in headers.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in definitions compiled in the library. For any particular type,
|
||||
there should be only one file which contains
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
for that type. This ensures that only one copy
|
||||
of serialization code will exist within the program. It avoids
|
||||
wasted space and the possibility of having different
|
||||
versions of the serialization code in the same program.
|
||||
Including
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in multiple files could result in a failure
|
||||
to link due to duplicated symbols or the throwing
|
||||
of a runtime exception.
|
||||
<li> Code for serialization should be only in the library,
|
||||
<li>Familiarize yourself with the <b>PIMPL</b> idiom.
|
||||
</ul>
|
||||
This is illustrated by
|
||||
<h3><a name="dlls">DLLS - Serialization and Runtime Linking</a></h3>
|
||||
Serialization code can be placed in libraries to be linked at runtime. That is,
|
||||
code can be placed in DLLS(Windows) or Shared Libraries(*nix).
|
||||
Along with the "export" facility, this
|
||||
permits a program to written without knowledge of the actual types to be serialized.
|
||||
This package doesn't include an example of this technique - but coding would be
|
||||
very similar to the example
|
||||
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl.cpp</code>
|
||||
</a>,
|
||||
@@ -507,150 +362,52 @@ and
|
||||
<a href = "../example/demo_pimpl_A.hpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl_A.hpp</code>
|
||||
</a>
|
||||
where implementation of serialization is in a static library
|
||||
completely separate from the main program.
|
||||
|
||||
<h3><a name="dlls">DLLS - Serialization and Runtime Linking</a></h3>
|
||||
Serialization code can be placed in libraries to be linked at runtime. That is,
|
||||
code can be placed in DLLS(Windows) Shared Libraries(*nix), or static libraries
|
||||
as well as the main executable. The best technique is the
|
||||
same as that described above for libraries. The serialization
|
||||
library test suite includes the following programs
|
||||
to illustrate how this works:
|
||||
<p>
|
||||
|
||||
<a href = "../test/test_dll_simple.cpp" target="test_dll_simple">
|
||||
<code style="white-space: normal">test_dll_simple</code>
|
||||
</a>,
|
||||
and
|
||||
<a href = "../test/dll_a.cpp" target="dll_a">
|
||||
<code style="white-space: normal">dll_a.cpp</code>
|
||||
</a>
|
||||
where implementation of serialization is also completely separate
|
||||
from the main program but the code is loaded at runtime. In this
|
||||
example, this code is loaded automatically when the program which
|
||||
uses it starts up, but it could just as well be loaded and unloaded
|
||||
with an OS dependent API call.
|
||||
<p>
|
||||
Also included are
|
||||
<a href = "../test/test_dll_exported.cpp" target="test_dll_exported">
|
||||
<code style="white-space: normal">test_dll_exported.cpp</code>
|
||||
</a>,
|
||||
and
|
||||
<a href = "../test/polymorphic_derived2.cpp" target="polymorphic_derived2">
|
||||
<code style="white-space: normal">polymorphic_derived2.cpp</code>
|
||||
</a>
|
||||
which are similar to the above but include tests of the export
|
||||
and no_rtti facilities in the context of DLLS.
|
||||
<p>
|
||||
For best results, write your code to conform to the following
|
||||
guidelines:
|
||||
<ul>
|
||||
<li>Don't include <code>inline</code> code in classes used in DLLS.
|
||||
This will generate duplicate code in the DLLS and mainline. This
|
||||
needlessly duplicates code. Worse, it makes is possible for
|
||||
different versions of the same code to exist simultaneously. This
|
||||
type of error turns out to be excruciatingly difficult to debug.
|
||||
Finally, it opens the possibility that a module being referred to
|
||||
might be explicitly unloaded which would (hopefully) result in
|
||||
a runtime error. This is another bug that is not always
|
||||
reproducible or easy to find. For class member templates use something like
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version);
|
||||
</code></pre>
|
||||
in the header, and
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void myclass::serialize(Archive & ar, const unsigned int version){
|
||||
...
|
||||
}
|
||||
|
||||
BOOST_CLASS_EXPORT_IMPLEMENT(my_class)
|
||||
|
||||
#include <boost/archive/text_oarchive>
|
||||
#include <boost/archive/text_iarchive>
|
||||
template myclass::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
|
||||
template myclass::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
|
||||
... // repeat for each archive class to be used.
|
||||
</code></pre>
|
||||
in the implementation file. This will result in generation of all code
|
||||
required in only one place. The library does not detect this type of error for you.
|
||||
<li>If DLLS are to be loaded and unloaded explicitly (e.g. using <code>dlopen</code> in *nix or
|
||||
<code>LoadLibrary</code> in Windows). Try to arrange that they are unloaded in the reverse
|
||||
sequence. This should guarantee that problems are avoided even if the
|
||||
above guideline hasn't been followed.
|
||||
|
||||
</ul>
|
||||
|
||||
<h3><a name="plugins">Plugins</a></h3>
|
||||
In order to implement the library, various facilities for runtime
|
||||
manipulation of types at runtime were required. These
|
||||
are <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
for associating classes with external identifying strings (<b>GUID</b>)
|
||||
and <a target="detail" href="void_cast.html"><code>void_cast</code></a>
|
||||
for casting between pointers of related types.
|
||||
|
||||
To complete the functionality of
|
||||
<a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
the ability to construct and destroy corresponding types has been
|
||||
added. In order to use this functionality, one must specify
|
||||
how each type is created. This should be done at the time
|
||||
a class is exported. So, a more complete example of the code above would be:
|
||||
|
||||
<pre><code>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
... // other archives
|
||||
|
||||
#include "a.hpp" // header declaration for class a
|
||||
|
||||
// this class has a default constructor
|
||||
BOOST_SERIALIZATION_FACTORY_0(a)
|
||||
// as well as one that takes one integer argument
|
||||
BOOST_SERIALIZATION_FACTORY_1(a, int)
|
||||
|
||||
// specify the GUID for this class
|
||||
BOOST_CLASS_EXPORT(a)
|
||||
... // other class headers and exports
|
||||
</code></pre>
|
||||
|
||||
With this in place, one can construct, serialize and destroy a class
|
||||
about which is known only the <b>GUID</b> and a base class.
|
||||
|
||||
where implementation of serializaton is completely separate
|
||||
from the main program.
|
||||
|
||||
<h3><a name="multi_threading">Multi-Threading</a></h3>
|
||||
The fundamental purpose of serialization would conflict with multiple
|
||||
threads concurrently writing/reading from/to a single open archive instance.
|
||||
The library implementation presumes that the application avoids such a situation.
|
||||
The nature of serialization would conflict with multiple thread concurrently
|
||||
writing/reading from/to a single open archive. Since each archive is
|
||||
independent from ever other one, there should be no problem
|
||||
in having multiple open archives from one or more threads.
|
||||
<p>
|
||||
However, Writing/Reading different archives simultaneously
|
||||
in different tasks is permitted as each archive instance is (almost)
|
||||
completely independent from any other archive instance. The only shared
|
||||
information is some type tables which have been implemented using a
|
||||
lock-free thread-safe
|
||||
<a target="detail" href="singleton.html">
|
||||
<code style="white-space: normal">singleton</code>
|
||||
</a>
|
||||
described elsewhere in this documentation.
|
||||
Well, not quite.
|
||||
<p>
|
||||
This singleton implementation guarantees that all of this shared
|
||||
information is initialized when the code module which contains
|
||||
it is loaded. The serialization library takes care to
|
||||
ensure that these data structures are not subsequently
|
||||
modified. The only time there could be a problem would
|
||||
be if code is loaded/unloaded while another task is
|
||||
serializing data. This could only occur for types whose
|
||||
serialization is implemented in a dynamically loaded/unloaded DLL
|
||||
or shared library. So if the following is avoided:
|
||||
<ul>
|
||||
<li>Accessing the same archive instance from different tasks.
|
||||
<li>Loading/Unloading DLLS or shared libraries while any archive
|
||||
instances are open.
|
||||
</ul>
|
||||
The library should be thread safe.
|
||||
There are a couple of global data structures for holding
|
||||
information of serializable types. These structures are
|
||||
used to dispatch to correct code to handle each pair
|
||||
of serializable types and archive types. Since this
|
||||
information is shared among all archives, there is
|
||||
potential for problems. This has been addressed
|
||||
carefully implementing the library so that these
|
||||
structures are all initialized before
|
||||
<code style="white-space: normal">main(...)</code>
|
||||
is called. From then on they are never altered. So
|
||||
there SHOULD be no problem having mulitple archives
|
||||
open simultaneously - be it from the same or different
|
||||
threads.
|
||||
<p>
|
||||
Well, almost.
|
||||
<p>
|
||||
With dynamically loaded code - DLLS or Shared Libraries,
|
||||
these global data structures can be altered when a library
|
||||
is loaded or unloaded. That is, in this case, these
|
||||
globa data structures can be altered after
|
||||
<code style="white-space: normal">main(...)</code>
|
||||
is called. So if a thread is dynamically loading/unloading
|
||||
modules which contain serialization code while an
|
||||
archive is open there could be problems. Also, if
|
||||
such loading/unloading is happening concurrently
|
||||
in different threads, there could also be problems.
|
||||
<p>
|
||||
It might not be easy to control this. Is possible that
|
||||
some systems may not actually load modules until they
|
||||
are actually needed. So even though we think that
|
||||
there is not dynamic loading/unloading of such code
|
||||
it could be occurring as "help" to manage resources.
|
||||
On such systems, access to archive code would have
|
||||
to be syncronized with some multi-threading construct
|
||||
in order to be functional.
|
||||
|
||||
<h3><a name="optimizations">Optimizations</a></h3>
|
||||
In performance critical applications that serialize large sets of contiguous data of homogeneous
|
||||
|
||||
@@ -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<class T>
|
||||
template<class T>
|
||||
// T requirements:
|
||||
// - POD or object semantic (cannot be reference, function, ...)
|
||||
// - copy constructor
|
||||
@@ -43,20 +43,20 @@ private:
|
||||
... // implementation
|
||||
|
||||
public:
|
||||
state_saver(T & object);
|
||||
state_saver(T & object);
|
||||
~state_saver();
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
The complete implementation can be found
|
||||
<a target="state_saver" href="../../../boost/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 <boost/state_saver.hpp>
|
||||
|
||||
void func(A & a)
|
||||
void func(A & a)
|
||||
boost::state_saver<A> s(a);
|
||||
... // alter state of a by calling non-const functions
|
||||
... // call other functions
|
||||
|
||||
+3
-21
@@ -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>
|
||||
@@ -25,25 +25,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
The header <code><boost/serialization/static_warning.hpp></code> supplies a single macro
|
||||
<code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>, which generates a compile time warning message if
|
||||
the integral-constant-expression x is not true.
|
||||
<p>
|
||||
Note that if the condition is true, then the macro will generate neither
|
||||
code nor data - and the macro can also be used at either namespace,
|
||||
class or function scope. When used in a template, the expression x
|
||||
will be evaluated at the time the template is instantiated; this is
|
||||
particularly useful for validating template parameters.
|
||||
<p>
|
||||
It is intended that the functioning of <code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>
|
||||
be identical to that of <code style="white-space: normal">BOOST_STATIC_ASSERT(x)</code>
|
||||
except that rather than resulting in a compilation error, it will result in
|
||||
a compiler warning. In all other respects it should be the same. So
|
||||
for more information on using <code style="white-space: normal">BOOST_STATIC_WARNING(x)</code>
|
||||
consult the documentation for <code style="white-space: normal">BOOST_STATIC_ASSERT(x)</code>
|
||||
<a href="../../../doc/html/boost_staticassert.html">here</a>.
|
||||
|
||||
To do.
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -1,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 <boost/serialization/strong_typedef.hpp>
|
||||
#include <boost/strong_typedef.hpp>
|
||||
</a>
|
||||
|
||||
BOOST_STRONG_TYPEDEF(int, a)
|
||||
@@ -78,7 +78,7 @@ type but still of distinct type.
|
||||
|
||||
<h3>Implemenation</h3>
|
||||
<code style="white-space: normal">BOOST_STRONG_TYPEDEF</code> is a macro
|
||||
which generates a class named "name" 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.
|
||||
|
||||
|
||||
@@ -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
@@ -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>© 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>
|
||||
+53
-394
@@ -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
|
||||
@@ -92,21 +90,6 @@ so that instead of the above, we could write:
|
||||
BOOST_CLASS_VERSION(my_class, 2)
|
||||
</code></pre>
|
||||
which expands to the code above.
|
||||
<p>
|
||||
<code style="white-space: normal">BOOST_CLASS_VERSION</code> writes a full
|
||||
specialization, so it applies to a concrete class. To assign a version to a
|
||||
class <i>template</i> a partial specialization is needed instead, which
|
||||
<code style="white-space: normal">BOOST_CLASS_TEMPLATE_VERSION</code>
|
||||
provides. The template parameter list and the specialized type are each
|
||||
passed parenthesized, as they normally contain commas:
|
||||
<pre><code>
|
||||
BOOST_CLASS_TEMPLATE_VERSION((class T, class U), (my_class<T, U>), 2)
|
||||
</code></pre>
|
||||
This assigns version 2 to every instantiation of
|
||||
<code style="white-space: normal">my_class</code>. Non-type template
|
||||
parameters are written the same way, for example
|
||||
<code style="white-space: normal">(class T, std::size_t N)</code> paired with
|
||||
<code style="white-space: normal">(my_class<T, N>)</code>.
|
||||
|
||||
<h3><a name="level">Implementation Level</a></h3>
|
||||
In the same manner as the above, the "level" of implementation of serialization is
|
||||
@@ -196,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>
|
||||
@@ -211,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
|
||||
@@ -219,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.
|
||||
@@ -247,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
|
||||
@@ -348,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>
|
||||
@@ -389,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<class T>
|
||||
struct is_bitwise_serializable
|
||||
: public is_arithmetic<T>
|
||||
{};
|
||||
} }
|
||||
</code></pre>
|
||||
is used, and can be specialized for other classes. The specialization
|
||||
is made easy by the corresponding macro:
|
||||
<pre><code>
|
||||
BOOST_IS_BITWISE_SERIALIZABLE(my_class)
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="templates">Template Serialization Traits</a></h3>
|
||||
In some instances it might be convenient to assign serialization traits
|
||||
@@ -485,7 +429,7 @@ struct tracking_level<nvp<T> >
|
||||
#endif
|
||||
</code></pre>
|
||||
This can be problematic when one wants to make his code <strong>and archives</strong>
|
||||
portable to other platforms. It means the 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>
|
||||
@@ -527,291 +471,6 @@ and template parameters should be assigned according to the following table:
|
||||
<tr><td><code>IsWrapper</code></td><td><code></code>is the type a wrapper?</td><td><code>mpl::false_<br>mpl::true_</code></td><td><code>mpl::false_</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="compiletime_messages">Compile Time Warnings and Errors</a></h3>
|
||||
Some serialization traits can conflict with other ones. Sometimes these conflicts
|
||||
will result in erroneous behavior (E.G. creating of archives which could not be read)
|
||||
and other times they represent a probable misconception on the part of the
|
||||
library user which could result in surprising behavior. To the extent possible,
|
||||
these conflicts are detected at compile time and errors (BOOST_STATIC_ASSERT)
|
||||
or warnings (BOOST_STATIC_WARNING) are generated. They are generated in a
|
||||
compiler dependent manner which should show a chain of instantiation
|
||||
to the point where the error/warning is detected. Without this capability,
|
||||
it would be very hard to track down errors or unexpected behavior in library
|
||||
usage. Here is a list of the conflicts trapped:
|
||||
|
||||
<dl>
|
||||
<dt><h2><a name="object_level">object_level</a> - error</h2></dt>
|
||||
<dd>
|
||||
This error traps attempts to serialize types whose
|
||||
implementation level is set to non_serializable.
|
||||
</dd>
|
||||
<dt><h2><a name="object_versioning">object_versioning</a> - error</h2></dt>
|
||||
<dd>
|
||||
It's possible that for efficiency reasons, a type can be
|
||||
assigned a serialization level which doesn't include type information
|
||||
in the archive. This would preclude the assignment
|
||||
of a new version number to the type. This error
|
||||
traps attempts to assign a version number in this case.
|
||||
This has to be a user error.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="object_tracking">object_tracking</a> - warning</h2></dt>
|
||||
<dd>
|
||||
The following code will display a message when compiled:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
T t;
|
||||
ar << t;
|
||||
</pre></code>
|
||||
|
||||
unless the tracking_level serialization trait is set to "track_never". The following
|
||||
will compile without problem:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
const T t
|
||||
ar << t;
|
||||
</pre></code>
|
||||
|
||||
Likewise, the following code will trap at compile time:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
T * t;
|
||||
ar >> t;
|
||||
</pre></code>
|
||||
|
||||
if the tracking_level serialization trait is set to "track_never".
|
||||
<p>
|
||||
|
||||
The following case illustrates the function of this message.
|
||||
It was originally used as an example in the
|
||||
mailing list by Peter Dimov.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class construct_from
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
Suppose that the above message is not displayed and the code is used as is.
|
||||
<ol>
|
||||
<li>this example compiles and executes fine. No tracking is done because
|
||||
construct_from has never been serialized through a pointer. Now some time
|
||||
later, the next programmer(2) comes along and makes an enhancement. He
|
||||
wants the archive to be sort of a log.
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
void main(){
|
||||
...
|
||||
Y y;
|
||||
construct_from x(y);
|
||||
ar << x;
|
||||
...
|
||||
x.f(); // change x in some way
|
||||
...
|
||||
ar << x
|
||||
}
|
||||
</pre></code>
|
||||
<p>
|
||||
Again no problem. He gets two different of copies in the archive, each one is different.
|
||||
That is he gets exactly what he expects and is naturally delighted.
|
||||
<p>
|
||||
<li>Now sometime later, a third programmer(3) sees construct_from and says -
|
||||
oh cool, just what I need. He writes a function in a totally disjoint
|
||||
module. (The project is so big, he doesn't even realize the existence of
|
||||
the original usage) and writes something like:
|
||||
|
||||
<code style="white-space: normal"><pre>
|
||||
class K {
|
||||
shared_ptr <construct_from> z;
|
||||
template <class Archive>
|
||||
void serialize(Archive & ar, const unsigned version){
|
||||
ar << z;
|
||||
}
|
||||
};
|
||||
</pre></code>
|
||||
|
||||
<p>
|
||||
He builds and runs the program and tests his new functionality. It works
|
||||
great and he's delighted.
|
||||
<p>
|
||||
<li>Things continue smoothly as before. A month goes by and it's
|
||||
discovered that when loading the archives made in the last month (reading the
|
||||
log). Things don't work. The second log entry is always the same as the
|
||||
first. After a series of very long and increasingly acrimonious email exchanges,
|
||||
it's discovered
|
||||
that programmer(3) accidentally broke programmer(2)'s code .This is because by
|
||||
serializing via a pointer, the "log" object is now being tracked. This is because
|
||||
the default tracking behavior is "track_selectively". This means that class
|
||||
instances are tracked only if they are serialized through pointers anywhere in
|
||||
the program. Now multiple saves from the same address result in only the first one
|
||||
being written to the archive. Subsequent saves only add the address - even though the
|
||||
data might have been changed. When it comes time to load the data, all instances of the log record show the same data.
|
||||
In this way, the behavior of a functioning piece of code is changed due the side
|
||||
effect of a change in an otherwise disjoint module.
|
||||
Worse yet, the data has been lost and cannot be recovered from the archives.
|
||||
People are really upset and disappointed with boost (at least the serialization system).
|
||||
<p>
|
||||
<li>
|
||||
After a lot of investigation, it's discovered what the source of the problem is
|
||||
and class construct_from is marked "track_never" by including:
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
<li>Now everything works again. Or - so it seems.
|
||||
<p>
|
||||
<li><code style="white-space: normal">shared_ptr<construct_from></code>
|
||||
is not going to have a single raw pointer shared amongst the instances. Each loaded
|
||||
<code style="white-space: normal">shared_ptr<construct_from></code> is going to
|
||||
have its own distinct raw pointer. This will break
|
||||
<code style="white-space: normal">shared_ptr</code> and cause a memory leak. Again,
|
||||
The cause of this problem is very far removed from the point of discovery. It could
|
||||
well be that the problem is not even discovered until after the archives are loaded.
|
||||
Now we not only have a difficult to find and fix program bug, but we have a bunch of
|
||||
invalid archives and lost data.
|
||||
</ol>
|
||||
|
||||
<p>Now consider what happens when the message is displayed:
|
||||
|
||||
<ol>
|
||||
<p>
|
||||
<li>Right away, the program traps at
|
||||
<code style="white-space: normal"><pre>
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
<li>The programmer curses (another %^&*&* hoop to jump through). He's in a
|
||||
hurry (and who isn't) and would prefer not to <code style="white-space: normal">const_cast</code>
|
||||
- because it looks bad. So he'll just make the following change an move on.
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
ar << x;
|
||||
</pre></code>
|
||||
<p>
|
||||
Things work fine and he moves on.
|
||||
<p>
|
||||
<li>Now programmer (2) wants to make his change - and again another
|
||||
annoying const issue;
|
||||
<code style="white-space: normal"><pre>
|
||||
Y y;
|
||||
const construct_from x(y);
|
||||
...
|
||||
x.f(); // change x in some way ; compile error f() is not const
|
||||
...
|
||||
ar << x
|
||||
</pre></code>
|
||||
<p>
|
||||
He's mildly annoyed now he tries the following:
|
||||
<ul>
|
||||
<li>He considers making f() a const - but presumably that shifts the const
|
||||
error to somewhere else. And he doesn't want to fiddle with "his" code to
|
||||
work around a quirk in the serializaition system
|
||||
<p>
|
||||
<li>He removes the <code style="white-space: normal">const</code>
|
||||
from <code style="white-space: normal">const construct_from</code> above - damn now he
|
||||
gets the trap. If he looks at the comment code where the
|
||||
<code style="white-space: normal">BOOST_STATIC_ASSERT</code>
|
||||
occurs, he'll do one of two things
|
||||
<ol>
|
||||
<p>
|
||||
<li>This is just crazy. Its making my life needlessly difficult and flagging
|
||||
code that is just fine. So I'll fix this with a <code style="white-space: normal">const_cast</code>
|
||||
and fire off a complaint to the list and maybe they will fix it.
|
||||
In this case, the story branches off to the previous scenario.
|
||||
<p>
|
||||
<li>Oh, this trap is suggesting that the default serialization isn't really
|
||||
what I want. Of course in this particular program it doesn't matter. But
|
||||
then the code in the trap can't really evaluate code in other modules (which
|
||||
might not even be written yet). OK, I'll add the following to my
|
||||
construct_from.hpp to solve the problem.
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
</ol>
|
||||
</ul>
|
||||
<p>
|
||||
<li>Now programmer (3) comes along and make his change. The behavior of the
|
||||
original (and distant module) remains unchanged because the
|
||||
<code style="white-space: normal">construct_from</code> trait has been set to
|
||||
"track_never" so he should always get copies and the log should be what we expect.
|
||||
<p>
|
||||
<li>But now he gets another trap - trying to save an object of a
|
||||
class marked "track_never" through a pointer. So he goes back to
|
||||
construct_from.hpp and comments out the
|
||||
<code style="white-space: normal">BOOST_CLASS_TRACKING</code> that
|
||||
was inserted. Now the second trap is avoided, But damn - the first trap is
|
||||
popping up again. Eventually, after some code restructuring, the differing
|
||||
requirements of serializating <code style="white-space: normal">construct_from</code>
|
||||
are reconciled.
|
||||
</ol>
|
||||
Note that in this second scenario
|
||||
<ul>
|
||||
<li>all errors are trapped at compile time.
|
||||
<li>no invalid archives are created.
|
||||
<li>no data is lost.
|
||||
<li>no runtime errors occur.
|
||||
</ul>
|
||||
|
||||
It's true that these messages may sometimes flag code that is currently correct and
|
||||
that this may be annoying to some programmers. However, this example illustrates
|
||||
my view that these messages are useful and that any such annoyance is a small price to
|
||||
pay to avoid particularly vexing programming errors.
|
||||
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="pointer_level">pointer_level</a> - warning</h2></dt>
|
||||
<dd>
|
||||
This trap addresses the following situation when serializing
|
||||
a pointer:
|
||||
<ul>
|
||||
<li>A type doesn't save class information in the
|
||||
archive. That is, the serialization trait implementation
|
||||
level <= object_serializable.
|
||||
<li>Tracking for this type is set to "track selectively"
|
||||
in this case, indication that an object is tracked is
|
||||
not stored in the archive itself - see level == object_serializable.
|
||||
Since class information is not saved in the archive, the existence
|
||||
or absence of the operation <code style="white-space: normal">ar << T *</code> anywhere else in the
|
||||
program is used to infer that an object of this type should be tracked.
|
||||
<p>
|
||||
A problem arises when a program which reads an archive
|
||||
includes the operation <code style="white-space: normal">ar >> T *</code> so that tracking information
|
||||
will be included in the archive. When a program which
|
||||
creates the archive doesn't include <code style="white-space: normal">ar << T</code> it is presumed
|
||||
that the archive doesn't include tracking information and
|
||||
the archive will fail to load. Also the reverse situation could
|
||||
trigger a similar problem.
|
||||
<p>
|
||||
Though this situation is unlikely for several reasons,
|
||||
it is possible - hence this warning.
|
||||
</ul>
|
||||
So if your program traps here, consider changing the
|
||||
tracking or implementation level traits - or not
|
||||
serializing via a pointer.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="pointer_tracking">pointer_tracking</a> - warning</h2></dt>
|
||||
<dd>
|
||||
Serializing an object of a type marked "track_never" through a pointer
|
||||
could result in creating more objects than were saved! There are cases
|
||||
in which a user might really want to do this so we leave it as a warning.
|
||||
</dd>
|
||||
|
||||
<dt><h2><a name="const_loading">const_loading</a> - error</h2></dt>
|
||||
<dd>
|
||||
One cannot load data into a "const" object unless it's a
|
||||
wrapper around some other non-const object.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004 and Matthias Troyer 2006.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
+10
-10
@@ -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 >> 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 & ar, const unsigned int version)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 10; ++i)
|
||||
for(i = 0; i < 10; ++i)
|
||||
ar & stops[i];
|
||||
}
|
||||
public:
|
||||
@@ -327,7 +327,7 @@ clas pointer may require explicit enumeration of the derived
|
||||
classes to be serialized. This is referred to as "registration" or "export"
|
||||
of derived classes. This requirement and the methods of
|
||||
satisfying it are explained in detail
|
||||
<a href="serialization.html#derivedpointers">here</a>.
|
||||
<a href="serialization.html#derivedpointers">here</a>
|
||||
<p>
|
||||
All this is accomplished automatically by the serialization
|
||||
library. The above code is all that is necessary to accomplish
|
||||
@@ -541,7 +541,7 @@ This is described later in the manual.
|
||||
<dd>This is a variation the original demo which supports xml archives in addition
|
||||
to the others. The extra wrapping macro, BOOST_SERIALIZATION_NVP(name), is
|
||||
needed to associate a data item name with the corresponding xml
|
||||
tag. It is 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>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
|
||||
+11
-11
@@ -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<T>(U * u)</code>
|
||||
for casting a pointer at runtime between two related types. However, this can only be
|
||||
used for polymorphic classes. That is, it can only be used with related classes which have at least one virtual function.
|
||||
Limiting the 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<class Derived, class Base>
|
||||
const void_cast_detail::void_caster &
|
||||
const void_cast_detail::void_caster &
|
||||
void_cast_register(
|
||||
Derived const * derived = NULL,
|
||||
Base * const base = NULL
|
||||
);
|
||||
const Derived * derived = NULL,
|
||||
const Base * base = NULL
|
||||
)
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This function "registers" a pair of related types. It stores the fact that
|
||||
@@ -67,8 +67,8 @@ This function "registers" a pair of related types. It stores the fact that
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_upcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
@@ -76,8 +76,8 @@ void_upcast(
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_downcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
|
||||
+16
-16
@@ -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<T></code> or a <code>std::vector<T></code>.
|
||||
C-array, a <code>boost::array<T></code> or a <code>std::vector<T></code>.
|
||||
The purpose of this wrapper is to support archive types (such as binary
|
||||
archives) that provide optimized serialization for contiguous sequences of
|
||||
objects of the same type.
|
||||
@@ -75,12 +75,12 @@ array.hpp
|
||||
</a>
|
||||
includes the function
|
||||
<pre><code>
|
||||
template <T>
|
||||
template <T>
|
||||
boost::serialization::make_array(T* t, std::size_t size);
|
||||
</code></pre>
|
||||
which will construct a temporary <code>array</code> object
|
||||
<pre><code>
|
||||
template<class T>
|
||||
template<class T>
|
||||
class array
|
||||
{
|
||||
public:
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
};
|
||||
</code></pre>
|
||||
that can be serialized just like any other object.
|
||||
Its default serialization is to 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<class T>
|
||||
xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
{
|
||||
// write an xml start tag
|
||||
start_tag(t.name());
|
||||
|
||||
// serialize the data as usual
|
||||
*this & t.value();
|
||||
*this & t.value();
|
||||
|
||||
// write an xml end tag
|
||||
end_tag(t.name());
|
||||
}
|
||||
</code></pre>
|
||||
The most obvious and 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 & make_nvp("my_variable", my_variable);
|
||||
ar & make_nvp("my_variable", my_variable);
|
||||
</code></pre>
|
||||
To simplify typing and enhance readability a macro is defined so we can write:
|
||||
<pre><code>
|
||||
ar & BOOST_SERIALIZATION_NVP(my_variable);
|
||||
ar & BOOST_SERIALIZATION_NVP(my_variable);
|
||||
</code></pre>
|
||||
Similarly there exists a macro definition that permits us to write:
|
||||
<pre><code>
|
||||
@@ -200,7 +200,7 @@ is example of the XML Archive corresponding to our tutorial example.
|
||||
Wrappers should be designed so that they can be composed as necessary.
|
||||
For example, to pass binary data as a name value pair use:
|
||||
<pre><code>
|
||||
ar & make_nvp("named_binary_object", make_binary_object(address, size));
|
||||
ar & make_nvp("named_binary_object", make_binary_object(address, size));
|
||||
</code></pre>
|
||||
</html>
|
||||
<hr>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Boost serialization Library Build Jamfile
|
||||
# (C) Copyright Robert Ramey 2002-2004.
|
||||
# Use, modification, and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/serialization for the library home page.
|
||||
|
||||
subproject libs/serialization/example ;
|
||||
|
||||
rule demo-bsl-build ( demo-name )
|
||||
{
|
||||
exe $(demo-name)
|
||||
: # sources
|
||||
$(demo-name).cpp
|
||||
<lib>../build/boost_serialization
|
||||
: # requirements
|
||||
# copy to a path rooted at BOOST_ROOT:
|
||||
<locate>$(BOOST_ROOT)
|
||||
<include>$(BOOST_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>-w-8080
|
||||
<msvc><release><cxxflags>-Gy
|
||||
<vc7><release><cxxflags>-Gy
|
||||
<vc-7_0><release><cxxflags>-Gy
|
||||
<vc-7_1><release><cxxflags>-Gy
|
||||
: # default build
|
||||
debug
|
||||
;
|
||||
}
|
||||
|
||||
demo-bsl-build demo ;
|
||||
demo-bsl-build demo_auto_ptr ;
|
||||
demo-bsl-build demo_exception ;
|
||||
demo-bsl-build demo_fast_archive ;
|
||||
demo-bsl-build demo_pimpl ;
|
||||
demo-bsl-build demo_portable_archive ;
|
||||
demo-bsl-build demo_shared_ptr ;
|
||||
demo-bsl-build demo_xml ;
|
||||
demo-bsl-build demo_xml_save ;
|
||||
demo-bsl-build demo_xml_load ;
|
||||
@@ -1,47 +0,0 @@
|
||||
# Boost serialization Library Build Jamfile
|
||||
# (C) Copyright Robert Ramey 2002-2004.
|
||||
# Use, modification, and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/serialization for the library home page.
|
||||
|
||||
project libs/serialization/example
|
||||
: id serialization_example
|
||||
: 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 ;
|
||||
|
||||
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 ]
|
||||
;
|
||||
|
||||
+24
-25
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,17 +3,14 @@
|
||||
// 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>
|
||||
|
||||
#define BOOST_ARCHIVE_SOURCE
|
||||
#include "portable_binary_oarchive.hpp"
|
||||
#include "portable_binary_iarchive.hpp"
|
||||
|
||||
@@ -23,38 +20,30 @@
|
||||
namespace std{ using ::rand; }
|
||||
#endif
|
||||
|
||||
// the following is required to be sure the "EXPORT" works if it is used
|
||||
#define CUSTOM_ARCHIVE_TYPES portable_binary_oarchive,portable_binary_iarchive
|
||||
|
||||
class A
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
char c;
|
||||
A *pa;
|
||||
int i;
|
||||
int i2; // special tricky case to check sign extension
|
||||
unsigned int ui;
|
||||
long l;
|
||||
unsigned long ul;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* version */){
|
||||
ar & c & i & i2 & ui & l & ul ;
|
||||
ar & i & ui & l & ul ;
|
||||
}
|
||||
public:
|
||||
bool operator==(const A & rhs) const {
|
||||
return
|
||||
c == rhs.c
|
||||
&& i == rhs.i
|
||||
&& i2 == rhs.i2
|
||||
&& ui == rhs.ui
|
||||
&& l == rhs.l
|
||||
&& ul == rhs.ul
|
||||
i == rhs.i && ui == rhs.ui && l == rhs.l && ul == rhs.ul
|
||||
;
|
||||
}
|
||||
A() :
|
||||
c(0xFF & std::rand()),
|
||||
pa(0),
|
||||
i(std::rand()),
|
||||
i2(0x80),
|
||||
ui(std::rand()),
|
||||
l(std::rand() * std::rand()),
|
||||
l(std::rand()),
|
||||
ul(std::rand())
|
||||
{}
|
||||
};
|
||||
@@ -65,7 +54,7 @@ int main( int /* argc */, char* /* argv */[] )
|
||||
A a1;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
{
|
||||
portable_binary_oarchive pboa(ss);
|
||||
pboa << a;
|
||||
}
|
||||
@@ -73,31 +62,6 @@ int main( int /* argc */, char* /* argv */[] )
|
||||
portable_binary_iarchive pbia(ss);
|
||||
pbia >> a1;
|
||||
}
|
||||
if(! (a == a1))
|
||||
return 1;
|
||||
|
||||
ss.clear();
|
||||
{
|
||||
portable_binary_oarchive pboa(ss, endian_big);
|
||||
pboa << a;
|
||||
}
|
||||
{
|
||||
portable_binary_iarchive pbia(ss, endian_big);
|
||||
pbia >> a1;
|
||||
}
|
||||
if(! (a == a1))
|
||||
return 1;
|
||||
|
||||
ss.clear();
|
||||
{
|
||||
portable_binary_oarchive pboa(ss, endian_big);
|
||||
pboa << a;
|
||||
}
|
||||
{
|
||||
portable_binary_iarchive pbia(ss, endian_big);
|
||||
pbia >> a1;
|
||||
}
|
||||
|
||||
return !(a == a1);
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_xml.hpp
|
||||
//
|
||||
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
// 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 <string>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
// This illustration models the bus system of a small city.
|
||||
// This includes, multiple bus stops, bus routes and schedules.
|
||||
// There are different kinds of stops. Bus stops in general
|
||||
// will appear on multiple routes. A schedule will include
|
||||
// multiple trips on the same route.
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// gps coordinate
|
||||
//
|
||||
// illustrates serialization for a simple type
|
||||
//
|
||||
class gps_position
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
|
||||
|
||||
int degrees;
|
||||
int minutes;
|
||||
float seconds;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
ar & BOOST_SERIALIZATION_NVP(degrees)
|
||||
& BOOST_SERIALIZATION_NVP(minutes)
|
||||
& BOOST_SERIALIZATION_NVP(seconds);
|
||||
}
|
||||
|
||||
public:
|
||||
// every serializable class needs a constructor
|
||||
gps_position(){};
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
degrees(_d), minutes(_m), seconds(_s)
|
||||
{}
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
|
||||
{
|
||||
return os << ' ' << gp.degrees << (unsigned char)176 << gp.minutes << '\'' << gp.seconds << '"';
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// One bus stop
|
||||
//
|
||||
// illustrates serialization of serializable members
|
||||
//
|
||||
|
||||
class bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
virtual std::string description() const = 0;
|
||||
gps_position latitude;
|
||||
gps_position longitude;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(latitude);
|
||||
ar & BOOST_SERIALIZATION_NVP(longitude);
|
||||
}
|
||||
|
||||
protected:
|
||||
bus_stop(const gps_position & _lat, const gps_position & _long) :
|
||||
latitude(_lat), longitude(_long)
|
||||
{}
|
||||
public:
|
||||
bus_stop(){}
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
|
||||
virtual ~bus_stop(){}
|
||||
};
|
||||
|
||||
BOOST_IS_ABSTRACT(bus_stop)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
|
||||
{
|
||||
return os << bs.latitude << bs.longitude << ' ' << bs.description();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Several kinds of bus stops
|
||||
//
|
||||
// illustrates serialization of derived types
|
||||
//
|
||||
class bus_stop_corner : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string street1;
|
||||
std::string street2;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return street1 + " and " + street2;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
// save/load base class information
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
|
||||
ar & BOOST_SERIALIZATION_NVP(street1);
|
||||
ar & BOOST_SERIALIZATION_NVP(street2);
|
||||
}
|
||||
public:
|
||||
bus_stop_corner(){}
|
||||
bus_stop_corner(const gps_position & _lat, const gps_position & _long,
|
||||
const std::string & _s1, const std::string & _s2
|
||||
) :
|
||||
bus_stop(_lat, _long), street1(_s1), street2(_s2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class bus_stop_destination : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string name;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
|
||||
& BOOST_SERIALIZATION_NVP(name);
|
||||
}
|
||||
public:
|
||||
bus_stop_destination(){}
|
||||
bus_stop_destination(
|
||||
const gps_position & _lat, const gps_position & _long, const std::string & _name
|
||||
) :
|
||||
bus_stop(_lat, _long), name(_name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// a bus route is a collection of bus stops
|
||||
//
|
||||
// illustrates serialization of STL collection templates.
|
||||
//
|
||||
// illustrates serialization of polymorphic pointer (bus stop *);
|
||||
//
|
||||
// illustrates storage and recovery of shared pointers is correct
|
||||
// and efficient. That is objects pointed to by more than one
|
||||
// pointer are stored only once. In such cases only one such
|
||||
// object is restored and pointers are restored to point to it
|
||||
//
|
||||
class bus_route
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
|
||||
typedef bus_stop * bus_stop_pointer;
|
||||
std::list<bus_stop_pointer> stops;
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
// in this program, these classes are never serialized directly but rather
|
||||
// through a pointer to the base class bus_stop. So we need a way to be
|
||||
// sure that the archive contains information about these derived classes.
|
||||
//ar.template register_type<bus_stop_corner>();
|
||||
ar.register_type(static_cast<bus_stop_corner *>(NULL));
|
||||
//ar.template register_type<bus_stop_destination>();
|
||||
ar.register_type(static_cast<bus_stop_destination *>(NULL));
|
||||
// serialization of stl collections is already defined
|
||||
// in the header
|
||||
ar & BOOST_SERIALIZATION_NVP(stops);
|
||||
}
|
||||
public:
|
||||
bus_route(){}
|
||||
void append(bus_stop *_bs)
|
||||
{
|
||||
stops.insert(stops.end(), _bs);
|
||||
}
|
||||
};
|
||||
std::ostream & operator<<(std::ostream &os, const bus_route &br)
|
||||
{
|
||||
std::list<bus_stop *>::const_iterator it;
|
||||
// note: we're displaying the pointer to permit verification
|
||||
// that duplicated pointers are properly restored.
|
||||
for(it = br.stops.begin(); it != br.stops.end(); it++){
|
||||
os << '\n' << "0x" << std::hex << reinterpret_cast<boost::uintptr_t>(*it) << std::dec << ' ' << **it;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// a bus schedule is a collection of routes each with a starting time
|
||||
//
|
||||
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
|
||||
// See definition of operator<< <pair<F, S> >(ar, pair)
|
||||
//
|
||||
// illustrates nesting of serializable classes
|
||||
//
|
||||
// illustrates use of version number to automatically grandfather older
|
||||
// versions of the same class.
|
||||
|
||||
class bus_schedule
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(schedule);
|
||||
}
|
||||
// note: this structure was made public. because the friend declarations
|
||||
// didn't seem to work as expected.
|
||||
public:
|
||||
struct trip_info
|
||||
{
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int file_version)
|
||||
{
|
||||
// in versions 2 or later
|
||||
if(file_version >= 2)
|
||||
// read the drivers name
|
||||
ar & BOOST_SERIALIZATION_NVP(driver);
|
||||
// all versions have the following info
|
||||
ar & BOOST_SERIALIZATION_NVP(hour)
|
||||
& BOOST_SERIALIZATION_NVP(minute);
|
||||
}
|
||||
|
||||
// starting time
|
||||
int hour;
|
||||
int minute;
|
||||
// only after system shipped was the driver's name added to the class
|
||||
std::string driver;
|
||||
|
||||
trip_info(){}
|
||||
trip_info(int _h, int _m, const std::string &_d) :
|
||||
hour(_h), minute(_m), driver(_d)
|
||||
{}
|
||||
~trip_info(){
|
||||
}
|
||||
};
|
||||
// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
|
||||
private:
|
||||
std::list<std::pair<trip_info, bus_route *> > schedule;
|
||||
public:
|
||||
void append(const std::string &_d, int _h, int _m, bus_route *_br)
|
||||
{
|
||||
schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
|
||||
}
|
||||
bus_schedule(){}
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
|
||||
BOOST_CLASS_VERSION(bus_schedule, 2)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
|
||||
{
|
||||
return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
|
||||
}
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
|
||||
{
|
||||
std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
|
||||
for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
|
||||
os << it->first << *(it->second);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,46 +0,0 @@
|
||||
#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)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <climits>
|
||||
#if CHAR_BIT != 8
|
||||
#error This code assumes an eight-bit byte.
|
||||
#endif
|
||||
|
||||
#include <boost/archive/basic_archive.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
|
||||
enum portable_binary_archive_flags {
|
||||
endian_big = 0x4000,
|
||||
endian_little = 0x8000
|
||||
};
|
||||
|
||||
//#if ( endian_big <= boost::archive::flags_last )
|
||||
//#error archive flags conflict
|
||||
//#endif
|
||||
|
||||
inline void
|
||||
reverse_bytes(char size, char *address){
|
||||
char * first = address;
|
||||
char * last = first + size - 1;
|
||||
for(;first < last;++first, --last){
|
||||
char x = *last;
|
||||
*last = *first;
|
||||
*first = x;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PORTABLE_BINARY_ARCHIVE_HPP
|
||||
@@ -1,131 +0,0 @@
|
||||
/////////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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <istream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/serialization/throw_exception.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
|
||||
#include "portable_binary_iarchive.hpp"
|
||||
|
||||
void
|
||||
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
|
||||
char size;
|
||||
l = 0;
|
||||
this->primitive_base_t::load(size);
|
||||
|
||||
if(0 == size){
|
||||
return;
|
||||
}
|
||||
|
||||
bool negative = (size < 0);
|
||||
if(negative)
|
||||
size = -size;
|
||||
|
||||
if(size > maxsize)
|
||||
boost::serialization::throw_exception(
|
||||
portable_binary_iarchive_exception()
|
||||
);
|
||||
|
||||
char * cptr = reinterpret_cast<char *>(& l);
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
cptr += (sizeof(boost::intmax_t) - size);
|
||||
#endif
|
||||
this->primitive_base_t::load_binary(cptr, size);
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
if(m_flags & endian_little)
|
||||
#else
|
||||
if(m_flags & endian_big)
|
||||
#endif
|
||||
reverse_bytes(size, cptr);
|
||||
|
||||
if(negative)
|
||||
l = -l;
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_iarchive::load_override(
|
||||
boost::archive::class_name_type & t
|
||||
){
|
||||
std::string cn;
|
||||
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
|
||||
load_override(cn);
|
||||
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::invalid_class_name)
|
||||
);
|
||||
std::memcpy(t, cn.data(), cn.size());
|
||||
// borland tweak
|
||||
t.t[cn.size()] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_iarchive::init(unsigned int flags){
|
||||
if(0 == (flags & boost::archive::no_header)){
|
||||
// read signature in an archive version independent manner
|
||||
std::string file_signature;
|
||||
* this >> file_signature;
|
||||
if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::invalid_signature
|
||||
)
|
||||
);
|
||||
// make sure the version of the reading archive library can
|
||||
// support the format of the archive being read
|
||||
boost::archive::library_version_type input_library_version;
|
||||
* this >> input_library_version;
|
||||
|
||||
// extra little .t is to get around borland quirk
|
||||
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
|
||||
boost::serialization::throw_exception(
|
||||
boost::archive::archive_exception(
|
||||
boost::archive::archive_exception::unsupported_version
|
||||
)
|
||||
);
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
|
||||
this->set_library_version(input_library_version);
|
||||
//#else
|
||||
//#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
//detail::
|
||||
//#endif
|
||||
boost::archive::detail::basic_iarchive::set_library_version(
|
||||
input_library_version
|
||||
);
|
||||
#endif
|
||||
}
|
||||
unsigned char x;
|
||||
load(x);
|
||||
m_flags = x << CHAR_BIT;
|
||||
}
|
||||
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
namespace detail {
|
||||
template class archive_serializer_map<portable_binary_iarchive>;
|
||||
}
|
||||
|
||||
template class basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
@@ -2,203 +2,172 @@
|
||||
#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
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4244 )
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// portable_binary_iarchive.hpp
|
||||
|
||||
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
|
||||
// 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 <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/item_version_type.hpp>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/archive/basic_binary_iprimitive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
#include "portable_binary_archive.hpp"
|
||||
#include <ostream>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// exception to be thrown if integer read from archive doesn't fit
|
||||
// variable being loaded
|
||||
class portable_binary_iarchive_exception :
|
||||
public boost::archive::archive_exception
|
||||
class portable_binary_archive_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_archive_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
|
||||
// that binary archives can be passed across systems. Note:floating point types
|
||||
// not addressed here
|
||||
// "Portable" input binary archive. This is a variation of the native binary
|
||||
// archive. it addresses integer size and endienness so that binary archives can
|
||||
// be passed across systems. Note:floating point types not addressed here
|
||||
class portable_binary_iarchive :
|
||||
public boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
// don't derive from binary_iarchive !!!
|
||||
public boost::archive::binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>,
|
||||
public boost::archive::detail::common_iarchive<
|
||||
portable_binary_iarchive
|
||||
>
|
||||
{
|
||||
typedef boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
public boost::archive::detail::shared_ptr_helper
|
||||
{
|
||||
typedef boost::archive::binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> primitive_base_t;
|
||||
typedef boost::archive::detail::common_iarchive<
|
||||
portable_binary_iarchive
|
||||
> archive_base_t;
|
||||
typedef boost::archive::basic_binary_iprimitive<
|
||||
portable_binary_iarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> primitive_base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend archive_base_t;
|
||||
friend primitive_base_t; // since with override load below
|
||||
friend class boost::archive::detail::interface_iarchive<
|
||||
portable_binary_iarchive
|
||||
>;
|
||||
friend class boost::archive::basic_binary_iarchive<portable_binary_iarchive>;
|
||||
friend class boost::archive::load_access;
|
||||
protected:
|
||||
#endif
|
||||
unsigned int m_flags;
|
||||
void load_impl(boost::intmax_t & l, char maxsize);
|
||||
void load_impl(long & l, char maxsize){
|
||||
char size;
|
||||
this->archive_base_t::load(size);
|
||||
if(size > maxsize)
|
||||
throw portable_binary_archive_exception() ;
|
||||
l = 0;
|
||||
load_binary(& l, size);
|
||||
// we choose to use litle endian
|
||||
#ifdef BOOST_BIG_ENDIAN
|
||||
char * first = static_cast<char *>(static_cast<void *>(& l));
|
||||
char * last = first + sizeof(l) - 1;
|
||||
for(;first < last;++first, --last){
|
||||
char x = *last;
|
||||
*last = *first;
|
||||
*first = x;
|
||||
}
|
||||
#endif
|
||||
|
||||
// extend sign if necessary
|
||||
if((l >> (size - 1) * 8) & 0x80){
|
||||
l |= (-1 << (size * 8));
|
||||
}
|
||||
}
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void load(T & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(T));
|
||||
// use cast to avoid compile time warning
|
||||
//t = static_cast< T >(l);
|
||||
t = T(l);
|
||||
}
|
||||
void load(boost::serialization::item_version_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::serialization::item_version_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::serialization::item_version_type(l);
|
||||
}
|
||||
void load(boost::archive::version_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::archive::version_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::archive::version_type(l);
|
||||
}
|
||||
void load(boost::archive::class_id_type & t){
|
||||
boost::intmax_t l;
|
||||
load_impl(l, sizeof(boost::archive::class_id_type));
|
||||
// use cast to avoid compile time warning
|
||||
t = boost::archive::class_id_type(static_cast<int>(l));
|
||||
}
|
||||
void load(std::string & t){
|
||||
this->primitive_base_t::load(t);
|
||||
}
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
void load(std::wstring & t){
|
||||
this->primitive_base_t::load(t);
|
||||
void load(unsigned short & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned short));
|
||||
t = l;
|
||||
}
|
||||
#endif
|
||||
void load(float & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// floats not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
void load(short & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(short));
|
||||
t = l;
|
||||
}
|
||||
void load(double & t){
|
||||
this->primitive_base_t::load(t);
|
||||
// doubles not supported
|
||||
//BOOST_STATIC_ASSERT(false);
|
||||
void load(unsigned int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned int));
|
||||
t = l;
|
||||
}
|
||||
void load(char & t){
|
||||
this->primitive_base_t::load(t);
|
||||
void load(int & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(int));
|
||||
t = l;
|
||||
}
|
||||
void load(unsigned char & t){
|
||||
this->primitive_base_t::load(t);
|
||||
void load(unsigned long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(unsigned long));
|
||||
t = l;
|
||||
}
|
||||
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(long & t){
|
||||
long l;
|
||||
load_impl(l, sizeof(long));
|
||||
t = l;
|
||||
}
|
||||
void load_override(boost::archive::class_name_type & t);
|
||||
// binary files don't include the optional information
|
||||
void load_override(boost::archive::class_id_optional_type &){}
|
||||
|
||||
void init(unsigned int flags);
|
||||
public:
|
||||
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
|
||||
primitive_base_t(
|
||||
* is.rdbuf(),
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(0)
|
||||
archive_base_t(
|
||||
is,
|
||||
flags | boost::archive::no_header // skip default header checking
|
||||
)
|
||||
{
|
||||
init(flags);
|
||||
}
|
||||
|
||||
portable_binary_iarchive(
|
||||
std::basic_streambuf<
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> & bsb,
|
||||
unsigned int flags
|
||||
) :
|
||||
primitive_base_t(
|
||||
bsb,
|
||||
0 != (flags & boost::archive::no_codecvt)
|
||||
),
|
||||
archive_base_t(flags),
|
||||
m_flags(0)
|
||||
{
|
||||
init(flags);
|
||||
// use our own header checking
|
||||
if(0 != (flags & boost::archive::no_header)){
|
||||
this->archive_base_t::init(flags);
|
||||
// skip the following for "portable" binary archives
|
||||
// boost::archive::basic_binary_oprimitive<derived_t, std::ostream>::init();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// required by export in boost version > 1.34
|
||||
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
|
||||
#endif
|
||||
// explicitly instantiate for this type of text stream
|
||||
#include <boost/archive/impl/basic_binary_iarchive.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
template class binary_iarchive_impl<
|
||||
portable_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>;
|
||||
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
// required by export in boost <= 1.34
|
||||
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif // PORTABLE_BINARY_IARCHIVE_HPP
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/////////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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <ostream>
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include "portable_binary_oarchive.hpp"
|
||||
|
||||
void
|
||||
portable_binary_oarchive::save_impl(
|
||||
const boost::intmax_t l,
|
||||
const char maxsize
|
||||
){
|
||||
char size = 0;
|
||||
|
||||
if(l == 0){
|
||||
this->primitive_base_t::save(size);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::intmax_t ll;
|
||||
bool negative = (l < 0);
|
||||
if(negative)
|
||||
ll = -l;
|
||||
else
|
||||
ll = l;
|
||||
|
||||
do{
|
||||
ll >>= CHAR_BIT;
|
||||
++size;
|
||||
}while(ll != 0);
|
||||
|
||||
this->primitive_base_t::save(
|
||||
static_cast<char>(negative ? -size : size)
|
||||
);
|
||||
|
||||
if(negative)
|
||||
ll = -l;
|
||||
else
|
||||
ll = l;
|
||||
char * cptr = reinterpret_cast<char *>(& ll);
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
cptr += (sizeof(boost::intmax_t) - size);
|
||||
if(m_flags & endian_little)
|
||||
reverse_bytes(size, cptr);
|
||||
#else
|
||||
if(m_flags & endian_big)
|
||||
reverse_bytes(size, cptr);
|
||||
#endif
|
||||
this->primitive_base_t::save_binary(cptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
portable_binary_oarchive::init(unsigned int flags) {
|
||||
if(m_flags == (endian_big | endian_little)){
|
||||
boost::serialization::throw_exception(
|
||||
portable_binary_oarchive_exception()
|
||||
);
|
||||
}
|
||||
if(0 == (flags & boost::archive::no_header)){
|
||||
// write signature in an archive version independent manner
|
||||
const std::string file_signature(
|
||||
boost::archive::BOOST_ARCHIVE_SIGNATURE()
|
||||
);
|
||||
* this << file_signature;
|
||||
// write library version
|
||||
const boost::archive::library_version_type v(
|
||||
boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
);
|
||||
* this << v;
|
||||
}
|
||||
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
|
||||
}
|
||||
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
namespace detail {
|
||||
template class archive_serializer_map<portable_binary_oarchive>;
|
||||
}
|
||||
|
||||
template class basic_binary_oprimitive<
|
||||
portable_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> ;
|
||||
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user