Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f79d98377 | |||
| c0dc251074 | |||
| 628a0c5617 | |||
| c78a93fb4f | |||
| 01ebdab663 | |||
| c9b3b6f1b8 | |||
| e77824a75e | |||
| 07ffdca96c | |||
| e1a3663b78 | |||
| 4bd765004d | |||
| 4e0e3fa25f | |||
| c75affd38c | |||
| 64d8aca650 | |||
| 1582fe4f4f | |||
| 64fb92e164 | |||
| f9bcd5c6bd | |||
| b6dae88a3d | |||
| 085c44275b |
@@ -1,72 +0,0 @@
|
||||
# Copyright 2016 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
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b $TRAVIS_BRANCH --depth 1 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/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/filesystem
|
||||
- git submodule init libs/function
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/intrusive
|
||||
- git submodule init libs/io
|
||||
- git submodule init libs/iterator
|
||||
- git submodule init libs/lexical_cast
|
||||
- git submodule init libs/math
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/mpl
|
||||
- git submodule init libs/numeric/conversion
|
||||
- git submodule init libs/optional
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/range
|
||||
- git submodule init libs/smart_ptr
|
||||
- git submodule init libs/spirit
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/system
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/tuple
|
||||
- git submodule init libs/type_index
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init libs/unordered
|
||||
- git submodule init libs/utility
|
||||
- git submodule init libs/variant
|
||||
- git submodule init tools/build
|
||||
- git submodule update --depth 1
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/serialization
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- TOOLSET=gcc,clang
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi
|
||||
- ./b2 libs/serialization/test toolset=$TOOLSET
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
@@ -1,434 +0,0 @@
|
||||
# CMake build control file for Serialization Library tests
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy (SET CMP0054 NEW)
|
||||
endif (POLICY CMP0054)
|
||||
|
||||
if (POLICY CMP0063)
|
||||
cmake_policy (SET CMP0063 NEW)
|
||||
endif (POLICY CMP0063)
|
||||
|
||||
if(Boost_USE_STATIC_LIBS)
|
||||
project("Serialization-Static")
|
||||
else()
|
||||
project("Serialization-Shared")
|
||||
endif()
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
message(STATUS "compiler is ${CMAKE_CXX_COMPILER_ID}" )
|
||||
add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
|
||||
|
||||
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
|
||||
add_definitions( -ftemplate-depth=300 )
|
||||
# we use gcc to test for C++03 compatibility
|
||||
add_definitions( -std=c++03 )
|
||||
message(STATUS "compiler is g++ c++03")
|
||||
set(COMPILER_SUPPORTS_CXX11 FALSE)
|
||||
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
|
||||
add_definitions( /wd4996 )
|
||||
message(STATUS "compiler is MSVC")
|
||||
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 "${CMAKE_CXX_FLAGS} -std=c++98")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
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()
|
||||
|
||||
#
|
||||
# IDE settings
|
||||
#
|
||||
|
||||
if( CMAKE_HOST_APPLE )
|
||||
# note: it seems that bjam builds both address models in any case
|
||||
# so we can defer this decision to the IDE just as we do for debug/release
|
||||
# so we'll not use this now
|
||||
# set(Boost_ADDRESS_MODEL 64 CACHE INTEGER "32/64 bits")
|
||||
set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link to Boost static libraries")
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
else()
|
||||
set(Boost_ADDRESS_MODEL 64 CACHE INTEGER "32/64 bits")
|
||||
set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link to Boost static libraries")
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Locate Project Prerequisites
|
||||
#
|
||||
|
||||
# Boost
|
||||
|
||||
# note: we're assuming that boost has been built with:
|
||||
# ./b2 —-layout=versioned toolset=clang-darwin link=static,shared variant=debug,release stage
|
||||
|
||||
###########################
|
||||
# special notes for Xcode.
|
||||
|
||||
# these three should result in CMake setting the variables
|
||||
# Boost_SERIALIZATION_LIBRARY_DEBUG … to the correct values.
|
||||
|
||||
# But my current version of CMake doesn't automatically set the library names
|
||||
# to point to the the libraries to be used. The variables are created
|
||||
# but they are not initialized. So be prepared to set these variables by hand.
|
||||
# If you want to use the static libraries - point to the boost libraries ending
|
||||
# in ".a". If you want to use the shared boost libraries - point to the libraries
|
||||
# ending in ".dylib".
|
||||
|
||||
# But wait - there's more.
|
||||
# if both lib.a and lib.dylib both exist in the library directory, Xcode will
|
||||
# automatically chose the *.dylib one - and there's nothing you can do to fix this.
|
||||
# So my recommendation is
|
||||
# a) to place the compiled libraries in two different directories
|
||||
# - e.g. stage/lib-static/*.a and stage/lib-shared/*.dylib
|
||||
# and set the CMake variable Boost_LIBRARY_DIR to point to one or the other
|
||||
# b) create two different CMake build directories - build-static and build-shared
|
||||
# and switch between projects as desired. I like to test both since
|
||||
# there are things like dead code elimination and visibility which vary
|
||||
# between the two environments.
|
||||
#
|
||||
# caveat - as I write this, I've been unable to get the tests on the shared
|
||||
# library to function. Problem is that one needs to either put the shared
|
||||
# libraries in a special known place or set an environmental
|
||||
# variable which points to the shared library directory. I prefer the latter
|
||||
# but I've been unable to figure out how to get Xcode to do on a global basis
|
||||
# and it's not practical to do this for 247 test targets one at a time.
|
||||
|
||||
# c) The targets in the project will by default be built as universal 32/64 binaries
|
||||
# I have yet to experiment with these yet so I just set the target to 64 bit.
|
||||
|
||||
# end special note for Xcode
|
||||
############################
|
||||
|
||||
set(Boost_DEBUG true)
|
||||
set(Boost_DETAILED_FAILURE_MSG true)
|
||||
set(Boost_FOUND true)
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem program_options)
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
message(STATUS "Boost_FOUND is ${Boost_FOUND}")
|
||||
|
||||
if(Boost_FOUND)
|
||||
message(STATUS "Boost Found!")
|
||||
message(STATUS "Boost is ${BOOST_ROOT}")
|
||||
message(STATUS "Boost directories found at ${Boost_INCLUDE_DIRS}")
|
||||
message(STATUS "Boost libraries found at ${Boost_LIBRARY_DIRS}")
|
||||
message(STATUS "Boost libraries prefix is ${Boost_LIB_PREFIX}")
|
||||
message(STATUS "Boost component libraries to be linked are ${Boost_LIBRARIES}")
|
||||
message(STATUS "Boost version found is ${Boost_VERSION}")
|
||||
#include_directories("../include" "${Boost_INCLUDE_DIRS}")
|
||||
#link_directories("${Boost_LIBRARY_DIRS}")
|
||||
else()
|
||||
message(STATUS "Boost NOT Found!")
|
||||
endif()
|
||||
|
||||
if(Boost_USE_STATIC_LIBS)
|
||||
message(STATUS "Use static libraries")
|
||||
set(LINK_TYPE "STATIC")
|
||||
else()
|
||||
message(STATUS "Building shared libraries")
|
||||
set(LINK_TYPE "SHARED")
|
||||
add_definitions( "-DBOOST_ALL_DYN_LINK=1")
|
||||
add_definitions( "-DBOOST_ALL_NO_LIB=1")
|
||||
add_definitions( "-DBOOST_LIB_DIAGNOSTICS=1")
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(VISIBILITY_INLINES_HIDDEN)
|
||||
endif()
|
||||
|
||||
###########################
|
||||
# library builds
|
||||
|
||||
add_library(serialization ${LINK_TYPE}
|
||||
../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_no_rtti.cpp
|
||||
../src/extended_type_info_typeid.cpp
|
||||
../src/extended_type_info.cpp
|
||||
../src/polymorphic_iarchive.cpp
|
||||
../src/polymorphic_oarchive.cpp
|
||||
../src/singleton.cpp
|
||||
../src/stl_port.cpp
|
||||
../src/text_iarchive.cpp
|
||||
../src/text_oarchive.cpp
|
||||
../src/void_cast.cpp
|
||||
../src/xml_archive_exception.cpp
|
||||
../src/xml_iarchive.cpp
|
||||
../src/xml_oarchive.cpp
|
||||
../src/xml_grammar.cpp
|
||||
../src/utf8_codecvt_facet.cpp
|
||||
../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"'
|
||||
)
|
||||
|
||||
add_library(wserialization ${LINK_TYPE}
|
||||
../src/codecvt_null.cpp
|
||||
../src/basic_text_wiprimitive.cpp
|
||||
../src/basic_text_woprimitive.cpp
|
||||
../src/text_wiarchive.cpp
|
||||
../src/text_woarchive.cpp
|
||||
../src/xml_wiarchive.cpp
|
||||
../src/xml_woarchive.cpp
|
||||
../src/xml_wgrammar.cpp
|
||||
../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"'
|
||||
)
|
||||
|
||||
# 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_link_libraries(${test_name} serialization wserialization ${Boost_LIBRARIES})
|
||||
add_test( ${test_name} ${test_name} )
|
||||
endfunction(serialization_test)
|
||||
|
||||
function(archive_test test_name)
|
||||
set(arglist)
|
||||
foreach(a IN ITEMS ${ARGN} )
|
||||
set(arglist ${arglist} ../test/${a}.cpp)
|
||||
endforeach()
|
||||
foreach(
|
||||
archive-name
|
||||
IN ITEMS portable_archive
|
||||
# text_archive text_warchive binary_archive xml_archive xml_warchive
|
||||
)
|
||||
set(amended_test_name ${test_name}_${archive-name})
|
||||
message(STATUS ${amended_test_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_link_libraries(${amended_test_name} serialization wserialization ${Boost_LIBRARIES})
|
||||
add_test(${amended_test_name} ${amended_test_name})
|
||||
endforeach()
|
||||
endfunction(archive_test)
|
||||
|
||||
function(polymorphic_archive_test test_name)
|
||||
set(arglist)
|
||||
foreach(a IN ITEMS ${ARGN} )
|
||||
set(arglist ${arglist} ../test/${a}.cpp)
|
||||
endforeach()
|
||||
foreach(
|
||||
archive-name
|
||||
IN ITEMS portable_archive
|
||||
# text_archive text_warchive binary_archive xml_archive xml_warchive
|
||||
)
|
||||
set(amended_test_name ${test_name}_polymorphic_${archive-name})
|
||||
message(STATUS ${amended_test_name})
|
||||
add_executable(${amended_test_name} ../test/${test_name}.cpp ${arglist})
|
||||
set_property(
|
||||
TARGET ${amended_test_name}
|
||||
PROPERTY COMPILE_DEFINITIONS BOOST_ARCHIVE_TEST=polymorphic_${archive-name}.hpp
|
||||
)
|
||||
target_link_libraries(${amended_test_name} serialization wserialization ${Boost_LIBRARIES})
|
||||
add_test(${amended_test_name} ${amended_test_name})
|
||||
endforeach()
|
||||
endfunction(polymorphic_archive_test)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# serialization(test_dll_exported dll_polymorphic_derived2_lib)
|
||||
# serialization(test_dll_simple dll_a_lib)
|
||||
# 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)
|
||||
|
||||
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_smart_cast)
|
||||
serialization_test(test_codecvt_null ../src/codecvt_null)
|
||||
serialization_test(test_strong_typedef)
|
||||
|
||||
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)
|
||||
archive_test(test_exported polymorphic_base)
|
||||
archive_test(test_forward_list A)
|
||||
archive_test(test_forward_list_ptrs A)
|
||||
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)
|
||||
archive_test(test_map_boost_unordered A)
|
||||
archive_test(test_mi)
|
||||
archive_test(test_multiple_ptrs A)
|
||||
archive_test(test_multiple_inheritance)
|
||||
archive_test(test_no_rtti polymorphic_base polymorphic_derived1)
|
||||
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_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)
|
||||
else()
|
||||
message(STATUS "slist header NOT found")
|
||||
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)
|
||||
archive_test(test_set A)
|
||||
archive_test(test_set_boost_unordered A)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
archive_test(test_set_unordered A)
|
||||
else()
|
||||
CHECK_INCLUDE_FILE_CXX(hash_set HASH_SET_FOUND)
|
||||
if(HASH_SET_FOUND)
|
||||
archive_test(test_set_hashed A)
|
||||
endif()
|
||||
endif()
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
archive_test(test_map_unordered A)
|
||||
else()
|
||||
CHECK_INCLUDE_FILE_CXX(hash_map HASH_MAP_FOUND)
|
||||
if(HASH_MAP_FOUND)
|
||||
archive_test(test_map_hashed A)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
polymorphic_archive_test(test_polymorphic test_polymorphic_A A)
|
||||
polymorphic_archive_test(test_polymorphic2 test_polymorphic2imp)
|
||||
polymorphic_archive_test(test_polymorphic_helper)
|
||||
|
||||
# end test targets
|
||||
####################
|
||||
|
||||
####################
|
||||
# add headers in IDE
|
||||
|
||||
# for serialisation
|
||||
|
||||
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
|
||||
#####################
|
||||
@@ -1,67 +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
|
||||
|
||||
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/core
|
||||
- git submodule init libs/detail
|
||||
- git submodule init libs/filesystem
|
||||
- git submodule init libs/function
|
||||
- git submodule init libs/functional
|
||||
- git submodule init libs/integer
|
||||
- git submodule init libs/intrusive
|
||||
- git submodule init libs/io
|
||||
- git submodule init libs/iterator
|
||||
- git submodule init libs/lexical_cast
|
||||
- git submodule init libs/math
|
||||
- git submodule init libs/move
|
||||
- git submodule init libs/mpl
|
||||
- git submodule init libs/numeric/conversion
|
||||
- git submodule init libs/optional
|
||||
- git submodule init libs/predef
|
||||
- git submodule init libs/preprocessor
|
||||
- git submodule init libs/range
|
||||
- git submodule init libs/smart_ptr
|
||||
- git submodule init libs/spirit
|
||||
- git submodule init libs/static_assert
|
||||
- git submodule init libs/system
|
||||
- git submodule init libs/throw_exception
|
||||
- git submodule init libs/tuple
|
||||
- git submodule init libs/type_index
|
||||
- git submodule init libs/type_traits
|
||||
- git submodule init libs/unordered
|
||||
- git submodule init libs/utility
|
||||
- git submodule init libs/variant
|
||||
- git submodule init 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 toolset=gcc link=static,shared
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,107 @@
|
||||
# Boost serialization Library Build Jamfile
|
||||
# (C) Copyright Robert Ramey 2002-2004.
|
||||
# Use, modification, and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# See http://www.boost.org/libs/serialization for the library home page.
|
||||
|
||||
subproject libs/serialization/build ;
|
||||
|
||||
SOURCES =
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_oarchive
|
||||
basic_serializer_map
|
||||
basic_text_iprimitive
|
||||
basic_text_oprimitive
|
||||
basic_xml_archive
|
||||
binary_iarchive
|
||||
binary_oarchive
|
||||
extended_type_info
|
||||
extended_type_info_no_rtti
|
||||
extended_type_info_typeid
|
||||
polymorphic_iarchive
|
||||
polymorphic_oarchive
|
||||
text_iarchive
|
||||
text_oarchive
|
||||
void_cast
|
||||
xml_grammar
|
||||
xml_iarchive
|
||||
xml_oarchive
|
||||
;
|
||||
|
||||
WSOURCES =
|
||||
codecvt_null
|
||||
basic_text_wiprimitive
|
||||
basic_text_woprimitive
|
||||
binary_wiarchive
|
||||
binary_woarchive
|
||||
text_wiarchive
|
||||
text_woarchive
|
||||
xml_wgrammar
|
||||
xml_wiarchive
|
||||
xml_woarchive
|
||||
utf8_codecvt_facet
|
||||
;
|
||||
|
||||
lib boost_serialization
|
||||
: ## sources ##
|
||||
../src/$(SOURCES).cpp
|
||||
: ## requirements ##
|
||||
std::locale-support
|
||||
<msvc><*><include>$(SPIRIT_ROOT)
|
||||
<msvc-stlport><*><include>$(SPIRIT_ROOT)
|
||||
<vc7><*><include>$(SPIRIT_ROOT)
|
||||
<borland><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_5_1><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_6_4><*><include>$(SPIRIT_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>"-w-8080 -w-8071 -w-8057"
|
||||
<msvc><*><cxxflags>-Gy
|
||||
<vc7><*><cxxflags>-Gy
|
||||
<vc7_1><*><cxxflags>-Gy
|
||||
<define>BOOST_TEST_NO_AUTO_LINK=1
|
||||
: ## default-build
|
||||
<runtime-link>static/dynamic <threading>single/multi
|
||||
;
|
||||
|
||||
lib boost_wserialization
|
||||
: ## sources ##
|
||||
../src/$(WSOURCES).cpp
|
||||
: ## requirements ##
|
||||
std::locale-support
|
||||
<msvc><*><include>$(SPIRIT_ROOT)
|
||||
<msvc-stlport><*><include>$(SPIRIT_ROOT)
|
||||
<vc7><*><include>$(SPIRIT_ROOT)
|
||||
<borland><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_5_1><*><include>$(SPIRIT_ROOT)
|
||||
<borland-5_6_4><*><include>$(SPIRIT_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>"-w-8080 -w-8071 -w-8057"
|
||||
<msvc><*><cxxflags>-Gy
|
||||
<vc7><*><cxxflags>-Gy
|
||||
<vc7_1><*><cxxflags>-Gy
|
||||
<define>BOOST_TEST_NO_AUTO_LINK=1
|
||||
<vacpp><*><define>BOOST_MPL_USE_APPLY_INTERNALLY
|
||||
: ## default-build
|
||||
<runtime-link>static/dynamic <threading>single/multi
|
||||
;
|
||||
|
||||
install serialization lib :
|
||||
<lib>boost_serialization
|
||||
<lib>boost_wserialization
|
||||
;
|
||||
|
||||
stage stage/lib :
|
||||
<lib>boost_serialization
|
||||
<lib>boost_wserialization
|
||||
:
|
||||
<locate>$(BOOST_ROOT)
|
||||
common-stage-tag
|
||||
<tag><postfix>-$(version-tag)
|
||||
<target>stage
|
||||
<target>all
|
||||
:
|
||||
debug release
|
||||
;
|
||||
@@ -8,121 +8,47 @@
|
||||
|
||||
project boost/serialization
|
||||
: source-location ../src
|
||||
: requirements
|
||||
<conditional>@include-spirit
|
||||
;
|
||||
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
;
|
||||
|
||||
SOURCES =
|
||||
basic_archive
|
||||
basic_iarchive
|
||||
basic_iserializer
|
||||
basic_oarchive
|
||||
basic_oserializer
|
||||
basic_pointer_iserializer
|
||||
basic_pointer_oserializer
|
||||
basic_serializer_map
|
||||
basic_text_iprimitive
|
||||
basic_text_oprimitive
|
||||
basic_xml_archive
|
||||
binary_iarchive
|
||||
binary_oarchive
|
||||
codecvt_null
|
||||
extended_type_info
|
||||
extended_type_info_typeid
|
||||
extended_type_info_no_rtti
|
||||
extended_type_info_typeid
|
||||
polymorphic_iarchive
|
||||
polymorphic_oarchive
|
||||
stl_port
|
||||
text_iarchive
|
||||
text_oarchive
|
||||
void_cast
|
||||
archive_exception
|
||||
xml_grammar
|
||||
xml_iarchive
|
||||
xml_oarchive
|
||||
xml_archive_exception
|
||||
codecvt_null
|
||||
utf8_codecvt_facet
|
||||
singleton
|
||||
;
|
||||
|
||||
WSOURCES =
|
||||
basic_text_wiprimitive
|
||||
basic_text_woprimitive
|
||||
binary_wiarchive
|
||||
binary_woarchive
|
||||
text_wiarchive
|
||||
text_woarchive
|
||||
xml_wgrammar
|
||||
xml_wiarchive
|
||||
xml_woarchive
|
||||
utf8_codecvt_facet
|
||||
;
|
||||
|
||||
lib boost_serialization
|
||||
: $(SOURCES).cpp
|
||||
:
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>clang:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>darwin:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>clang:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>darwin:<cxxflags>"-ftemplate-depth-255"
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
lib boost_serialization : $(SOURCES).cpp :
|
||||
<toolset>msvc:<cxxflags>/Gy ;
|
||||
|
||||
lib boost_wserialization
|
||||
: $(WSOURCES).cpp boost_serialization
|
||||
:
|
||||
<toolset>msvc:<cxxflags>/Gy
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>clang:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>darwin:<cxxflags>"-fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
<toolset>gcc:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>clang:<cxxflags>"-ftemplate-depth-255"
|
||||
<toolset>darwin:<cxxflags>"-ftemplate-depth-255"
|
||||
# note: both serialization and wserialization are conditioned on the this
|
||||
# switch - don't change it to BOOST_WSERIALIZATION_DYN_LINK
|
||||
<link>shared:<define>BOOST_SERIALIZATION_DYN_LINK=1
|
||||
;
|
||||
|
||||
boost-install boost_serialization boost_wserialization ;
|
||||
lib boost_wserialization : $(WSOURCES).cpp :
|
||||
<toolset>msvc:<cxxflags>/Gy ;
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Acknowledgments</title>
|
||||
@@ -27,36 +27,23 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<ul>
|
||||
<li>Takatoshi Kondo found and corrected a very obscure and difficult bug in the
|
||||
serialization of virtual base classes.
|
||||
<li><a href="http://www.autoform.com">AutoForm Engineering GmbH</a> supported
|
||||
development efforts to extend correct serialization to objects stored in DLLS.
|
||||
<li><a href"http://www.cadence.com/il">Cadence Israel</a> supported enhancement
|
||||
and testing of the portable binary archive.
|
||||
<li>David Abrahams improved implementation of "export" functionality. This not
|
||||
only eliminated an annoying header sequencing requirement, but also the need to maintain
|
||||
a list of "known archives".
|
||||
<li>Mattias Troyer enhanced the implementation of native binary archives. This includes
|
||||
enhancement and generalization of the library itself including generalization of
|
||||
the wrapper concept.
|
||||
<li>Markus Schö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
|
||||
(still pending at the writing) regarding this.
|
||||
<li>Pavel Vozenilek invested much effort in review of code and documentation
|
||||
resulting in many improvements. In addition he 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 fuction specification.
|
||||
<li><a href="http://www.boost.org/people/vladimir_prus.htm">Vladimir Prus</a> for evaluating an
|
||||
<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 +63,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.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<!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 .
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - More on Archives</title>
|
||||
@@ -26,96 +26,70 @@ 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="implementation">Implementation</a></h3>
|
||||
All input archives should be derived from the following template:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
detail::common_iarchive;
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="trivial">Trivial Archive</a></h3>
|
||||
The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
|
||||
class must implement 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.
|
||||
This class uses the "Curiously Recurring Template Pattern" (CRTP)
|
||||
to implement static (I.E. compile time) polymorphism. It traps common
|
||||
functions and invokes functionality in the most derived class.
|
||||
In order to do the latter, the class is a template with the class
|
||||
name of the most derived class as an argument.
|
||||
|
||||
<h4>Minimum Requirments</h4>
|
||||
A new archive class derived from the above <strong>must</strong> contain
|
||||
the following declarations:
|
||||
<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>
|
||||
|
||||
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:
|
||||
<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>
|
||||
#include <cstddef> // std::size_t
|
||||
//////////////////////////////////////////////////////////////
|
||||
// class trivial_oarchive
|
||||
class trivial_oarchive {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////
|
||||
// public interface used by programs that use the
|
||||
// serialization library
|
||||
typedef boost::mpl::bool_<true> is_saving;
|
||||
typedef boost::mpl::bool_<false> is_loading;
|
||||
template<class T> void register_type(){}
|
||||
template<class T> trivial_oarchive & operator<<(const T & t){
|
||||
return *this;
|
||||
}
|
||||
template<class T> trivial_oarchive & operator&(const T & t){
|
||||
return *this << t;
|
||||
}
|
||||
void save_binary(void *address, std::size_t count){};
|
||||
};
|
||||
</code></pre>
|
||||
The simplest possible input archive class is analogous to the above.
|
||||
In the following discussion, only output archives will be addressed.
|
||||
Input archives are exactly symmetrical to output archives.
|
||||
<p>
|
||||
This archive will compile and execute with any types which implement the
|
||||
<a href="serialization.html"><strong>Serializable</strong></a> concept.
|
||||
For an example see
|
||||
<a href="../example/demo_trivial_archive.cpp" target="demo_trivial_archive">
|
||||
<code style="white-space: normal">demo_trivial_archive.cpp</code></a>.
|
||||
Of course this program won't produce any output as it is. But it provides
|
||||
the starting point for a simple class which can be used to log formatted
|
||||
output. See the implementation of a <a href="simple_log.html">simple
|
||||
log archive</a> to how this has been done.
|
||||
|
||||
<h3><a name="implementation">More Useful Archive Classes</a></h3>
|
||||
The above example is fine as far as it goes. But it doesn't implement
|
||||
useful features such as serialization of pointers, class versioning
|
||||
and others. This library implements a family of full featured archive
|
||||
classes appropriate for a variety of purposes.
|
||||
|
||||
<p>
|
||||
Our archives have been factored into a tree of classes in order to minimize
|
||||
repetition of code. This is shown in the accompanying
|
||||
<a target="class_diagram" href="class_diagram.html">class diagram</a>.
|
||||
|
||||
Any class which fulfills the following requirements will fit into
|
||||
this hierarchy and implement all the features we require. Deriving from
|
||||
the base class <a href="../../../boost/archive/detail/common_oarchive.hpp" target="common_oarchive_hpp">
|
||||
common_oarchive.hpp</a> provides all features we desire which
|
||||
are missing from trivial_oarchive above.
|
||||
|
||||
<pre><code>
|
||||
<a href="../../../boost/archive/detail/common_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 +97,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 definition of <code style="white-space: normal">load</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
|
||||
@@ -159,31 +137,31 @@ by XML archive to inject "</name>" after data.
|
||||
<dt><h4><code>void end_preamble()</code></h4></dt>
|
||||
<dd>
|
||||
<strong>Default</strong>:Does nothing.<br>
|
||||
<strong>Purpose</strong>:Called <strong>each time</strong> user data 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
|
||||
<strong>Purpose</strong>:Called <strong>each time</strong> user data data is saved.
|
||||
Its not called when archive book keeping data is saved. This is used by XML archives
|
||||
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 though it is not used.
|
||||
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>.
|
||||
@@ -195,14 +173,12 @@ implement partial function template ordering. For more information see
|
||||
The serialization library injects bookkeeping data into the serialization archive.
|
||||
This data includes things like object ids, version numbers, class names etc. Each
|
||||
of these objects is included in a wrapper so that the archive class can override the
|
||||
implementation of <code style="white-space: normal">void 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:
|
||||
"object_id=_23". The following table lists the types used 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>
|
||||
@@ -214,7 +190,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
|
||||
@@ -222,7 +198,7 @@ These are defined in
|
||||
All of these types have been assigned an
|
||||
<a target="detail" href="traits.html#level">implementation level</a> of
|
||||
<code style="white-space: normal">primitive</code> and are convertible to types such as int, unsigned int, etc.
|
||||
so that they have default implementations. This is illustrated by
|
||||
So that they have default implementations. This is illustrated by
|
||||
<a href="../../../boost/archive/basic_text_iarchive.hpp" target="basic_text_iarchive_hpp"><code style="white-space: normal">basic_text_iarchive.hpp</code></a>.
|
||||
which relies upon the default. However, in some cases, overrides will have to be
|
||||
explicitly provided for these types. For an example see
|
||||
@@ -242,10 +218,8 @@ One or more of the following issues may need to be addressed:
|
||||
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>
|
||||
@@ -260,15 +234,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">BOOT_CLASS_EXPORT</code> is used
|
||||
to instantiate the serialization code for the included archives.
|
||||
is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used to instantiate the serialization
|
||||
code for the included archives.
|
||||
</ul>
|
||||
|
||||
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>
|
||||
#define 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
|
||||
@@ -276,24 +252,25 @@ 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 charactor 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
|
||||
library would include DLL vs static library, release vs debug so the actual total
|
||||
would be closer to 1032 tests.
|
||||
the above described tests. This will result in as many as 36 archive tests * 5
|
||||
standard archives + 22 general tests = 202 tests.
|
||||
<p>
|
||||
For each archive there is a header file in the test directory similar to the one below.
|
||||
The name of this archive is passed to the test program by setting the
|
||||
environmental variable <code style="white-space: normal">BOOST_ARCHIVE_TEST</code>
|
||||
environmental variable <code style="white-space: normal">BOOST_TEST_ARCHIVE</code>
|
||||
to the name of the header. Here is the header file
|
||||
<code style="white-space: normal">test_archive.hpp</code> . Test header files for
|
||||
other archives are similar.
|
||||
@@ -316,16 +293,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>
|
||||
|
||||
@@ -339,7 +316,7 @@ However:
|
||||
<ul>
|
||||
<li>Much inline code may be replicated.
|
||||
<li>If there are several archive classes, code will be regenerated for each archive class.
|
||||
<li>If serialization code is placed in a library, that library must be rebuilt
|
||||
<li>If seriaiization code is placed in a library, that library must be rebuilt
|
||||
each time a new archive class is created.
|
||||
<li>If serialization code is placed in a DLL,
|
||||
<ul>
|
||||
@@ -354,7 +331,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.
|
||||
|
||||
@@ -371,7 +348,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.
|
||||
@@ -381,15 +358,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_impl_hpp href="../../../boost/archive/detail/polymorphic_iarchive_impl.hpp"><code style="white-space: normal">polymorphic_iarchive_impl.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_impl_hpp href="../../../boost/archive/detail/polymorphic_oarchive_impl.hpp"><code style="white-space: normal">polymorphic_oarchive_impl.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
|
||||
@@ -400,29 +376,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 polymophic 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 polymorhic
|
||||
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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archives</title>
|
||||
@@ -14,220 +14,371 @@
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Archive Concepts</h2>
|
||||
<h2 align="center">Archive Class Usage</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#saving_interface">Saving Archive Concept</a>
|
||||
<dt><a href="#loading_interface">Loading Archive Concept</a>
|
||||
<dt><a href="#archive_models">Models</a>
|
||||
<dt><a href="#exceptions">Exceptions</a>
|
||||
<dt><a href="#creation">Archive Classes</a>
|
||||
<dt><a href="#interface">Library Interface</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#saving_interface">Saving</a>
|
||||
<dt><a href="#loading_interface">Loading</a>
|
||||
</dl>
|
||||
<dt><a href="#details_by_type">Details by Type</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#primitiveoperators">Primitive Types</a>
|
||||
<dt><a href="#classoperators">Class Types</a>
|
||||
<dt><a href="#baseclasses">Base Classes</a>
|
||||
<dt><a href="#pointeroperators">Pointers</a>
|
||||
<dt><a href="#referenceoperators">References</a>
|
||||
</dl>
|
||||
<dt><a href="#charactersets">Character Sets</a>
|
||||
</dl>
|
||||
<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 instance of type SA.
|
||||
<li><code>LA</code> is an type modeling the <a href="#loading_interface">Loading Archive Concept</a>.
|
||||
<li><code>la</code> is an instance of type LA.
|
||||
<li><code>T</code> is an <a href="serialization.html"><strong>Serializable</strong></a> Type.
|
||||
<li><code>x</code> is an instance of type T Type.
|
||||
<li><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
|
||||
Saving Archive concept (SA) may be associated with another type modeling the
|
||||
<a href="#loading_interface">Loading Archive Concept</a>(LA).
|
||||
This associated type will perform the inverse operation.
|
||||
That is, given a sequence of bytes generated by SA, it will generate a set of
|
||||
C++ data structures that is equivalent to the original.
|
||||
The notion of equivalence is defined by the implementations of the pair of archives and the
|
||||
way the data are rendered <a href="serialization.html">serializable</a>.
|
||||
<p>
|
||||
<h4>Valid Expressions</h4>
|
||||
|
||||
<h3><a name="archive_classes">Archive Classes</a></h3>
|
||||
An archive is defined by two complementary classes. One is for saving data while
|
||||
the other is for loading it.
|
||||
The system includes a number of archive implementations "ready to go" for the
|
||||
most common requirements. These can be used "as is" or as a basis for developing
|
||||
one's own particular type of archive. To invoke serialization using one of
|
||||
these archives, one or more of the following header files must be
|
||||
included in the code module containing the serialization code.
|
||||
<pre><code>
|
||||
// a portable text archive</a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive(istream &s)</a> // loading
|
||||
|
||||
// a portable text archive using a wide character stream</a>
|
||||
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive(wistream &s)</a> // loading
|
||||
|
||||
// a non-portable native binary archive</a>
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive(istream &s)</a> // loading
|
||||
<!--
|
||||
// a non-portable native binary archive which use wide character streams
|
||||
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive(wistream &s)</a> // loading
|
||||
-->
|
||||
// a portable XML archive</a>
|
||||
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive(ostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive(istream &s)</a> // loading
|
||||
|
||||
// a portable XML archive which uses wide characters - use for utf-8 output</a>
|
||||
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive(wostream &s)</a> // saving
|
||||
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive(wistream &s)</a> // loading
|
||||
</code></pre>
|
||||
<h3><a name="interface">Archive Library Interface</a></h3>
|
||||
An <strong>archive</strong> contains a sequence of bytes created from
|
||||
an arbitrary nested set of C++ data structures. Archives are implemented as a
|
||||
hierarchy of classes. However, the interface to all archives included with
|
||||
the library can best be represented by the following public interface.
|
||||
|
||||
<h4><a name="saving_interface">Saving</a></h4>
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
enum archive_flags {
|
||||
no_header = 1, // suppress archive header info
|
||||
no_codecvt = 2, // suppress alteration of codecvt facet
|
||||
no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
<pre><code>
|
||||
template<class OStream>
|
||||
class oarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
// called to save objects
|
||||
template<class T>
|
||||
oarchive & operator<<(const T & t);
|
||||
|
||||
template<class T>
|
||||
oarchive & operator&(T & t)
|
||||
{
|
||||
return *this << t;
|
||||
}
|
||||
|
||||
void save_binary(const void *address, std::size_t count);
|
||||
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
|
||||
unsigned int library_version() const;
|
||||
|
||||
struct is_saving {
|
||||
typedef mpl::bool_<true> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
|
||||
struct is_loading {
|
||||
typedef mpl::bool_<false> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
};
|
||||
|
||||
oarchive(OStream & os, unsigned int flags = 0);
|
||||
|
||||
~oarchive();
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
<dt><h4><code>
|
||||
SA::is_saving
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
SA::is_loading
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa << x
|
||||
<br>
|
||||
sa & x
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These expressions must perform exactly the same function. They append the
|
||||
value of <code style="white-space: normal">x</code> along with other information to <code>sa</code>.
|
||||
This other information is defined by the implementation of the archive.
|
||||
Typically this information is that which is required by a corresponding
|
||||
Loading Archive type to properly restore the value of <code>x</code>.
|
||||
<p>
|
||||
Returns a reference to <code>sa</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.save_binary(u, count)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends to the archive <code style="white-space: normal">size_t(count)</code> bytes found at
|
||||
<code style="white-space: normal">u</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.register_type<T>()
|
||||
<br>
|
||||
sa.register_type(u)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends information about class T to the archive. This information is used to
|
||||
construct the correct class when a derived pointer is loaded by a corresponding
|
||||
Loading Archive type.
|
||||
Invocation of this member function is referred to as "class registration".
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
|
||||
The second syntax is included to permit this function to be called on non-conforming
|
||||
compilers when <code style="white-space: normal">sa</code> is a template argument.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
sa.get_library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the current version number of the serialization
|
||||
library. This number will be incremented each time the library is altered in such a
|
||||
way that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
<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>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
oarchive & operator<<(const T & t);
|
||||
|
||||
template<class T>
|
||||
oarchive & operator&(T & t);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<p>
|
||||
Appends an object of type T to the archive. The object may be
|
||||
<ul>
|
||||
<li>A primitive data type such as int, char, float, etc.
|
||||
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
|
||||
function has been defined.
|
||||
<li>A pointer to a serializable object.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void save_binary(const void *address, std::size_t count);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends to the archive <code style="white-space: normal">count</code> bytes found at
|
||||
<code style="white-space: normal">address</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Appends a sequential integer to the archive. This integer becomes the "key" used
|
||||
to look up the class type when the archive is later loaded. This process is
|
||||
referred to as "class registration". It is only necessary to invoke this function for
|
||||
objects of derived classes which are serialized through a base class pointer. This
|
||||
is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
unsigned int library_version() const;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the version number of the serialization library that created the archive.
|
||||
This number will be incremented each time the library is altered in such a way
|
||||
that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
is_saving::type = mpl::bool<true>;
|
||||
is_saving::value= true;
|
||||
is_loading::type = mpl::bool<false>;
|
||||
is_loading::value= false;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These integral constants permit archive attributes to be queried at compiler
|
||||
or execution time. They can used to generate code with boost
|
||||
<a href="../../mpl/doc/index.html">mpl</a>
|
||||
. For and example
|
||||
showing how these can beused, see the implementation of
|
||||
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
oarchive(OStream & os, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs and archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. For most applications there will be no need to use
|
||||
flags. Flags are taken from the following table and can be combined with the
|
||||
<code style="white-space: normal">|</code> operator.By default, archives prepend
|
||||
output with initial data which helps identify them as archives produced by this system.
|
||||
This permits a more graceful in the case where attempt is made to load an archive
|
||||
from an invalid file format. In addition to this, each type of archive might have
|
||||
its own information. For example, native binary archives include information about
|
||||
sizes of native types and endianess to gracefully handle the case where it has been
|
||||
erroneously assumed that such an archive is portable across platforms. In some cases
|
||||
where this extra overhead might be considered objectionable, it can be suppressed with the
|
||||
<code style="white-space: normal">no_header</code> flag.
|
||||
<p>
|
||||
In some cases, an archive may alter (and later restore)
|
||||
the codecvt facet of the stream locale. To suppress this action,
|
||||
include the <code style="white-space: normal">no_codecvt</code> flag.
|
||||
<p>
|
||||
XML archives contain nested tags signifying the start and end of data fields.
|
||||
These tags are normally checked for aggreement with the object name when
|
||||
data is loaded. If a mismatch occurs an exception is thrown. Its possible
|
||||
that this may not be desired behavior. To suppress this checking of XML
|
||||
tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~oarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to thier state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h4><a name="loading_interface">Loading Archive Concept</a></h4>
|
||||
<h4>Associated Types</h4>
|
||||
Each model of this concept presumes the
|
||||
existence of a corresponding type modeling the
|
||||
<a href="#saving_interface">Saving Archive Concept</a>.
|
||||
The purpose of an instance of this concept is to convert a sequence of bytes
|
||||
generated by this corresponding type to a set of C++ data structures
|
||||
equivalent to the original.
|
||||
<h4>Valid Expressions</h4>
|
||||
<h4><a name="loading_interface">Loading</a></h4>
|
||||
|
||||
<pre><code>
|
||||
template<class IStream>
|
||||
class iarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
// called to load objects
|
||||
template<class T>
|
||||
iarchive & operator>>(T & t);
|
||||
|
||||
template<class T>
|
||||
iarchive & operator&(T & t)
|
||||
{
|
||||
return *this >> t;
|
||||
}
|
||||
|
||||
void delete_created_pointers();
|
||||
|
||||
void load_binary(void *address, std::size_t count);
|
||||
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
|
||||
unsigned int library_version() const;
|
||||
|
||||
struct is_saving {
|
||||
typedef mpl::bool_<false> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
};
|
||||
|
||||
struct is_loading {
|
||||
typedef mpl::bool_<true> type;
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
|
||||
iarchive(IStream & is, unsigned int flags = 0);
|
||||
|
||||
~iarchive();
|
||||
};
|
||||
|
||||
} //namespace archive
|
||||
) //namespace boost
|
||||
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
<dt><h4><code>
|
||||
LA::is_saving
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
LA::is_loading
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la >> x
|
||||
<br>
|
||||
la & x
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These expressions must perform exactly the same function.
|
||||
Sets <code>x</code> to a value retrieved from <code>la</code>.
|
||||
<p>
|
||||
Returns a reference to <code>la</code>.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.load_binary(u, count)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves from <code style="white-space: normal">la</code> <code style="white-space: normal">size_t(count)</code> bytes and stores
|
||||
them in memory starting at <code style="white-space: normal">u</code>.
|
||||
</dd>
|
||||
<dt>
|
||||
<dt><h4><code>
|
||||
la.register_type<T>()
|
||||
<br>
|
||||
la.register_type(u)
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves information about class T from the archive. This information is used to
|
||||
construct the correct class when loading a pointer to a derived class not
|
||||
otherwise referred to in the program by name.
|
||||
Invocation of this member function is referred to as "class registration".
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>.
|
||||
The second syntax is included to permit this function to be called on non-conforming
|
||||
compilers when <code style="white-space: normal">la</code> is a template argument.
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.get_library_version()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns an unsigned integer containing the version number of the serialization
|
||||
library that created the archive. This number will be incremented each time the
|
||||
library is altered in such a way that serialization could be altered for some type.
|
||||
For example, suppose the type used for a count of collection members is changed.
|
||||
The code that loads collections might be conditioned on the library version to make
|
||||
sure that libraries created by previous versions of the library can still be read.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.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>
|
||||
<dd>
|
||||
Communicates to the archive that the object originally at address u has been
|
||||
moved to address v.
|
||||
<p>
|
||||
When an object is loaded to a temporary variable and later moved to another location,
|
||||
this function must be called in order communicate this fact. This permits the
|
||||
archive to properly implement object tracking. Object tracking is required in order
|
||||
to correctly implement serialization of pointers to instances of derived classes.
|
||||
</dd>
|
||||
<dt><h4><code>
|
||||
la.delete_created_pointers()
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Deletes all objects created by the loading of pointers. This can be used to
|
||||
avoid memory leaks that might otherwise occur if pointers are being loaded
|
||||
and the archive load encounters an exception.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
iarchive & operator>>(T & t);
|
||||
|
||||
template<class T>
|
||||
iarchive & operator&(T & t);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
<p>
|
||||
Retrieves an object of type T from the archive. The object may be
|
||||
<ul>
|
||||
<li>A primitive data type such as int, char, float, etc.
|
||||
<li>A class or struct for which a <code style="white-space: normal">serialize</code>
|
||||
function has been defined.
|
||||
<li>A pointer to a serializable object.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void load_binary(void *address, std::size_t count);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves from the archive <code style="white-space: normal">count</code> bytes and stores
|
||||
them in memory starting at <code style="white-space: normal">address</code>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
void delete_created_pointers();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Deletes all objects created by the loading of pointers. This can be used to
|
||||
avoid memory leaks that might otherwise occur if pointers are being loaded
|
||||
and the archive load encounters an exception.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
template<class T>
|
||||
register_type(T * t = NULL);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Retrieves the next integer from the archive and adds an entry to a table which
|
||||
relates the integer to the type T. When pointers are loaded, this integer is
|
||||
used to indicate which object type should be created. This process is
|
||||
referred to as "class registration". It is only necessary to invoke this function for
|
||||
objects of derived classes which are serialized through a base class pointer. If this
|
||||
function is called during the saving of data to the archive, it should be called during the
|
||||
loading of the data from the archive at the same point in the serialization process.
|
||||
This is explained in detail in
|
||||
<a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
unsigned int library_version() const;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Returns the version number of the serialization library that created the archive.
|
||||
This number will be incremented each time the library is altered in such a way
|
||||
that serialization could be altered for some type. For example, suppose the type
|
||||
used for a count of collection members is changed. The code that loads collections
|
||||
might be conditioned on the library version to make sure that libraries created by
|
||||
previous versions of the library can still be read.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
is_saving::type = mpl::bool<false>;
|
||||
is_saving::value= false;
|
||||
is_loading::type = mpl::bool<true>;
|
||||
is_loading::value= true;
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
These integral constants permit archive attributes to be queried at compiler
|
||||
or execution time. They can used to generate code with boost
|
||||
<a href="../../mpl/doc/index.html">mpl</a>
|
||||
. For and example
|
||||
showing how these can beused, see the implementation of
|
||||
<a target="splithpp" href="../../../boost/serialization/split_free.hpp">split_free.hpp</a>.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
iarchive(IStream & is, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. If flags are used, they should be the same
|
||||
as those used when the archive was created. Function and usage of flags is described
|
||||
above.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~iarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to thier state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
There are archives based on text, binary and XML file
|
||||
@@ -241,7 +392,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.
|
||||
@@ -249,191 +400,132 @@ However, this is not a requirement of the serialization functions or the
|
||||
archive interface. It just turns out that the archives written so far have
|
||||
found it useful to base their implementation on streams.
|
||||
|
||||
<h3><a name="archive_models">Archive Models</a></h3>
|
||||
This library includes various implementations of the Archive concept.
|
||||
<h3><a name="details_by_type">Details by Type</a></h3>
|
||||
|
||||
An archive is defined by two complementary classes. One is for saving data while
|
||||
the other is for loading it.
|
||||
|
||||
This library includes a number of archive implementations that are "ready to go" for the
|
||||
most common requirements. These classes implement the archive concept for differing data formats.
|
||||
They can be used "as is" or as a basis for developing one's own particular type of archive.
|
||||
An archive is defined by two complementary classes. One is for saving data while the other is for loading it.
|
||||
|
||||
To invoke serialization using one of
|
||||
these archives, one or more of the following header files must be
|
||||
included in the code module containing the serialization code.
|
||||
<pre><code>
|
||||
// a portable text archive</a>
|
||||
<a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive</a> // loading
|
||||
|
||||
// a portable text archive using a wide character stream</a>
|
||||
<a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive</a> // loading
|
||||
|
||||
// a portable XML archive</a>
|
||||
<a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive</a> // loading
|
||||
|
||||
// a portable XML archive which uses wide characters - use for utf-8 output</a>
|
||||
<a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive</a> // loading
|
||||
|
||||
// a non-portable native binary archive</a>
|
||||
<a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive</a> // saving
|
||||
<a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive</a> // loading
|
||||
|
||||
<!--
|
||||
// a non-portable native binary archive which use wide character streams
|
||||
<a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive</a> // saving
|
||||
<a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive</a> // loading
|
||||
-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
All of these archives implement the same interface. Hence, it should suffice to describe only one
|
||||
of them in detail. For this purpose we will use the text archive.
|
||||
|
||||
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
enum archive_flags {
|
||||
no_header = 1, // suppress archive header info
|
||||
no_codecvt = 2, // suppress alteration of codecvt facet
|
||||
no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving
|
||||
};
|
||||
|
||||
} // archive
|
||||
} // boost
|
||||
</code></pre>
|
||||
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
class text_oarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Saving Archive</strong> concept
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
~text_oarchive();
|
||||
};
|
||||
|
||||
} // archive
|
||||
} // boost
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_oarchive(std::ostream & os, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Constructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. For most applications there will be no need to use flags.
|
||||
Flags are defined by <code style="white-space: normal">enum archive_flags</code> enumerator.
|
||||
Multiple flags can be combined with the <code style="white-space: normal">|</code> operator.
|
||||
|
||||
By default, archives prepend
|
||||
output with initial data which helps identify them as archives produced by this system.
|
||||
This permits a more graceful handling of the case where an attempt is made to load an archive
|
||||
from an invalid file format. In addition to this, each type of archive might have
|
||||
its own information. For example, native binary archives include information about
|
||||
sizes of native types and endianess to gracefully handle the case where it has been
|
||||
erroneously assumed that such an archive is portable across platforms. In some cases,
|
||||
where this extra overhead might be considered objectionable, it can be suppressed with the
|
||||
<code style="white-space: normal">no_header</code> flag.
|
||||
<h4><a name="primitiveoperators">Primitive Types</a></h4>
|
||||
In this document, we use the term primitive type to mean
|
||||
types whose data is simply saved/loaded to/from an archive
|
||||
with no further processing. By default, arithmetic (including characters),
|
||||
bool, and enum types are primitive types. Using
|
||||
<a target="detail" href="traits.html#Traits">serialization traits</a>,
|
||||
any user type can also be designated as "primitive"
|
||||
so that it is handled in this way.
|
||||
<p>
|
||||
In some cases, an archive may alter (and later restore)
|
||||
the codecvt facet of the stream locale. To suppress this action,
|
||||
include the <code style="white-space: normal">no_codecvt</code> flag.
|
||||
<p>
|
||||
XML archives contain nested tags signifying the start and end of data fields.
|
||||
These tags are normally checked for agreement with the object name when
|
||||
data is loaded. If a mismatch occurs an exception is thrown. It's possible
|
||||
that this may not be desired behavior. To suppress this checking of XML
|
||||
tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag.
|
||||
</dd>
|
||||
The template operators &, <<, and >> of the archive classes
|
||||
described above will generate code to save/load all primitive types
|
||||
to/from an archive. This code will usually just add the
|
||||
data to the archive according to the archive format.
|
||||
For example, a four byte integer is appended to a binary archive
|
||||
as 4 binary bytes while a to a text archive it would be
|
||||
rendered as a space followed by a string representation.
|
||||
|
||||
<dt><h4><code>
|
||||
~text_oarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to their state before the
|
||||
archive was opened.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
<h4><a name="classoperators">Class Types</a></h4>
|
||||
For class/struct types, the template operators &, <<, and >>
|
||||
will generate code that invokes the programmer's serialization code for the
|
||||
particular data type. There is no default. An attempt to serialize a
|
||||
class/struct for which no serialization has been explicitly specified
|
||||
will result in a compile time error. Specification of serialization
|
||||
for user defined types is explained in detail in the next section
|
||||
of this manual.
|
||||
|
||||
<h4><a name="baseclasses">Base Classes</a></h4>
|
||||
The header file
|
||||
<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
|
||||
base_object.hpp
|
||||
</a>
|
||||
includes the template:
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
|
||||
class text_iarchive : ...
|
||||
{
|
||||
...
|
||||
public:
|
||||
... // implementation of the <strong>Loading Archive</strong> concept
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
~text_iarchive();
|
||||
};
|
||||
|
||||
} //namespace archive
|
||||
) //namespace boost
|
||||
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
</code></pre>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code>
|
||||
text_iarchive(std::istream & is, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Contructs an archive given an open <code style="white-space: normal">stream</code> as
|
||||
an argument and optional flags. If flags are used, they should be the same
|
||||
as those used when the archive was created. Function and usage of flags is described
|
||||
above.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code>
|
||||
~text_iarchive();
|
||||
</code></h4></dt>
|
||||
<dd>
|
||||
Destructor for an archive. This should be called before the stream is
|
||||
closed. It restores any altered stream facets to their state before the
|
||||
the archive was opened.
|
||||
</dd>
|
||||
</dl>
|
||||
which should be used to create a reference to an object of the base
|
||||
which can be used as an argument to the archive save/load operators:
|
||||
<pre><code>
|
||||
ar & boost::serialization::base_object<Base>(*this);
|
||||
</code></pre>
|
||||
Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
|
||||
This might seem to work but may fail to invoke code necessary for
|
||||
proper serialization.
|
||||
<h4><a name="pointeroperators">Pointers</a></h4>
|
||||
A pointer to any class instance can be serialized with any of the archive
|
||||
save/load operators.
|
||||
<p>
|
||||
The <code style="white-space: normal">binary_oarchive</code> and
|
||||
<code style="white-space: normal">binary_iarchive</code> classes are
|
||||
implemented in terms of the more basic
|
||||
<code style="white-space: normal">std::streambuf</code>. So, in addition
|
||||
to the common class interface described above, they include the following
|
||||
constructors:
|
||||
<dl>
|
||||
<dt><h4><code>
|
||||
binary_oarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
and
|
||||
<dt><h4><code>
|
||||
binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);
|
||||
</code></h4></dt>
|
||||
</dl>
|
||||
To properly save and restore an object through a pointer the
|
||||
following situations must be addressed:
|
||||
<ol>
|
||||
<li>If the same object is saved multiple times through different
|
||||
pointers, only one copy of the object need be saved.
|
||||
<li>If an object is loaded multiple times through different pointers,
|
||||
only one new object should be created and all returned pointers
|
||||
should point to it.
|
||||
<li>The system must detect the case where an object is first
|
||||
saved through a pointer then the object itself is saved.
|
||||
Without taking extra precautions, loading would result in the
|
||||
creation of multiple copies of the original object. This system detects
|
||||
this case when saving and throws an exception - see below.
|
||||
<li>An object of a derived class may be stored through a
|
||||
pointer to the base class. The true type of the object must
|
||||
be determined and saved. Upon restoration the correct type
|
||||
must be created and its address correctly cast to the base
|
||||
class. That is, polymorphic pointers have to be considered.
|
||||
<li>NULL pointers must be dectected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
|
||||
<h3><a name="exceptions">Exceptions</h3>
|
||||
All of the archive classes included may throw exceptions. The list of exceptions that might
|
||||
be thrown can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a>
|
||||
of this documentation.
|
||||
This serialization library addresses all of the above
|
||||
considerations. The process of saving and loading an object
|
||||
through a pointer is non-trivial. It can be summarized as
|
||||
follows:
|
||||
<p>Saving a pointer:
|
||||
<ol>
|
||||
<li>determine the true type of the object being pointed to.
|
||||
<li>write a special tag to the archive
|
||||
<li>if the object pointed to has not already been written
|
||||
to the archive, do so now
|
||||
</ol>
|
||||
Loading a pointer:
|
||||
<ol>
|
||||
<li>read a tag from the archive.
|
||||
<li>determine the type of object to be created
|
||||
<li>if the object has already been loaded, return it's address.
|
||||
<li>otherwise, create a new instance of the object
|
||||
<li>read the data back in using the operators described above
|
||||
<li>return the address of the newly created object.
|
||||
</ol>
|
||||
|
||||
Given that class instances are saved/loaded to/from the archive
|
||||
only once, regardless of how many times they are serialized with
|
||||
the <code style="white-space: normal"><<</code>
|
||||
and <code style="white-space: normal">>></code> operators
|
||||
<ul>
|
||||
<li>Loading the same pointer object multiple times
|
||||
results in only one object being created, thereby replicating
|
||||
the original pointer configuration.
|
||||
<li>Structures such as collections of polymorphic pointers,
|
||||
are handled with no special effort on the part of users of this library.
|
||||
</ul>
|
||||
Serialization of pointers of derived types through a pointer to the
|
||||
base class may require a little extra "help". Also, the programmer
|
||||
may desire to modify the process described above for his own reasons.
|
||||
For example, it might be desired to suppress the tracking of objects
|
||||
as it is known a priori that the application in question can never
|
||||
create duplicate objects. Serialization of pointers can be "fine tuned"
|
||||
via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
as described in
|
||||
<a target="detail" href="special.html#derivedpointers">
|
||||
another section of this manual
|
||||
</a>
|
||||
<h4><a name="referenceoperators">References</a></h4>
|
||||
In general, references are serialized just as any other objects are.
|
||||
However, references have the property that several references may
|
||||
refer to the same object - much like pointers. So, there exists
|
||||
the opportunity to gain some storage efficiency by storing only
|
||||
one copy. This subject is addressed the chapter Class Serialization Traits -
|
||||
<a target="detail" href="traits.html#tracking">Object Tracking</a>.
|
||||
|
||||
<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">
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Bibliography</title>
|
||||
@@ -36,7 +36,6 @@ 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>
|
||||
@@ -46,13 +45,13 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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.
|
||||
|
||||
@@ -7,7 +7,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archive Class Diagram</title>
|
||||
@@ -20,7 +20,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Text Archive Class Diagram</h2>
|
||||
<h2 align="center">Archive Class Diagram</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -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>
|
||||
|
|
||||
|
|
||||
<font color="blue">basic_text_oarchive<text_oarchive></font> <a href="../../../boost/archive/basic_text_oarchive.hpp">-></a>
|
||||
|
|
||||
|
|
||||
| <font color="blue">basic_text_oprimitive<basic_ostream></font> <a href="../../../boost/archive/basic_text_oprimitive.hpp">-></a>
|
||||
| /
|
||||
| ______________/
|
||||
| /
|
||||
| /
|
||||
| /
|
||||
common_iarchive<text_iarchive> <a href="../../../boost/archive/detail/common_iarchive.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_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>
|
||||
| / |
|
||||
| / |
|
||||
| / |
|
||||
<font color="blue">text_oarchive_impl<text_oarchive></font> <a href="../../../boost/archive/text_oarchive.hpp">-></a> polymorphic_oarchive_impl <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
| \ |
|
||||
| \ |
|
||||
| \_____________________________________ <font color="red">polymorphic_oarchive</font> <a href="../../../boost/archive/polymorphic_oarchive.hpp">-></a>
|
||||
| \ /
|
||||
| /
|
||||
| ____________/ interface_iarchive<polymorphic_iarchive> <a href="../../../boost/archive/detail/interface_iarchive.hpp">-></a>
|
||||
| / /
|
||||
| / /
|
||||
| / /
|
||||
<font color="blue">text_iarchive_impl<text_iarchive></font> <a href="../../../boost/archive/text_iarchive.hpp">-></a> <font color="red">polymorphic_iarchive</font> <a href="../../../boost/archive/polymorphic_iarchive.hpp">-></a>
|
||||
| \ /
|
||||
| \ /
|
||||
| \_________________________________________ /
|
||||
| \ /
|
||||
| \ /
|
||||
| \ /
|
||||
<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_impl<text_iarchive_impl<text_iarchive> > <a href="../../../boost/archive/detail/polymorphic_iarchive_impl.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 hierachy 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 its text archives).
|
||||
Users include classes in <font color="red">red</font> to save their data from a partcular
|
||||
type of archive. Other classes whose names are in black implement the library and should
|
||||
implement loading for a given archive type. (in this case its text archives).
|
||||
Users include classes in <font color="red">red</font> to load their data from a partcular
|
||||
type of archive. Other classes whose names are in black implment the library and should
|
||||
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_impl.hpp">polymorphic_iarchive_impl<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 impelenting 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 polymorphic_text_archive rather than
|
||||
<code style="white-space: normal">polymorphic_oarchive_route<text_oarchive_impl&'t;text_oarchive> ></code>
|
||||
<code style="white-space: normal">polymorphic_iarchive_impl<text_iarchive_impl<text_iarchive> ></code>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
== representations about the suitability of this software for any
|
||||
== purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<head>
|
||||
@@ -28,7 +28,7 @@ width="277" height="86"> <br clear="all">
|
||||
<a name="sec:utf8-codecvt-facet-class"></a>
|
||||
|
||||
|
||||
<h1><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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Configuration</title>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<title>Serialization</title>
|
||||
|
||||
@@ -83,257 +83,192 @@ 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>
|
||||
|
||||
<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 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#Platforms">Platforms</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#recent_improvements">Differences from Draft #20</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="release.html#todo">Pending Issues</a></dt>
|
||||
</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="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>
|
||||
</dl></div></dd>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="reference"><a target="detail" href="archives.html">Reference</a></dt>
|
||||
<dd><div id="reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_class"><a target="detail" href="archives.html">Archive Class Usage</a>
|
||||
<dd>
|
||||
<div id="archive_class_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#archive_classes">Archive Classes</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="library_interface"><a target="detail" href="archives.html#interface">Library Interface</a>
|
||||
|
||||
<dd><div id="library_interface_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#saving_interface">Saving Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#loading_interface">Loading Interface</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="details_by_type"><a target="detail" href="archives.html#details_by_type">Details by Type</a>
|
||||
<dd><div id="details_by_type_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#primitiveoperators">Primitive Types</a>
|
||||
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#classoperators">Class Types</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#baseclasses">Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#pointeroperators">Pointers</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#referenceoperators">References</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archives.html#charactersets">Character Sets</a>
|
||||
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="serialization"><a target="detail" href="serialization.html">Class Serialization</a>
|
||||
<dd><div id="serialization_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#member">Member Function</a>
|
||||
<dt><img style="display:none" src="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" s'c="dot.gif"><a target="detail" href="serialization.html#splitting">Splitting <code>serialize</code> into <code>save/load</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="pointers"><a target="detail" href="serialization.html#pointeroperators">Pointers</a>
|
||||
<dd><div id="pointers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Free">Free Function</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Base">Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Versioning">Versioning</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Splitting">Splitting <code>serialize</code> into <code>save/load</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#const"><code>const</code> Members</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#constructors">Non-Default Constructors</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="derivedpointers"><a target="detail" href="serialization.html#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#templates">Templates</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="traits"><a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
<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#templates">Template Serialization Traits</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="wrappers"><a target="detail" href="wrappers.html">Serialization Wrappers</a>
|
||||
<dd><div id="wrappers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#binaryobjects">Binary Objects</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#strong_type"><code style="white-space: normal">strong_type</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#composition">Composition</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#Implementations">Serialization Implementations Included in the Library</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="special"><a target="detail" href="special.html">Special Considerations</a>
|
||||
<dd><div id="special_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="derivedpointers"><a target="detail" href="special.html#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dd><div id="derivedpointers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="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="special.html#registration">Registration</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#instantiation">Instantiation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#selectivetracking">Selective Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#runtimecasting">Runtime Casting</a>
|
||||
</dl></div></dd>
|
||||
</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="dot.gif"><a target="detail" href="special.html#objecttracking">Object Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#classinfo">Class Information</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
<dd><div id="portability_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#numerics">Numerics</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#traits">Traits</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#binary_archives">Binary Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#xml_archives">XML Archives</a>
|
||||
<dt><img style="display:none" src="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_parse_error"><code>xml_archive_parse_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_mismatch"><code>xml_archive_tag_mismatch</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exception_safety.html">Exception Safety</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
|
||||
<dd><div id="archive_reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#implementation">Implementation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#usage">Usage</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#testing">Testing</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#polymorphic">Polymorphic Archives</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="implementation"><a target="detail" href="implementation.html">Implementation Notes</a>
|
||||
<dd><div id="implementation_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#functiontemplateordering">Partial Function Template Ordering</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#charencoding">Character Encoding</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#partialtemplatespecialization">Partial Template Specialization</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="othercompilerissues"><a target="detail" href="implementation.html#othercompilerissues">Specific Compiler/Library Issues</a>
|
||||
<div id="othercompilerissues_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.x</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#vc71">Visual C++ 7.1</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc70">Visual C++ 7.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc6">Visual C++ 6.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland564">Borland 5.64</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland551">Borland 5.51</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#dinkumware">Dinkumware Library</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#serializationdeclarations">Serialization Declarations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#serializationimplementations">Serialization Implementations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveimplementations">Archive Implementations</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="plus.gif" id="libraryimplementation"><a target="detail" href="headers.html#libraryimplementation">Files Which Implement the Library</a>
|
||||
<div id="libraryimplementation_detail"><dl class="page-index">
|
||||
<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>
|
||||
<dt><img style="display:none" src="plus.gif" id="wrappers"><a target="detail" href="wrappers.html">Serialization Wrappers</a>
|
||||
<dd><div id="wrappers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#binaryobjects">Binary Objects</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#arrays">Arrays</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#strong_type"><code style="white-space: normal">strong_type</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#collection_size_type">Collection Sizes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="wrappers.html#composition">Composition</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="serialization.html#models">Models - Serialization Implementations Included in the Library</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="special"><a target="detail" 'ref="special.html">Special Considerations</a>
|
||||
<dd><div id="special_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#objecttracking">Object Tracking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#classinfo">Class Information</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#helpersupport">Helper Support</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="portability"><a target="detail" href="special.html#portability">Archive Portability</a>
|
||||
<dd><div id="portability_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#numerics">Numerics</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#traits">Traits</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#binary_archives">Binary Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#xml_archives">XML Archives</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#export">Exporting Class Serialization</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#static_libraries">Static Libraries and Serialization</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#dlls">DLLS - Serialization and Runtime Linking</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#plugins">Plugins</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#multi_threading">Multi-Threading</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="special.html#optimizations">Optimzations</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="exceptions"><a target="detail" href="exceptions.html">Archive Exceptions</a>
|
||||
<dd><div id="exceptions_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_class"><code>unregistered_class</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_signature"><code>invalid_signature</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unsupported_version"><code>unsupported_version</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#pointer_conflict"><code>pointer_conflict</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#incompatible_native_format"><code>incompatible_format</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#array_size_too_short"><code>array_size_too_short</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#stream_error"><code>stream_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#invalid_class_name"><code>invalid_class_name</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#unregistered_cast"><code>unregistered_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_parsing_error"><code>xml_archive_parsing_error</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_mismatch"><code>xml_archive_tag_mismatch</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exceptions.html#xml_archive_tag_name_error"><code>xml_archive_tag_name_error</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="exception_safety.html">Exception Safety</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="archive_reference"><a target="detail" href="archive_reference.html">Archive Class Reference</a>
|
||||
<dd><div id="archive_reference_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="archive_reference.html#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>
|
||||
<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="pimpl.html">PIMPL</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="miscellaneous">Miscellaneous
|
||||
<dd><div id="miscellaneous_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html">utf-8 code_cvt</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="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>
|
||||
<dd><div id="othercompilerissues_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc3x">GCC 3.X,4.X</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#gcc295">GCC 2.95</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#intel80">Intel 8.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc80">Visual C++ 8.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc71">Visual C++ 7.1</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc70">Visual C++ 7.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#vc6">Visual C++ 6.0</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#borland">Borland 5.64 and 5.51</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#comeau">Comeau 4.3.3</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#codewarrior">Code Warrior 8.3</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#tru64">TRU64</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#dinkumware">Dinkumware Library</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="implementation.html#stlport">STLPort 4.5.3</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="headers"><a target="detail" href="headers.html">Code Structure</a>
|
||||
<dd><div id="headers_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="userincludes"><a target="detail" href="headers.html#userincludes">Files Included by User Programs</a>
|
||||
<dd><div id="userincludes_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveimplementations">Archive Implementations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#serializationdeclarations">Serialization Declarations</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#serializationimplementations">Serialization Implementations</a>
|
||||
</dl></div>
|
||||
<dt><img style="display:none" src="plus.gif" id="libraryimplementation"><a target="detail" href="headers.html#libraryimplementation">Files Which Implement the Library</a>
|
||||
<dd><div id="libraryimplementation_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archivedevelopment">Archive Development</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#archiveinternals">Archive Internals</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#codemodules">Archive Library Code Modules</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="headers.html#dataflowiterators">Dataflow Iterators</a>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="case_studies">Case Studies
|
||||
<dd><div id="case_studies_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr.html">Template serialization - <code>shared_ptr<class T></code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="shared_ptr2.html"><code>shared_ptr<class T></code>Revisited</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="pimpl.html">PIMPL</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="private_base.html">Private Base Classes</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="simple_log.html">A Simple Logging Archive Class</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="derivation.html">Derivation from an Existing Archive Class</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="plus.gif" id="otherclasses">Other Classes
|
||||
<dd><div id="otherclasses_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="plus.gif" id="extended_type_info"><a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
<dd><div id="extended_type_info_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#motivation">Motivation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#runtime">Runtime Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#requirements">Requirements</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="extended_type_info.html#models">Models</a>
|
||||
</dl></div></dd>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="void_cast.html"><code>void_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="codecvt.html"><code>utf8_codecvt_facet</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="strong_typedef.html"><code>BOOST_STRONG_TYPEDEF</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="state_saver.html"><code>state_saver</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="dataflow.html">Dataflow Iterators</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="smart_cast.html"><code>smart_cast</code></a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="static_warning.html"><code>BOOST_STATIC_WARNING</code></a>
|
||||
<dt><img style="display:none" src="plus.gif" id="singleton"><a target="detail" href="singleton.html"><code>singleton</code></a>
|
||||
<dd><div id="singleton_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#motivation">Motivation</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#features">Features</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#classinterface">Class Interface</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#requirements">Requirements</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#examples">Examples</a>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="singleton.html#multithreading">Multi-Threading</a>
|
||||
</dl></div></dd>
|
||||
</dl></div></dd>
|
||||
<!--
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="configuration.html">Configuration Information</a></dt>
|
||||
<!--
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="configuration.html">Configuration Information</a></dt>
|
||||
-->
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="faq.html">Tips and Tricks</a>
|
||||
<dt><img style="display:none" src="plus.gif" id="rationale"><a target="detail" href="rationale.html">Rationale</a></dt>
|
||||
<dd><div id="rationale_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#serialization">The term "serialization" is preferred to "persistence"</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#archives">Archives are not streams</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
|
||||
</dl></div></dd>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="todo"><a target="detail" href="todo.html">To Do</a></dt>
|
||||
<dd><div id="todo_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#portablebinaryarchive">Portable Binary Archive</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#performancetesting">Performance Testing and Profiling</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#backversioning">Back Versioning</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="todo.html#nortti">Environments without RTTI</a></dt>
|
||||
|
||||
<dt><img style="display:none" src="plus.gif" id="newcasestudies"><a target="detail" href="new_case_studies.html">Proposed Case Studies</a></dt>
|
||||
<dd><div id="newcasestudies_detail"><dl class="page-index">
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#functionobject">Serializing a Function Object</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archiveadaptor">Archive Adaptors</a></dt>
|
||||
<dt><img style="display:none" src="dot.gif"><a target="detail" href="new_case_studies.html#archivehelper">Archive Helpers</a></dt>
|
||||
</dl></div></dd>
|
||||
|
||||
</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="rationale.html">Rationale</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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Dataflow Iterators</title>
|
||||
@@ -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,12 +110,12 @@ 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"
|
||||
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(
|
||||
@@ -124,7 +124,7 @@ std::copy(
|
||||
ostream_iterator<char>(os)
|
||||
);
|
||||
</code></pre>
|
||||
This macro is defined in <a target="pfto" href="../../../boost/serialization/pfto.hpp"><boost/serialization/pfto.hpp></a>.
|
||||
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>
|
||||
@@ -195,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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Definitions</title>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<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>
|
||||
@@ -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,27 +70,20 @@ 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>;
|
||||
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>Note the usage of PFTO.</i> Some compilers fail to provide support for
|
||||
partial function template ordering. The serialization library works around this by
|
||||
using <a target="detail" href="implementation.html#functiontemplateordering">
|
||||
<b>P</b>artial <b>F</b>unction <b>T</b>emplate <b>O</b>rdering</a> in several places.
|
||||
This is done
|
||||
in several places, including the archive classes themselves.
|
||||
<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>
|
||||
@@ -106,13 +93,13 @@ that the following equivalent works on more compilers.
|
||||
// default fall through for any types not specified here
|
||||
template<class T>
|
||||
void save(const T & t){
|
||||
xml_oarchive_impl<derived_t>::save(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
|
||||
@@ -120,34 +107,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
|
||||
|
||||
|
Before Width: | Height: | Size: 846 B After Width: | Height: | Size: 838 B |
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Reference</title>
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Archive Exceptions</title>
|
||||
@@ -29,26 +29,20 @@ 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>
|
||||
</dl>
|
||||
|
||||
Archive operators can throw a <code style="white-space: normal">boost::archive_exception</code>
|
||||
object which can be caught by an application program. These exceptions are defined
|
||||
in the files <a target="archive_exception_hpp" href="../../../boost/archive/archive_exception.hpp">
|
||||
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>.
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace archive {
|
||||
@@ -57,7 +51,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 +60,12 @@ 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
|
||||
invalid_class_name, // class name greater than the maximum permitted.
|
||||
// most likely a corrupted archive or an attempt
|
||||
// to insert virus via buffer overrun method.
|
||||
unregistered_cast, // base - derived relationship not registered with
|
||||
// void_cast_register
|
||||
unsupported_class_version, // type saved with a version # greater than the
|
||||
// one used by the program. This indicates that the proggram
|
||||
// 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
|
||||
stream_error // i/o error on stream
|
||||
} exception_code;
|
||||
exception_code code;
|
||||
archive_exception(exception_code c) : code(c) {}
|
||||
@@ -94,12 +77,24 @@ class xml_archive_exception : public virtual archive_exception
|
||||
public:
|
||||
typedef enum {
|
||||
xml_archive_parsing_error, // archive doesn't contain expected data
|
||||
xml_archive_tag_mismatch, // start/end tag in archive doesn't match program
|
||||
xml_archive_tag_name_error // tag name contains invalid characters
|
||||
|
||||
xml_archive_tag_mismatch // start/end tag in archive doesn't match program
|
||||
} exception_code;
|
||||
xml_archive_exception(exception_code c){}
|
||||
virtual const char *what( ) const throw();
|
||||
virtual const char *what( ) const throw( )
|
||||
{
|
||||
const char *msg;
|
||||
switch(code){
|
||||
case xml_archive_parsing_error:
|
||||
msg = "unrecognized XML syntax";
|
||||
break;
|
||||
case xml_archive_tag_mismatch:
|
||||
msg = "XML start/end tag mismatch";
|
||||
break;
|
||||
default:
|
||||
archive_exception::what();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
} // archive
|
||||
@@ -109,7 +104,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 +113,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,14 +124,6 @@ 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>
|
||||
@@ -179,16 +166,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 occured during stream input or ouput. Aside from the common
|
||||
situations such as a corrupted or truncated input file, there are
|
||||
several less obvious ones that sometimes occur.
|
||||
<p>
|
||||
This includes
|
||||
<h3><a name="stream_error"><code style="white-space: normal">stream_error</code></a></h3>
|
||||
An error has occured durring stream input or ouput. This includes
|
||||
an attempt to read past the end of the file. Text files need a terminating
|
||||
new line character at the end of the file which is appended when the
|
||||
archive destructor is invoked. Be sure that an output archive on a stream
|
||||
@@ -215,17 +194,10 @@ std::vector<V> v;
|
||||
ia >> v;
|
||||
}
|
||||
</code></pre>
|
||||
<p>
|
||||
Another one is the passing of uninitialized data. In general, the behavior
|
||||
of the serialization library when passed uninitialized data is undefined.
|
||||
If it can be detected, it will invoke an assertion in debug builds.
|
||||
Otherwise, depending on the type of archive, it may pass through without
|
||||
incident or it may result in an archive with unexpected data in it.
|
||||
This, in turn, can result in the throwing of this exception.
|
||||
|
||||
<h3><a name="invalid_class_name"><code style="white-space: normal">invalid_class_name</code></a></h3>
|
||||
Class name length greater than the maximum permitted. Most likely cause is a corrupted
|
||||
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
|
||||
@@ -233,15 +205,10 @@ at runtime, a collection of legitimate conversions is maintained by the system.
|
||||
Normally this collection is maintained without any explicit action
|
||||
on the part of the user of the library. However, there are special cases
|
||||
where this might have to be done explicitly and could be overlooked. This
|
||||
is described in <a href="serialization.html#runtimecasting">Runtime Casting</a>.
|
||||
is described in <a href="special.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 +217,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,14 +226,9 @@ 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 he start or end tag of and XML element doesn't match
|
||||
the name specified for the object in the program.
|
||||
|
||||
<h3><a name="xml_archive_tag_name_error"><code style="white-space: normal">xml_archive_tag_name_error</code></a></h3>
|
||||
This exception will be thrown if the tag name contains invalid characters. Valid characters
|
||||
for an XML tag are: upper and lower case letters, digits, and the following punctuation: .(period),
|
||||
_(underscore), :(colon), and -(hyphen).
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -1,418 +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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - extended_type_info</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">extended_type_info</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#motivation">Motivation</a>
|
||||
<dt><a href="#runtime">Runtime Interface</a>
|
||||
<dt><a href="#requirements">Requirements</a>
|
||||
<dt><a href="#models">Models</a>
|
||||
<dt><a href="#example">Example</a>
|
||||
</dl>
|
||||
|
||||
<h3><a name="motivation">Motivation</a></h3>
|
||||
The serialization library needs a system like
|
||||
<code style="white-space: normal">type_info/typeid()</code> to perform
|
||||
the following functions
|
||||
<ol>
|
||||
<li>
|
||||
given a pointer to a type T discover the true type pointed to.
|
||||
<li>
|
||||
given an "external" key - determine what type of object to create.
|
||||
</ol>
|
||||
<h3>The problem with <code style="white-space: normal">std::type_info</code></h3>
|
||||
<ul>
|
||||
<li>
|
||||
The main function we require - <code style="white-space: normal">std::typeid()</code>
|
||||
is not available in all environments. Support for this function depends upon
|
||||
runtime typing(RTTI) support from the compiler. This may be non-existent
|
||||
or not enabled for reasons such as a percieved inefficiency.
|
||||
<li>
|
||||
<code style="white-space: normal">std::type_info</code> includes a string
|
||||
containing type name. This would seem to satisfy 2) above.
|
||||
But the format of this string is not consistent accross compilers, libraries,
|
||||
and operating systems. This makes it unusable for support of portable archives.
|
||||
<li>
|
||||
Even if the type name string could somehow be made portable, there is no
|
||||
guarantee that class headers would be included in the same namespace accross
|
||||
different applications. In fact, including different headers in different
|
||||
namespaces is an accepted method used to avoid namespace conflicts.
|
||||
Thus the namespace::class_name can't be used as a key.
|
||||
<li>
|
||||
There exists the possibility that different classes use different type id
|
||||
mechanisms. The class header might include this information. If we want to
|
||||
import class headers accross applications, it's convenient that the type id
|
||||
mechanism support inter-operability accross different type id systems.
|
||||
</ul>
|
||||
<h3>Features</h3>
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
extended_type_info</a></code> is an implementation
|
||||
of <code style="white-space: normal">std::type_info</code> functionality with the
|
||||
following features:
|
||||
<ul>
|
||||
<li>
|
||||
Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">extended_type_info</a></code> records - one for each type
|
||||
serialized.
|
||||
<li>
|
||||
permits association of an arbitrary string key with a type. Often this key would
|
||||
be the class name - but it doesn't have to be. This key is referred to as
|
||||
a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe.
|
||||
Typically this GUID would be in header files and be used to match type accross
|
||||
applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string
|
||||
key with any known type. We'll refer to these types as "exported types"
|
||||
<li>
|
||||
permits the "mixing" of type info systems. For example, one class might use
|
||||
<code style="white-space: normal">typeid()</code> to find the external identifier
|
||||
of a class while another might not.
|
||||
</ul>
|
||||
|
||||
Exported types are maintained in a global table so that given a string key, the
|
||||
corresponding type can be found. This facility is used by the serialization library
|
||||
in order to construct types serialized through a base class pointer.
|
||||
|
||||
<h3><a name="runtime">Runtime Interface</a></h3>
|
||||
<pre><code">
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
class extended_type_info
|
||||
{
|
||||
protected:
|
||||
// this class can't be used as is. It's just the
|
||||
// common functionality for all type_info replacement
|
||||
// systems. Hence, make these protected
|
||||
extended_type_info(
|
||||
const unsigned int type_info_key,
|
||||
const char * key
|
||||
);
|
||||
~extended_type_info();
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
public:
|
||||
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;
|
||||
static const extended_type_info * find(const char *key);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
<p>
|
||||
Generally, there will be one and only one
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance created for each type. However, this is enforced only at the executable
|
||||
module level. That is, if a program includes some shared libraries or DLLS,
|
||||
there may be more than one instance of this class correponding to a particular type.
|
||||
For this reason the comparison functions below can't just compare the addresses of
|
||||
this instance but rather must be programmed to compare the actual information
|
||||
the instances contain.
|
||||
<dl>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
extended_type_info(unsigned int type_info_key, const char *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.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void key_register();
|
||||
void key_unregister();
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This system maintains a global table which relates
|
||||
external strings to
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
This table is used when loading pointers to objects serialized
|
||||
through a base class pointer. In this case, the archive
|
||||
contains a string which is looked up in this table to
|
||||
determine which <code style="white-space: normal">extended_type_info</code>
|
||||
to use for creating a new object.
|
||||
<p>
|
||||
These functions are called by constructors and
|
||||
destructors of classes which implement
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
to add and remove entries from this table.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
const char *get_key() const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Retrieves the key for <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
instance. If no key has been associated with the instance, then a NULL is returned.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
bool operator<(const extended_type_info & rhs) const;
|
||||
bool operator==(const extended_type_info & rhs) const;
|
||||
bool operator!=(const extended_type_info & rhs) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
These functions are used to compare
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
objects. They impose a strict total ordering on all
|
||||
<code style="white-space: normal">extended_type_info</code> records.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void * construct(unsigned int count = 0, ...) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Construct a new instance of the type to which this
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
record corresponds. This function takes a variable list of up to 4 arguments
|
||||
of any type. These arguments are passed to the type's constructor
|
||||
at runtime. In order to use the facility,
|
||||
one must declare a type sequence for the constructor arguments.
|
||||
Arguments for this function must match in number and type
|
||||
with those specified when the type was exported.
|
||||
This function permits one to create instances of
|
||||
any exported type given only the exported <strong>GUID</strong> assigned
|
||||
with BOOST_CLASS_EXPORT.
|
||||
If these types are defined in DLLS or shared libraries loaded at runtime,
|
||||
these constructors can be called until the module is unloaded.
|
||||
Such modules are referred to as <b>plugins</b>.
|
||||
</code>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
virtual void destroy(void const * const p) const;
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance created by the above constructor.
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
static const extended_type_info * find(const char *key);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
Given a character string key or <strong>GUID</strong>, return the address of a
|
||||
corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
object.
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="requirements">Requirements for an Implementation</a></h3>
|
||||
In order to be used by the serialization library, an implementation of
|
||||
<code style="white-space: normal">extended_type_info</code>,
|
||||
(referred to as ETI here), must be derived from
|
||||
<a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
|
||||
<code style="white-space: normal">
|
||||
extended_type_info
|
||||
</code>
|
||||
</a>
|
||||
and also implement the following:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
template<class ETI>
|
||||
const extended_type_info *
|
||||
ETI::get_derived_extended_type_info(const T & t) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Return a pointer to the
|
||||
<code style="white-space: normal">extended_type_info</code>
|
||||
instance that corresponds to
|
||||
the "true type" of the type T. The "true type" is the lowest type in the
|
||||
hierarchy of classes. The type T can always be cast to the "true type" with
|
||||
a static cast. Implementation of this function will vary among type id systems
|
||||
and sometimes will make presumptions about the type T than can be identified
|
||||
with a particular <code style="white-space: normal">extended_type_info</code> implementation.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Compare this instance to another one using the same
|
||||
<code style="white-space: normal">extended_type_info</code> implementation.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual bool ETI::is_equal(const extended_type_info &rhs) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Compare this instance to another one using the same
|
||||
<code style="white-space: normal">extended_type_info</code> implementation.
|
||||
Return <code style="white-space: normal">true</code> if the types referred
|
||||
to are the same. Otherwise return
|
||||
<code style="white-space: normal">false</code>
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
const char ETI::get_key() const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Retrieve the external key (aka GUID) for this class.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual void * construct(unsigned int count, ...) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Construct an instance of the corresponding type
|
||||
with the include argument list.
|
||||
</dd>
|
||||
|
||||
<dt><h4><code style="white-space: normal"><pre>
|
||||
virtual void * destroy(void const * const ptr ) const;
|
||||
</pre></code></h4></dt>
|
||||
<dd>
|
||||
Destroy an instance of this type. This calls the
|
||||
proper destructor and recovers allocated memory.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="models">Models</a></h3>
|
||||
The serialization library includes two distinct
|
||||
<code style="white-space: normal"><a target="extended_type_info.hpp" href="../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
|
||||
implementations.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
|
||||
extended_type_info_typeid</a></h4></code>is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled
|
||||
by the compiler.
|
||||
<p>
|
||||
<code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
|
||||
extended_type_info_no_rtti</a></h4></code>
|
||||
is implemented in a way that doesn't rely on the existence RTTI.
|
||||
Instead, it requires that all polymorphic types be explictly exported.
|
||||
In addition, if the export facility is to be used to serialize types
|
||||
through base class pointers, those types are required to implement
|
||||
a virtual function with the signature:
|
||||
|
||||
<code><pre>
|
||||
virtual const char * get_key();
|
||||
</pre></code>
|
||||
which returns a unique string the most derived object this class.
|
||||
This function must be virtual in order to implement the functionality required by
|
||||
<code style="white-space: normal">ETI::get_derived_extended_type_info</code>
|
||||
as described above.
|
||||
|
||||
<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>.
|
||||
|
||||
<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 type_info 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.
|
||||
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>
|
||||
@@ -7,45 +7,11 @@ 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=iso-8859-1">
|
||||
<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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Code Structure</title>
|
||||
@@ -29,9 +29,9 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dl class="page-index">
|
||||
<dt><a href="#userincludes">Files Included by User Programs</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#archiveimplementations">Archive Implementations</a>
|
||||
<dt><a href="#serializationdeclarations">Serialization Declarations</a>
|
||||
<dt><a href="#serializationimplementations">Serialization Implementations</a>
|
||||
<dt><a href="#archiveimplementations">Archive Implementations</a>
|
||||
</dl>
|
||||
<dt><a href="#libraryimplementation">Files Which Implement the Library</a>
|
||||
<dl class="page-index">
|
||||
@@ -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
|
||||
@@ -60,70 +60,6 @@ is included with the following declaration
|
||||
Using this library entails including headers listed in this section.
|
||||
It should not be necessary to explictly include any other header files.
|
||||
|
||||
<a name="archiveimplementations">
|
||||
<h4>Archive Implementations</h4>
|
||||
These header files contain declarations used to save and restore data to each type
|
||||
of archive. Include the archives according to the facilities the code module requires.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><a target="archive_exception" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_exception.hpp
|
||||
</a>
|
||||
<dd>Exceptions which might be invoked by the library.</dd>
|
||||
|
||||
<dt><a target="binary_iarchive" href="../../../boost/archive/binary_iarchive.hpp">
|
||||
boost/archive/binary_iarchive.hpp
|
||||
</a>
|
||||
<dd>native binary input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="binary_oarchive" href="../../../boost/archive/binary_oarchive.hpp">
|
||||
boost/archive/binary_oarchive.hpp
|
||||
</a>
|
||||
<dd>native binary output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_iarchive" href="../../../boost/archive/text_iarchive.hpp">
|
||||
boost/archive/text_iarchive.hpp
|
||||
</a>
|
||||
<dd>text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/text_oarchive.hpp">
|
||||
boost/archive/text_oarchive.hpp
|
||||
</a>
|
||||
<dd>text output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/text_wiarchive.hpp">
|
||||
boost/archive/text_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
|
||||
boost/archive/text_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used for saving.</dd>
|
||||
|
||||
<dt><a target="xml_iarchive" href="../../../boost/archive/xml_iarchive.hpp">
|
||||
boost/archive/xml_iarchive.hpp
|
||||
</a>
|
||||
<dd>xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/xml_oarchive.hpp">
|
||||
boost/archive/xml_oarchive.hpp
|
||||
</a>
|
||||
<dd>xml output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/xml_wiarchive.hpp">
|
||||
boost/archive/xml_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/xml_woarchive.hpp">
|
||||
boost/archive/xml_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml output archive used for saving.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<a name="serializationdeclarations">
|
||||
<h4>Serialization Declarations</h4>
|
||||
To specify how a type is serialized, one codes templates for serialization functions.
|
||||
@@ -161,14 +97,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>
|
||||
|
||||
@@ -207,7 +142,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
|
||||
|
||||
@@ -235,6 +170,70 @@ as templates for <code style="white-space: normal">boost::optional</code>,
|
||||
<code style="white-space: normal">boost::scoped_ptr</code>.
|
||||
Presumably, this list will expand with the passage of time.
|
||||
|
||||
<a name="archiveimplementations">
|
||||
<h4>Archive Implementations</h4>
|
||||
These header files contain declarations used to save and restore data to each type
|
||||
of archive. Include the archives according to the facilities the code module requires.
|
||||
|
||||
<dl/>
|
||||
|
||||
<dt><a target="archive_exception" href="../../../boost/archive/archive_exception.hpp">
|
||||
boost/archive/archive_exception.hpp
|
||||
</a>
|
||||
<dd>Exceptions which might be invoked by the library.</dd>
|
||||
|
||||
<dt><a target="binary_iarchive" href="../../../boost/archive/binary_iarchive.hpp">
|
||||
boost/archive/binary_iarchive.hpp
|
||||
</a>
|
||||
<dd>native binary input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="binary_oarchive" href="../../../boost/archive/binary_oarchive.hpp">
|
||||
boost/archive/binary_oarchive.hpp
|
||||
</a>
|
||||
<dd>native binary output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_iarchive" href="../../../boost/archive/text_iarchive.hpp">
|
||||
boost/archive/text_iarchive.hpp
|
||||
</a>
|
||||
<dd>text input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/text_oarchive.hpp">
|
||||
boost/archive/text_oarchive.hpp
|
||||
</a>
|
||||
<dd>text output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/text_wiarchive.hpp">
|
||||
boost/archive/text_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used forloading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/text_woarchive.hpp">
|
||||
boost/archive/text_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character text input archive used for saving.</dd>
|
||||
|
||||
<dt><a target="xml_iarchive" href="../../../boost/archive/xml_iarchive.hpp">
|
||||
boost/archive/xml_iarchive.hpp
|
||||
</a>
|
||||
<dd>xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_oarchive" href="../../../boost/archive/xml_oarchive.hpp">
|
||||
boost/archive/xml_oarchive.hpp
|
||||
</a>
|
||||
<dd>xml output archive used for saving.</dd>
|
||||
|
||||
<dt><a target="text_wiarchive" href="../../../boost/archive/xml_wiarchive.hpp">
|
||||
boost/archive/xml_wiarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml input archive used for loading.</dd>
|
||||
|
||||
<dt><a target="text_woarchive" href="../../../boost/archive/xml_woarchive.hpp">
|
||||
boost/archive/xml_woarchive.hpp
|
||||
</a>
|
||||
<dd>wide character xml output archive used for saving.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<a name="libraryimplementation">
|
||||
<h3>Files Which Implement the Library</h3>
|
||||
|
||||
@@ -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,10 +314,10 @@ 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 ingore any names attached to objects.
|
||||
<p>
|
||||
@@ -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 implemenations 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,7 +358,7 @@ 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
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - History</title>
|
||||
@@ -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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Implementation Notes</title>
|
||||
@@ -26,27 +26,104 @@ 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="#gcc">GCC 3.X</a>
|
||||
<dt><a href="#gcc">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="#comeau">Comeau 4.3.3</a>
|
||||
<dt><a href="#codewarrior9">Code Warrior 9.x</a>
|
||||
<dt><a href="#codewarrior">Code Warrior 8.3</a>
|
||||
<dt><a href="#tru64">TRU64</a>
|
||||
<dt><a href="#vc70">Visual C++ 7.0</a>
|
||||
<dt><a href="#vc6">Visual C++ 6.0</a>
|
||||
<dt><a href="#borland564">Borland 5.64</a>
|
||||
<dt><a href="#borland551">Borland 5.51 and earlier</a>
|
||||
<dt><a href="#dinkumware">Dinkumware Library</a>
|
||||
<dt><a href="#stlport">STLPort 4.5.3</a>
|
||||
</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 +144,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,161 +170,128 @@ 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</a></h4>
|
||||
GCC versions for Cygwin and MinGW fail to support wide character I/O.
|
||||
So all tests using wide char I/O fail. Note that if wide character I/O support
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<h4><a name="gcc295">GCC 2.95</a></h4>
|
||||
All of the above plus:<br>
|
||||
<ul>
|
||||
<li>GCC versions for Cygwin and MinGW fail to support wide character I/O.
|
||||
So all tests using wide char I/O fail. Note that if wide character I/O support
|
||||
is added with STLPort, all tests complete successfully.
|
||||
<li>This compiler generates long warning messages related to the usage of
|
||||
non virtual destructors in polymorphic classes. These warnings have been
|
||||
carefully considered and the code that generates these warning has been
|
||||
unchanged. In this case the warning should should be ignored as in certain
|
||||
usages of the library, making the destructors virtual could lead to problems.
|
||||
As an alternative, base class destructors have been made "protected" to
|
||||
address the concerns that motivate these warning messages. When building
|
||||
the serialization library and tests with bjam, these warnings are suppressed.
|
||||
When building one's own applications, these warnings can be suppressed by
|
||||
adding the following to the compiler command line:
|
||||
<pre><code>
|
||||
-Wno-non-virtual-dtor
|
||||
-Wno-ctor-dtor-privacy
|
||||
</code></pre>
|
||||
<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.
|
||||
</ul>
|
||||
<h4><a name="intel80">Intel C++ 8.0</a></h4>
|
||||
<h4><a name="Intel80">Intel C++ 8.0</a></h4>
|
||||
No known issues. All tests compile and run in debug and release modes.
|
||||
|
||||
<h4><a name="vc80">Visual C++ 8.0</a></h4>
|
||||
This compiler emits warnings for calls to functions from the standard
|
||||
library which are deemed security risks. The serialization depends upon
|
||||
making some of these calls so programs which use the serialization library
|
||||
will get warning messages. These messages can be suppressed from the command
|
||||
line by including the following switch:
|
||||
<pre><code>
|
||||
/wd4996
|
||||
</code></pre>
|
||||
|
||||
<h4><a name="vc71">Visual C++ 7.1</a></h4>
|
||||
Derivation from an archive class defined in a DLL as described in ... will not work.
|
||||
This is due to the way that VC++ handles templated code with __decl(dllexport) and
|
||||
__decl(dllimport) specifications. Basically, this compiler requires that all the
|
||||
instantiations have the same specification - even though they have different
|
||||
template arguments. The example <code style="white-space: normal">
|
||||
demo_portable_iarchive.cpp</code> would have to be reformulated as a library or dll
|
||||
similar to the pre-defined archives in order to function.
|
||||
<p>
|
||||
This compiler does not have RTTI or exception handling turned on by default. Although
|
||||
they are not strictly necessary to use the serialization package, the example and test
|
||||
programs presume that they are enabled. So be sure your command line or IDE settings
|
||||
enable these features if you want to build and run these programs.
|
||||
<p>
|
||||
This compiler can treat <code style="white-space: normal">wchar_t</code> as either
|
||||
a short integer or an intrinsic type.
|
||||
If <code style="white-space: normal">/Zc:wchar_t</code> is specified on the
|
||||
compile command line, <code style="white-space: normal">wchar_t</code> will be
|
||||
considered an intrinsic type - otherwise
|
||||
it will be treated as a synonym for a 16 bit integer. The library can be used
|
||||
either way - <strong>BUT</strong> - both the libray <strong>AND</strong> the application
|
||||
must be compiled with the same switch settings. Note that <code style="white-space: normal">BJAM</code>
|
||||
includes this switch by default. So if want to use the libraries that
|
||||
<code style="white-space: normal">BJAM</code> builds, you should include this switch
|
||||
when you compile your own applications.
|
||||
<h5>Using the Visual C++ IDE</h5>
|
||||
The library includes a VC++ 7.1 "Solution" - <code style="white-space: normal">BoostSerializationLibrary</code>
|
||||
along with a set of project files - one for each demo and test. Consider the following if you
|
||||
decide to use these configurations.
|
||||
No known issues. All tests compile and run in debug and release modes.
|
||||
<h4><a name="vc70">Visual C++ 7.0</a></h4>
|
||||
<ul>
|
||||
<li>The projects assume that the tests have been built with bjam using the default
|
||||
locations. This will result in a <code style="white-space: normal">bin</code> subdirectory
|
||||
within one's main boost directory. Below this there is a whole structure which maintains
|
||||
object and library files according to the type of build. The easiest way to build this is to
|
||||
invoke the runtest script which uses bjam (see below). If the libraries are not in these locations,
|
||||
the projects will have to be modified accordingly.
|
||||
<li>There are project configurations for all the combinations of build variants that boost
|
||||
supports. That is for release, debug, static, static multi-threading, etc..
|
||||
<li>If you want to use/debug the DLL versions of libraries and corresponding tests, alter
|
||||
the project file to define <code style="white-space: normal">BOOST_ALL_DYN_LINK=1</code>.
|
||||
Note that for the executables to run, the <code style="white-space: normal">PATH</code>
|
||||
environmental variable will have to include the directories that contain the DLL versions of
|
||||
the boost libraries.
|
||||
<li>If you have difficulties building your own projects and linking with the boost libraries,
|
||||
compare the project settings of your own projects with the ones here. VC sometimes requires
|
||||
consistent settings between projects and the libraries they use in order to link properly.
|
||||
In particular, check support for exceptions, runtime typing(RTTI), and intrinsic support for
|
||||
wide characters. The standard version of this library presumes that these facilities are
|
||||
enabled. Projects generated by the IDE wizard do not have these features enabled by default.
|
||||
<li>Frequently when trying to build a project or view project properties, one is presented with
|
||||
a message box with the message "unspecified error". This seems to occur when one changes the
|
||||
build configuration selection. It turns out this can be "fixed" by going to the "Build"
|
||||
menu item, selecting "Configuration Manager" and selecting a build configuration for the project
|
||||
you're working with.
|
||||
<li>To test that boost libraries are built correctly, one can build and test them the way we do.
|
||||
This entails:
|
||||
<ol>
|
||||
<li>downloading a copy of bjam.exe
|
||||
<li>building process_jam_log
|
||||
<li>building compiler_status
|
||||
<li>invoking runtest.bat
|
||||
</ol>
|
||||
This will build the serialization library and run the tests on your system. If there are more than a
|
||||
a couple of test failures, you likely won't be able to get your own projects working. If most of the
|
||||
tests pass, you can be confident that your own projects will work once you get your project settings
|
||||
in sync with those included here.
|
||||
<li>The "pimpl" demo fails to link. Cause and workaround for this is unknown
|
||||
<li>XML serialization only works with version 1.6x of spirit. In order to build and use this
|
||||
library with this compiler, one must use version 1.6x rather than the latest version
|
||||
shipped with boost. See <a href="release.html#Installation">Release Notes</a>.
|
||||
</ul>
|
||||
|
||||
<h4><a name="comeau">Comeau 4.3.3</a></h4>
|
||||
<h4><a name="vc6">Visual C++ 6.0</a></h4>
|
||||
all the above issues for Visual C++ 7.0 plus:
|
||||
<ul>
|
||||
<li>This compiler fails to make a DLL with export under windows.
|
||||
<li>The associated library - libcomo fails when using a codecvt facet.
|
||||
This generates a failure with all wide character archives.
|
||||
<li>the test_set fails by going into an infinite memory leak.
|
||||
<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="codewarrior9">Code Warrior 9.x</a></h4>
|
||||
<h4><a name="borland564">Borland 5.64</a></h4>
|
||||
<ul>
|
||||
<li>Some tests and demos fail - still under investigation
|
||||
<li><code style="white-space: normal">enum</code> data members cannot be serialized.
|
||||
Conversion to/from integers will work around the problem.
|
||||
<li>Default array serialization fails. Workaround this by doing it with a loop.
|
||||
<li>If class serialize functions are not accessable either by making them public or by
|
||||
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.
|
||||
</ul>
|
||||
|
||||
<h4><a name="codewarrior">Code Warrior 8.3</a></h4>
|
||||
all the above issues for Code Warrior 9.x plus:
|
||||
<h4><a name="borland551">Borland 5.51 and earlier</a></h4>
|
||||
All of the above issues for Borland 5.64 plus:
|
||||
<ul>
|
||||
<li>This compiler only supports templated streams with the static library version.
|
||||
<li>The above inhibits the build of DLL versions of the library.
|
||||
<li>Some demos fail - still under investigation
|
||||
<li>Most tests using Wide character XML files fail. This happens somewhere within the
|
||||
spirit library but we've been unable to track it further than this.
|
||||
<li>A couple of other tests fail.
|
||||
</ul>
|
||||
|
||||
<h4><a name="tru64">TRU64</a></h4>
|
||||
All tests and demos pass except for test_variant. Boost Variant doesn't function
|
||||
wih this compiler
|
||||
|
||||
<h4><a name="dinkumware">Dinkumware Library</a></h4>
|
||||
Several compilers, including Visual C++ 6.0, use an older dinkumware library.
|
||||
These platforms have several issues:
|
||||
<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
|
||||
files, one cannot depend on the "automatic" setting of local that archives implement. The
|
||||
stream local must be set explicitly on the stream before an archive is opened on it. The
|
||||
archive should be opened with the <code style="white-space: normal">no_codecvt</code> flag. Note this problem will
|
||||
occur on all compilers shipped with this library.
|
||||
<li>Other issues have been worked around in the file.
|
||||
<a href="../../../boost/archive/dinkumware.hpp" target="dinkumware_hpp">dinkumware.hpp</a>
|
||||
</ul>
|
||||
|
||||
<h4><a name="stlport">STLPort 4.5.3</a></h4>
|
||||
<ul>
|
||||
<li>when built to use the dynamic linking versions of the C++ runtime code (<runtime-link>dynamic)
|
||||
all tests fail to link. This is due to a missing symbol in the stlport library related
|
||||
to custom codecvt facets.
|
||||
<li>the test_set fails to run correctly. It seems the hashed set iterator doesn't
|
||||
implement the ++ operator correctly. This causes the test to fail by consuming all available
|
||||
memory. Given this, this test is commented out.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2004
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-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>
|
||||
|
||||
@@ -7,7 +7,7 @@ Revised 1 November, 2004
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<title>Serialization</title>
|
||||
</head>
|
||||
|
||||
|
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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Proposed Case Studies</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Proposed Case Studies</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#functionobject">Serializing a Function Object</a></dt>
|
||||
<dt><a href="#archiveadaptor">Archive Adaptors</a></dt>
|
||||
<dt><a href="#archivehelper">Archive Helpers</a></dt>
|
||||
</dl>
|
||||
|
||||
These are not part of the library itself, but rather
|
||||
techiques on how to use the library to address specific situations.
|
||||
|
||||
<h2><a name="functionobject"></a>Serializing a Function Object</h2>
|
||||
An example on how to serialize a function object. I believe this
|
||||
could be done by serializing 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>
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Overview</title>
|
||||
@@ -28,12 +28,15 @@ 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
|
||||
to a sequence of bytes. Such a system can be used to reconstitute
|
||||
an equivalent structure in another program context. Depending on
|
||||
the context, this might used implement object persistence, remote
|
||||
this context, this might used implement object persistence, remote
|
||||
parameter passing or other facility. In this system we use the term
|
||||
<strong>"archive"</strong> to refer to a specific rendering of this
|
||||
stream of bytes. This could be a file of binary data, text data,
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Boost Library Status Automatic Test</title>
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td><img border="0" src="../../../boost.png" width="277" height="86"></td>
|
||||
<td>
|
||||
<h1>Library Status: serialization</h1>
|
||||
<b>Run Date:</b> 02:42:48 UTC, Tuesday 10 June 2008
|
||||
</td>
|
||||
</table>
|
||||
<br>
|
||||
<table border="1" cellspacing="0" cellpadding="5">
|
||||
<tr>
|
||||
<td rowspan="2">Test Name</td>
|
||||
<td align="center" >gcc-3.4.4</td>
|
||||
</tr><tr>
|
||||
<td align="center" >profile</td>
|
||||
</tr><tr><td>peformance_array_binary_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_text_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_text_warchive</a></td><td align="right"><i>Missing</i></td></tr>
|
||||
<tr><td>peformance_array_xml_archive</a></td><td align="right">Pass <a href="profile1.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>peformance_array_xml_warchive</a></td><td align="right"><i>Missing</i></td></tr>
|
||||
<tr><td>performance_iterators</a></td><td align="right">Pass <a href="profile2.txt"><i>Profile</i></a></td></tr>
|
||||
<tr><td>performance_iterators_base64</a></td><td align="right">Pass <a href="profile3.txt"><i>Profile</i></a></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - PIMPL</title>
|
||||
@@ -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
|
||||
@@ -45,11 +45,8 @@ struct A {
|
||||
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>
|
||||
@@ -93,7 +90,7 @@ void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_ve
|
||||
</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
|
||||
|
||||
|
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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Private Base Classes</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Private Base Classes</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
In many cases, serialization of private or protected base classes present no special problems.
|
||||
This is true for both simple classes and types as well as pointers to those
|
||||
classes and types. That is, the following program compiles and runs exactly as one would expect.
|
||||
<pre><code>
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// test_private_base.cpp
|
||||
|
||||
// (C) Copyright 2009 Eric Moyer - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <fstream>
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::remove;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class Base {
|
||||
friend class boost::serialization::access;
|
||||
int m_i;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_NVP(m_i);
|
||||
}
|
||||
protected:
|
||||
bool equals(const Base &rhs) const {
|
||||
return m_i == rhs.m_i;
|
||||
}
|
||||
Base(int i = 0) :
|
||||
m_i(i)
|
||||
{}
|
||||
};
|
||||
|
||||
class Derived : private Base {
|
||||
friend class boost::serialization::access;
|
||||
private:
|
||||
Base & base_cast(){
|
||||
return static_cast<Base &>(*this);
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version){
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
|
||||
}
|
||||
public:
|
||||
bool operator==(const Derived &rhs) const {
|
||||
return Base::equals(static_cast<const Base &>(rhs));
|
||||
}
|
||||
Derived(int i = 0) :
|
||||
Base(i)
|
||||
{}
|
||||
};
|
||||
|
||||
int
|
||||
main( int /* argc */, char* /* argv */[] )
|
||||
{
|
||||
const char * testfile = boost::archive::tmpnam(NULL);
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived a(1), a1(2);
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("a", a);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("a", a1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
|
||||
if(a != a1)
|
||||
return 1;
|
||||
|
||||
// serialize Derived and Base
|
||||
Derived *ta = &a;
|
||||
Derived *ta1 = NULL;
|
||||
{
|
||||
test_ostream os(testfile);
|
||||
test_oarchive oa(os);
|
||||
oa << boost::serialization::make_nvp("ta", ta);
|
||||
}
|
||||
{
|
||||
test_istream is(testfile, TEST_STREAM_FLAGS);
|
||||
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
|
||||
ia >> boost::serialization::make_nvp("ta", ta1);
|
||||
}
|
||||
std::remove(testfile);
|
||||
if(*ta != *ta1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code></pre>
|
||||
Difficulties start to occur when the base class is made polymorphic by the designation
|
||||
of one or more functions as "virtual". If a class is polymorphic, the library
|
||||
presumes that one will want the ability to serialize a derived class through
|
||||
a pointer to the base class. Included in the macro
|
||||
<code>
|
||||
BOOST_SERIALIZATION_BASE_OBJECT_NVP
|
||||
</code>
|
||||
is code which links derived and base class definitions in tables used to serialize
|
||||
derived classes through pointers to a polymorphinc 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()
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Seriealization - Rationale</title>
|
||||
@@ -49,7 +49,7 @@ streams even though they have similar syntax rules.
|
||||
<ul>
|
||||
<li>Archive classes are not kinds of streams though they
|
||||
are implemented in terms of streams. This
|
||||
distinction is addressed in <a href="bibliography.html#5">[5]</a> item number 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
|
||||
@@ -108,7 +108,7 @@ pointers never before loaded/saved. This is addressed with the <code style="whi
|
||||
and/or <code style="white-space: normal">export</code> facilities described in the reference.
|
||||
In effect, <code style="white-space: normal">export</code> generates a portable equivalent to
|
||||
<code style="white-space: normal">typeid</code> information.
|
||||
|
||||
</p>
|
||||
<!--
|
||||
<h2><a name="footnotes"></a>Footnotes</h2>
|
||||
<dl>
|
||||
|
||||
@@ -1,42 +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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization of Classes</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Serializable Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="archives.html">Archive Concepts</a>
|
||||
<dt><a href="serialization.html">Serializable Concept</a>
|
||||
<dt><a href="special.html">Special Considerations</a>
|
||||
<dt><a href="archive_reference.html">Archive Class Reference</a>
|
||||
<dt><a href="implementation.html">Implementation Notes</a>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,289 +7,73 @@ 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">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<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="#Platforms">Platforms</a></dt>
|
||||
<dt><a href="#recent_improvements">Differences from Draft #20</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.
|
||||
This is the Boost 1.32 Serialization Library.
|
||||
There are currently no known bugs. However, due to compiler/library quirks and or
|
||||
bugs, some tests fail.
|
||||
<h2><a name="requirements"></a>Requirements</h2>
|
||||
This library requires Boost version 1.32 or later. Depending on the compiler used,
|
||||
It may also require spirit 1.6x which is not part of the standard boost distribution.
|
||||
<p>
|
||||
Changes have been made to archive classes included with the library. Users who
|
||||
have used these a guide to making their own archive classes will find that
|
||||
these will likely no longer compile. This can be remedied by making the
|
||||
following changes in the code which instantiates these archive classes.
|
||||
</p>
|
||||
Old Code:<br>
|
||||
<code><pre>
|
||||
...
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_pointer_iserializer<text_iarchive> ;
|
||||
</pre></code>should be replaced with this new code: <code><pre>
|
||||
#include <boost/archive/impl/archive_serializer_map.ipp>
|
||||
...
|
||||
template class detail::archive_serializer_map<naked_text_iarchive> ;
|
||||
...
|
||||
template class detail::archive_serializer_map<text_iarchive> ;
|
||||
</pre></code>
|
||||
<!--
|
||||
<p>
|
||||
The serialization library uses the boost spirit package to load XML archives.
|
||||
The serialization library requires 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.
|
||||
If you are using one of these compilers, you may download a version
|
||||
older compilers - specificallly MSVC 6, Borland and GCC < 3.0.
|
||||
If you are using one of these two compilers, you may download a version
|
||||
of spirit 1.6 <a href="http://spirit.sourceforge.net/index.php?doc=download/index.html">here</a>.
|
||||
To use this downloaded version rather than the one included with boost,
|
||||
set an environmental variable SPIRIT_ROOT to be equal to the root
|
||||
directory where the downloaded copy of spirit has been placed. E. G.
|
||||
<pre><code>
|
||||
set SPIRIT_ROOT=c:/spirit16
|
||||
set SPIRIT_ROOT=c:/spirit161
|
||||
</code></pre>
|
||||
If you're not using bjam and the Jamfile to build the library, be sure that
|
||||
If you're not using bjam and the jamfile to build the library, be sure that
|
||||
the directory which contains the version of spirit you plan to use is placed
|
||||
at the front of the list of include paths.
|
||||
-->
|
||||
<h2><a name="differences_1_39"></a>Differences from Boost 1.39</h2>
|
||||
|
||||
<h2><a name="recent_improvements"></a>Differences from Draft #20</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.
|
||||
</ul>
|
||||
<h2><a name="differences_1_33"></a>Differences from Boost 1.33</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Native Binary archives use the <code style="white-space: normal">std::streambuf</code>
|
||||
interface. This should result in noticeably faster execution in many cases.
|
||||
</ul>
|
||||
<h2><a name="differences_1_32"></a>Differences from Boost 1.32</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Dynamic Linking Library (DLLs and shared libraries) for platforms which support
|
||||
them. See <a href="../../../more/getting_started/windows.html#auto-linking">Automatic
|
||||
Linking on Windows</a>.
|
||||
<li>
|
||||
Implementation of auto-link for compilers which can support this.
|
||||
<li>
|
||||
Better support for <em>Argument Dependent Lookup</em>
|
||||
and two-phase lookup. This results in simpler rules regarding the placing of
|
||||
serialization specializations namespaces.
|
||||
<li>
|
||||
Enhanced documentation to help explain usage of the above.
|
||||
<li>
|
||||
Adjustments to improve support for less conformant compilers.
|
||||
<li>
|
||||
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>Support for <em>Argument Dependent Looup</em> for serialization override invocations.
|
||||
<li>Enhanced documentation to help explain usage of the above.
|
||||
<li>Adjustments to improve support for less conformant compilers.
|
||||
<li>A few bug fixes.
|
||||
</ul>
|
||||
|
||||
<h2><a name="todo"></a>Pending issues</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Rvalues cannot be serialized. It would be possible to implement this for
|
||||
untracked types, but this has not been done.
|
||||
<li>
|
||||
Pointers to pointers cannot currently be serialized
|
||||
<li>
|
||||
It's possible that <code style="white-space: normal">std::string</code> and <code style="white-space: normal">
|
||||
std::wstring</code>
|
||||
contain characters such as '\0' and -1 (EOF) which cannot be rendered in text
|
||||
and XML archives without an escape mechanism. Currently there is no such escape
|
||||
mechanism implemented.
|
||||
<li>
|
||||
A subtle error in the implementation of serializaton of <code style="white-space: normal">
|
||||
std::map</code> is fixed in this version. Unfortunately, the fix breaks
|
||||
serialization of <code style="white-space: normal">std::map</code>
|
||||
for those compilers which do not support partial template specialization. Also,
|
||||
types which contain pointers or tracked types might not work correctly.
|
||||
<li>
|
||||
Serialization of virtual base classes relies upon RTTI. It will fail when used on
|
||||
systems which don't have RTTI enabled.
|
||||
<li>Compile, and test on more platforms
|
||||
<li>implement <code>is_virtual_base<T></code> to automatically
|
||||
eliminate redundancy in virtual base class serialization.
|
||||
<li>currently can't serialize through a pointer an object a of class
|
||||
that implements its own <code style="white-space: normal">new/delete</code> operators.
|
||||
</ul>
|
||||
<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>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization of Classes</title>
|
||||
@@ -20,115 +20,58 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">Serializable Concept</h2>
|
||||
<h2 align="center">Class Serialization</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#primitiveoperators">Primitive Types</a>
|
||||
<dt><a href="#classoperators">Class Types</a>
|
||||
<dt><a href="#member">Member Function</a>
|
||||
<dt><a href="#Free">Free Function</a>
|
||||
<dt><a href="#Base">Base Classes</a>
|
||||
<dt><a href="#Versioning">Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
|
||||
<code style="white-space: normal">save/load</code></a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#member">Member Function</a>
|
||||
<dt><a href="#free">Free Function</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#namespaces">Namespaces for Free Function Overrides</a>
|
||||
</dl>
|
||||
<dt><a href="#classmembers">Class Members</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#base">Base Classes</a>
|
||||
<dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
|
||||
<dt><a href="#templates">Templates</a>
|
||||
</dl>
|
||||
<dt><a href="#versioning">Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
|
||||
<code style="white-space: normal">save/load</code></a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#splittingmemberfunctions">Member Functions</a>
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
</dl>
|
||||
<dt><a href="#splittingmemberfunctions">Member Functions</a>
|
||||
<dt><a href="#splittingfreefunctions">Free Functions</a>
|
||||
</dl>
|
||||
<dt><a href="#pointeroperators">Pointers</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#constructors">Non-Default Constructors</a>
|
||||
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#registration">Registration</a>
|
||||
<dt><a href="#export">Export</a>
|
||||
<dt><a href="#instantiation">Instantiation</a>
|
||||
<dt><a href="#selectivetracking">Selective Tracking</a>
|
||||
<dt><a href="#runtimecasting">Runtime Casting</a>
|
||||
</dl>
|
||||
</dl>
|
||||
<dt><a href="#references">References</a>
|
||||
<dt><a href="#arrays">Arrays</a>
|
||||
<dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
|
||||
<dt><a href="#constructors">Non-Default Constructors</a>
|
||||
<dt><a href="#referencemembers">Reference Members</a>
|
||||
<dt><a href="#templates">Templates</a>
|
||||
<dt><a href="traits.html">Class Serialization Traits</a>
|
||||
<dt><a href="wrappers.html">Serialization Wrappers</a>
|
||||
<dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
|
||||
<dt><a href="#implementations">Serialization Implementations Included in the Library</a>
|
||||
</dl>
|
||||
|
||||
A type <code style="white-space: normal">T</code> is <strong>Serializable</strong>
|
||||
if and only if one of the following is true:
|
||||
<ul>
|
||||
<li>it is a primitive type.<br>
|
||||
By <i>primitive type</i> we mean a C++ built-in type and <i>ONLY</i>
|
||||
a C++ built-in type. Arithmetic (including characters), bool, enum are primitive types.
|
||||
Below in <a target="detail" href="traits.html#Traits">serialization traits</a>,
|
||||
we define a "primitive" implementation level in a different way for a
|
||||
different purpose. This can be a source of confusion.
|
||||
<li>It is a class type and one of the following has been declared according
|
||||
to the prototypes detailed below:
|
||||
<ul>
|
||||
<li>a class member function <code style="white-space: normal">serialize</code>
|
||||
<li>a global function <code style="white-space: normal">serialize</code>
|
||||
</ul>
|
||||
<li>it is a pointer to a <strong>Serializable</strong> type.
|
||||
<li>it is a reference to a <strong>Serializable</strong> type.
|
||||
<li>it is a native C++ Array of <strong>Serializable</strong> type.
|
||||
</ul>
|
||||
|
||||
<h2><a name="primitiveoperators">Primitive Types</a></h2>
|
||||
The template operators &, <<, and >> of the archive classes
|
||||
described above will generate code to save/load all primitive types
|
||||
to/from an archive. This code will usually just add the
|
||||
data to the archive according to the archive format.
|
||||
For example, a four byte integer is appended to a binary archive
|
||||
as 4 binary bytes while a to a text archive it would be
|
||||
rendered as a space followed by a string representation.
|
||||
|
||||
<h2><a name="classoperators">Class Types</a></h2>
|
||||
For class/struct types, the template operators &, <<, and >>
|
||||
will generate code that invokes the programmer's serialization code for the
|
||||
particular data type. There is no default. An attempt to serialize a
|
||||
class/struct for which no serialization has been explicitly specified
|
||||
will result in a compile time error. The serialiation of a class can
|
||||
be specified via either a class member function or a free funcation which
|
||||
takes a reference to an instance of the class as an argument.
|
||||
|
||||
<h3><a name="member">Member Function</a></h3>
|
||||
The serialization library invokes the following code to save or load a class instance
|
||||
to/from and archive.
|
||||
The header file <a target="serialization_hpp"
|
||||
href="../../../boost/serialization/serialization.hpp">
|
||||
<code style="white-space: normal">serialization.hpp</code></a> contains public interface to the
|
||||
serialization library. This entire interface consists of three overridable
|
||||
function templates.
|
||||
<h4><a name="member">Member Function</a></h4>
|
||||
The first of these three templates is:
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
T & t,
|
||||
const unsigned int file_version
|
||||
const unsigned long int file_version
|
||||
){
|
||||
// invoke member function for class T
|
||||
t.serialize(ar, file_version);
|
||||
}
|
||||
</code></pre>
|
||||
That is, the default definition of template <code style="white-space: normal">serialize</code>
|
||||
presumes the existence of a class member function template of the following
|
||||
signature:
|
||||
It is invoked each time the data members of a class instance are to be saved to
|
||||
or loaded from an archive. The default definition of this template presumes the
|
||||
existence of a class member function template of the following signature:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version){
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
If such a member function is not declared, a compile time error will occur. In order
|
||||
If this is not declared, then a compile time error will occur. In order
|
||||
that the member function generated by this template can be called to
|
||||
append the data to an archive, it either must be public or the class must
|
||||
be made accessible to the serialization library by including:
|
||||
@@ -136,7 +79,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>
|
||||
@@ -165,7 +108,7 @@ template<class Archive>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
my_class & t,
|
||||
const unsigned int file_version
|
||||
const unsigned long int file_version
|
||||
){
|
||||
...
|
||||
}
|
||||
@@ -181,26 +124,8 @@ class to be serialized will be necessary even when using this "non-intrusive"
|
||||
method. In practice this may not be such a problem as many libraries
|
||||
(E.G. STL) expose enough information to permit implementation of non-intrusive
|
||||
serialization with absolutly no changes to the library.
|
||||
|
||||
<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
|
||||
For maximum portability, include any free functions templates and definitions in the
|
||||
namespace <code style="white-space: normal">boost::serialization</code>. If portability is not a concern and the
|
||||
compiler being used supports ADL (Argument Dependent Lookup) the free functions and
|
||||
templates can be in any of the following namespaces:
|
||||
<ul>
|
||||
<li><code style="white-space: normal">boost::serialization</code>
|
||||
<li>namespace of the archive class
|
||||
<li>namespace of the type being serialized
|
||||
</ul>
|
||||
<p>
|
||||
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
|
||||
<a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
|
||||
|
||||
<h3><a name="classmembers">Serialization of Class Members</a></h3>
|
||||
Regardless of which of the above methods is used, the body of the serialize function must
|
||||
Regardless of which method is used the body of the serialize function will
|
||||
specify the data to be saved/loaded by sequential application of the archive
|
||||
<code style="white-space: normal">operator &</code> to all the data members of the class.
|
||||
<pre><code>
|
||||
@@ -211,21 +136,76 @@ specify the data to be saved/loaded by sequential application of the archive
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h4><a name="base">Base Classes</a></h4>
|
||||
The header file
|
||||
<a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
|
||||
base_object.hpp
|
||||
</a>
|
||||
includes the template:
|
||||
<h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
|
||||
The question arises as to which <code>namespace</code> free serialization functions should be part of.
|
||||
<p>
|
||||
The options for this depend on:
|
||||
<ul>
|
||||
<li>Whether or not the compiler implements Argument Dependent Lookup.
|
||||
<li>whether or not the compiler implements Two Phase Lookup
|
||||
<li>whether or not the type to be serialized is a dependent type.
|
||||
</ul>
|
||||
according to the following table:
|
||||
<p>
|
||||
<table border>
|
||||
<tr><th align="right">ADL</th><th align="right">Two Phase<br>Lookup</th><th align="right">Dependent<br>Type T?</th><th>Namespace permitted</th></tr>
|
||||
<tr><td align="right">no<td align="right">no<td align="right">-<td><code>boost::serialization</tr>
|
||||
<tr><td align="right">no<td align="right">yes<td align="right">-<td>no compilers do this</tr>
|
||||
<tr><td align="right">yes<td align="right">no<td align="right">-<td><code>boost::serialzation</code><br><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
<tr><td align="right">yes<td align="right">yes<td align="right">no<td><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
<tr><td align="right">yes<td align="right">yes<td align="right">yes<td><code>boost::serialization<br><code>namespace of T<br><code>namespace of Archive</code></tr>
|
||||
</table>
|
||||
<p>
|
||||
To deal with this while maintaining portability, the test programs use the following
|
||||
before specifying free function overloads:
|
||||
<pre><code>
|
||||
template<class Base, class Derived>
|
||||
Base & base_object(Derived &d);
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace boost { namespace serialization {
|
||||
#endif
|
||||
</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.
|
||||
So for a class of <strong>Serializable</strong> type
|
||||
<code style="white-space: normal">T</code> the base class state should be
|
||||
serialized like this:
|
||||
which works for all compilers.
|
||||
<p>
|
||||
|
||||
From Vandervoorde and Josuttis book
|
||||
"C++ Templates - A Complete Guide"<a href="bibliography.html#14">[14]</a>
|
||||
page 509:
|
||||
<blockquote>
|
||||
<strong>dependant name</strong><br>
|
||||
A name the meaning of which depends on a template parameter.
|
||||
For example, A<T>::x is a dependant name when A or T is a template parameter.
|
||||
The name of a function in a function call is also dependant if any of the arguments in the call
|
||||
has a type that depends on a template parameter.
|
||||
For example, f in f((T*)0) is dependent if T is a template parameter.
|
||||
The name of a template parameter is not considered dependent, however.
|
||||
</blockquote>
|
||||
|
||||
and page 515:
|
||||
<blockquote>
|
||||
<strong>two-phase lookup</strong><br>
|
||||
The name lookup mechanism used for names in templates. The "two phases" are
|
||||
(1) the phase during which a template definition is first encountered by a compiler, and
|
||||
(2) the instantiation of a template. <i>Nondependant names</i> are looked up only in the first phase,
|
||||
but during this first phase <i>nondepdendent</i> base class are not considered.
|
||||
<i>Dependant</i> names with a scope qualifier(::) are looked up only in the second phase.
|
||||
Dependant names without a scop qualifier may be looked up in both places, but in the
|
||||
second phase only argument-dependant lookup is performed.
|
||||
</blockquote>
|
||||
|
||||
In this library, the file <code style="white-space: normal">serialization.hpp</code>,
|
||||
which calls the serialization override,
|
||||
is included by including any archive classes. This would suggest that all serialization
|
||||
overrides could be in any of the three possible namespaces if the serialization code is
|
||||
included before the archives. However, this is not always possible. Our implementation
|
||||
of "export" functionality requires just the opposite.
|
||||
|
||||
<p>
|
||||
This is consided inelegant to say the least. Hopefully, this may be improved in the future.
|
||||
|
||||
<h3><a name="Base">Base Classes</a></h3>
|
||||
If the class to be serialized is derived from another class, its data
|
||||
should be serialized with the following syntax:
|
||||
<pre><code>
|
||||
{
|
||||
// invoke serialization of the base class
|
||||
@@ -235,76 +215,13 @@ serialized like this:
|
||||
ar & member2;
|
||||
}
|
||||
</code></pre>
|
||||
Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
|
||||
This might seem to work but may fail to invoke code necessary for
|
||||
proper serialization.
|
||||
<p>
|
||||
Note that this is <strong>NOT</strong> the same as calling the <code style="white-space: normal">serialize</code>
|
||||
function of the base class. This might seem to work but will circumvent
|
||||
certain code used for tracking of objects, and registering base-derived
|
||||
relationships and other bookkeeping that is required for the serialization
|
||||
system to function as designed. For this reason, all <code style="white-space: normal">serialize</code>
|
||||
member functions should be <code style="white-space: normal">private</code>.
|
||||
|
||||
<h4><a name="const"><code style="white-space: normal">const</code> Members</a></h4>
|
||||
Saving <code style="white-space: normal">const</code> members to an archive
|
||||
requires no special considerations.
|
||||
Loading <code style="white-space: normal">const</code> members can be addressed by using a
|
||||
<code style="white-space: normal">const_cast</code>:
|
||||
<pre><code>
|
||||
ar & const_cast<T &>(t);
|
||||
</code></pre>
|
||||
Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
|
||||
keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
|
||||
is constructed and not changed thereafter. However, this may
|
||||
be most appropriate in many cases. Ultimately, it comes down to
|
||||
the question about what <code style="white-space: normal">const</code> means in the context
|
||||
of serialization.
|
||||
|
||||
<h4><a name="templates"></a>Templates</h4>
|
||||
Implementation of serialization for templates is exactly the same process
|
||||
as for normal classes and requires no additional considerations. Among
|
||||
other things, this implies that serialization of compositions of templates
|
||||
are automatically generated when required if serialization of the
|
||||
component templates is defined. For example, this library includes
|
||||
definition of serialization for <code style="white-space: normal">boost::shared_ptr<T></code> and for
|
||||
<code style="white-space: normal">std::list<T></code>. If I have defined serialization for my own
|
||||
class <code style="white-space: normal">my_t</code>, then serialization for
|
||||
<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
|
||||
for use.
|
||||
<p>
|
||||
For an example that shows how this idea might be implemented for your own
|
||||
class templates, see
|
||||
<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
|
||||
demo_auto_ptr.cpp</a>.
|
||||
This shows how non-intrusive serialization
|
||||
for the template <code style="white-space: normal">auto_ptr</code> from the standard library
|
||||
can be implemented.
|
||||
<p>
|
||||
A somewhat trickier addition of serialization to a standard template
|
||||
can be found in the example
|
||||
<a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
|
||||
shared_ptr.hpp
|
||||
</a>
|
||||
<!--
|
||||
Only the most minimal change to
|
||||
<code>shared_count.hpp</code>
|
||||
(to gain access to some private members) was necessary to achieve this.
|
||||
This should demonstrate how easy it is to non-intrusively
|
||||
implement serialization to any data type or template.
|
||||
-->
|
||||
<p>
|
||||
In the specification of serialization for templates, its common
|
||||
to split <code style="white-space: normal">serialize</code>
|
||||
into a <code style="white-space: normal">load/save</code> pair.
|
||||
Note that the convenience macro described
|
||||
<a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
|
||||
isn't helpful in these cases as the number and kind of
|
||||
template class arguments won't match those used when splitting
|
||||
<code style="white-space: normal">serialize</code> for a simple class. Use the override
|
||||
syntax instead.
|
||||
|
||||
<h3><a name="versioning">Versioning</a></h3>
|
||||
<h3><a name="Versioning">Versioning</a></h3>
|
||||
It will eventually occur that class definitions change after archives have
|
||||
been created. When a class instance is saved, the current version
|
||||
in included in the class information stored in the archive. When the class instance
|
||||
@@ -330,8 +247,7 @@ The current version of the class is assigned as a
|
||||
ar & member3;
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
|
||||
<h3><a name="Splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
|
||||
There are times when it is inconvenient to use the same
|
||||
template for both save and load functions. For example, this might occur if versioning
|
||||
gets complex.
|
||||
@@ -434,86 +350,32 @@ 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>
|
||||
Also note that <code style="white-space: normal">BOOST_SERIALIZATION_SPLIT_FREE</code>
|
||||
must be used outside of any namespace.
|
||||
|
||||
<h2><a name="pointeroperators">Pointers</a></h2>
|
||||
A pointer to any class instance can be serialized with any of the archive
|
||||
save/load operators.
|
||||
<p>
|
||||
To properly save and restore an object through a pointer the
|
||||
following situations must be addressed:
|
||||
<ol>
|
||||
<li>If the same object is saved multiple times through different
|
||||
pointers, only one copy of the object need be saved.
|
||||
<li>If an object is loaded multiple times through different pointers,
|
||||
only one new object should be created and all returned pointers
|
||||
should point to it.
|
||||
<li>The system must detect the case where an object is first
|
||||
saved through a pointer then the object itself is saved.
|
||||
Without taking extra precautions, loading would result in the
|
||||
creation of multiple copies of the original object. This system detects
|
||||
this case when saving and throws an exception - see below.
|
||||
<li>An object of a derived class may be stored through a
|
||||
pointer to the base class. The true type of the object must
|
||||
be determined and saved. Upon restoration the correct type
|
||||
must be created and its address correctly cast to the base
|
||||
class. That is, polymorphic pointers have to be considered.
|
||||
<li>NULL pointers must be dectected when saved and restored
|
||||
to NULL when deserialized.
|
||||
</ol>
|
||||
|
||||
This serialization library addresses all of the above
|
||||
considerations. The process of saving and loading an object
|
||||
through a pointer is non-trivial. It can be summarized as
|
||||
follows:
|
||||
<p>Saving a pointer:
|
||||
<ol>
|
||||
<li>determine the true type of the object being pointed to.
|
||||
<li>write a special tag to the archive
|
||||
<li>if the object pointed to has not already been written
|
||||
to the archive, do so now
|
||||
</ol>
|
||||
Loading a pointer:
|
||||
<ol>
|
||||
<li>read a tag from the archive.
|
||||
<li>determine the type of object to be created
|
||||
<li>if the object has already been loaded, return its address.
|
||||
<li>otherwise, create a new instance of the object
|
||||
<li>read the data back in using the operators described above
|
||||
<li>return the address of the newly created object.
|
||||
</ol>
|
||||
|
||||
Given that class instances are saved/loaded to/from the archive
|
||||
only once, regardless of how many times they are serialized with
|
||||
the <code style="white-space: normal"><<</code>
|
||||
and <code style="white-space: normal">>></code> operators
|
||||
<ul>
|
||||
<li>Loading the same pointer object multiple times
|
||||
results in only one object being created, thereby replicating
|
||||
the original pointer configuration.
|
||||
<li>Structures, such as collections of polymorphic pointers,
|
||||
are handled with no special effort on the part of users of this library.
|
||||
</ul>
|
||||
Serialization of pointers of derived types through a pointer to the
|
||||
base class may require a little extra "help". Also, the programmer
|
||||
may desire to modify the process described above for his own reasons.
|
||||
For example, it might be desired to suppress the tracking of objects
|
||||
as it is known a priori that the application in question can never
|
||||
create duplicate objects. Serialization of pointers can be "fine tuned"
|
||||
via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
|
||||
as described in
|
||||
<a target="detail" href="special.html#derivedpointers">
|
||||
another section of this manual
|
||||
</a>
|
||||
<h3><a name="const"><code style="white-space: normal">const</code> Members</a></h3>
|
||||
Saving <code style="white-space: normal">const</code> members to an archive
|
||||
requires no special considerations.
|
||||
Loading <code style="white-space: normal">const</code> members can be addressed by using a
|
||||
<code style="white-space: normal">const_cast</code>:
|
||||
<pre><code>
|
||||
ar & const_cast<T &>(t);
|
||||
</code></pre>
|
||||
Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
|
||||
keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
|
||||
is constructed and not changed thereafter. However, this may
|
||||
be most appropriate in many cases. Ultimately, it comes down to
|
||||
the question about what <code style="white-space: normal">const</code> means in the context
|
||||
of serialization.
|
||||
|
||||
<h3><a name="constructors">Non-Default Constructors</a></h3>
|
||||
Serialization of pointers is implemented in the library with code
|
||||
similar to the following:
|
||||
The general procedure used for serialization of objects
|
||||
through a pointer has been described in a
|
||||
<a href="archives.html#pointeroperators">previous section</a>.
|
||||
This is implemented by code in the serialization library
|
||||
which is similar to the following:
|
||||
|
||||
<pre><code>
|
||||
// load data required for construction and invoke constructor in place
|
||||
template<class Archive, class T>
|
||||
@@ -536,18 +398,14 @@ will have to be overridden. Here is a simple example:
|
||||
class my_class {
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
const int m_attribute; // some immutable aspect of the instance
|
||||
int m_state; // mutable state of this instance
|
||||
int member;
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int file_version){
|
||||
ar & m_state;
|
||||
ar & member;
|
||||
}
|
||||
public:
|
||||
// no default construct guarentees that no invalid object
|
||||
// ever exists
|
||||
my_class(int attribute) :
|
||||
m_attribute(attribute),
|
||||
m_state(0)
|
||||
my_class(int m) :
|
||||
member(m)
|
||||
{}
|
||||
};
|
||||
</code></pre>
|
||||
@@ -556,271 +414,28 @@ the overrides would be:
|
||||
namespace boost { namespace serialization {
|
||||
template<class Archive>
|
||||
inline void save_construct_data(
|
||||
Archive & ar, const my_class * t, const unsigned int file_version
|
||||
Archive & ar, const my_class * t, const unsigned long int file_version
|
||||
){
|
||||
// save data required to construct instance
|
||||
ar << t->m_attribute;
|
||||
ar << t->member;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void load_construct_data(
|
||||
Archive & ar, my_class * t, const unsigned int file_version
|
||||
Archive & ar, my_class * t, const unsigned long int file_version
|
||||
){
|
||||
// retrieve data from archive required to construct new instance
|
||||
int attribute;
|
||||
ar >> attribute;
|
||||
int m;
|
||||
ar >> m;
|
||||
// invoke inplace constructor to initialize instance of my_class
|
||||
::new(t)my_class(attribute);
|
||||
::new(t)my_class(m);
|
||||
}
|
||||
}} // namespace ...
|
||||
</code></pre>
|
||||
In addition to the deserialization of pointers, these overrides are used
|
||||
in the deserialization of STL containers whose element type has no default
|
||||
constructor.
|
||||
|
||||
<h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
|
||||
<h4><a name="registration">Registration</a></h4>
|
||||
Consider the following:
|
||||
<pre><code>
|
||||
class base {
|
||||
...
|
||||
};
|
||||
class derived_one : public base {
|
||||
...
|
||||
};
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When saving <code style="white-space: normal">b</code> what kind of object should be saved?
|
||||
When loading <code style="white-space: normal">b</code> what kind of object should be created?
|
||||
Should it be an object of class <code style="white-space: normal">derived_one</code>,
|
||||
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
|
||||
<p>
|
||||
It turns out that the kind of object serialized depends upon whether the base class
|
||||
(<code style="white-space: normal">base</code> in this case) is polymophic or not.
|
||||
If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
|
||||
virtual functions, then an object of the type <code style="white-space: normal">base</code>
|
||||
will be serialized. Information in any derived classes will be lost. If this is what is desired
|
||||
(it usually isn't) then no other effort is required.
|
||||
<p>
|
||||
|
||||
If the base class is polymorphic, an object of the most derived type
|
||||
(<code style="white-space: normal">derived_one</code>
|
||||
or <code style="white-space: normal">derived_two</code>
|
||||
in this case) will be serialized. The question of which type of object is to be
|
||||
serialized is (almost) automatically handled by the library.
|
||||
<p>
|
||||
The system "registers" each class in an archive the first time an object of that
|
||||
class it is serialized and assigns a sequential number to it. Next time an
|
||||
object of that class is serialized in that same archive, this number is written
|
||||
in the archive. So every class is identified uniquely within the archive.
|
||||
When the archive is read back in, each new sequence number is re-associated with
|
||||
the class being read. Note that this implies that "registration" has to occur
|
||||
during both save and load so that the class-integer table built on load
|
||||
is identical to the class-integer table built on save. In fact, the key to
|
||||
whole serialization system is that things are always saved and loaded in
|
||||
the same sequence. This includes "registration".
|
||||
<p>
|
||||
Expanding our previous example:
|
||||
<pre><code>
|
||||
main(){
|
||||
derived_one d1;
|
||||
derived_two d2:
|
||||
...
|
||||
ar & d1;
|
||||
ar & d2;
|
||||
// A side effect of serialization of objects d1 and d2 is that
|
||||
// the classes derived_one and derived_two become known to the archive.
|
||||
// So subsequent serialization of those classes by base pointer works
|
||||
// without any special considerations.
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When <code style="white-space: normal">b</code> is read it is
|
||||
preceded by a unique (to the archive) class identifier which
|
||||
has previously been related to class <code style="white-space: normal">derived_one</code> or
|
||||
<code style="white-space: normal">derived_two</code>.
|
||||
<p>
|
||||
If a derived class has NOT been automatically "registered" as described
|
||||
above, an <a target="detail" href="exceptions.html#unregistered_class">
|
||||
<code style="white-space: normal">unregistered_class</code></a> exception
|
||||
will be thrown when serialization is invoked.
|
||||
<p>
|
||||
This can be addressed by registering the derived class explicitly. All archives are
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type();
|
||||
</code></pre>
|
||||
So our problem could just as well be addressed by writing:
|
||||
<pre><code>
|
||||
main(){
|
||||
...
|
||||
ar.template register_type<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Note that if the serialization function is split between save and load, both
|
||||
functions must include the registration. This is required to keep the save
|
||||
and corresponding load in syncronization.
|
||||
|
||||
<h4><a name="export">Export</a></h4>
|
||||
The above will work but may be inconvenient. We don't always know which derived
|
||||
classes we are going to serialize when we write the code to serialize through
|
||||
a base class pointer. Every time a new derived class is written we have to
|
||||
go back to all the places where the base class is serialized and update the
|
||||
code.
|
||||
<p>
|
||||
So we have another method:
|
||||
<pre><code>
|
||||
#include <boost/serialization/export.hpp>
|
||||
...
|
||||
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
|
||||
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
|
||||
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
...
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
|
||||
with a class. In the above example we've used a string rendering
|
||||
of the class name. If a object of such an "exported" class is serialized
|
||||
through a pointer and is otherwise unregistered, the "export" string is
|
||||
included in the archive. When the archive
|
||||
is later read, the string literal is used to find the class which
|
||||
should be created by the serialization library.
|
||||
This permits each class to be in a separate header file along with its
|
||||
string identifier. There is no need to maintain a separate "pre-registration"
|
||||
of derived classes that might be serialized. This method of
|
||||
registration is referred to as "key export". More information on this
|
||||
topic is found in the section Class Traits -
|
||||
<a target="detail" href="traits.html#export">Export Key</a>.
|
||||
<p>
|
||||
<h4><a name="instantiation">Instantiation</a></h4>
|
||||
Registration by means of any of the above methods fulfill another role
|
||||
whose importance might not be obvious. This system relies on templated
|
||||
functions of the form <code style="white-space: normal">template<class Archive, class T></code>.
|
||||
This means that serialization code must be instantiated for each
|
||||
combination of archive and data type that is serialized in the program.
|
||||
<p>
|
||||
Polymorphic pointers of derived classes may never be referred to
|
||||
explictly by the program so normally code to serialize such classes
|
||||
would never be instantiated. So in addition to including export key
|
||||
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
|
||||
instantiates the class serialization code for all archive classes used
|
||||
by the program.
|
||||
|
||||
<h4><a name="selectivetracking">Selective Tracking</a></h4>
|
||||
Whether or not an object is tracked is determined by its
|
||||
<a target="detail" href="traits.html#tracking">object tracking trait</a>.
|
||||
The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
|
||||
That is, track objects if and only if they are serialized through pointers anywhere
|
||||
in the program. Any objects that are "registered" by any of the above means are presumed
|
||||
to be serialized through pointers somewhere in the program and therefore
|
||||
would be tracked. In certain situations this could lead to an inefficiency.
|
||||
Suppose we have a class module used by multiple programs. Because
|
||||
some programs serializes polymorphic pointers to objects of this class, we
|
||||
<a target="detail" href="traits.html#export">export</a> a class
|
||||
identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
|
||||
class header. When this module is included by another program,
|
||||
objects of this class will always be tracked even though it
|
||||
may not be necessary. This situation could be addressed by using
|
||||
<a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
in those programs.
|
||||
<p>
|
||||
It could also occur that even though a program serializes through
|
||||
a pointer, we are more concerned with efficiency than avoiding the
|
||||
the possibility of creating duplicate objects. It could be
|
||||
that we happen to know that there will be no duplicates. It could
|
||||
also be that the creation of a few duplicates is benign and not
|
||||
worth avoiding given the runtime cost of tracking duplicates.
|
||||
Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
can be used.
|
||||
<h4><a name="runtimecasting">Runtime Casting</a></h4>
|
||||
In order to properly translate between base and derived pointers
|
||||
at runtime, the system requires each base/derived pair be found
|
||||
in a table. A side effect of serializing a base object with
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
is to ensure that the base/derived pair is added to the table
|
||||
before the <code style="white-space: normal">main</code> function is entered.
|
||||
This is very convenient and results in a clean syntax. The only
|
||||
problem is that it can occur where a derived class serialized
|
||||
through a pointer has no need to invoke the serialization of
|
||||
its base class. In such a case, there are two choices. The obvious
|
||||
one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
|
||||
and specify an empty function for the base class serialization.
|
||||
The alternative is to "register" the Base/Derived relationship
|
||||
explicitly by invoking the template
|
||||
<code style="white-space: normal">void_cast_register<Derived, Base>();</code>.
|
||||
Note that this usage of the term "register" is not related
|
||||
to its usage in the previous section. Here is an example of how this is done:
|
||||
<pre><code>
|
||||
#include <sstream>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class base {
|
||||
friend class boost::serialization::access;
|
||||
//...
|
||||
// only required when using method 1 below
|
||||
// no real serialization required - specify a vestigial one
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){}
|
||||
};
|
||||
|
||||
class derived : public base {
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
ar & boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<derived, base>(
|
||||
static_cast<derived *>(NULL),
|
||||
static_cast<base *>(NULL)
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
base *b;
|
||||
ar >> b;
|
||||
}
|
||||
</code></pre>
|
||||
<p>
|
||||
|
||||
In order for this template to be invoked in code compiled by non-conforming
|
||||
compilers, the following syntax may be used:
|
||||
<pre><code>
|
||||
boost::serialization::void_cast_register(
|
||||
static_cast<Derived *>(NULL),
|
||||
static_cast<Base *>(NULL)
|
||||
);
|
||||
</code></pre>
|
||||
For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
|
||||
|
||||
<h3><a name="references"></a>References</h3>
|
||||
<h3><a name="referencemembers"></a>Reference Members</h3>
|
||||
Classes that contain reference members will generally require
|
||||
non-default constructors as references can only be set when
|
||||
an instance is constructed. The example of the previous section
|
||||
@@ -878,11 +493,58 @@ inline void load_construct_data(
|
||||
}} // namespace ...
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="arrays"></a>Arrays</h3>
|
||||
If <code style="white-space: normal">T</code> is a serializable type,
|
||||
then any native C++ array of type T is a serializable type.
|
||||
That is, if <code style="white-space: normal">T</code>
|
||||
is a serializable type, then the following
|
||||
<h3><a name="templates"></a>Templates</h3>
|
||||
Implementation serialization for templates is exactly the same process
|
||||
as for normal classes and requires no additional considerations. Among
|
||||
other things, this implies that serialization of compositions of templates
|
||||
are automatically generateded when required if serialization of the
|
||||
component templates is defined. For example, this library includes
|
||||
definition of serialization for <code style="white-space: normal">boost::shared_ptr<T></code> and for
|
||||
<code style="white-space: normal">std::list<T></code>. If I have defined serialization for my own
|
||||
class <code style="white-space: normal">my_t</code>, then serialization for
|
||||
<code style="white-space: normal">std::list< boost::shared_ptr< my_t> ></code> is already available
|
||||
for use.
|
||||
<p>
|
||||
See for an example that shows how this idea might be implemented for your own
|
||||
class templates, see
|
||||
<a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
|
||||
demo_auto_ptr.cpp</a>.
|
||||
This shows how non-intrusive serialization
|
||||
for the template <code style="white-space: normal">auto_ptr</code> from the standard library
|
||||
can be implemented.
|
||||
<p>
|
||||
A somewhat trickier addition of serialization to a standard template
|
||||
can be found in the example
|
||||
<a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
|
||||
shared_ptr.hpp
|
||||
</a>
|
||||
<!--
|
||||
Only the most minimal change to
|
||||
<a href="../../../boost/serialization/shared_count.hpp" target="shared_count_hpp">
|
||||
shared_count.hpp</a>
|
||||
(to gain access to some private members) was necessary to achieve this.
|
||||
This should demonstrate how easy it is to non-intrusively
|
||||
implement serialization to any data type or template.
|
||||
-->
|
||||
<p>
|
||||
In the specification of serialization for templates, its common
|
||||
to split <code style="white-space: normal">serialize</code>
|
||||
into a <code style="white-space: normal">load/save</code> pair.
|
||||
Note that the convenience macro described
|
||||
<a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
|
||||
isn't helpful in these cases as the number and kind of
|
||||
template class arguments won't match those used when splitting
|
||||
<code style="white-space: normal">serialize</code> for a simple class. Use the override
|
||||
syntax instead.
|
||||
|
||||
<h2><a href="traits.html">Class Serialization Traits</a></h2>
|
||||
|
||||
<h2><a href="wrappers.html">Serialization Wrappers</a></h2>
|
||||
|
||||
|
||||
<h2><a name="implementations"></a>Serialization Implementations Included in the Library</h2>
|
||||
This library includes code to serialize C style arrays of other
|
||||
serializable types. That is, if T is a serializable type, then the following
|
||||
is automatically available and will function as expected:
|
||||
<pre><code>
|
||||
T t[4];
|
||||
@@ -890,12 +552,6 @@ ar << t;
|
||||
...
|
||||
ar >> t;
|
||||
</code></pre>
|
||||
|
||||
<h2><a href="traits.html">Class Serialization Traits</a></h2>
|
||||
|
||||
<h2><a href="wrappers.html">Serialization Wrappers</a></h2>
|
||||
|
||||
<h2><a name="models"></a>Models - Serialization Implementations Included in the Library</h2>
|
||||
The facilities described above are sufficient to implement
|
||||
serialization for all STL containers. In fact, this has been done
|
||||
and has been included in the library. For example, in order to use
|
||||
@@ -907,20 +563,9 @@ 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:
|
||||
<ul>
|
||||
<li>optional
|
||||
<li>variant
|
||||
<li>scoped_ptr
|
||||
<li>shared_ptr
|
||||
<li>auto_ptr (demo)
|
||||
</ul>
|
||||
Others are being added to the list so check the boost files section and headers for
|
||||
new implementations!
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Template serialization - shared_ptr</title>
|
||||
@@ -121,7 +121,7 @@ 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
|
||||
@@ -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>,
|
||||
@@ -193,11 +193,11 @@ base object serialization with:
|
||||
// register the relationship between each derived class
|
||||
// its polymorphic base
|
||||
void_cast_register<
|
||||
boost::detail::sp_counted_base_impl<P, D>
|
||||
boost::detail::sp_counted_base,
|
||||
boost::detail::sp_counted_base_impl<P, D>
|
||||
>();
|
||||
</code></pre>
|
||||
and we don't have to include a trival serializer for <code style="white-space: normal">sp_counted_base</code>.
|
||||
and we don't have to include a 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.
|
||||
@@ -212,16 +212,7 @@ this implementation are:
|
||||
<li>Exception handling hasn't been exhaustively considered.
|
||||
<li>Other issues yet to be discovered.
|
||||
</ul>
|
||||
One thing that has been considered is export of shared_ptr. The header which
|
||||
declares shared pointer serialization includes some special macros for exporting
|
||||
shared pointers:
|
||||
<code><pre>
|
||||
BOOST_SHARED_POINTER_EXPORT(T)
|
||||
BOOST_SHARED_POINTER_EXPORT_GUID(T, K)
|
||||
</pre></code>
|
||||
These are specialized 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>
|
||||
|
||||
@@ -1,103 +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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Template serialization - shared_ptr</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">shared_ptr<class T></code> Revisited</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
The previously described serialization of <code style="white-space: normal">shared_ptr</code>
|
||||
illustrates the straightforward way of serializing a moderately complicated class structure.
|
||||
Unfortunately, this way of doing it suffered from some undesirable features
|
||||
<ul>
|
||||
<li>It was dependent on the Boost implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
The <code style="white-space: normal">shared_ptr</code> interface has been included
|
||||
in <code style="white-space: normal">std::tr1</code> and may someday be included in the standard
|
||||
C++ library. An implementation which depends only on the public interface can be guaranteed to
|
||||
function with any other future implementation of <code style="white-space: normal">shared_ptr</code>.
|
||||
<li>It required extra macros for export.
|
||||
</ul>
|
||||
|
||||
<pre><code>
|
||||
template<class Archive, class T>
|
||||
inline void save(
|
||||
Archive & ar,
|
||||
const boost::shared_ptr<T> &t,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
const T * t_ptr = t.get();
|
||||
// just serialize the underlying raw pointer
|
||||
ar <<: boost::serialization::make_nvp("px", t_ptr);
|
||||
}
|
||||
|
||||
template<class Archive, class T>
|
||||
inline void load(
|
||||
Archive & ar,
|
||||
boost::shared_ptr<T> &t,
|
||||
const unsigned int file_version
|
||||
){
|
||||
T* r;
|
||||
// recover the underlying raw pointer
|
||||
ar >> boost::serialization::make_nvp("px", r);
|
||||
|
||||
// To Do - match up with other shared pointers which
|
||||
// use this same raw pointer.
|
||||
...
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
In principle, this is very much simpler than the original implementation. Completion of
|
||||
this code requires:
|
||||
|
||||
<ol>
|
||||
<li>Filling in the "To Do". This required making an extra map for
|
||||
<code style="white-space: normal">shared_ptr</code> instances.
|
||||
<li>A method for identifying pointers to the same objects from pointers to their base classes.
|
||||
<li>Backward compatibility with pointers serialized by the previous method. This exploits
|
||||
the serialization class versioning.
|
||||
<li>Proper handling of <code style="white-space: normal">weak_ptr</code>.
|
||||
</ol>
|
||||
|
||||
The result of this effort can be found in
|
||||
<a target = serialization_shared_ptr href="../../../boost/serialization/shared_ptr.hpp">
|
||||
<code style="white-space: normal">boost::serialization::shared_ptr.hpp</code>
|
||||
</a>
|
||||
<p>
|
||||
Note that if your code needs to read archives created under boost version 1.32, you will
|
||||
have to include the following
|
||||
|
||||
<pre><code>
|
||||
#include <boost/serialization/shared_ptr_132.hpp>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
</code></pre>
|
||||
rather than just
|
||||
<pre><code>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
</code></pre>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Derivation from an Existing Archive</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">A Simple Logging Archive Class</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
The purpose of this example is to help clarify the usage of the
|
||||
<a href="archives.html"><strong>Archive Concept</strong></a>
|
||||
so that one can implement his own archive classes.
|
||||
<a href="../example/simple_log_archive.hpp" target="simple_archive_hpp">
|
||||
<code>simple_log_archive.hpp</code></a> implements a simple but useful
|
||||
archive class. This class can be used to send any serializable types
|
||||
on an output text stream in a readable format. Usage of this facility
|
||||
is trivially easy:
|
||||
|
||||
<pre><code>
|
||||
#include "simple_log_archive.hpp"
|
||||
...
|
||||
// display the complete schedule
|
||||
simple_log_archive log(std::cout);
|
||||
log << schedule;
|
||||
</code></pre>
|
||||
|
||||
and it produces the following output
|
||||
|
||||
<pre><code>
|
||||
schedule
|
||||
count 6
|
||||
item
|
||||
first
|
||||
driver bob
|
||||
hour 6
|
||||
minute 24
|
||||
second ->
|
||||
stops
|
||||
count 3
|
||||
item ->
|
||||
latitude
|
||||
degrees 34
|
||||
minutes 135
|
||||
seconds 52.56
|
||||
longitude
|
||||
degrees 134
|
||||
minutes 22
|
||||
seconds 78.3
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
The complete example is <a href="../example/demo_simple_log.cpp" target="demo_simple_log_cpp">
|
||||
<code>demo_simple_log.cpp</code></a>. Look at
|
||||
<a href="archive_reference.html#trivial">Trivial Archive</a> to get a
|
||||
better understanding of how this works.
|
||||
|
||||
Also, note the following:
|
||||
<ul>
|
||||
<li>Only 160 lines of code.
|
||||
<li>Header only - linking with the serialization library not required.
|
||||
<li>Displays ALL <a href="serialization.html"><strong>Serializable</strong></a> types.
|
||||
<li>Lacks some features.
|
||||
<ul>
|
||||
<li>it will not display the data from the derived type given the pointer to a
|
||||
polymorphic base class. That is, only displays the information of the base class.
|
||||
To add that see the next example.
|
||||
<li>doesn't display information serialized as binary data
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2010.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - singleton</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code style="white-space: normal">singleton</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#motivation">Motivation</a>
|
||||
<dt><a href="#features">Features</a>
|
||||
<dt><a href="#classinterface">Class Interface</a>
|
||||
<dt><a href="#requirements">Requirements</a>
|
||||
<dt><a href="#example">Examples</a>
|
||||
<dt><a href="#multithreading">Multi-Threading</a>
|
||||
</dl>
|
||||
|
||||
<h3><a name="motivation">Motivation</a></h3>
|
||||
The serialization library relies on the existence of a number
|
||||
of static variables and tables to store information related
|
||||
to runtime types. Examples are tables which relate exported
|
||||
names to types and tables which relate base classes to derived
|
||||
classes. Construction, destruction and usage of these variables
|
||||
requires consideration of the following issues:
|
||||
<ul>
|
||||
<li>Some static data variable and constant entries refer to others.
|
||||
The sequence of initialization cannot be arbitrary but must be in proper
|
||||
sequence.</li>
|
||||
<li>A number of static variables aren't referred to explicitly and, without
|
||||
special precautions, will be stripped by most code optimizers</li>
|
||||
<li>Many of these variables are created by templates and special care must
|
||||
be taken to be sure that they are instantiated</li>
|
||||
<li>In a multi-threading system, its possible that these static variables
|
||||
will be accessed concurrently by separate threads. This would create a
|
||||
race condition with unpredictabe behavior</li>
|
||||
</ul>
|
||||
This singleton class addresses all of the above issues.
|
||||
|
||||
<h3><a name="features">Features</a></h3>
|
||||
This singleton implementation has the following features:
|
||||
<ul>
|
||||
<li>
|
||||
Any instance will be constructed before any attempt is made to access it.</li>
|
||||
<li>
|
||||
Any instance created with a template is 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 constructable.
|
||||
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 accesss is through the above static interface
|
||||
functions, common member functions of T become
|
||||
the functional equivalent of
|
||||
<code style="white-space: normal">static</code> functions.
|
||||
|
||||
<h3><a name="example">Examples</a></h3>
|
||||
There are at least two different ways to use this class template.
|
||||
Both are used in the serialization library.
|
||||
<p>
|
||||
The first way is illustrated by 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 progam. For programs compiled in release
|
||||
mode these functions have no effect.
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
@@ -33,9 +33,9 @@ operators:
|
||||
<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 polymophic 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>
|
||||
@@ -46,7 +46,7 @@ operators:
|
||||
<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,7 +121,7 @@ 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:
|
||||
@@ -134,14 +134,14 @@ Note that the above syntax doesn't include
|
||||
<pre><code>
|
||||
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)
|
||||
</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.
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Special Considerations</title>
|
||||
@@ -26,9 +26,15 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#registration">Registration</a>
|
||||
<dt><a href="#instantiation">Instantiation</a>
|
||||
<dt><a href="#selectivetracking">Selective Tracking</a>
|
||||
<dt><a href="#runtimecasting">Runtime Casting</a>
|
||||
</dl>
|
||||
<dt><a href="#objecttracking">Object Tracking</a>
|
||||
<dt><a href="#classinfo">Class Information</a>
|
||||
<dt><a href="#helpersupport">Helper Support</a>
|
||||
<dt><a href="#portability">Archive Portability</a>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#numerics">Numerics</a>
|
||||
@@ -36,25 +42,241 @@ 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>
|
||||
<dt><a href="exception_safety.html">Exception Safety</a>
|
||||
</dl>
|
||||
<h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
|
||||
<h4><a name="registration">Registration</a></h4>
|
||||
Consider the following:
|
||||
<pre><code>
|
||||
class base {
|
||||
...
|
||||
};
|
||||
class derived_one : public base {
|
||||
...
|
||||
};
|
||||
class derived_two : public base {
|
||||
...
|
||||
};
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
When loading <code style="white-space: normal">b</code> what kind of object should be created?
|
||||
An object of class <code style="white-space: normal">derived_one</code>,
|
||||
<code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
|
||||
<p>
|
||||
If this situation is not addressed by one of the methods described below,
|
||||
an <a target="detail" href="exceptions.html#unregistered_class">
|
||||
<code style="white-space: normal">unregistered_class</code></a> exception will be thrown when serialization is
|
||||
invoked.
|
||||
<p>Many times this situation is resolved automatically by the serialization
|
||||
library.
|
||||
<p>
|
||||
The system "registers" each class in an archive the first time an object of that
|
||||
class it is serialized and assigns a sequential number to it. Next time an
|
||||
object of that class is serialized in that same archive, this number is written
|
||||
in the archive. So every class is identified uniquely within the archive.
|
||||
When the archive is read back in, each new sequence number is re-associated with
|
||||
the class being read. Note that this implies that "registration" has to occur
|
||||
during both save and load so that the class-integer table built on load
|
||||
is identical to the class-integer table built on save. In fact, the key to
|
||||
whole serialization system is that things are always saved and loaded in
|
||||
the same sequence. This includes "registration"
|
||||
<p>
|
||||
In many situations the problem never comes up. Consider:
|
||||
<pre><code>
|
||||
main(){
|
||||
derived_one d1;
|
||||
derived_two d2:
|
||||
...
|
||||
ar >> d1;
|
||||
ar >> d2;
|
||||
// A side effect of serialization of objects d1 and d2 is that
|
||||
// the classes derived_one and derived_two become known to the archive.
|
||||
// So subsequent serialization of those classes by base pointer works
|
||||
// without any special considerations.
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Here, the problem doesn't present itself. When <code style="white-space: normal">b</code> is read it is
|
||||
preceded by a unique (to the archive) class identifier which
|
||||
has previously been related to class <code style="white-space: normal">derived_one</code> or
|
||||
<code style="white-space: normal">derived_two</code>.
|
||||
<p>
|
||||
If a derived class hasn't been automatically "registered" as described
|
||||
above, we have the option of registering it explicitly. All archives are
|
||||
derived from a base class which implements the following template:
|
||||
<pre><code>
|
||||
template<class T>
|
||||
register_type();
|
||||
</code></pre>
|
||||
So our problem could just as well be addressed by writing:
|
||||
<pre><code>
|
||||
main(){
|
||||
...
|
||||
ar.template register_type<derived_one>();
|
||||
ar.template register_type<derived_two>();
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
Note that if the serialization function is split between save and load, both
|
||||
functions must include the registration. This is required to keep the save
|
||||
and corresponding load in syncronization.
|
||||
<p>
|
||||
This will work but may be inconvenient. We don't always know which derived
|
||||
classes we are going to serialize when we write the code to serialize through
|
||||
a base class pointer. Every time a new derived class is written we have to
|
||||
go back to all the places where the base class is serialized and update the
|
||||
code.
|
||||
<p>
|
||||
So we have another method:
|
||||
<pre><code>
|
||||
#include <boost/serialization/export.hpp>
|
||||
...
|
||||
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
|
||||
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
|
||||
|
||||
main(){
|
||||
...
|
||||
base *b;
|
||||
ar & b;
|
||||
}
|
||||
</code></pre>
|
||||
The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
|
||||
with a class. In the above example we've used a string rendering
|
||||
of the class name. If a object of such an "exported" class is serialized
|
||||
through a pointer and is otherwise unregistered, the "export" string is
|
||||
included in the archive. When the archive
|
||||
is later read, the string literal is used to find the class which
|
||||
should be created by the serialization library.
|
||||
This permits each class to be in a separate header file along with its
|
||||
string identifier. There is no need to maintain a separate "pre-registration"
|
||||
of derived classes that might be serialized. This method of
|
||||
registration is referred to as "key export". More information on this
|
||||
topic is found in the section Class Traits -
|
||||
<a target="detail" href="traits.html#export">Export Key</a>.
|
||||
<p>
|
||||
<h4><a name="instantiation">Instantiation</a></h4>
|
||||
Registration by means of any of the above methods fulfill another role
|
||||
whose importance might not be obvious. This system relies on templated
|
||||
functions of the form <code style="white-space: normal">template<class Archive, class T></code>.
|
||||
This means that serialization code must be instantiated for each
|
||||
combination of archive and data type that is serialized in the program.
|
||||
<p>
|
||||
Polymorphic pointers of derived classes may never be referred to
|
||||
explictly by the program so normally code to serialize such classes
|
||||
would never be instantiated. So in addition to including export key
|
||||
strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
|
||||
instantiates the class serialization code for all archive classes used
|
||||
by the program.
|
||||
<p>
|
||||
In order to do this,
|
||||
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
|
||||
includes meta programming code to build a <code style="white-space: normal">mpl::list</code>
|
||||
of all the file types used by the module by checking for definition of the header
|
||||
inclusion guards.
|
||||
|
||||
Using this list,
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> will explicitly instantiate serialization
|
||||
code for all exported classes.
|
||||
For this implementaton to function, the header file
|
||||
<a href="../../../boost/serialization/export.hpp" target="export_hpp">export.hpp</a>
|
||||
has to come after all the archive header files. This is enforced
|
||||
by code at the end of the header file:
|
||||
<a href="../../../boost/archive/basic_archive.hpp" target="basic_archive_hpp">basic_archive.hpp</a>
|
||||
which will trip a STATIC_ASSERT if this requirement is violated.
|
||||
|
||||
<h4><a name="selectivetracking">Selective Tracking</a></h4>
|
||||
Whether or not an object is tracked is determined by its
|
||||
<a target="detail" href="traits.html#tracking">object tracking trait</a>.
|
||||
The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
|
||||
That is, track objects if and only if they are serialized through pointers anywhere
|
||||
in the program. Any objects that are "registered" by any of the above means are presumed
|
||||
to be serialized through pointers somewhere in the program and therefore
|
||||
would be tracked. In certain situations this could lead to an inefficiency.
|
||||
Suppose we have a class module used by multiple programs. Because
|
||||
some programs serializes polymorphic pointers to objects of this class, we
|
||||
<a target="detail" href="traits.html#export">export</a> a class
|
||||
identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
|
||||
class header. When this module is included by another program,
|
||||
objects of this class will always be tracked even though it
|
||||
may not be necessary. This situation could be addressed by using
|
||||
<a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
in those programs.
|
||||
<p>
|
||||
It could also occur that even though a program serializes through
|
||||
a pointer, we are more concerned with efficiency than avoiding the
|
||||
the possibility of creating duplicate objects. It could be
|
||||
that we happen to know that there will be no duplicates. It could
|
||||
also be that the creation of a few duplicates is benign and not
|
||||
worth avoiding given the runtime cost of tracking duplicates.
|
||||
Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
|
||||
can be used.
|
||||
<h4><a name="runtimecasting">Runtime Casting</a></h4>
|
||||
In order to properly translate between base and derived pointers
|
||||
at runtime, the system requires each base/derived pair be found
|
||||
in a table. A side effect of serializing a base object with
|
||||
<code style="white-space: normal">boost::serialization::base_object<Base>(Derived &)</code>
|
||||
is to ensure that the base/derived pair is added to the table
|
||||
before the <code style="white-space: normal">main</code> function is entered.
|
||||
This is very convenient and results in a clean syntax. The only
|
||||
problem is that it can occur where a derived class serialized
|
||||
through a pointer has no need to invoke the serialization of
|
||||
its base class. In such a case, there are two choices. The obvious
|
||||
one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
|
||||
and specify an empty function for the base class serialization.
|
||||
The alternative is to "register" the Base/Derived relationship
|
||||
explicitly by invoking the template
|
||||
<code style="white-space: normal">void_cast_register<Base, Derived>();</code>.
|
||||
Note that this usage of the term "register" is not related
|
||||
to its usage in the previous section. Here is an example of how this is done:
|
||||
<pre><code>
|
||||
#include <sstream>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
class base {
|
||||
friend class boost::serialization::access;
|
||||
//...
|
||||
// only required when using method 1 below
|
||||
// no real serialization required - specify a vestigial one
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){}
|
||||
};
|
||||
|
||||
class derived : public base {
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int file_version){
|
||||
// method 1 : invoke base class serialization
|
||||
boost::serialization::base_object<base>(*this);
|
||||
// method 2 : explicitly register base/derived relationship
|
||||
boost::serialization::void_cast_register<base, derived>();
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_CLASS_EXPORT_GUID(derived, "derived")
|
||||
|
||||
main(){
|
||||
//...
|
||||
std::stringstream ss;
|
||||
boost::archive::text_iarchive ar(ss);
|
||||
base *b;
|
||||
ar >> b;
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h3><a name="objecttracking">Object Tracking</a></h3>
|
||||
Depending on how the class is used and other factors, serialized objects
|
||||
may be tracked by memory address. This prevents the same object from being
|
||||
written to or read from an archive multiple times. These stored addresses
|
||||
can also be used to delete objects created during a loading process
|
||||
that has been interrupted by throwing of an exception.
|
||||
<p>
|
||||
This could cause problems in
|
||||
progams where the copies of different objects are saved from the same address.
|
||||
written to or read from an archive multiple times. This could cause problems in
|
||||
progams where the copies of different objects are serialized from the same address.
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
@@ -87,57 +309,25 @@ void save(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
}
|
||||
</code></pre>
|
||||
which will compile and run without problem.
|
||||
<p>
|
||||
The usage of <code style="white-space: normal">const</code> by the output archive operators
|
||||
will ensure that the process of serialization doesn't
|
||||
change the state of the objects being serialized. An attempt to do this
|
||||
would constitute augmentation of the concept of saving of state with
|
||||
some sort of non-obvious side effect. This would almost surely be a mistake
|
||||
and a likely source of very subtle bugs.
|
||||
<p>
|
||||
Unfortunately, implementation issues currently prevent the detection of this kind of
|
||||
error when the data item is wrapped as a name-value pair.
|
||||
<p>
|
||||
A similar problem can occur when different objects are loaded to an address
|
||||
which is different from the final location:
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void load(boost::basic_oarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
ar >> x;
|
||||
std::m_set.insert(x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
In this case, the address of <code>x</code> is the one that is tracked rather than
|
||||
the address of the new item added to the set. Left unaddressed
|
||||
this will break the features that depend on tracking such as loading an object through a pointer.
|
||||
Subtle bugs will be introduced into the program. This can be
|
||||
addressed by altering the above code thusly:
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void load(boost::basic_iarchive & ar, const unsigned int version) const
|
||||
{
|
||||
for(int i = 0; i < 10; ++i){
|
||||
A x;
|
||||
ar >> x;
|
||||
std::pair<std::set::const_iterator, bool> result;
|
||||
result = std::m_set.insert(x);
|
||||
ar.reset_object_address(& (*result.first), &x);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
This will adjust the tracking information to reflect the final resting place of
|
||||
the moved variable and thereby rectify the above problem.
|
||||
<p>
|
||||
If it is known a priori that no pointer
|
||||
and a likely source of very subtle bugs. As described
|
||||
<a target="detail" href="traits.html#tracking">above</a>,
|
||||
addresses of objects serialized as pointers are stored in memory to
|
||||
prevent saving/loading of duplicate objects. These stored addresses
|
||||
can also be used to delete objects created during a loading process
|
||||
that has been interrupted by throwing of an exception. By default, code
|
||||
to implement this tracking is instantiated if and only if an object of the class
|
||||
is serialized through a pointer. If it is known a priori that no pointer
|
||||
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 definition, 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
|
||||
@@ -155,97 +345,6 @@ redundant save/load operations.
|
||||
<pre><code>
|
||||
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 prinicple motivating case is that of shared_ptr. As instances
|
||||
are loaded, they have to be "matched up" with any other instances which have
|
||||
already been loaded. Thus, a table of previously loaded instances has to be
|
||||
maintained while the archive containing the shared_ptr instances is being loaded.
|
||||
Without maintaining such a table, the shared_ptr would be a serializable type.
|
||||
<p>
|
||||
To implement this facility, one declares a <i>helper object</i>
|
||||
associated to the current archive that can be used to store contextual
|
||||
information relevant to the particular type serialization algorithm.
|
||||
|
||||
<pre><code>
|
||||
template<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
|
||||
</code></pre>
|
||||
<code style="white-space: normal">get_helper<shared_ptr_serialization_helper>();</code>
|
||||
creates a helper object associated to the archive the first time it is invoked;
|
||||
subsequent invocations return a reference to the object created in the first
|
||||
place, so that <code style="white-space: normal">hlp</code> can effectively be
|
||||
used to store contextual information persisting through the serialization
|
||||
of different <code style="white-space: normal">complex_type</code> objects on
|
||||
the same archive.
|
||||
|
||||
<p>
|
||||
Helpers may be created for saving and loading archives.
|
||||
The same program might have several different helpers or the same helper instantiated
|
||||
separately from different parts of the program. This is what makes the helper_instance_id
|
||||
necessary. In principle it could be any unique integer. In practice it seems
|
||||
easiest to use the address of the serialization function which contains it. The
|
||||
above example uses this technique.
|
||||
|
||||
<h3><a name="classinfo">Class Information</a></h3>
|
||||
By default, for each class serialized, class information is written to the archive.
|
||||
This information includes version number, implementation level and tracking
|
||||
@@ -267,7 +366,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,26 +394,16 @@ 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>
|
||||
A special integral type is <code>std::size_t</code> which is a typedef
|
||||
of an integral types guaranteed to be large enough
|
||||
to hold the size of any collection, but its actual size can differ depending
|
||||
on the platform. The
|
||||
<a href="wrappers.html#collection_size_type"><code>collection_size_type</code></a>
|
||||
wrapper exists to enable a portable serialization of collection sizes by an archive.
|
||||
Recommended choices for a portable serialization of collection sizes are to
|
||||
use either 64-bit or variable length integer representation.
|
||||
|
||||
|
||||
<h4><a name="traits">Traits</a></h4>
|
||||
Another potential problem is illustrated by the following example:
|
||||
@@ -330,7 +419,7 @@ struct my_wrapper {
|
||||
class my_class {
|
||||
wchar_t a;
|
||||
short unsigned b;
|
||||
template<class Archive>
|
||||
template<<class Archive>
|
||||
Archive & serialize(Archive & ar, unsigned int version){
|
||||
ar & my_wrapper(a);
|
||||
ar & my_wrapper(b);
|
||||
@@ -387,288 +476,7 @@ not wrapped in a in a <a target="detail" href="wrappers.html#nvp">name-value pai
|
||||
be trapped at compile time. The system is implemented in such a way that for other archive classes,
|
||||
just the value portion of the data is serialized. The name portion is discarded during compilation.
|
||||
So by always using <a target="detail" href="wrappers.html#nvp">name-value pairs</a>, it will
|
||||
be guaranteed that all data can be serialized to all archive classes with maximum efficiency.
|
||||
|
||||
<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 dyanmic 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">Polymoprhic 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 catastophic error, the library traps ALL serializations through
|
||||
a pointer to a polymorphic class which are not exported or otherwise registered.
|
||||
So, in practice, be prepared to register or export all classes with one
|
||||
or more virtual functions which are serialized through a pointer.
|
||||
|
||||
<p>
|
||||
Note that the implementation of this functionality depends upon vendor
|
||||
specific extensions to the C++ language. So, there is no guaranteed portability
|
||||
of programs which use this facility. However, all C++ compilers which
|
||||
are tested with boost provide the required extensions. The library
|
||||
includes the extra declarations required by each of these compilers.
|
||||
It's reasonable to expect that future C++ compilers will support
|
||||
these extensions or something equivalent.
|
||||
|
||||
<h3><a name="static_libraries">Static Libraries and Serialization</a></h3>
|
||||
Code for serialization of data types can be saved in libraries
|
||||
just as it can for the rest of the type implementation.
|
||||
This works well, and can save a huge amount of compilation time.
|
||||
<ul>
|
||||
<li>Only compile serialization definitions in the library.
|
||||
<li>Explicitly instantiate serialization code for ALL
|
||||
archive classes you intend to use in the library.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
|
||||
in headers.
|
||||
<li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in definitions compiled in the library. For any particular type,
|
||||
there should be only one file which contains
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
for that type. This ensures that only one copy
|
||||
of serialization code will exist within the program. It avoids
|
||||
wasted space and the possibility of having different
|
||||
versions of the serialization code in the same program.
|
||||
Including
|
||||
<code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
|
||||
in multiple files could result in a failure
|
||||
to link due to duplicated symbols or the throwing
|
||||
of a runtime exception.
|
||||
<li> Code for serialization should be only in the library,
|
||||
<li>Familiarize yourself with the <b>PIMPL</b> idiom.
|
||||
</ul>
|
||||
This is illustrated by
|
||||
<a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl.cpp</code>
|
||||
</a>,
|
||||
<a href = "../example/demo_pimpl_A.cpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl_A.cpp</code>
|
||||
</a>
|
||||
and
|
||||
<a href = "../example/demo_pimpl_A.hpp" target="demo_pimpl">
|
||||
<code style="white-space: normal">demo_pimpl_A.hpp</code>
|
||||
</a>
|
||||
where implementation of serializaton is in a static library
|
||||
completely separate from the main program.
|
||||
|
||||
<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 serializaton is also completely separate
|
||||
from the main program but the code is loaded at runtime. In this
|
||||
example, this code is loaded automatically when the program which
|
||||
uses it starts up, but it could just as well be loaded and unloaded
|
||||
with an OS dependent API call.
|
||||
<p>
|
||||
Also included are
|
||||
<a href = "../test/test_dll_exported.cpp" target="test_dll_exported">
|
||||
<code style="white-space: normal">test_dll_exported.cpp</code>
|
||||
</a>,
|
||||
and
|
||||
<a href = "../test/polymorphic_derived2.cpp" target="polymorphic_derived2">
|
||||
<code style="white-space: normal">polymorphic_derived2.cpp</code>
|
||||
</a>
|
||||
which are similar to the above but include tests of the export
|
||||
and no_rtti facilities in the context of DLLS.
|
||||
<p>
|
||||
For best results, write your code to conform to the following
|
||||
guidelines:
|
||||
<ul>
|
||||
<li>Don't include <code>inline</code> code in classes used in DLLS.
|
||||
This will generate duplicate code in the DLLS and mainline. This
|
||||
needlessly duplicates code. Worse, it makes is possible for
|
||||
different versions of the same code to exist simultaneously. This
|
||||
type of error turns out to be excruciatingly difficult to debug.
|
||||
Finally, it opens the possibility that a module being referred to
|
||||
might be explictly unloaded which would (hopefully) result in
|
||||
a runtime error. This is another bug that is not always
|
||||
reproducible or easy to find. For class member templates use something like
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version);
|
||||
</code></pre>
|
||||
in the header, and
|
||||
|
||||
<pre><code>
|
||||
template<class Archive>
|
||||
void myclass::serialize(Archive & ar, const unsigned int version){
|
||||
...
|
||||
}
|
||||
|
||||
BOOST_CLASS_EXPORT_IMPLEMENT(my_class)
|
||||
|
||||
#include <boost/archive/text_oarchive>
|
||||
#include <boost/archive/text_iarchive>
|
||||
template myclass::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
|
||||
template myclass::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
|
||||
... // repeat for each archive class to be used.
|
||||
</code></pre>
|
||||
in the implementation file. This will result in generation of all code
|
||||
required in only one place. The library does not detect this type of error for you.
|
||||
<li>If DLLS are to be loaded and unloaded explicitly (e.g. using <code>dlopen</code> in *nix or
|
||||
<code>LoadLibrary</code> in Windows). Try to arrange that they are unloaded in the reverse
|
||||
sequence. This should guarantee that problems are avoided even if the
|
||||
above guideline hasn't been followed.
|
||||
|
||||
</ul>
|
||||
|
||||
<h3><a name="plugins">Plugins</a></h3>
|
||||
In order to implement the library, various facilities for runtime
|
||||
manipulation of types at runtime were required. These
|
||||
are <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
for associating classes with external identifying strings (<b>GUID</b>)
|
||||
and <a target="detail" href="void_cast.html"><code>void_cast</code></a>
|
||||
for casting between pointers of related types.
|
||||
|
||||
To complete the functionality of
|
||||
<a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
|
||||
the ability to construct and destroy corresponding types has been
|
||||
added. In order to use this functionality, one must specify
|
||||
how each type is created. This should be done at the time
|
||||
a class is exported. So, a more complete example of the code above would be:
|
||||
|
||||
<pre><code>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
... // other archives
|
||||
|
||||
#include "a.hpp" // header declaration for class a
|
||||
|
||||
// this class has a default constructor
|
||||
BOOST_SERIALIZATION_FACTORY_0(a)
|
||||
// as well as one that takes one integer argument
|
||||
BOOST_SERIALIZATION_FACTORY_1(a, int)
|
||||
|
||||
// specify the GUID for this class
|
||||
BOOST_CLASS_EXPORT(a)
|
||||
... // other class headers and exports
|
||||
</code></pre>
|
||||
|
||||
With this in place, one can construct, serialize and destroy a class
|
||||
about which is known only the <b>GUID</b> and a base class.
|
||||
|
||||
|
||||
<h3><a name="multi_threading">Multi-Threading</a></h3>
|
||||
The 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 situtation.
|
||||
<p>
|
||||
However, Writing/Reading different archives simultaneously
|
||||
in different tasks is permitted as each archive instance is (almost)
|
||||
completely independent from any other archive instance. The only shared
|
||||
information is some type tables which have been implemented using a
|
||||
lock-free thread-safe
|
||||
<a target="detail" href="singleton.html">
|
||||
<code style="white-space: normal">singleton</code>
|
||||
</a>
|
||||
described elsewhere in this documentation.
|
||||
<p>
|
||||
This singleton implementation guarantees that all of this shared
|
||||
information is initialized when the code module which contains
|
||||
it is loaded. The serialization library takes care to
|
||||
ensure that these data structures are not subsequently
|
||||
modified. The only time there could be a problem would
|
||||
be if code is loaded/unloaded while another task is
|
||||
serializing data. This could only occur for types whose
|
||||
serialization is implemented in a dynamically loaded/unloaded DLL
|
||||
or shared library. So if the following is avoided:
|
||||
<ul>
|
||||
<li>Accessing the same archive instance from different tasks.
|
||||
<li>Loading/Unloading DLLS or shared libraries while any archive
|
||||
instances are open.
|
||||
</ul>
|
||||
The library should be thread safe.
|
||||
|
||||
<h3><a name="optimizations">Optimizations</a></h3>
|
||||
In performance critical applications that serialize large sets of contiguous data of homogeneous
|
||||
types one wants to avoid the overhead of serializing each element individually, which is
|
||||
the motivation for the <a href="wrappers.html#arrays"><code>array</code></a>
|
||||
wrapper.
|
||||
|
||||
Serialization functions for data types containing contiguous arrays of homogeneous
|
||||
types, such as for <code>std::vector</code>, <code>std::valarray</code> or
|
||||
<code>boost::multiarray</code> should serialize them using an
|
||||
<a href="wrappers.html#arrays"><code>array</code></a> wrapper to make use of
|
||||
these optimizations.
|
||||
|
||||
Archive types that can provide optimized serialization for contiguous arrays of
|
||||
homogeneous types should implement these by overloading the serialization of
|
||||
the <a href="wrappers.html#arrays"><code>array</code></a> wrapper, as is done
|
||||
for the binary archives.
|
||||
|
||||
be guarenteed that all data can be serialized to all archive classes with maximum efficiency.
|
||||
|
||||
<h3><a href="exceptions.html">Archive Exceptions</a></h3>
|
||||
<h3><a href="exception_safety.html">Exception Safety</a></h3>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - <code style="white-space: normal">state_saver</code></title>
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
</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.
|
||||
|
||||
@@ -65,7 +65,7 @@ void func(A & a)
|
||||
</pre></code>
|
||||
|
||||
<h3>History</h3>
|
||||
This is a generalization of Daryle Walker's
|
||||
This is a generalization if Daryle Walker's
|
||||
<a href="../../../libs/io/doc/ios_state.html">io_state_saver</a> library.
|
||||
<p>
|
||||
Robert Ramey made an initial version for the serialization library.
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
@@ -25,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,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
@@ -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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
@@ -1,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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - To Do</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center">To Do</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="index">
|
||||
<dt><a href="#portablebinaryarchives">Portable Binary Archives</a></dt>
|
||||
<dt><a href="#performancetesting">Performance Testing and Profiling</a></dt>
|
||||
<dt><a href="#backversioning">Back Versioning</a></dt>
|
||||
<dt><a href="#nortti">Testing for Environments with No RTTI</a></dt>
|
||||
<dt><a href="new_case_studies.html">Additional Case Studies</a></dt>
|
||||
</dl>
|
||||
|
||||
These are enhancements that the serialization library needs but have not been done.
|
||||
Some of these projects, though tricky, are not huge and would be suitable
|
||||
for someone who has a limited time to spend on them. In particular, they
|
||||
might be of interest as student projects such as the Google Summer of Code.
|
||||
|
||||
<h2><a name="portablebinaryarchives"></a>Portable Binary Archives</h2>
|
||||
Currently there is a portable binary archive in the examples directory.
|
||||
It is not regularly submitted to the exhaustive boost testing regimen
|
||||
but it is tested occasionally and has been used in production code.
|
||||
<p>
|
||||
It's missing the following:
|
||||
<ul>
|
||||
<li>Addition of portable floating point types. This is not trivial. In addition to
|
||||
handling floating point types of varying sizes, It requires
|
||||
handling invalid floating point numbers (NaNs) in a portable manner.
|
||||
<li>Integration into the Boost testing regimen similar to the other archive classes.
|
||||
</ul>
|
||||
|
||||
<h2><a name="performancetesting"></a>Performance Testing and Profiling</h2>
|
||||
|
||||
I've managed to setup performance profiling using the following:
|
||||
<ul>
|
||||
<li>current (as I write this) Boost.Build tools.
|
||||
<li>the gcc compiler.
|
||||
<li>and a shell script - profile.sh
|
||||
<li>library_status program from the tools/regression/src directory
|
||||
</ul>
|
||||
Invoking profile script produces a
|
||||
<a href="performance_status.html">table</a>
|
||||
which shows the results of each test and links to the actual
|
||||
profile.
|
||||
<p>
|
||||
The first thing I did was include some of the serialization library tests.
|
||||
It became immediately apparent that these tests were totally unsuitable
|
||||
for performance testing and that new tests needed to be written for this
|
||||
purpose. These tests would highlight the location of any performance
|
||||
bottlenecks in the serialization library. Whenever I've subjected my
|
||||
code in the past to this type of analysis, I've always been surprised
|
||||
to find bottlenecks in totally unanticipated places and fixing those
|
||||
has always led to large improvements in performance. I expect that
|
||||
this project would have a huge impact on the utility of the serialization
|
||||
library.
|
||||
|
||||
<h2><a name="backversioning"></a>Back Versioning</h2>
|
||||
|
||||
It has been suggested that a useful feature of the library would be
|
||||
the ability to create "older versions" of archives. Currently,
|
||||
the library permits one to make programs that are guaranteed
|
||||
the ability to load archives with classes of a previous version.
|
||||
But there is no way to save classes in accordance with a
|
||||
previous version. At first I dismissed this as a huge project
|
||||
with small demand. A cursory examination of the code revealed
|
||||
that this would not be very difficult. It would require some
|
||||
small changes in code and some additional tests. Also it
|
||||
would require special treatment in the documentation - perhaps
|
||||
a case study.
|
||||
|
||||
|
||||
<h2><a name="nortti"></a>Environments without RTTI</h2>
|
||||
|
||||
I note that some have commented that this library requires RTTI.
|
||||
This is not strictly true. The examples and almost all the
|
||||
tests presume the existence of RTTI. But it should be possible
|
||||
to use the library without it. The example used for testing is an
|
||||
<code style="white-space: normal">extended_typeinfo</code>
|
||||
implemenation which presumes that all classes names have been exported.
|
||||
So, to make this library compatible for platforms without RTTI,
|
||||
a set of tests, examples and new manual section would have to be created.
|
||||
|
||||
<hr>
|
||||
<p>Revised 1 November, 2008
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2008.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Class Serialization Traits</title>
|
||||
@@ -32,13 +32,10 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#export">Export Key</a>
|
||||
<dt><a href="#abstract">Abstract</a>
|
||||
<dt><a href="#typeinfo">Type Information Implementation</a>
|
||||
<dt><a href="#wrappers">Wrappers</a>
|
||||
<dt><a href="#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
|
||||
@@ -174,24 +171,12 @@ A corresponding macro is defined so that we can use:
|
||||
<pre><code>
|
||||
BOOST_CLASS_TRACKING(my_class, boost::serialization::track_never)
|
||||
</code></pre>
|
||||
Default tracking traits are:
|
||||
<ul>
|
||||
<li>For primitive, <code style="white-space: normal">track_never</code>.
|
||||
<li>For pointers, <code style="white-space: normal">track_never</code>.
|
||||
That is, addresses of addresses are not tracked by default.
|
||||
<li>All current serialization wrappers such as <code style="white-space: normal">boost::serialization::nvp</code>,
|
||||
<code style="white-space: normal">track_never</code>.
|
||||
<li>For all other types, <code style="white-space: normal">track_selectively</code>.
|
||||
That is addresses of serialized objects are tracked if and only if
|
||||
one or more of the following is true:
|
||||
<ul>
|
||||
<li>an object of this type is anywhere in the program serialized
|
||||
through a pointer.
|
||||
<li>the class is explicitly "exported" - see below.
|
||||
<li>the class is explicitly "registered" in the archive
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
The default value for primitive types is <code style="white-space: normal">track_never</code>.
|
||||
<p>
|
||||
The default value for all other types is <code style="white-space: normal">track_selectivly</code>.
|
||||
That is addresses of serialized objects are tracked if and only if
|
||||
an object of the same type is anywhere in the program serialized
|
||||
through a pointer.
|
||||
<p>
|
||||
The default behavior is almost always the most convenient one. However,
|
||||
there a few cases where it would be desirable to override the
|
||||
@@ -204,23 +189,13 @@ 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 explicity 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
|
||||
statisfactory for our purposes for the following reasons:
|
||||
@@ -232,52 +207,43 @@ statisfactory for our purposes for the following reasons:
|
||||
<li>There might be classes locally defined in different code modules
|
||||
that have the same name.
|
||||
<li>There might be classes with different names that we want to
|
||||
consider equivalent for purposes of 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>entfier.)</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.
|
||||
</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
|
||||
@@ -318,8 +284,8 @@ target="extended_type_info_rtti_hpp">extended_type_info_no_rtti.hpp</a>.
|
||||
By invoking the macro:
|
||||
<pre><code>
|
||||
BOOST_CLASS_TYPE_INFO(
|
||||
my_class,
|
||||
extended_type_info_no_rtti<my_class>
|
||||
derived_class,
|
||||
extended_type_info_no_rtti<base_class>
|
||||
)
|
||||
</code></pre>
|
||||
we can assign the type information implementation to each class on a case by
|
||||
@@ -333,72 +299,6 @@ This is illustrated by the test program
|
||||
Other implementations are possible and might be necessary for
|
||||
certain special cases.
|
||||
|
||||
<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
|
||||
serialized object (with the exception of a wrapper) be const.
|
||||
|
||||
This header file <a href="../../../boost/serialization/wrapper.hpp">wrapper.hpp</a>
|
||||
includes the following code:
|
||||
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
template<class T>
|
||||
struct is_wrapper
|
||||
: public mpl::false_
|
||||
{};
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
|
||||
For any class <code style="white-space: normal">T</code>, The default definition
|
||||
of <code style="white-space: normal">boost::serialization::is_wrapper<T>::value</code> is thus false.
|
||||
|
||||
If we want to declare that a class <code style="white-space: normal">my_class</code>
|
||||
is a wrapper we specialize the version template:
|
||||
<pre><code>
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
struct is_wrapper<my_class>
|
||||
: mpl::true_
|
||||
{};
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
</code></pre>
|
||||
<p>
|
||||
To diminish typing and enhance readability, a macro is defined
|
||||
so that instead of the above, we could write:
|
||||
<pre><code>
|
||||
BOOST_CLASS_IS_WRAPPER(my_class)
|
||||
</code></pre>
|
||||
which expands to the code above.
|
||||
|
||||
<h3><a name="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
|
||||
to a whole group of classes at once. Consider, the name-value pair
|
||||
@@ -424,11 +324,10 @@ convenience macros, use the original definitions
|
||||
template<class T>
|
||||
struct implementation_level<nvp<T> >
|
||||
{
|
||||
typedef mpl::integral_c_tag tag;
|
||||
typedef mpl::int_<object_serializable> type;
|
||||
typedef mpl::int_<object_serializable> type; \
|
||||
BOOST_STATIC_CONSTANT(
|
||||
int,
|
||||
value = implementation_level::type::value
|
||||
enum level_type,
|
||||
value = static_cast<enum level_type>(type::value)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -436,11 +335,10 @@ struct implementation_level<nvp<T> >
|
||||
template<class T>
|
||||
struct tracking_level<nvp<T> >
|
||||
{
|
||||
typedef mpl::integral_c_tag tag;
|
||||
typedef mpl::int_<track_never> type;
|
||||
BOOST_STATIC_CONSTANT(
|
||||
int,
|
||||
value = tracking_level::type::value
|
||||
enum tracking_type,
|
||||
value = static_cast<enum tracking_type>(type::value)
|
||||
);
|
||||
};
|
||||
</code></pre>
|
||||
@@ -470,7 +368,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>
|
||||
@@ -495,8 +393,7 @@ template<
|
||||
int Level,
|
||||
int Tracking,
|
||||
unsigned int Version = 0,
|
||||
class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T),
|
||||
class IsWrapper = mpl::false_
|
||||
class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T)
|
||||
>
|
||||
struct traits
|
||||
</code></pre>
|
||||
@@ -509,296 +406,10 @@ and template parameters should be assigned according to the following table:
|
||||
<tr><td><code>Tracking</code></td><td>tracking level</td><td><code>track_never<br>track_selectivly<br>track_always</code></td><td>none</td></tr>
|
||||
<tr><td><code>Version</code></td><td><code>class version</td><td>unsigned integer</td><td><code>0</code></td></tr>
|
||||
<tr><td><code>ETTI</code></td><td><code>type_info</code> implementation</td><td><code>extended_type_info_typeid<br>extended_type_info_no_rtti</code></td><td>default <code>type_info implementation</code></td></tr>
|
||||
<tr><td><code>IsWrapper</code></td><td><code></code>is the type a wrapper?</td><td><code>mpl::false_<br>mpl::true_</code></td><td><code>mpl::false_</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="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 suprising 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
|
||||
implentation 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 acrimonius email exchanges,
|
||||
it's discovered
|
||||
that programmer(3) accidently 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 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 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 mabe they will fix it.
|
||||
In this case, the story branches off to the previous scenario.
|
||||
<p>
|
||||
<li>Oh, this trap is suggesting that the default serialization isn't really
|
||||
what I want. Of course in this particular program it doesn't matter. But
|
||||
then the code in the trap can't really evaluate code in other modules (which
|
||||
might not even be written yet). OK, I'll add the following to my
|
||||
construct_from.hpp to solve the problem.
|
||||
<code style="white-space: normal"><pre>
|
||||
BOOST_CLASS_TRACKING(construct_from, track_never)
|
||||
</pre></code>
|
||||
</ol>
|
||||
</ul>
|
||||
<p>
|
||||
<li>Now programmer (3) comes along and make his change. The behavior of the
|
||||
original (and distant module) remains unchanged because the
|
||||
<code style="white-space: normal">construct_from</code> trait has been set to
|
||||
"track_never" so he should always get copies and the log should be what we expect.
|
||||
<p>
|
||||
<li>But now he gets another trap - trying to save an object of a
|
||||
class marked "track_never" through a pointer. So he goes back to
|
||||
construct_from.hpp and comments out the
|
||||
<code style="white-space: normal">BOOST_CLASS_TRACKING</code> that
|
||||
was inserted. Now the second trap is avoided, But damn - the first trap is
|
||||
popping up again. Eventually, after some code restructuring, the differing
|
||||
requirements of serializating <code style="white-space: normal">construct_from</code>
|
||||
are reconciled.
|
||||
</ol>
|
||||
Note that in this second scenario
|
||||
<ul>
|
||||
<li>all errors are trapped at compile time.
|
||||
<li>no invalid archives are created.
|
||||
<li>no data is lost.
|
||||
<li>no runtime errors occur.
|
||||
</ul>
|
||||
|
||||
It's true that these 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 situaion 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 ar << T * 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 ar >> T * so that tracking information
|
||||
will be included in the archive. When a program which
|
||||
creates the archive doesn't include ar << T 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 reasones,
|
||||
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.
|
||||
<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>
|
||||
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Tutorial</title>
|
||||
@@ -36,7 +36,6 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<dt><a href="#versioning">Class Versioning</a>
|
||||
<dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into <code style="white-space: normal">save/load</code></a>
|
||||
<dt><a href="#archives">Archives</a>
|
||||
<dt><a href="#examples">List of examples</a>
|
||||
</dl>
|
||||
An output archive is similar to an output data stream. Data can be saved to the archive
|
||||
with either the << or the & operator:
|
||||
@@ -60,7 +59,7 @@ all the data contained in the class is saved/loaded.
|
||||
|
||||
<h3><a name="simplecase">A Very Simple Case</a></h3>
|
||||
These operators are used inside the <code style="white-space: normal">serialize</code>
|
||||
function to save and load class data members.
|
||||
function> to save and load class data members.
|
||||
<p>
|
||||
Included in this library is a program called
|
||||
<a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a> which illustrates how
|
||||
@@ -107,28 +106,24 @@ public:
|
||||
int main() {
|
||||
// create and open a character archive for output
|
||||
std::ofstream ofs("filename");
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
|
||||
// create class instance
|
||||
const gps_position g(35, 59, 24.567f);
|
||||
|
||||
// save data to archive
|
||||
{
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
// write class instance to archive
|
||||
oa << g;
|
||||
// archive and stream closed when destructors are called
|
||||
}
|
||||
// write class instance to archive
|
||||
oa << g;
|
||||
// close archive
|
||||
ofs.close();
|
||||
|
||||
// ... some time later restore the class instance to its orginal state
|
||||
// create and open an archive for input
|
||||
std::ifstream ifs("filename", std::ios::binary);
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
// read class state from archive
|
||||
gps_position newg;
|
||||
{
|
||||
// create and open an archive for input
|
||||
std::ifstream ifs("filename");
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
// read class state from archive
|
||||
ia >> newg;
|
||||
// archive and stream closed when destructors are called
|
||||
}
|
||||
ia >> newg;
|
||||
// close archive
|
||||
ifs.close();
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
@@ -299,7 +294,7 @@ public:
|
||||
</code>
|
||||
</pre>
|
||||
Each member of the array <code style="white-space: normal">stops</code> will be serialized.
|
||||
But remember each member is a pointer - so what can this really
|
||||
But, remember each member is a pointer - so what can this really
|
||||
mean? The whole object of this serialization is to permit
|
||||
reconstruction of the original data structures at another place
|
||||
and time. In order to accomplish this with a pointer, it is
|
||||
@@ -308,27 +303,6 @@ object it points to must be saved. When the member is later
|
||||
loaded, a new object has to be created and a new pointer has
|
||||
to be loaded into the class member.
|
||||
<p>
|
||||
If the same pointer is serialized more than once, only one instance
|
||||
is be added to the archive. When read back, no data is read back in.
|
||||
The only operation that occurs is for the second pointer is set equal to the first
|
||||
<p>
|
||||
Note that, in this example, the array consists of polymorphic pointers.
|
||||
That is, each array element point to one of several possible
|
||||
kinds of bus stops. So when the pointer is saved, some sort of class
|
||||
identifier must be saved. When the pointer is loaded, the class
|
||||
identifier must be read and and instance of the corresponding class
|
||||
must be constructed. Finally the data can be loaded to newly created
|
||||
instance of the correct type.
|
||||
|
||||
As can be seen in
|
||||
<a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>,
|
||||
serialization of pointers to derived classes through a base
|
||||
clas pointer may require explicit enumeration of the derived
|
||||
classes to be serialized. This is referred to as "registration" or "export"
|
||||
of derived classes. This requirement and the methods of
|
||||
satisfying it are explained in detail
|
||||
<a href="serialization.html#derivedpointers">here</a>.
|
||||
<p>
|
||||
All this is accomplished automatically by the serialization
|
||||
library. The above code is all that is necessary to accomplish
|
||||
the saving and loading of objects accessed through pointers.
|
||||
@@ -505,76 +479,39 @@ to be usable with any archive.
|
||||
<p>
|
||||
In this tutorial, we have used a particular
|
||||
archive class - <code style="white-space: normal">text_oarchive</code> for saving and
|
||||
<code style="white-space: normal">text_iarchive</code> for loading.
|
||||
text archives render data as text and are portable across platforms. In addition
|
||||
to text archives, the library includes archive class for native binary data
|
||||
and xml formatted data. Interfaces to all archive classes are all identical.
|
||||
Once serialization has been defined for a class, that class can be serialized to
|
||||
any type of archive.
|
||||
<code style="white-space: normal">text_iarchive</code> for loading. There other archives
|
||||
included in with the library and their interfaces are identical
|
||||
(with one exception). Once serialization has been defined for
|
||||
a class, that class can be serialized to any type of archive.
|
||||
<p>
|
||||
If the current set of archive classes doesn't provide the
|
||||
attributes, format, or behavior needed for a particular application,
|
||||
one can either make a new archive class or derive from an existing one.
|
||||
If the current set of archives doesn't provide one with the
|
||||
attributes, format, or behavior need for a particular application,
|
||||
one can either make a new one or derive from an existing one.
|
||||
This is described later in the manual.
|
||||
|
||||
<h3><a name="examples">List of Examples</h3>
|
||||
<dl>
|
||||
<dt><a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>
|
||||
<dd>This is the completed example used in this tutorial.
|
||||
It does the following:
|
||||
<ol>
|
||||
<li>Creates a structure of differing kinds of stops, routes and schedules
|
||||
<li>Displays it
|
||||
<li>Serializes it to a file named "testfile.txt" with one
|
||||
statement
|
||||
<li>Restores to another structure
|
||||
<li>Displays the restored structure
|
||||
</ol>
|
||||
<a href="../example/demo_output.txt" target="demo_output">Output of
|
||||
this program</a> is sufficient to verify that all the
|
||||
originally stated requirements for a serialization system
|
||||
are met with this system. The <a href="../example/demofile.txt"
|
||||
target="test_file">contents of the archive file</a> can
|
||||
also be displayed as serialization files are ASCII text.
|
||||
|
||||
<dt><a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp</a>
|
||||
<dd>This is a variation the original demo which supports xml archives in addition
|
||||
to the others. The extra wrapping macro, BOOST_SERIALIZATION_NVP(name), is
|
||||
needed to associate a data item name with the corresponding xml
|
||||
tag. It is importanted that 'name' be a valid xml tag, else it
|
||||
will be impossible to restore the archive.
|
||||
For more information see
|
||||
<a target="detail" href="wrappers.html#nvp">Name-Value Pairs</a>.
|
||||
<a href="../example/demo_save.xml" target="demo_save_xml">Here</a>
|
||||
is what an xml archive looks like.
|
||||
|
||||
<dt><a href="../example/demo_xml_save.cpp" target="demo_xml_save_cpp">demo_xml_save.cpp</a>
|
||||
and <a href="../example/demo_xml_load.cpp" target="demo_xml_load_cpp">demo_xml_load.cpp</a>
|
||||
<dd>Note also that though our examples save and load the program data
|
||||
to an archive within the same program, this merely a convenience
|
||||
for purposes of illustration. In general, the archive may or may
|
||||
not be loaded by the same program that created it.
|
||||
</dl>
|
||||
<p>
|
||||
The astute reader might notice that these examples contain a subtle but important flaw.
|
||||
They leak memory. The bus stops are created in the <code style="white-space: normal">
|
||||
main</code> function. The bus schedules may refer to these bus stops
|
||||
any number of times. At the end of the main function after the bus schedules are destroyed,
|
||||
the bus stops are destroyed. This seems fine. But what about the structure
|
||||
<code style="white-space: normal">new_schedule</code> data item created by the
|
||||
process of loading from an archive? This contains its own separate set of bus stops
|
||||
that are not referenced outside of the bus schedule. These won't be destroyed
|
||||
anywhere in the program - a memory leak.
|
||||
Note also that though our examples save and load the program data
|
||||
to an archive within the same program, this merely a convenience
|
||||
for purposes of illustration. In general, the archive may or may
|
||||
not be loaded by the same program that created it.
|
||||
<p>
|
||||
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
|
||||
includes implementation of serialization for
|
||||
<code style="white-space: normal">boost::shared ptr</code>. Given this, it should be
|
||||
easy to alter any of these examples to eliminate the memory leak. This is left
|
||||
as an excercise for the reader.
|
||||
|
||||
The complete demo program - <a href="../example/demo.cpp" target="demo_cpp">demo.cpp</a>
|
||||
does the following:
|
||||
<ol>
|
||||
<li>Creates a structure of differing kinds of stops, routes
|
||||
and schedules
|
||||
<li>Displays it
|
||||
<li>Serializes it to a file named "testfile.txt" with one
|
||||
statement
|
||||
<li>Restores to another structure
|
||||
<li>Displays the restored structure
|
||||
</ol>
|
||||
<p>
|
||||
<a href="../example/demo_output.txt" target="demo_output">Output of
|
||||
this program</a> is sufficient to verify that all the
|
||||
originally stated requirements for a serialization system
|
||||
are met with this system. The <a href="../example/demofile.txt"
|
||||
target="test_file">contents of the archive file</a> can
|
||||
also be displayed as serialization files are ASCII text.
|
||||
<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,38 +0,0 @@
|
||||
IMPORTANT:
|
||||
|
||||
This is the last release from me as EOS employee. I plan to contribute all of this
|
||||
work to the official boost libraries distribution and will continue to support users.
|
||||
Francois Mauger joined me recently and already added a valuable tutorial for you!
|
||||
|
||||
Changelog:
|
||||
|
||||
07.11.2015 5.1 Small fix to get it running up to 1.59.
|
||||
|
||||
26.06.2012 5.0 Ported to boost versions up to 1.49.
|
||||
Added support for wstring, added tutorial by Francois Mauger.
|
||||
|
||||
01.04.2011 4.2 Ported to boost versions up to 1.46.1.
|
||||
Allow serialization of inf and nan values.
|
||||
|
||||
17.12.2009 4.1 Ported to boost versions up to 1.41.
|
||||
|
||||
4.0 Changes in inheritance make arrays work.
|
||||
|
||||
13.02.2009 3.1 Shared pointer serialization capabilities added
|
||||
Ported to recent boost versions (up to 1.38)
|
||||
|
||||
25.09.2008 3.0 Refactored, fixed and ported to recent boost versions
|
||||
Archives are now named eos::portable_[io]archive
|
||||
|
||||
17.09.2008 2.1 Improved floating point handling and error detection.
|
||||
Extracted the exception class into an extra file.
|
||||
|
||||
28.04.2008 2.0 Major Bugfix resolving negative number collision!
|
||||
|
||||
28.11.2007 1.1 Small Bugfix in portable_binary_archive_exception class:
|
||||
throwing specifiers did not match base class declaration
|
||||
|
||||
12.11.2007 1.0 Initial Release to boost-users!
|
||||
|
||||
Christian Pfligersdorffer
|
||||
christian.pfligersdorffer@gmx.at
|
||||
@@ -1,56 +0,0 @@
|
||||
/** tutorial_pba_0.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This quick start example shows how to store some variables
|
||||
* of basic types (bool, integer, floating point numbers, STL string)
|
||||
* using the portable binary archive format associated to a
|
||||
* standard output file stream.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
// The name for the example data file :
|
||||
std::string filename = "pba_0.data";
|
||||
|
||||
// Some variables of various primitive types :
|
||||
bool b = true;
|
||||
char c = 'B';
|
||||
uint32_t answer = 42;
|
||||
float computing_time = 7.5e6;
|
||||
double e = 2.71828182845905;
|
||||
std::string slogan = "DON'T PANIC";
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
std::ofstream fout (filename.c_str (), std::ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file :
|
||||
boost::archive::portable_binary_oarchive opba (fout);
|
||||
|
||||
// Store (serializing) variables :
|
||||
opba & b & c & answer & computing_time & e & slogan;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_0.cpp
|
||||
@@ -1,68 +0,0 @@
|
||||
/** tutorial_pba_1.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization package.
|
||||
*
|
||||
* This quick start example shows how to load some variables
|
||||
* of basic types (bool, integer, floating point numbers, STL string)
|
||||
* using the portable binary archive format associated to a
|
||||
* standard input file stream.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// The name for the example data file :
|
||||
string filename = "pba_0.data";
|
||||
|
||||
// Some variables of various types :
|
||||
bool b;
|
||||
char c;
|
||||
uint32_t answer;
|
||||
float computing_time;
|
||||
double e;
|
||||
string slogan;
|
||||
|
||||
// Open an input file stream in binary mode :
|
||||
ifstream fin (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an input portable binary archive attached to the input file :
|
||||
boost::archive::portable_binary_iarchive ipba (fin);
|
||||
|
||||
// Loading (de-serializing) variables using the same
|
||||
// order than for serialization (see tutorial_pba_0.cpp) :
|
||||
ipba & b & c & answer & computing_time & e & slogan;
|
||||
}
|
||||
|
||||
cout.precision (15);
|
||||
cout << "Variable 'b' is : " << b << " " << "(bool)" << endl;
|
||||
cout << "Variable 'c' is : '" << c << "' " << " " << "(char)" << endl;
|
||||
cout << "Variable 'answer' is : " << answer << " " << "(unsigned 32-bit integer)" << endl;
|
||||
cout << "Variable 'computing_time' is : " << computing_time << " " << "(single precision 32-bit float)" << endl;
|
||||
cout << "Variable 'e' is : " << e << " " << "(double precision 64-bit float)" << endl;
|
||||
cout << "Variable 'slogan' is : \"" << slogan << "\" " << "(std::string)" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_1.cpp
|
||||
@@ -1,162 +0,0 @@
|
||||
/** tutorial_pba_10.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example shows how use PBAs combined with on-the-fly
|
||||
* compressed I/O streams.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class data_type
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version);
|
||||
public:
|
||||
void print (ostream & out, const string & title) const;
|
||||
public:
|
||||
vector<double> values;
|
||||
data_type ();
|
||||
};
|
||||
|
||||
data_type::data_type () : values ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void data_type::print (ostream & out, const string & title) const
|
||||
{
|
||||
out << endl;
|
||||
out << title << " :" << endl;
|
||||
for (int i = 0; i < this->values.size (); ++i)
|
||||
{
|
||||
out.precision (16);
|
||||
out.width (18);
|
||||
out << this->values [i] << ' ' ;
|
||||
if ((i%4) == 3) clog << endl;
|
||||
}
|
||||
out << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void data_type::serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & values;
|
||||
return;
|
||||
}
|
||||
|
||||
void do_gzipped_out (void)
|
||||
{
|
||||
// The name for the output data file :
|
||||
string filename = "pba_10.data.gz";
|
||||
|
||||
// A data structure to be stored :
|
||||
data_type my_data;
|
||||
|
||||
// Fill the vector with arbitrary (possibly non-finite) values :
|
||||
size_t dim = 1000;
|
||||
my_data.values.reserve (dim);
|
||||
for (int i = 0; i < dim; ++i)
|
||||
{
|
||||
double val = (i + 1) * (1.0 + 3 * numeric_limits<double>::epsilon ());
|
||||
if (i == 4) val = numeric_limits<double>::quiet_NaN ();
|
||||
if (i == 23) val = numeric_limits<double>::infinity ();
|
||||
if (i == 73) val = -numeric_limits<double>::infinity ();
|
||||
if (i == 90) val = 0.0;
|
||||
my_data.values.push_back (val);
|
||||
}
|
||||
|
||||
// Print:
|
||||
my_data.print (clog, "Stored data");
|
||||
|
||||
// Create an output filtering stream :
|
||||
boost::iostreams::filtering_ostream zout;
|
||||
zout.push (boost::iostreams::gzip_compressor ());
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
ofstream fout (filename.c_str (), ios_base::binary);
|
||||
zout.push (fout);
|
||||
|
||||
// Save to PBA :
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file :
|
||||
boost::archive::portable_binary_oarchive opba (zout);
|
||||
|
||||
// Store (serializing) the data :
|
||||
opba & my_data;
|
||||
}
|
||||
|
||||
// Clean termination of the streams :
|
||||
zout.flush ();
|
||||
zout.reset ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void do_gzipped_in (void)
|
||||
{
|
||||
// The name for the input data file :
|
||||
string filename = "pba_10.data.gz";
|
||||
|
||||
// A data structure to be loaded :
|
||||
data_type my_data;
|
||||
|
||||
// Create an input filtering stream :
|
||||
boost::iostreams::filtering_istream zin;
|
||||
zin.push (boost::iostreams::gzip_decompressor ());
|
||||
|
||||
// Open an input file stream in binary mode :
|
||||
ifstream fin (filename.c_str (), ios_base::binary);
|
||||
zin.push (fin);
|
||||
|
||||
// Load from PBA :
|
||||
{
|
||||
// Create an input portable binary archive attached to the input file :
|
||||
boost::archive::portable_binary_iarchive ipba (zin);
|
||||
|
||||
// Load (deserializing) the data :
|
||||
ipba & my_data;
|
||||
}
|
||||
|
||||
// Print:
|
||||
my_data.print (clog, "Loaded data");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
do_gzipped_out ();
|
||||
do_gzipped_in ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_10.cpp
|
||||
@@ -1,198 +0,0 @@
|
||||
/** tutorial_pba_10b.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example shows how use PBAs combined with on-the-fly
|
||||
* compressed I/O streams.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/archive/xml_oarchive.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class data_type
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version);
|
||||
public:
|
||||
void print (ostream & out, const string & title) const;
|
||||
public:
|
||||
vector<double> values;
|
||||
data_type ();
|
||||
};
|
||||
|
||||
//BOOST_CLASS_VERSION(data_type, 7)
|
||||
|
||||
data_type::data_type () : values ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void data_type::print (ostream & out, const string & title) const
|
||||
{
|
||||
out << endl;
|
||||
out << title << " :" << endl;
|
||||
for (int i = 0; i < this->values.size (); ++i)
|
||||
{
|
||||
out.precision (16);
|
||||
out.width (18);
|
||||
out << this->values [i] << ' ' ;
|
||||
if ((i%4) == 3) clog << endl;
|
||||
}
|
||||
out << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void data_type::serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP (values);
|
||||
return;
|
||||
}
|
||||
|
||||
class data_type2
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version);
|
||||
public:
|
||||
double value;
|
||||
data_type2 ();
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(data_type2, 99)
|
||||
|
||||
data_type2::data_type2 () : value (666.666)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void data_type2::serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP (value);
|
||||
return;
|
||||
}
|
||||
|
||||
class data_type3
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version);
|
||||
public:
|
||||
vector<data_type2> values;
|
||||
data_type3 ();
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(data_type3, 33)
|
||||
|
||||
data_type3::data_type3 ()
|
||||
{
|
||||
{
|
||||
data_type2 d;
|
||||
d.value = 6.66;
|
||||
values.push_back (d);
|
||||
}
|
||||
{
|
||||
data_type2 d;
|
||||
d.value = 66.66;
|
||||
values.push_back (d);
|
||||
}
|
||||
{
|
||||
data_type2 d;
|
||||
d.value = 666.66;
|
||||
values.push_back (d);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void data_type3::serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP (values);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************/
|
||||
|
||||
void do_xml_out (void)
|
||||
{
|
||||
// The name for the output data file :
|
||||
string filename = "pba_10.xml";
|
||||
|
||||
// A data structure to be stored :
|
||||
data_type my_data;
|
||||
|
||||
// Fill the vector with arbitrary (possibly non-finite) values :
|
||||
size_t dim = 6;
|
||||
my_data.values.reserve (dim);
|
||||
for (int i = 0; i < dim; ++i)
|
||||
{
|
||||
double val = (i + 1) * (1.0 + 3 * numeric_limits<double>::epsilon ());
|
||||
if (i == 4) val = numeric_limits<double>::quiet_NaN ();
|
||||
if (i == 7) val = numeric_limits<double>::infinity ();
|
||||
if (i == 9) val = -numeric_limits<double>::infinity ();
|
||||
if (i == 13) val = 0.0;
|
||||
my_data.values.push_back (val);
|
||||
}
|
||||
|
||||
// Print:
|
||||
my_data.print (clog, "Stored data");
|
||||
|
||||
data_type2 my_data2;
|
||||
data_type3 my_data3;
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
ofstream fout (filename.c_str ());
|
||||
|
||||
// Save to PBA :
|
||||
{
|
||||
// Create an output XML archive attached to the output file :
|
||||
boost::archive::xml_oarchive oxa (fout);
|
||||
|
||||
// Store (serializing) the data :
|
||||
oxa & BOOST_SERIALIZATION_NVP(my_data);
|
||||
oxa & BOOST_SERIALIZATION_NVP(my_data2);
|
||||
oxa & BOOST_SERIALIZATION_NVP(my_data3);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
do_xml_out ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_10b.cpp
|
||||
@@ -1,187 +0,0 @@
|
||||
/** tutorial_pba_11.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example program compares the times needed to serialize
|
||||
* and deserialize some large amount of data using PBA and
|
||||
* text archives.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/random/uniform_real_distribution.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class data_type
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version);
|
||||
public:
|
||||
void print (ostream & out, const string & title) const;
|
||||
public:
|
||||
vector<double> values;
|
||||
data_type ();
|
||||
};
|
||||
|
||||
data_type::data_type () : values ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void data_type::print (ostream & out, const string & title) const
|
||||
{
|
||||
out << endl;
|
||||
out << title << " :" << endl;
|
||||
bool skip = false;
|
||||
for (int i = 0; i < this->values.size (); ++i)
|
||||
{
|
||||
if ((i >= 12) && (i < (int) this->values.size () - 8))
|
||||
{
|
||||
if (! skip) out << " ..." << endl;
|
||||
skip = true;
|
||||
continue;
|
||||
}
|
||||
out.precision (16);
|
||||
out.width (18);
|
||||
out << this->values [i] << ' ' ;
|
||||
if ((i%4) == 3) clog << endl;
|
||||
}
|
||||
out << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void data_type::serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & values;
|
||||
return;
|
||||
}
|
||||
|
||||
double do_pba_out (const data_type & a_data)
|
||||
{
|
||||
string filename = "pba_11.data";
|
||||
ofstream fout (filename.c_str (), ios_base::binary);
|
||||
boost::timer io_timer;
|
||||
{
|
||||
boost::archive::portable_binary_oarchive opba (fout);
|
||||
opba & a_data;
|
||||
}
|
||||
return io_timer.elapsed ();
|
||||
}
|
||||
|
||||
double do_pba_in (data_type & a_data)
|
||||
{
|
||||
string filename = "pba_11.data";
|
||||
ifstream fin (filename.c_str (), ios_base::binary);
|
||||
boost::timer io_timer;
|
||||
{
|
||||
boost::archive::portable_binary_iarchive ipba (fin);
|
||||
ipba & a_data;
|
||||
}
|
||||
return io_timer.elapsed ();
|
||||
}
|
||||
|
||||
double do_text_out (const data_type & a_data)
|
||||
{
|
||||
string filename = "pba_11.txt";
|
||||
ofstream fout (filename.c_str ());
|
||||
boost::timer io_timer;
|
||||
{
|
||||
boost::archive::text_oarchive ota (fout);
|
||||
ota & a_data;
|
||||
}
|
||||
return io_timer.elapsed ();
|
||||
}
|
||||
|
||||
double do_text_in (data_type & a_data)
|
||||
{
|
||||
string filename = "pba_11.txt";
|
||||
ifstream fin (filename.c_str ());
|
||||
boost::timer io_timer;
|
||||
{
|
||||
boost::archive::text_iarchive ita (fin);
|
||||
ita & a_data;
|
||||
}
|
||||
return io_timer.elapsed ();
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
double elapsed_time_pba_out;
|
||||
double elapsed_time_text_out;
|
||||
double elapsed_time_pba_in;
|
||||
double elapsed_time_text_in;
|
||||
data_type my_data; // A data structure to be stored then loaded.
|
||||
|
||||
{
|
||||
// Fill the vector with random values :
|
||||
size_t dim = 10000000;
|
||||
my_data.values.reserve (dim);
|
||||
boost::random::mt19937 rng;
|
||||
boost::random::uniform_real_distribution<> flat (0.0, 100.0);
|
||||
for (int i = 0; i < dim; ++i)
|
||||
{
|
||||
double val = flat (rng);
|
||||
my_data.values.push_back (val);
|
||||
}
|
||||
my_data.print (clog, "Stored data in PBA and text archive");
|
||||
}
|
||||
|
||||
{
|
||||
// Store in PBA :
|
||||
elapsed_time_pba_out = do_pba_out (my_data);
|
||||
}
|
||||
|
||||
{
|
||||
// Store in text archive :
|
||||
elapsed_time_text_out = do_text_out (my_data);
|
||||
}
|
||||
|
||||
{
|
||||
my_data.values.clear ();
|
||||
// Load from PBA :
|
||||
elapsed_time_pba_in = do_pba_in (my_data);
|
||||
my_data.print (clog, "Loaded data from PBA");
|
||||
}
|
||||
|
||||
{
|
||||
my_data.values.clear ();
|
||||
// Load from text archive :
|
||||
elapsed_time_text_in = do_text_in (my_data);
|
||||
my_data.print (clog, "Loaded data from text archive");
|
||||
}
|
||||
|
||||
clog << "PBA store I/O elapsed time : " << elapsed_time_pba_out << " (second)" << endl;
|
||||
clog << "Text store I/O elapsed time : " << elapsed_time_text_out << " (second)" << endl;
|
||||
clog << "PBA load I/O elapsed time : " << elapsed_time_pba_in << " (second)" << endl;
|
||||
clog << "Text load I/O elapsed time : " << elapsed_time_text_in << " (second)" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_11.cpp
|
||||
@@ -1,105 +0,0 @@
|
||||
/** tutorial_pba_2.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This sample program shows how to use a portable binary archive
|
||||
* to store/load floating point numbers including non-finite and
|
||||
* special (denormalized) values.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// The name for the example data file :
|
||||
string filename = "pba_2.data";
|
||||
|
||||
{
|
||||
// A normal single precision floating point number :
|
||||
float pi = 3.14159265;
|
||||
|
||||
// Single precision zeroed floating point number :
|
||||
float zero = 0.0;
|
||||
|
||||
// A denormalized single precision floating point number :
|
||||
float tiny = 1.e-40;
|
||||
|
||||
// A single precision floating point number with `+Infinity' value :
|
||||
float plus_infinity = numeric_limits<float>::infinity ();
|
||||
|
||||
// A single precision floating point number with `-Infinity' value :
|
||||
float minus_infinity = -numeric_limits<float>::infinity ();
|
||||
|
||||
// A single precision `Not-a-Number' (NaN):
|
||||
float nan = numeric_limits<float>::quiet_NaN ();
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
ofstream fout (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file :
|
||||
boost::archive::portable_binary_oarchive opba (fout);
|
||||
|
||||
// Store (serialize) variables :
|
||||
opba & pi & zero & tiny & plus_infinity & minus_infinity & nan;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Single precision floating point numbers to be loaded :
|
||||
float x[6];
|
||||
|
||||
// Open an input file stream in binary mode :
|
||||
ifstream fin (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an input portable binary archive attached to the input file :
|
||||
boost::archive::portable_binary_iarchive ipba (fin);
|
||||
|
||||
// Load (de-serialize) variables using the same
|
||||
// order than for serialization :
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
ipba & x[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Print :
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
cout.precision (8);
|
||||
cout << "Loaded x[" << i << "] = " << x[i];
|
||||
switch (fp::fpclassify(x[i]))
|
||||
{
|
||||
case FP_NAN: cout << " (NaN)"; break;
|
||||
case FP_INFINITE: cout << " (infinite)"; break;
|
||||
case FP_SUBNORMAL: cout << " (denormalized)"; break;
|
||||
case FP_NORMAL: cout << " (normalized)"; break;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_2.cpp
|
||||
@@ -1,70 +0,0 @@
|
||||
/** tutorial_pba_3.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This sample program shows how to use a portable binary archive
|
||||
* and prevent the serialization of non-finite floating numbers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// The name for the example data file :
|
||||
string filename = "pba_3.data";
|
||||
|
||||
try
|
||||
{
|
||||
// An array of single precision floating numbers:
|
||||
float x[5];
|
||||
x[0] = 3.14159; // Pi
|
||||
x[1] = 6.022e22; // Avogadro constant
|
||||
x[2] = 1.6e-19; // Electron charge magnitude
|
||||
x[3] = 1.e-40; // A tiny (denormalized) value
|
||||
x[4] = numeric_limits<float>::infinity (); // This will fail while serializing...
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
ofstream fout (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file,
|
||||
// using the special 'boost::archive::no_infnan' flag :
|
||||
boost::archive::portable_binary_oarchive opba (fout, boost::archive::no_infnan);
|
||||
|
||||
// Store (serialize) variables :
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
clog << "Serializing value : " << x[i] << " ... ";
|
||||
opba & x[i];
|
||||
clog << "Ok !" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exception & x)
|
||||
{
|
||||
cerr << "ERROR: " << x.what () << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_3.cpp
|
||||
@@ -1,105 +0,0 @@
|
||||
/** tutorial_pba_4.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This sample program shows how to use a portable binary archive
|
||||
* to store/load integer numbers of various sizes using the Boost
|
||||
* portable integer typedefs.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// The name for the example data file :
|
||||
string filename = "pba_4.data";
|
||||
|
||||
{
|
||||
// Some integer numbers :
|
||||
bool t = true;
|
||||
char c = 'c';
|
||||
unsigned char u = 'u';
|
||||
int8_t b = -3; // char
|
||||
uint8_t B = +6; // unsigned char
|
||||
int16_t s = -16;
|
||||
uint16_t S = +32;
|
||||
int32_t l = -128;
|
||||
uint32_t L = +127;
|
||||
int64_t ll = -1024;
|
||||
uint64_t LL = +2048;
|
||||
|
||||
// Open an output file stream in binary mode :
|
||||
ofstream fout (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file :
|
||||
boost::archive::portable_binary_oarchive opba (fout);
|
||||
|
||||
// Store (serialize) variables :
|
||||
opba & t & c & u & b & B & s & S & l & L & ll & LL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Single precision floating numbers to be loaded :
|
||||
// Some integer numbers :
|
||||
bool t;
|
||||
char c;
|
||||
unsigned char u;
|
||||
int8_t b;
|
||||
uint8_t B;
|
||||
int16_t s;
|
||||
uint16_t S;
|
||||
int32_t l;
|
||||
uint32_t L;
|
||||
int64_t ll;
|
||||
uint64_t LL;
|
||||
|
||||
// Open an input file stream in binary mode :
|
||||
ifstream fin (filename.c_str (), ios_base::binary);
|
||||
|
||||
{
|
||||
// Create an input portable binary archive attached to the input file :
|
||||
boost::archive::portable_binary_iarchive ipba (fin);
|
||||
|
||||
// Load (de-serialize) variables using the same
|
||||
// order than for serialization :
|
||||
ipba & t & c & u & b & B & s & S & l & L & ll & LL;
|
||||
}
|
||||
|
||||
clog << "t = " << t << " (bool)" << endl;
|
||||
clog << "c = '" << c << "' (char)" << endl;
|
||||
clog << "u = '" << u << "' (unsigned char)" << endl;
|
||||
clog << "b = " << (int) b << " (int8_t)" << endl;
|
||||
clog << "B = " << (int) B << " (uint8_t)" << endl;
|
||||
clog << "s = " << s << " (int16_t)" << endl;
|
||||
clog << "S = " << S << " (uint16_t)" << endl;
|
||||
clog << "l = " << l << " (int32_t)" << endl;
|
||||
clog << "L = " << L << " (uint32_t)" << endl;
|
||||
clog << "ll = " << ll << " (int64_t)" << endl;
|
||||
clog << "LL = " << LL << " (uint64_t)" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_4.cpp
|
||||
@@ -1,111 +0,0 @@
|
||||
/** tutorial_pba_5.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This sample program shows how to use a portable binary archive
|
||||
* to store/load data in a memory buffer.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// The memory buffer is implemented using a STL vector :
|
||||
typedef std::vector<char> buffer_type;
|
||||
buffer_type buffer;
|
||||
|
||||
{
|
||||
// Some data to be stored :
|
||||
bool t = true;
|
||||
char c = 'c';
|
||||
int16_t s = +16;
|
||||
int32_t l = -128;
|
||||
int64_t ll = +10000000000;
|
||||
float pi = 3.14159;
|
||||
double nan = numeric_limits<double>::quiet_NaN ();
|
||||
string hello = "World !";
|
||||
|
||||
buffer.reserve (1024); // pre-allocate some memory
|
||||
|
||||
// The output stream interface to the buffer :
|
||||
boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_type> > output_stream (buffer);
|
||||
|
||||
{
|
||||
// Create an output portable binary archive attached to the output file :
|
||||
boost::archive::portable_binary_oarchive opba (output_stream);
|
||||
|
||||
// Store (serialize) variables :
|
||||
opba & t & c & s & l & ll & pi & nan & hello;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clog << "Buffer content is " << buffer.size () << " bytes : " << endl << " ";
|
||||
for (int i = 0; i < buffer.size (); ++i)
|
||||
{
|
||||
clog << (int) ((unsigned char) buffer[i]) << ' ';
|
||||
if ((i + 1) % 20 == 0) clog << endl << " ";
|
||||
}
|
||||
clog << endl;
|
||||
|
||||
{
|
||||
// Some data to be loaded :
|
||||
bool t;
|
||||
char c;
|
||||
int16_t s;
|
||||
int32_t l;
|
||||
int64_t ll;
|
||||
float pi;
|
||||
double nan;
|
||||
string hello;
|
||||
|
||||
// The input stream interface to the buffer :
|
||||
boost::iostreams::stream<boost::iostreams::array_source> input_stream (&buffer[0],
|
||||
buffer.size ());
|
||||
|
||||
{
|
||||
// Create an input portable binary archive attached to the input file :
|
||||
boost::archive::portable_binary_iarchive ipba (input_stream);
|
||||
|
||||
// Load (de-serialize) variables :
|
||||
ipba & t & c & s & l & ll & pi & nan & hello;
|
||||
}
|
||||
|
||||
clog << "Loaded values from the buffer are: " << endl;
|
||||
clog << " t = " << t << " (bool)" << endl;
|
||||
clog << " c = '" << c << "' (char)" << endl;
|
||||
clog << " s = " << s << " (int16_t)" << endl;
|
||||
clog << " l = " << l << " (int32_t)" << endl;
|
||||
clog << " ll = " << ll << " (int64_t)" << endl;
|
||||
clog << " pi = " << pi << " (float)" << endl;
|
||||
clog << " nan = " << nan << " (double)" << endl;
|
||||
clog << " hello = \"" << hello << "\" (std::string)" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_5.cpp
|
||||
@@ -1,112 +0,0 @@
|
||||
/** tutorial_pba_6.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This sample program shows how to use a portable binary archive
|
||||
* associated to a memory buffer to copy a non-copyable object.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* A foo noncopyable class */
|
||||
struct foo : boost::noncopyable
|
||||
{
|
||||
uint32_t status;
|
||||
double value;
|
||||
double special;
|
||||
|
||||
string to_string () const
|
||||
{
|
||||
ostringstream sout;
|
||||
sout << "foo={status=" << status << "; value=" << value << "; special=" << special<< "}";
|
||||
return sout.str();
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize (Archive & ar, const unsigned int version)
|
||||
{
|
||||
ar & status;
|
||||
ar & value;
|
||||
ar & special;
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// A templatized copy function for Boost/Serialization equipped classes.
|
||||
// Here we use PBAs associated to a memory buffer :
|
||||
template <class Serializable>
|
||||
void copy (const Serializable & source, Serializable & target)
|
||||
{
|
||||
namespace io = boost::iostreams;
|
||||
namespace ba = boost::archive;
|
||||
if (&source == &target) return; // self-copy guard
|
||||
typedef std::vector<char> buffer_type;
|
||||
buffer_type buffer;
|
||||
buffer.reserve (1024);
|
||||
{
|
||||
io::stream<io::back_insert_device<buffer_type> > output_stream (buffer);
|
||||
ba::portable_binary_oarchive opba (output_stream);
|
||||
opba & source;
|
||||
}
|
||||
{
|
||||
io::stream<io::array_source> input_stream (&buffer[0], buffer.size ());
|
||||
ba::portable_binary_iarchive ipba (input_stream);
|
||||
ipba & target;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
// Some instance of the 'foo' class :
|
||||
foo dummy;
|
||||
dummy.status = 1;
|
||||
dummy.value = 3.14159;
|
||||
dummy.special = numeric_limits<double>::quiet_NaN ();
|
||||
clog << "dummy is : " << dummy.to_string () << endl;
|
||||
|
||||
// Another instance of the 'foo' class :
|
||||
foo clone;
|
||||
|
||||
/* The following instruction is forbidden because foo
|
||||
inherits 'boost::noncopyable' :
|
||||
|
||||
clone = dummy; // this ends in a compilation error.
|
||||
|
||||
*/
|
||||
|
||||
// Anyway, we can use this workaround :
|
||||
copy (dummy, clone);
|
||||
clog << "clone is : " << clone.to_string () << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_6.cpp
|
||||
@@ -1,54 +0,0 @@
|
||||
/** tutorial_pba_7.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example shows how the default behaviour of standard
|
||||
* I/O streams does not support the read/write operations of
|
||||
* non-finite floating point values in a portable way.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
{
|
||||
float x = numeric_limits<float>::infinity ();
|
||||
double y = numeric_limits<double>::quiet_NaN ();
|
||||
cout.precision (8);
|
||||
cout << "x = " << x << endl;
|
||||
cout.precision (16);
|
||||
cout << "y = " << y << endl;
|
||||
}
|
||||
|
||||
{
|
||||
string input ("inf nan");
|
||||
istringstream iss (input);
|
||||
float x;
|
||||
double y;
|
||||
iss >> x >> y;
|
||||
if (! iss)
|
||||
{
|
||||
cerr << "Cannot read 'x' or 'y' : non finite values are not supported !" << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_7.cpp
|
||||
@@ -1,118 +0,0 @@
|
||||
/** tutorial_pba_8.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example shows how to store some variables
|
||||
* of basic types (bool, integer, floating point numbers, STL string)
|
||||
* using the text or XML archive format associated to a
|
||||
* standard output file stream supporting portable non-finite
|
||||
* floating point values.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/xml_oarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/archive/codecvt_null.hpp>
|
||||
#include <boost/math/special_functions/nonfinite_num_facets.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void do_text_out (void)
|
||||
{
|
||||
// The name for the example data text file :
|
||||
string filename = "pba_8.txt";
|
||||
|
||||
// Some variables of various primitive types :
|
||||
bool b = true;
|
||||
char c = 'B';
|
||||
uint32_t answer = 42;
|
||||
float value = numeric_limits<float>::infinity ();
|
||||
double precision = numeric_limits<double>::quiet_NaN ();
|
||||
string question = "What makes you think she's a witch?";
|
||||
|
||||
// Open an output file stream :
|
||||
ofstream fout (filename.c_str ());
|
||||
|
||||
// Prepare the output file stream for inf/NaN support :
|
||||
locale default_locale (locale::classic (),
|
||||
new boost::archive::codecvt_null<char>);
|
||||
locale infnan_locale (default_locale,
|
||||
new boost::math::nonfinite_num_put<char>);
|
||||
fout.imbue (infnan_locale);
|
||||
|
||||
{
|
||||
// Create an output text archive attached to the output file :
|
||||
boost::archive::text_oarchive ota (fout, boost::archive::no_codecvt);
|
||||
|
||||
// Store (serializing) variables :
|
||||
ota & b & c & answer & value & precision & question;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void do_xml_out (void)
|
||||
{
|
||||
// The name for the example data XML file :
|
||||
string filename = "pba_8.xml";
|
||||
|
||||
// Some variables of various primitive types :
|
||||
bool b = true;
|
||||
char c = 'B';
|
||||
uint32_t answer = 42;
|
||||
float value = numeric_limits<float>::infinity ();
|
||||
double precision = numeric_limits<double>::quiet_NaN ();
|
||||
string question = "What makes you think she's a witch?";
|
||||
|
||||
// Open an output file stream :
|
||||
ofstream fout (filename.c_str ());
|
||||
|
||||
// Prepare the output file stream for inf/NaN support :
|
||||
locale default_locale (locale::classic (),
|
||||
new boost::archive::codecvt_null<char>);
|
||||
locale infnan_locale (default_locale,
|
||||
new boost::math::nonfinite_num_put<char>);
|
||||
fout.imbue (infnan_locale);
|
||||
|
||||
{
|
||||
// Create an output text archive attached to the output file :
|
||||
boost::archive::xml_oarchive oxa (fout, boost::archive::no_codecvt);
|
||||
|
||||
// Store (serializing) variables :
|
||||
oxa & BOOST_SERIALIZATION_NVP(b)
|
||||
& BOOST_SERIALIZATION_NVP(c)
|
||||
& BOOST_SERIALIZATION_NVP(answer)
|
||||
& BOOST_SERIALIZATION_NVP(value)
|
||||
& BOOST_SERIALIZATION_NVP(precision)
|
||||
& BOOST_SERIALIZATION_NVP(question);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
do_text_out ();
|
||||
do_xml_out ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_8.cpp
|
||||
@@ -1,134 +0,0 @@
|
||||
/** tutorial_pba_9.cpp
|
||||
*
|
||||
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The intent of this program is to serve as a tutorial for
|
||||
* users of the portable binary archive in the framework of
|
||||
* the Boost/Serialization library.
|
||||
*
|
||||
* This example shows how to load some variables of basic
|
||||
* types (bool, char, integer, floating point numbers, STL string)
|
||||
* using the text or XML archive format associated to a
|
||||
* standard file input stream supporting portable non-finite
|
||||
* floating point values.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/archive/xml_iarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/archive/codecvt_null.hpp>
|
||||
#include <boost/math/special_functions/nonfinite_num_facets.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void do_text_in (void)
|
||||
{
|
||||
// The name for the example data text file :
|
||||
string filename = "pba_8.txt";
|
||||
// Some variables of various primitive types :
|
||||
bool b;
|
||||
char c;
|
||||
uint32_t answer;
|
||||
float value;
|
||||
double precision;
|
||||
string question;
|
||||
|
||||
// Open an input file stream :
|
||||
ifstream fin (filename.c_str ());
|
||||
|
||||
// Prepare the input file stream for inf/NaN support :
|
||||
locale default_locale (locale::classic (),
|
||||
new boost::archive::codecvt_null<char>);
|
||||
locale infnan_locale (default_locale,
|
||||
new boost::math::nonfinite_num_get<char>);
|
||||
fin.imbue (infnan_locale);
|
||||
|
||||
{
|
||||
// Create an input text archive attached to the input file :
|
||||
boost::archive::text_iarchive ita (fin, boost::archive::no_codecvt);
|
||||
|
||||
// Store (serializing) variables :
|
||||
ita & b & c & answer & value & precision & question;
|
||||
}
|
||||
|
||||
clog << "Loaded values from text archive are: " << endl;
|
||||
clog << " b = " << b << endl;
|
||||
clog << " c = '" << c << "'" << endl;
|
||||
clog << " answer = " << answer << endl;
|
||||
clog << " value = " << value << endl;
|
||||
clog << " precision = " << precision << endl;
|
||||
clog << " question = \"" << question << "\"" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void do_xml_in (void)
|
||||
{
|
||||
// The name for the example data text file :
|
||||
string filename = "pba_8.xml";
|
||||
|
||||
// Some variables of various primitive types :
|
||||
bool b;
|
||||
char c;
|
||||
uint32_t answer;
|
||||
float value;
|
||||
double precision;
|
||||
string question;
|
||||
|
||||
// Open an input file stream :
|
||||
ifstream fin (filename.c_str ());
|
||||
|
||||
// Prepare the input file stream for inf/NaN support :
|
||||
locale default_locale (locale::classic (),
|
||||
new boost::archive::codecvt_null<char>);
|
||||
locale infnan_locale (default_locale,
|
||||
new boost::math::nonfinite_num_get<char>);
|
||||
fin.imbue (infnan_locale);
|
||||
|
||||
{
|
||||
// Create an output text archive attached to the output file :
|
||||
boost::archive::xml_iarchive ixa (fin, boost::archive::no_codecvt);
|
||||
|
||||
// Store (serializing) variables :
|
||||
ixa & BOOST_SERIALIZATION_NVP(b)
|
||||
& BOOST_SERIALIZATION_NVP(c)
|
||||
& BOOST_SERIALIZATION_NVP(answer)
|
||||
& BOOST_SERIALIZATION_NVP(value)
|
||||
& BOOST_SERIALIZATION_NVP(precision)
|
||||
& BOOST_SERIALIZATION_NVP(question);
|
||||
}
|
||||
|
||||
clog << "Loaded values from XML archive are: " << endl;
|
||||
clog << " b = " << b << endl;
|
||||
clog << " c = '" << c << "'" << endl;
|
||||
clog << " answer = " << answer << endl;
|
||||
clog << " value = " << value << endl;
|
||||
clog << " precision = " << precision << endl;
|
||||
clog << " question = \"" << question << "\"" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
do_text_in ();
|
||||
do_xml_in ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of tutorial_pba_9.cpp
|
||||
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,36 +0,0 @@
|
||||
IMPORTANT:
|
||||
|
||||
This is the last release from me as EOS employee. I plan to contribute all of this
|
||||
work to the official boost libraries distribution and will continue to support users.
|
||||
Francois Mauger joined me recently and already added a valuable tutorial for you!
|
||||
|
||||
|
||||
Dear user,
|
||||
|
||||
I am proud to announce the very first release of our portable_binary_[io]archive
|
||||
which we use here at EOS to move data between different platforms. It really is
|
||||
a conglomerate of pieces that already were there - as is most often the case in
|
||||
OO world - we simply put them together in a way that seemed to make sense. I know
|
||||
a lot of people were interested in portable binary archives, so here you are -
|
||||
give it a try and let me know what you think about it!
|
||||
|
||||
We rely heavily on boost::serialization and really appreciate the amount of time
|
||||
and knowledge that went into it. By publishing this small missing piece we hope
|
||||
to contribute our mite to this great library.
|
||||
|
||||
The work extends the portable binary example which was done by Robert Ramey and
|
||||
uses Beman Dawes' endian library plus the fp_utilities by Johan Rade. You will
|
||||
need to get those two libraries in order to use our classes - look for them at
|
||||
the boost vault (http://www.boost-consulting.com/vault/) in categories 'integer'
|
||||
and 'math - numerics'. Finally you will find the portable binary archive in
|
||||
category 'serialization' as well.
|
||||
|
||||
Regards,
|
||||
Christian Pfligersdorffer
|
||||
|
||||
Munich, End of 2007
|
||||
|
||||
--
|
||||
christian.pfligersdorffer@eos.info
|
||||
christian.pfligersdorffer@gmx.at
|
||||
http://www.eos.info
|
||||
@@ -1,151 +0,0 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v1.4
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://docs.jquery.com/License
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Wed Jan 13 15:23:05 2010 -0500
|
||||
*/
|
||||
(function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o<j;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,i);return a}return j?
|
||||
e(a[0],b):null}function K(){return(new Date).getTime()}function aa(){return false}function ba(){return true}function pa(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function qa(a){var b=true,d=[],f=[],e=arguments,i,j,o,p,n,t=c.extend({},c.data(this,"events").live);for(p in t){j=t[p];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget);
|
||||
n=0;for(l=i.length;n<l;n++)for(p in t){j=t[p];o=i[n].elem;f=null;if(i[n].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==o)d.push({elem:o,fn:j})}}n=0;for(l=d.length;n<l;n++){i=d[n];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}function ra(a,b){return["live",a,b.replace(/\./g,"`").replace(/ /g,"&")].join(".")}function sa(a){return!a||!a.parentNode||a.parentNode.nodeType===
|
||||
11}function ta(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ua(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:s;f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=
|
||||
i?f:1;return{fragment:f,cacheable:e}}function T(a){for(var b=0,d,f;(d=a[b])!=null;b++)if(!c.noData[d.nodeName.toLowerCase()]&&(f=d[H]))delete c.cache[f]}function L(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ma=A.jQuery,Na=A.$,s=A.document,U,Oa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/,
|
||||
Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
|
||||
c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector;
|
||||
this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=
|
||||
0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||
|
||||
c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];o=e[i];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(o)?[]:{};a[i]=c.extend(f,j,o)}else if(o!==w)a[i]=
|
||||
o}return a};c.extend({noConflict:function(a){A.$=Na;if(a)A.jQuery=Ma;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",M,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",
|
||||
M);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&oa()}}},isFunction:function(a){return ca.call(a)==="[object Function]"},isArray:function(a){return ca.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||ca.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!da.call(a,"constructor")&&!da.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===w||da.call(a,b)},
|
||||
isEmptyObject:function(a){for(var b in a)return false;return true},noop:function(){},globalEval:function(a){if(a&&Qa.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===w||c.isFunction(a);
|
||||
if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Ra,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ea.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=
|
||||
0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b===
|
||||
"string"){d=a;a=d[b];b=w}else if(b&&!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){var b={browser:""};a=a.toLowerCase();if(/webkit/.test(a))b={browser:"webkit",version:/webkit[\/ ]([\w.]+)/};else if(/opera/.test(a))b={browser:"opera",version:/version/.test(a)?/version[\/ ]([\w.]+)/:/opera[\/ ]([\w.]+)/};else if(/msie/.test(a))b={browser:"msie",version:/msie ([\w.]+)/};else if(/mozilla/.test(a)&&
|
||||
!/compatible/.test(a))b={browser:"mozilla",version:/rv:([\w.]+)/};b.version=(b.version&&b.version.exec(a)||[0,"0"])[1];return b},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=true;if(V)c.inArray=function(a,b){return V.call(b,a)};U=c(s);if(s.addEventListener)M=function(){s.removeEventListener("DOMContentLoaded",M,false);c.ready()};else if(s.attachEvent)M=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",
|
||||
M);c.ready()}};if(V)c.inArray=function(a,b){return V.call(b,a)};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+K();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,
|
||||
htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,
|
||||
a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in
|
||||
p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a,
|
||||
b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&&
|
||||
a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,
|
||||
a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,
|
||||
a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a,
|
||||
b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,o=b.length;j<o;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=
|
||||
" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.removeClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(za," "),j=0,o=b.length;j<o;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,
|
||||
b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),o=b,p=a.split(fa);e=p[i++];){o=f?o:!j.hasClass(e);j[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=
|
||||
" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(za," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(Aa.test(b.type)&&
|
||||
!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Va,"")}return w}var o=c.isFunction(a);return this.each(function(p){var n=c(this),t=a;if(this.nodeType===1){if(o)t=a.call(this,p,n.val());if(typeof t==="number")t+="";if(c.isArray(t)&&Aa.test(this.type))this.checked=c.inArray(n.val(),t)>=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex=
|
||||
-1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;
|
||||
if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===
|
||||
3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={};
|
||||
if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);
|
||||
for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+
|
||||
i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
|
||||
8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)},
|
||||
handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},
|
||||
props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||
|
||||
s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&
|
||||
a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a,
|
||||
b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=
|
||||
ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",
|
||||
mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+
|
||||
d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>
|
||||
-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d===
|
||||
"radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)},
|
||||
remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,
|
||||
f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,
|
||||
b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||
|
||||
a)},live:function(a,b,d){if(c.isFunction(b)){d=b;b=w}c(this.context).bind(ra(a,this.selector),{data:b,selector:this.selector,live:a},d);return this},die:function(a,b){c(this.context).unbind(ra(a,this.selector),b?{guid:b.guid+this.selector+a}:null);return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?
|
||||
this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",k,m=0;g[m];m++){k=g[m];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===
|
||||
k){y=m[u.sizset];break}if(u.nodeType===1&&!q){u.sizcache=k;u.sizset=r}if(u.nodeName.toLowerCase()===h){y=u;break}u=u[g]}m[r]=y}}}function d(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===k){y=m[u.sizset];break}if(u.nodeType===1){if(!q){u.sizcache=k;u.sizset=r}if(typeof h!=="string"){if(u===h){y=true;break}}else if(p.filter(h,[u]).length>0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();
|
||||
u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+
|
||||
(E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};p.matches=function(g,h){return p(g,null,null,h)};p.find=function(g,h,k){var m,r;if(!g)return[];
|
||||
for(var q=0,v=n.order.length;q<v;q++){var u=n.order[q];if(r=n.leftMatch[u].exec(g)){var y=r[1];r.splice(1,1);if(y.substr(y.length-1)!=="\\"){r[1]=(r[1]||"").replace(/\\/g,"");m=n.find[u](r,h,k);if(m!=null){g=g.replace(n.match[u],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};p.filter=function(g,h,k,m){for(var r=g,q=[],v=h,u,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var I in n.filter)if((u=n.leftMatch[I].exec(g))!=null&&u[2]){var N=n.filter[I],J,E;E=u[1];y=false;u.splice(1,1);if(E.substr(E.length-
|
||||
1)!=="\\"){if(v===q)q=[];if(n.preFilter[I])if(u=n.preFilter[I](u,v,k,q,m,S)){if(u===true)continue}else y=J=true;if(u)for(var X=0;(E=v[X])!=null;X++)if(E){J=N(E,u,X,v);var Ea=m^!!J;if(k&&J!=null)if(Ea)y=true;else v[X]=false;else if(Ea){q.push(E);y=true}}if(J!==w){k||(v=q);g=g.replace(n.match[I],"");if(!y)return[];break}}}if(g===r)if(y==null)throw"Syntax error, unrecognized expression: "+g;else break;r=g}return v};var n=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
||||
relative:{"+":function(g,h){var k=typeof h==="string",m=k&&!/\W/.test(h);k=k&&!m;if(m)h=h.toLowerCase();m=0;for(var r=g.length,q;m<r;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=k||q&&q.nodeName.toLowerCase()===h?q||false:q===h}k&&p.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m<r;m++){var q=g[m];if(q){k=q.parentNode;g[m]=k.nodeName.toLowerCase()===h?k:false}}}else{m=0;for(r=g.length;m<r;m++)if(q=g[m])g[m]=
|
||||
k?q.parentNode:q.parentNode===h;k&&p.filter(h,g,true)}},"":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("parentNode",h,m,g,q,k)},"~":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("previousSibling",h,m,g,q,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];
|
||||
h=h.getElementsByName(g[1]);for(var m=0,r=h.length;m<r;m++)h[m].getAttribute("name")===g[1]&&k.push(h[m]);return k.length===0?null:k}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,m,r,q){g=" "+g[1].replace(/\\/g,"")+" ";if(q)return g;q=0;for(var v;(v=h[q])!=null;q++)if(v)if(r^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m,
|
||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h=
|
||||
h[3];k=0;for(m=h.length;k<m;k++)if(h[k]===g)return false;return true}else throw"Syntax error, unrecognized expression: "+r;},CHILD:function(g,h){var k=h[1],m=g;switch(k){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(k==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":k=h[2];var r=h[3];if(k===1&&r===0)return true;h=h[0];var q=g.parentNode;if(q&&(q.sizcache!==h||!g.nodeIndex)){var v=0;for(m=q.firstChild;m;m=
|
||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;q.sizcache=h}g=g.nodeIndex-r;return k===0?g===0:g%k===0&&g/k>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
||||
"="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g,
|
||||
h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k<m;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var D;if(s.documentElement.compareDocumentPosition)D=function(g,h){if(!g.compareDocumentPosition||
|
||||
!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in s.documentElement)D=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(s.createRange)D=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),m=
|
||||
h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)j=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&&
|
||||
r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML="<a href='#'></a>";
|
||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}();
|
||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,
|
||||
h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r<q;r++)p(g,h[r],k);return p.filter(m,k)};c.find=p;c.expr=p.selectors;c.expr[":"]=c.expr.filters;c.unique=p.uniqueSort;c.getText=a;c.isXMLDoc=x;c.contains=F})();var ab=/Until$/,bb=/^(?:parents|prevUntil|prevAll)/,
|
||||
cb=/,/;R=Array.prototype.slice;var Fa=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Pa.test(b))return c.filter(b,f,!d);else b=c.filter(b,a)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
||||
c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Fa(this,a,false),"not",a)},filter:function(a){return this.pushStack(Fa(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i=
|
||||
{},j;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a===
|
||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType===
|
||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,hb=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},G={option:[1,"<select multiple='multiple'>","</select>"],
|
||||
legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);
|
||||
return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
||||
wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&
|
||||
this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,
|
||||
"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===
|
||||
1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!Y.test(a))&&!G[(Ha.exec(a)||["",""])[1].toLowerCase()])try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){T(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
||||
this[0].parentNode){c.isFunction(a)||(a=c(a).detach());return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(t){return c.nodeName(t,"table")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}var e,i,j=a[0],o=[];if(c.isFunction(j))return this.each(function(t){var z=
|
||||
c(this);a[0]=j.call(this,t,b?z.html():w);return z.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ua(a,this,o);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var p=0,n=this.length;p<n;p++)d.call(b?f(this[p],i):this[p],e.cacheable||this.length>1||p>0?e.fragment.cloneNode(true):e.fragment)}o&&c.each(o,La)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
|
||||
function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){T(this.getElementsByTagName("*"));T([this])}this.parentNode&&this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&T(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},
|
||||
function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j==="string"){j=j.replace(db,hb);var o=(Ha.exec(j)||["",""])[1].toLowerCase(),p=G[o]||G._default,n=p[0];i=b.createElement("div");for(i.innerHTML=p[1]+j+p[2];n--;)i=i.lastChild;
|
||||
if(!c.support.tbody){n=fb.test(j);o=o==="table"&&!n?i.firstChild&&i.firstChild.childNodes:p[1]==="<table>"&&!n?i.childNodes:[];for(p=o.length-1;p>=0;--p)c.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!c.support.leadingWhitespace&&Y.test(j)&&i.insertBefore(b.createTextNode(Y.exec(j)[0]),i.firstChild);j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()===
|
||||
"text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e}});var ib=/z-?index|font-?weight|opacity|zoom|line-?height/i,Ia=/alpha\([^)]*\)/,Ja=/opacity=([^)]*)/,ja=/float/i,ka=/-([a-z])/ig,jb=/([A-Z])/g,kb=/^-?\d+(?:px)?$/i,lb=/^-?\d/,mb={position:"absolute",visibility:"hidden",display:"block"},nb=["Left","Right"],ob=["Top","Bottom"],pb=s.defaultView&&
|
||||
s.defaultView.getComputedStyle,Ka=c.support.cssFloat?"cssFloat":"styleFloat",la=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return $(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!ib.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""===
|
||||
"NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ia.test(a)?a.replace(Ia,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ja.exec(f.filter)[1])/100+"":""}if(ja.test(b))b=Ka;b=b.replace(ka,la);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?nb:ob;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=
|
||||
parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,mb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Ja.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ja.test(b))b=Ka;if(!d&&e&&e[b])f=e[b];else if(pb){if(ja.test(b))b="float";b=b.replace(jb,"-$1").toLowerCase();e=
|
||||
a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ka,la);f=a.currentStyle[b]||a.currentStyle[d];if(!kb.test(f)&&lb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=
|
||||
f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var qb=K(),rb=/<script(.|\s)*?\/script>/gi,sb=/select|textarea/i,tb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,O=/=\?(&|$)/,ma=/\?/,ub=/(\?|&)_=.*?(&|$)/,vb=/^(\w+:)?\/\/([^\/?#]+)/,
|
||||
wb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}c.ajax({url:a,type:f,dataType:"html",data:b,context:this,complete:function(i,j){if(j==="success"||j==="notmodified")this.html(e?c("<div />").append(i.responseText.replace(rb,
|
||||
"")).find(e):i.responseText);d&&this.each(d,[i.responseText,j,i])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sb.test(this.nodeName)||tb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});
|
||||
c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},
|
||||
ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",
|
||||
text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(p,o,j,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(p,x,j);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(r,q){(e.context?c(e.context):c.event).trigger(r,q)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,o,p=e.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,
|
||||
e.traditional);if(e.dataType==="jsonp"){if(n==="GET")O.test(e.url)||(e.url+=(ma.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!O.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&O.test(e.data)||O.test(e.url))){i=e.jsonpCallback||"jsonp"+qb++;if(e.data)e.data=(e.data+"").replace(O,"="+i+"$1");e.url=e.url.replace(O,"="+i+"$1");e.dataType="script";A[i]=A[i]||function(r){o=r;b();d();A[i]=w;try{delete A[i]}catch(q){}B&&
|
||||
B.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&n==="GET"){var t=K(),z=e.url.replace(ub,"$1_="+t+"$2");e.url=z+(z===e.url?(ma.test(e.url)?"&":"?")+"_="+t:"")}if(e.data&&n==="GET")e.url+=(ma.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");t=(t=vb.exec(e.url))&&(t[1]&&t[1]!==location.protocol||t[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&t){var B=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");
|
||||
C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!i){var D=false;C.onload=C.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;b();d();C.onload=C.onreadystatechange=null;B&&C.parentNode&&B.removeChild(C)}}}B.insertBefore(C,B.firstChild);return w}var F=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",
|
||||
e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}t||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ia){}if(e.beforeSend&&e.beforeSend.call(p,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",
|
||||
[x,e]);var g=x.onreadystatechange=function(r){if(!x||x.readyState===0){F||d();F=true;if(x)x.onreadystatechange=c.noop}else if(!F&&x&&(x.readyState===4||r==="timeout")){F=true;x.onreadystatechange=c.noop;j=r==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";if(j==="success")try{o=c.httpData(x,e.dataType,e)}catch(q){j="parsererror"}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,x,j);d();r==="timeout"&&x.abort();if(e.async)x=
|
||||
null}};try{var h=x.abort;x.abort=function(){if(x){h.call(x);if(x)x.readyState=0}g()}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){x&&!F&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||A,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol===
|
||||
"file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;if(e&&a.documentElement.nodeName==="parsererror")throw"parsererror";if(d&&
|
||||
d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))a=A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+a))();else throw"Invalid JSON: "+a;else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(e,i){i=
|
||||
c.isFunction(i)?i():i;f[f.length]=encodeURIComponent(e)+"="+encodeURIComponent(i)}var f=[];if(b===w)b=c.ajaxSettings.traditional;c.isArray(a)||a.jquery?c.each(a,function(){d(this.name,this.value)}):c.each(a,function e(i,j){if(c.isArray(j))c.each(j,function(o,p){b?d(i,p):e(i+"["+(typeof p==="object"||c.isArray(p)?o:"")+"]",p)});else!b&&j!=null&&typeof j==="object"?c.each(j,function(o,p){e(i+"["+o+"]",p)}):d(i,j)});return f.join("&").replace(wb,"+")}});var na={},xb=/toggle|show|hide/,yb=/^([+-]=)?([\d+-.]+)(.*)$/,
|
||||
Z,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a!=null)return this.animate(L("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(na[d])f=na[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
|
||||
na[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a!=null)return this.animate(L("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
|
||||
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(L("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,o=this.nodeType===1&&c(this).is(":hidden"),
|
||||
p=this;for(j in a){var n=j.replace(ka,la);if(j!==n){a[n]=a[j];delete a[j];j=n}if(a[j]==="hide"&&o||a[j]==="show"&&!o)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(t,z){var B=new c.fx(p,i,t);if(xb.test(z))B[z==="toggle"?o?"show":"hide":z](a);
|
||||
else{var C=yb.exec(z),D=B.cur(true)||0;if(C){z=parseFloat(C[2]);var F=C[3]||"px";if(F!=="px"){p.style[t]=(z||1)+F;D=(z||1)/B.cur(true)*D;p.style[t]=D+F}if(C[1])z=(C[1]==="-="?-1:1)*z+D;B.custom(D,z,F)}else B.custom(D,z,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:L("show",1),slideUp:L("hide",1),slideToggle:L("toggle",
|
||||
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
|
||||
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
|
||||
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=K();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!Z)Z=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
|
||||
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=K(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
|
||||
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
|
||||
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(Z);Z=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
|
||||
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
|
||||
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(t){c.offset.setOffset(this,a,t)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
|
||||
b,e=b.ownerDocument,i,j=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var p=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;p-=b.scrollTop;n-=b.scrollLeft;if(b===d){p+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){p+=parseFloat(i.borderTopWidth)||
|
||||
0;n+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){p+=parseFloat(i.borderTopWidth)||0;n+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){p+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){p+=Math.max(j.scrollTop,o.scrollTop);n+=Math.max(j.scrollLeft,o.scrollLeft)}return{top:p,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),
|
||||
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
|
||||
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
|
||||
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
|
||||
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
|
||||
this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==w)return this.each(function(){if(i=wa(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=wa(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
|
||||
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+
|
||||
b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
||||
@@ -1,39 +0,0 @@
|
||||
/*=============================================================================
|
||||
Copyright 2002 William E. Kempf
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompany-
|
||||
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
H1
|
||||
{
|
||||
FONT-SIZE: 200%;
|
||||
COLOR: #00008B;
|
||||
}
|
||||
H2
|
||||
{
|
||||
FONT-SIZE: 150%;
|
||||
}
|
||||
H3
|
||||
{
|
||||
FONT-SIZE: 125%;
|
||||
}
|
||||
H4
|
||||
{
|
||||
FONT-SIZE: 108%;
|
||||
}
|
||||
/*
|
||||
BODY
|
||||
{
|
||||
FONT-SIZE: 100%;
|
||||
BACKGROUND-COLOR: #ffffff;
|
||||
COLOR: #000000;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
PRE
|
||||
{
|
||||
MARGIN-LEFT: 2em;
|
||||
FONT-FAMILY: Courier,
|
||||
monospace;
|
||||
}
|
||||
*/
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
body
|
||||
{
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
border-right: gray 1pt solid;
|
||||
border-top: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
margin-left: 0pt;
|
||||
background-color: #EEEEEE;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.button
|
||||
{
|
||||
color : black;
|
||||
background-color : #FFFFFF;
|
||||
border-radius: 0px;
|
||||
border: outset 3px #d6d6d6;
|
||||
text-decoration : none;
|
||||
outline:none;
|
||||
}
|
||||
|
||||
.fs
|
||||
{
|
||||
font-family: courier;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
.code_string
|
||||
{
|
||||
font-family: courier;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: #bc8f8f;
|
||||
}
|
||||
|
||||
.code
|
||||
{
|
||||
/*
|
||||
top: 0;
|
||||
border-style: inset;
|
||||
margin-top: 5pt;
|
||||
margin-bottom: 5pt;
|
||||
margin-left: 5pt;
|
||||
margin-right: 5pt;
|
||||
border-width: 2px 2px 2px 2px ;
|
||||
*/
|
||||
font-family: courier;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: #228b22;
|
||||
}
|
||||
|
||||
.byte
|
||||
{
|
||||
border-right: gray 1pt solid;
|
||||
border-top: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
margin-left: 2pt;
|
||||
margin-right: 2pt;
|
||||
font-family: courier;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
#pre
|
||||
{
|
||||
border-right: gray 1pt solid;
|
||||
border-top: gray 1pt solid;
|
||||
border-left: gray 1pt solid;
|
||||
border-bottom: gray 1pt solid;
|
||||
margin-left: 1pt;
|
||||
margin-right: 1pt;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
/*
|
||||
(C) Copyright 2011 François Mauger.
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
@@ -1,104 +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 .
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - BOOST_STATIC_WARNING</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Serialization</h1>
|
||||
<h2 align="center"><code>void_cast</code></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h3>Motivation</h3>
|
||||
C++ includes the operator <code style="white-space: normal">dynamic_cast<T>(U * u)</code>
|
||||
for casting a pointer at runtime between two related types. However, this can only be
|
||||
used for polymorphic classes. That is, it can only be used with related classes which have at least one virtual function.
|
||||
Limiting the serializaton of pointers to only such classes would diminish the applicability
|
||||
of the library.
|
||||
|
||||
<h3>Usage</h3>
|
||||
|
||||
The following functions are defined in the header
|
||||
<a target="void_cast" href="../../../boost/serialization/void_cast.hpp">void_cast.hpp</a>.
|
||||
They are declared in the namespace
|
||||
<code style="white-space: normal">boost::serialization</code>.
|
||||
|
||||
<dl>
|
||||
<dt><h4><pre><code>
|
||||
template<class Derived, class Base>
|
||||
const void_cast_detail::void_caster &
|
||||
void_cast_register(
|
||||
Derived const * derived = NULL,
|
||||
Base * const base = NULL
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
This function "registers" a pair of related types. It stores the fact that
|
||||
<code style="white-space: normal">Derived</code> is immediately derived from
|
||||
<code style="white-space: normal">Base</code> in a global table.
|
||||
<ul>
|
||||
<li>This "registration" can be invoked anywhere in the program. The table is built at
|
||||
pre-runtime and is available anywhere else in the program.
|
||||
<li>only adjacent base/derived pairs need be registered. That is,
|
||||
<pre><code>
|
||||
void_cast_register<A, B>();
|
||||
void_cast_register<B, C>();
|
||||
</code></pre>
|
||||
automatically derives the fact that A can be upcast to C and vice-versa.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_upcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
|
||||
<dt><h4><pre><code>
|
||||
void *
|
||||
void_downcast(
|
||||
extended_type_info const & derived_type,
|
||||
extended_type_info const & base_type,
|
||||
void * const t
|
||||
);
|
||||
</code></pre></h4></dt>
|
||||
<dd>
|
||||
These functions cast a void pointer from one type to another. The source and
|
||||
definition types are specified by passing references to the corresponding
|
||||
<a href="extended_type_info.html"><code style="white-space: normal">
|
||||
extended_type_info</code></a>
|
||||
records. An attempt to cast between types not "registered" with
|
||||
<code style="white-space: normal">void_cast_register</code>
|
||||
will throw a
|
||||
<a href="exceptions.html"><code style="white-space: normal">boost::archive::archive_exception</code></a>
|
||||
with value equal to
|
||||
<code style="white-space: normal">unregistered_cast</code>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<!--
|
||||
(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
@@ -7,7 +7,7 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Serialization - Serialization Wrappers</title>
|
||||
@@ -27,9 +27,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#binaryobjects">Binary Objects</a>
|
||||
<dt><a href="#arrays">Arrays</a>
|
||||
<dt><a href="#strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a>
|
||||
<dt><a href="#collection_size_type">Collection Sizes</a>
|
||||
<dt><a href="#nvp">Name-Value Pairs</a>
|
||||
<dt><a href="#composition">Composition</a>
|
||||
</dl>
|
||||
@@ -38,12 +36,9 @@ of some underlying data. This permits an archive class to define special
|
||||
handling of this type. The library includes several such types for varying
|
||||
purposes.
|
||||
<p>
|
||||
Wrappers need to be treated in a special way by some archives, and hence
|
||||
the <A href="traits.html#wrappers"><code>is_wrapper</code></a> trait for
|
||||
these wrapper classes is set to true.
|
||||
|
||||
<h3><a name="binaryobjects">Binary Objects</a></h3>
|
||||
A binary object is just 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,47 +54,8 @@ 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>.
|
||||
The purpose of this wrapper is to support archive types (such as binary
|
||||
archives) that provide optimized serialization for contiguous sequences of
|
||||
objects of the same type.
|
||||
|
||||
The header file
|
||||
<a href="../../../boost/serialization/array.hpp" target="array_hpp">
|
||||
array.hpp
|
||||
</a>
|
||||
includes the function
|
||||
<pre><code>
|
||||
template <T>
|
||||
boost::serialization::make_array(T* t, std::size_t size);
|
||||
</code></pre>
|
||||
which will construct a temporary <code>array</code> object
|
||||
<pre><code>
|
||||
template<class T>
|
||||
class array
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
array(value_type* t, std::size_t s);
|
||||
value_type* address() const;
|
||||
std::size_t count() const;
|
||||
};
|
||||
</code></pre>
|
||||
that can be serialized just like any other object.
|
||||
Its default serialization is to serialize each array element.
|
||||
Note that it doesn't allocated any storage or create any objects.
|
||||
Its sole purpose is to pass the data type, size and address to the archive class.
|
||||
|
||||
Archive types that can provide optimized implementations for contiguous
|
||||
arrays of homogeneous data types should overload the serialization of
|
||||
<code>array</code>.
|
||||
|
||||
|
||||
<h3><a name="strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></h3>
|
||||
Another example of a serialization wrapper is the
|
||||
<a href="strong_typedef.html"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a> template.
|
||||
@@ -111,26 +67,6 @@ as an XML attribute in the form "version=12". In the absence of any specific ov
|
||||
these types are automatically converted to the underlying integer type so the
|
||||
special overrides used for XML archives aren't needed for other archives.
|
||||
|
||||
|
||||
|
||||
<h3><a name="collection_size_type">Collection Sizes</h3>
|
||||
An example of a strong typedef is the <code>collection_size_type</code> in the
|
||||
header file
|
||||
<a href="../../../boost/serialization/collection_size_type.hpp" target="collection_size_type_hpp">
|
||||
collection_size_type.hpp
|
||||
</a>. This type should be used for serializaing the size of a C++ collection, so
|
||||
that the archive can pick the best integral representation for the serialization
|
||||
of collection sizes. This is necessary since, although <code>std::size_t</code>
|
||||
is guaranteed to be an integral type large enough to represent the size of
|
||||
a collection on a specific platform, the archive might want to serialize
|
||||
the size differently than this type. For example, the <code>collection_size_type</code>
|
||||
might be serialized as a variable length integer in a portable binary archive.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3><a name="nvp">Name-Value Pairs</h3>
|
||||
XML archives present a somewhat special case. XML format has a nested
|
||||
structure that maps well to the "recursive class member visitor" pattern used
|
||||
@@ -143,17 +79,7 @@ Our solution is to wrap class members to be serialized in a
|
||||
<strong>name-value-pair</strong>. This structure is defined in
|
||||
<a href="../../../boost/serialization/nvp.hpp" target="nvp_hpp">nvp.hpp</a>.
|
||||
It is just a reference to the data member coupled with a pointer to
|
||||
to a <code style="white-space: normal">const char *</code> which
|
||||
corresponds to the XML name. It implements the default
|
||||
serialization functions for a name-value pair. This default
|
||||
action is to just ignore the item name and serialize the
|
||||
data value in the normal manner. For archive classes that
|
||||
don't make any special provision for name-value pairs, this
|
||||
is the action which will be invoked when the name-value pair
|
||||
is serialized. Hence, wrapping a data value into a name-value
|
||||
pair will have no effect when used with archives which
|
||||
make no special provision for this wrapper.
|
||||
<p>
|
||||
to a <code style="white-space: normal">const char *</code> which corresponds to the XML name.
|
||||
The xml archive classes contain code similar to:
|
||||
<pre><code>
|
||||
// special treatment for name-value pairs.
|
||||
@@ -170,8 +96,26 @@ xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
end_tag(t.name());
|
||||
}
|
||||
</code></pre>
|
||||
Archive classes which don't use the name of the data item include
|
||||
code similar to the following:
|
||||
<pre><code>
|
||||
// special treatment for name-value pairs. In a simple
|
||||
// text archive, just output the value in the normal way.
|
||||
// the name is not used
|
||||
template<class IStream, class T>
|
||||
text_oarchive & operator&(const boost::serialization::nvp<T> & t)
|
||||
{
|
||||
*this & t.value();
|
||||
}
|
||||
</code></pre>
|
||||
That is, the name part is ignored and and the value part is serialized
|
||||
as usual.
|
||||
<p>
|
||||
Hence, adding the name of the data item does not in any way affect the usage
|
||||
of archives which don't use it.
|
||||
<p>
|
||||
The most obvious and convient name to assign to as the XML data item name
|
||||
is - surprise! - the name of the C++ class data member. So our serialization
|
||||
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);
|
||||
@@ -184,15 +128,12 @@ Similarly there exists a macro definition that permits us to write:
|
||||
<pre><code>
|
||||
BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class)
|
||||
</code></pre>
|
||||
|
||||
Note that these macros must be used in the namespace of the class,
|
||||
and without qualifying the namespace in the argument.
|
||||
|
||||
<p>
|
||||
<a href="../example/demo_gps.hpp" target="demo_gps_hpp">demo_gps.hpp<a>
|
||||
includes NVP wrappers or all data members.
|
||||
Included is
|
||||
<a href="../example/demo_xml.hpp" target="demo_xml_hpp">demo_xml.hpp<a>
|
||||
which renders it's data members as <strong>name-value-pair</strong>s and
|
||||
<a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp<a>
|
||||
saves and loads data to an XML archive.
|
||||
which saves and loads data to an XML archive.
|
||||
<a href="../example/demo_save.xml" target="demo_save_xml">Here</a>
|
||||
is example of the XML Archive corresponding to our tutorial example.
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# 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
|
||||
<include>$(BOOST_ROOT)
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<borland><*><cxxflags>-w-8080
|
||||
<msvc><release><cxxflags>-Gy
|
||||
<vc7><release><cxxflags>-Gy
|
||||
<vc7.1><release><cxxflags>-Gy
|
||||
: # default build
|
||||
debug
|
||||
<runtime-link>static
|
||||
;
|
||||
}
|
||||
|
||||
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,42 +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 ../util/test :
|
||||
run-template
|
||||
run-invoke
|
||||
run-winvoke
|
||||
test-bsl-run-no-lib
|
||||
test-bsl-run
|
||||
test-bsl-run_archive
|
||||
test-bsl-run_files
|
||||
test-bsl-run_polymorphic_archive
|
||||
;
|
||||
|
||||
test-suite "demo-suite" :
|
||||
# demos
|
||||
[ test-bsl-run demo ]
|
||||
[ test-bsl-run demo_auto_ptr ]
|
||||
[ test-bsl-run demo_exception ]
|
||||
[ test-bsl-run demo_fast_archive ]
|
||||
[ test-bsl-run demo_log : log_archive ]
|
||||
[ test-bsl-run demo_pimpl : demo_pimpl_A ]
|
||||
[ test-bsl-run demo_polymorphic : demo_polymorphic_A ]
|
||||
[ test-bsl-run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
|
||||
[ test-bsl-run demo_shared_ptr ]
|
||||
[ test-bsl-run demo_simple_log ]
|
||||
[ test-bsl-run demo_trivial_archive ]
|
||||
[ test-bsl-run demo_xml ]
|
||||
[ test-bsl-run demo_xml_save ]
|
||||
[ test-bsl-run demo_xml_load : : : <dependency>demo_xml_save ]
|
||||
;
|
||||
|
||||
@@ -7,21 +7,18 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#include <cstddef> // NULL
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/assume_abstract.hpp>
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// The intent of this program is to serve as a tutorial for
|
||||
@@ -94,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)
|
||||
{
|
||||
@@ -265,7 +262,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)
|
||||
{
|
||||
|
||||
@@ -20,34 +20,41 @@ namespace std{
|
||||
#endif
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
|
||||
#include <boost/serialization/split_free.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace boost { namespace serialization {
|
||||
#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
namespace _STLP_STD {
|
||||
#else
|
||||
namespace std {
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// the ref count is rebuilt automatically on load
|
||||
const T * const tx = t.get();
|
||||
ar << tx;
|
||||
ar << t.get();
|
||||
}
|
||||
|
||||
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 +62,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,14 +73,20 @@ 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);
|
||||
}
|
||||
|
||||
// function specializations must be defined in the appropriate
|
||||
// namespace - boost::serialization
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
#else
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// test auto_ptr serialization
|
||||
@@ -91,14 +104,14 @@ public:
|
||||
~A(){} // default destructor
|
||||
};
|
||||
|
||||
void save(const std::auto_ptr<A> & spa, const char *filename)
|
||||
void save(std::auto_ptr<A> &spa, const char *filename)
|
||||
{
|
||||
std::ofstream ofs(filename);
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
oa << spa;
|
||||
}
|
||||
|
||||
void load(std::auto_ptr<A> & spa, const char *filename)
|
||||
void load(std::auto_ptr<A> &spa, const char *filename)
|
||||
{
|
||||
// open the archive
|
||||
std::ifstream ifs(filename);
|
||||
|
||||
@@ -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 .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib> // for rand()
|
||||
#include <cmath> // for fabs()
|
||||
#include <cstddef> // size_t
|
||||
#include <boost/math/special_functions/next.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
using ::fabs;
|
||||
using ::size_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include <boost/test/test_exec_monitor.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
#include <boost/archive/dinkumware.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
// note: from an aesthetic perspective, I would much prefer to have this
|
||||
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
|
||||
// compiler. So hold our nose and put it her to permit running of tests.
|
||||
template<class Archive>
|
||||
void serialize(
|
||||
Archive &ar,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
ar & BOOST_SERIALIZATION_NVP(b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
ar & BOOST_SERIALIZATION_NVP(f);
|
||||
ar & BOOST_SERIALIZATION_NVP(g);
|
||||
#endif
|
||||
#if BOOST_WORKAROUND(__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 .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib> // for rand()
|
||||
#include <cmath> // for fabs()
|
||||
#include <cstddef> // size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
using ::fabs;
|
||||
using ::size_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include <boost/test/test_exec_monitor.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
#include <boost/archive/dinkumware.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
// note: from an aesthetic perspective, I would much prefer to have this
|
||||
// defined out of line. Unfortunately, this trips a bug in the VC 6.0
|
||||
// compiler. So hold our nose and put it her to permit running of tests.
|
||||
template<class Archive>
|
||||
void serialize(
|
||||
Archive &ar,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
ar & BOOST_SERIALIZATION_NVP(b);
|
||||
#ifndef BOOST_NO_INT64_T
|
||||
ar & BOOST_SERIALIZATION_NVP(f);
|
||||
ar & BOOST_SERIALIZATION_NVP(g);
|
||||
#endif
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 )
|
||||
int i;
|
||||
if(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 .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cstdlib> // for rand()
|
||||
#include <boost/math/special_functions/next.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
|
||||
#include "A.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Derived class test
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void save(Archive &ar, const unsigned int /* file_version */) const
|
||||
{
|
||||
// write any base class info to the archive
|
||||
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
|
||||
// write out members
|
||||
ar << BOOST_SERIALIZATION_NVP(s);
|
||||
ar << BOOST_SERIALIZATION_NVP(t);
|
||||
ar << BOOST_SERIALIZATION_NVP(u);
|
||||
ar << BOOST_SERIALIZATION_NVP(v);
|
||||
ar << BOOST_SERIALIZATION_NVP(w);
|
||||
ar << BOOST_SERIALIZATION_NVP(x);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, const unsigned int file_version)
|
||||
{
|
||||
// read any base class info to the archive
|
||||
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
switch(file_version){
|
||||
case 1:
|
||||
case 2:
|
||||
ar >> BOOST_SERIALIZATION_NVP(s);
|
||||
ar >> BOOST_SERIALIZATION_NVP(t);
|
||||
ar >> BOOST_SERIALIZATION_NVP(u);
|
||||
ar >> BOOST_SERIALIZATION_NVP(v);
|
||||
ar >> BOOST_SERIALIZATION_NVP(w);
|
||||
ar >> BOOST_SERIALIZATION_NVP(x);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
public:
|
||||
B();
|
||||
virtual ~B(){};
|
||||
bool operator==(const B &rhs) const;
|
||||
};
|
||||
|
||||
B::B() :
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand() / std::rand()),
|
||||
x((double)std::rand() / std::rand())
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(B, 2)
|
||||
|
||||
inline bool B::operator==(const B &rhs) const
|
||||
{
|
||||
return
|
||||
A::operator==(rhs)
|
||||
&& s == rhs.s
|
||||
&& t == rhs.t
|
||||
&& u == rhs.u
|
||||
&& v == rhs.v
|
||||
&& std::abs( boost::math::float_distance(w, rhs.w)) < 2
|
||||
&& std::abs( boost::math::float_distance(x, rhs.x)) < 2
|
||||
;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_B_HPP
|
||||
@@ -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 .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#include <cstdlib> // for rand()
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::rand;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
|
||||
#include "A.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Derived class test
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void save(Archive &ar, const unsigned int /* file_version */) const
|
||||
{
|
||||
// write any base class info to the archive
|
||||
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
|
||||
// write out members
|
||||
ar << BOOST_SERIALIZATION_NVP(s);
|
||||
ar << BOOST_SERIALIZATION_NVP(t);
|
||||
ar << BOOST_SERIALIZATION_NVP(u);
|
||||
ar << BOOST_SERIALIZATION_NVP(v);
|
||||
ar << BOOST_SERIALIZATION_NVP(w);
|
||||
ar << BOOST_SERIALIZATION_NVP(x);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive & ar, const unsigned int file_version)
|
||||
{
|
||||
// read any base class info to the archive
|
||||
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
|
||||
switch(file_version){
|
||||
case 1:
|
||||
case 2:
|
||||
ar >> BOOST_SERIALIZATION_NVP(s);
|
||||
ar >> BOOST_SERIALIZATION_NVP(t);
|
||||
ar >> BOOST_SERIALIZATION_NVP(u);
|
||||
ar >> BOOST_SERIALIZATION_NVP(v);
|
||||
ar >> BOOST_SERIALIZATION_NVP(w);
|
||||
ar >> BOOST_SERIALIZATION_NVP(x);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
signed char s;
|
||||
unsigned char t;
|
||||
signed int u;
|
||||
unsigned int v;
|
||||
float w;
|
||||
double x;
|
||||
public:
|
||||
B();
|
||||
virtual ~B(){};
|
||||
bool operator==(const B &rhs) const;
|
||||
};
|
||||
|
||||
B::B() :
|
||||
s(std::rand()),
|
||||
t(std::rand()),
|
||||
u(std::rand()),
|
||||
v(std::rand()),
|
||||
w((float)std::rand() / std::rand()),
|
||||
x((double)std::rand() / std::rand())
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(B, 2)
|
||||
|
||||
inline bool B::operator==(const B &rhs) const
|
||||
{
|
||||
return
|
||||
A::operator==(rhs)
|
||||
&& s == rhs.s
|
||||
&& t == rhs.t
|
||||
&& u == rhs.u
|
||||
&& v == rhs.v
|
||||
&& std::abs( boost::math::float_distance(w, rhs.w)) < 2
|
||||
&& std::abs( boost::math::float_distance(x, rhs.x)) < 2
|
||||
;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_TEST_B_HPP
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <cstddef> // NULL
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
@@ -37,12 +36,12 @@ namespace std{
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
template<class TPTR>
|
||||
struct deleter
|
||||
{
|
||||
@@ -214,7 +213,7 @@ void init(School *school){
|
||||
// carol has no courses
|
||||
}
|
||||
|
||||
void save(const School * const school, const char *filename){
|
||||
void save(School *school, const char *filename){
|
||||
std::ofstream ofile(filename);
|
||||
boost::archive::text_oarchive ar(ofile);
|
||||
ar << school;
|
||||
|
||||
@@ -11,158 +11,120 @@
|
||||
|
||||
#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 <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
|
||||
using namespace boost::archive;
|
||||
|
||||
// include template definitions for base classes used. Otherwise
|
||||
// you'll get link failure with undefined symbols
|
||||
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_oarchive.ipp>
|
||||
#include <boost/archive/impl/basic_binary_iarchive.ipp>
|
||||
|
||||
using namespace boost::archive;
|
||||
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
|
||||
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// "Fast" output binary archive. This is a variation of the native binary
|
||||
class fast_binary_oarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_oarchive_impl<
|
||||
fast_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>
|
||||
public binary_oarchive_impl<fast_binary_oarchive>
|
||||
{
|
||||
typedef fast_binary_oarchive derived_t;
|
||||
typedef binary_oarchive_impl<
|
||||
fast_binary_oarchive,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class boost::archive::detail::interface_oarchive<derived_t>;
|
||||
friend class basic_binary_oarchive<derived_t>;
|
||||
friend class basic_binary_oprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class basic_binary_oprimitive<derived_t, std::ostream>;
|
||||
friend class boost::archive::save_access;
|
||||
#endif
|
||||
// add base class to the places considered when matching
|
||||
// save function to a specific set of arguments. Note, this didn't
|
||||
// work on my MSVC 7.0 system using
|
||||
// binary_oarchive_impl<derived_t>::load_override;
|
||||
// work on my MSVC 7.0 system
|
||||
// using binary_oarchive_impl<derived_t>::load_override;
|
||||
// so we use the sure-fire method below. This failed to work as well
|
||||
template<class T>
|
||||
void save_override(T & t){
|
||||
base_t::save_override(t);
|
||||
void save_override(const T & t, BOOST_PFTO int){
|
||||
binary_oarchive_impl<fast_binary_oarchive>::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:
|
||||
fast_binary_oarchive(std::ostream & os, unsigned flags = 0) :
|
||||
base_t(os, flags)
|
||||
{}
|
||||
fast_binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) :
|
||||
base_t(bsb, flags)
|
||||
binary_oarchive_impl<derived_t>(os, flags)
|
||||
{}
|
||||
};
|
||||
|
||||
// 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
|
||||
class fast_binary_iarchive :
|
||||
// don't derive from binary_oarchive !!!
|
||||
public binary_iarchive_impl<
|
||||
fast_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
>
|
||||
public binary_iarchive_impl<fast_binary_iarchive>
|
||||
{
|
||||
typedef fast_binary_iarchive derived_t;
|
||||
typedef binary_iarchive_impl<
|
||||
fast_binary_iarchive,
|
||||
std::istream::char_type,
|
||||
std::istream::traits_type
|
||||
> base_t;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class boost::archive::detail::interface_iarchive<derived_t>;
|
||||
friend class basic_binary_iarchive<derived_t>;
|
||||
friend class basic_binary_iprimitive<
|
||||
derived_t,
|
||||
std::ostream::char_type,
|
||||
std::ostream::traits_type
|
||||
>;
|
||||
friend class basic_binary_iprimitive<derived_t, std::istream>;
|
||||
friend class boost::archive::load_access;
|
||||
#endif
|
||||
// add base class to the places considered when matching
|
||||
// save function to a specific set of arguments. Note, this didn't
|
||||
// work on my MSVC 7.0 system using
|
||||
// binary_oarchive_impl<derived_t>::load_override;
|
||||
// work on my MSVC 7.0 system
|
||||
// using binary_oarchive_impl<derived_t>::load_override;
|
||||
// so we use the sure-fire method below. This failed to work as well
|
||||
template<class T>
|
||||
void load_override(T & t){
|
||||
base_t::load_override(t);
|
||||
void load_override(T & t, BOOST_PFTO int){
|
||||
binary_iarchive_impl<derived_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:
|
||||
fast_binary_iarchive(std::istream & is, unsigned int flags = 0) :
|
||||
base_t(is, flags)
|
||||
{}
|
||||
fast_binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) :
|
||||
base_t(bsb, flags)
|
||||
fast_binary_iarchive(std::istream & is, unsigned flags = 0) :
|
||||
binary_iarchive_impl<derived_t>(is,flags)
|
||||
{}
|
||||
};
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_iarchive)
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
const int a[3] = {1, 2, 3};
|
||||
int a[3] = {1, 2, 3};
|
||||
int a1[3] = {4, 5, 6};
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
|
||||
#define BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_gps.hpp
|
||||
//
|
||||
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/utility.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/assume_abstract.hpp>
|
||||
|
||||
// This illustration models the bus system of a small city.
|
||||
// This includes, multiple bus stops, bus routes and schedules.
|
||||
// There are different kinds of stops. Bus stops in general will
|
||||
// will appear on multiple routes. A schedule will include
|
||||
// muliple trips on the same route.
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// gps coordinate
|
||||
//
|
||||
// llustrates serialization for a simple type
|
||||
//
|
||||
class gps_position
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
|
||||
|
||||
int degrees;
|
||||
int minutes;
|
||||
float seconds;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
ar & BOOST_SERIALIZATION_NVP(degrees)
|
||||
& BOOST_SERIALIZATION_NVP(minutes)
|
||||
& BOOST_SERIALIZATION_NVP(seconds);
|
||||
}
|
||||
|
||||
public:
|
||||
// every serializable class needs a constructor
|
||||
gps_position(){};
|
||||
gps_position(int _d, int _m, float _s) :
|
||||
degrees(_d), minutes(_m), seconds(_s)
|
||||
{}
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
|
||||
{
|
||||
return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// One bus stop
|
||||
//
|
||||
// illustrates serialization of serializable members
|
||||
//
|
||||
|
||||
class bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
virtual std::string description() const = 0;
|
||||
gps_position latitude;
|
||||
gps_position longitude;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(latitude);
|
||||
ar & BOOST_SERIALIZATION_NVP(longitude);
|
||||
}
|
||||
|
||||
protected:
|
||||
bus_stop(const gps_position & _lat, const gps_position & _long) :
|
||||
latitude(_lat), longitude(_long)
|
||||
{}
|
||||
public:
|
||||
bus_stop(){}
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
|
||||
virtual ~bus_stop(){}
|
||||
};
|
||||
|
||||
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
|
||||
{
|
||||
return os << bs.latitude << bs.longitude << ' ' << bs.description();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Several kinds of bus stops
|
||||
//
|
||||
// illustrates serialization of derived types
|
||||
//
|
||||
class bus_stop_corner : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string street1;
|
||||
std::string street2;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return street1 + " and " + street2;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
// save/load base class information
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
|
||||
ar & BOOST_SERIALIZATION_NVP(street1);
|
||||
ar & BOOST_SERIALIZATION_NVP(street2);
|
||||
}
|
||||
public:
|
||||
bus_stop_corner(){}
|
||||
bus_stop_corner(const gps_position & _lat, const gps_position & _long,
|
||||
const std::string & _s1, const std::string & _s2
|
||||
) :
|
||||
bus_stop(_lat, _long), street1(_s1), street2(_s2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class bus_stop_destination : public bus_stop
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
std::string name;
|
||||
virtual std::string description() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
|
||||
& BOOST_SERIALIZATION_NVP(name);
|
||||
}
|
||||
public:
|
||||
bus_stop_destination(){}
|
||||
bus_stop_destination(
|
||||
const gps_position & _lat, const gps_position & _long, const std::string & _name
|
||||
) :
|
||||
bus_stop(_lat, _long), name(_name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// a bus route is a collection of bus stops
|
||||
//
|
||||
// illustrates serialization of STL collection templates.
|
||||
//
|
||||
// illustrates serialzation of polymorphic pointer (bus stop *);
|
||||
//
|
||||
// illustrates storage and recovery of shared pointers is correct
|
||||
// and efficient. That is objects pointed to by more than one
|
||||
// pointer are stored only once. In such cases only one such
|
||||
// object is restored and pointers are restored to point to it
|
||||
//
|
||||
class bus_route
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
|
||||
typedef bus_stop * bus_stop_pointer;
|
||||
std::list<bus_stop_pointer> stops;
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
// in this program, these classes are never serialized directly but rather
|
||||
// through a pointer to the base class bus_stop. So we need a way to be
|
||||
// sure that the archive contains information about these derived classes.
|
||||
//ar.template register_type<bus_stop_corner>();
|
||||
ar.register_type(static_cast<bus_stop_corner *>(NULL));
|
||||
//ar.template register_type<bus_stop_destination>();
|
||||
ar.register_type(static_cast<bus_stop_destination *>(NULL));
|
||||
// serialization of stl collections is already defined
|
||||
// in the header
|
||||
ar & BOOST_SERIALIZATION_NVP(stops);
|
||||
}
|
||||
public:
|
||||
bus_route(){}
|
||||
void append(bus_stop *_bs)
|
||||
{
|
||||
stops.insert(stops.end(), _bs);
|
||||
}
|
||||
};
|
||||
std::ostream & operator<<(std::ostream &os, const bus_route &br)
|
||||
{
|
||||
std::list<bus_stop *>::const_iterator it;
|
||||
// note: we're displaying the pointer to permit verification
|
||||
// that duplicated pointers are properly restored.
|
||||
for(it = br.stops.begin(); it != br.stops.end(); it++){
|
||||
os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// a bus schedule is a collection of routes each with a starting time
|
||||
//
|
||||
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
|
||||
// See definition of operator<< <pair<F, S> >(ar, pair)
|
||||
//
|
||||
// illustrates nesting of serializable classes
|
||||
//
|
||||
// illustrates use of version number to automatically grandfather older
|
||||
// versions of the same class.
|
||||
|
||||
class bus_schedule
|
||||
{
|
||||
friend class boost::serialization::access;
|
||||
friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(schedule);
|
||||
}
|
||||
// note: this structure was made public. because the friend declarations
|
||||
// didn't seem to work as expected.
|
||||
public:
|
||||
struct trip_info
|
||||
{
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int file_version)
|
||||
{
|
||||
// in versions 2 or later
|
||||
if(file_version >= 2)
|
||||
// read the drivers name
|
||||
ar & BOOST_SERIALIZATION_NVP(driver);
|
||||
// all versions have the follwing info
|
||||
ar & BOOST_SERIALIZATION_NVP(hour)
|
||||
& BOOST_SERIALIZATION_NVP(minute);
|
||||
}
|
||||
|
||||
// starting time
|
||||
int hour;
|
||||
int minute;
|
||||
// only after system shipped was the driver's name added to the class
|
||||
std::string driver;
|
||||
|
||||
trip_info(){}
|
||||
trip_info(int _h, int _m, const std::string &_d) :
|
||||
hour(_h), minute(_m), driver(_d)
|
||||
{}
|
||||
~trip_info(){
|
||||
}
|
||||
};
|
||||
// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
|
||||
private:
|
||||
std::list<std::pair<trip_info, bus_route *> > schedule;
|
||||
public:
|
||||
void append(const std::string &_d, int _h, int _m, bus_route *_br)
|
||||
{
|
||||
schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
|
||||
}
|
||||
bus_schedule(){}
|
||||
};
|
||||
|
||||
BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
|
||||
BOOST_CLASS_VERSION(bus_schedule, 2)
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
|
||||
{
|
||||
return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
|
||||
}
|
||||
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
|
||||
{
|
||||
std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
|
||||
for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
|
||||
os << it->first << *(it->second);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
|
||||
@@ -1,76 +0,0 @@
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
//
|
||||
// demo_log.cpp
|
||||
//
|
||||
// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include "demo_gps.hpp"
|
||||
#include "log_archive.hpp"
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
// make the schedule
|
||||
bus_schedule schedule;
|
||||
|
||||
// fill in the data
|
||||
// make a few stops
|
||||
bus_stop *bs0 = new bus_stop_corner(
|
||||
gps_position(34, 135, 52.560f),
|
||||
gps_position(134, 22, 78.30f),
|
||||
"24th Street", "10th Avenue"
|
||||
);
|
||||
bus_stop *bs1 = new bus_stop_corner(
|
||||
gps_position(35, 137, 23.456f),
|
||||
gps_position(133, 35, 54.12f),
|
||||
"State street", "Cathedral Vista Lane"
|
||||
);
|
||||
bus_stop *bs2 = new bus_stop_destination(
|
||||
gps_position(35, 136, 15.456f),
|
||||
gps_position(133, 32, 15.300f),
|
||||
"White House"
|
||||
);
|
||||
bus_stop *bs3 = new bus_stop_destination(
|
||||
gps_position(35, 134, 48.789f),
|
||||
gps_position(133, 32, 16.230f),
|
||||
"Lincoln Memorial"
|
||||
);
|
||||
|
||||
// make a routes
|
||||
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 aother routes
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
const A a;
|
||||
A a, a1;
|
||||
|
||||
{
|
||||
boost::archive::text_oarchive oa(ss);
|
||||
oa << a;
|
||||
}
|
||||
A a1;
|
||||
{
|
||||
boost::archive::text_iarchive ia(ss);
|
||||
ia >> a1;
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
#include "demo_pimpl_A.hpp"
|
||||
|
||||
// "hidden" definition of class B
|
||||
@@ -35,6 +32,9 @@ void A::serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
// without the explicit instantiations below, the program will
|
||||
// fail to link for lack of instantiantiation of the above function
|
||||
// note: the following failed to fix link errors for vc 7.0 !
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
|
||||
template void A::serialize<boost::archive::text_iarchive>(
|
||||
boost::archive::text_iarchive & ar,
|
||||
const unsigned int file_version
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const A a;
|
||||
A a1;
|
||||
A a, a1;
|
||||
{
|
||||
// test with a text archive
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "demo_polymorphic_A.hpp"
|
||||
|
||||
#include <boost/archive/polymorphic_iarchive.hpp>
|
||||
#include <boost/archive/polymorphic_oarchive.hpp>
|
||||
|
||||
#include "demo_polymorphic_A.hpp"
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -20,20 +20,12 @@ 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;
|
||||
}
|
||||
A() :
|
||||
data(0)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// should pass compilation and execution
|
||||
|
||||
// note:: this example can only be built with the static library
|
||||
// (at least with MSVC - due to conflicts related to import of library
|
||||
// code and instantiation of templates.
|
||||
#include <sstream>
|
||||
|
||||
#include "portable_binary_oarchive.hpp"
|
||||
@@ -23,46 +19,37 @@
|
||||
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 {
|
||||
bool operator==(A & rhs){
|
||||
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())
|
||||
{}
|
||||
};
|
||||
|
||||
int main( int /* argc */, char* /* argv */[] )
|
||||
{
|
||||
const A a;
|
||||
A a1;
|
||||
A a, a1;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
@@ -73,31 +60,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cstddef> // NULL
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
@@ -23,11 +22,11 @@ namespace std{
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/tmpdir.hpp>
|
||||
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
|
||||
///////////////////////////
|
||||
// test shared_ptr serialization
|
||||
@@ -42,11 +41,10 @@ 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)
|
||||
|
||||
/////////////////
|
||||
// ADDITION BY DT
|
||||
@@ -61,12 +59,9 @@ private:
|
||||
}
|
||||
public:
|
||||
static int count;
|
||||
B() : A() {};
|
||||
virtual ~B() {};
|
||||
B::B() : A() {};
|
||||
virtual B::~B() {};
|
||||
};
|
||||
|
||||
BOOST_SERIALIZATION_SHARED_PTR(B)
|
||||
|
||||
/////////////////
|
||||
|
||||
int A::count = 0;
|
||||
@@ -82,7 +77,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";
|
||||
@@ -134,6 +129,13 @@ int main(int /* argc */, char * /*argv*/[])
|
||||
std::ofstream ofs(filename.c_str());
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
oa.register_type(static_cast<B *>(NULL));
|
||||
oa.register_type(
|
||||
static_cast<
|
||||
boost::detail::sp_counted_base_impl<
|
||||
B *, boost::checked_deleter<B>
|
||||
> *
|
||||
>(NULL)
|
||||
);
|
||||
oa << spa;
|
||||
oa << spa1;
|
||||
}
|
||||
@@ -151,6 +153,13 @@ int main(int /* argc */, char * /*argv*/[])
|
||||
|
||||
// restore the schedule from the archive
|
||||
ia.register_type(static_cast<B *>(NULL));
|
||||
ia.register_type(
|
||||
static_cast<
|
||||
boost::detail::sp_counted_base_impl<
|
||||
B *, boost::checked_deleter<B>
|
||||
> *
|
||||
>(NULL)
|
||||
);
|
||||
ia >> spa;
|
||||
ia >> spa1;
|
||||
}
|
||||
|
||||