Repository: boostorg/serialization Branch: develop Commit: 097a6c63a137 Files: 540 Total size: 2.1 MB Directory structure: gitextract_ba__d2tt/ ├── .drone/ │ └── drone.sh ├── .drone.star ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── posix.yml │ └── windows.yml ├── .gitignore ├── .travis.yml ├── CMake/ │ └── CMakeLists.txt ├── CMakeLists.txt ├── appveyor.yml ├── build/ │ └── Jamfile.v2 ├── build.jam ├── doc/ │ ├── acknowledgments.html │ ├── archive_reference.html │ ├── archives.html │ ├── bibliography.html │ ├── class_diagram.html │ ├── codecvt.html │ ├── configuration.html │ ├── contents.html │ ├── dataflow.html │ ├── definitions.html │ ├── derivation.html │ ├── exception_safety.html │ ├── exceptions.html │ ├── extended_type_info.html │ ├── faq.html │ ├── headers.html │ ├── history.html │ ├── implementation.html │ ├── index.html │ ├── new_case_studies.html │ ├── overview.html │ ├── performance_status.html │ ├── pimpl.html │ ├── private_base.html │ ├── profile1.txt │ ├── profile2.txt │ ├── profile3.txt │ ├── rationale.html │ ├── reference.html │ ├── release.html │ ├── serialization.html │ ├── shared_ptr.html │ ├── shared_ptr2.html │ ├── simple_log.html │ ├── singleton.html │ ├── smart_cast.html │ ├── special.html │ ├── state_saver.html │ ├── static_warning.html │ ├── strong_typedef.html │ ├── style.css │ ├── todo.html │ ├── traits.html │ ├── tutorial.html │ ├── void_cast.html │ └── wrappers.html ├── example/ │ ├── Jamfile.v2 │ ├── demo.cpp │ ├── demo_auto_ptr.cpp │ ├── demo_dll_a.hpp │ ├── demo_dll_a.ipp │ ├── demo_dll_b.hpp │ ├── demo_dll_b.ipp │ ├── demo_exception.cpp │ ├── demo_fast_archive.cpp │ ├── demo_gps.hpp │ ├── demo_log.cpp │ ├── demo_output.txt │ ├── demo_pimpl.cpp │ ├── demo_pimpl_A.cpp │ ├── demo_pimpl_A.hpp │ ├── demo_polymorphic.cpp │ ├── demo_polymorphic_A.cpp │ ├── demo_polymorphic_A.hpp │ ├── demo_portable_archive.cpp │ ├── demo_save.xml │ ├── demo_shared_ptr.cpp │ ├── demo_simple_log.cpp │ ├── demo_trivial_archive.cpp │ ├── demo_xml.cpp │ ├── demo_xml.hpp │ ├── demo_xml_load.cpp │ ├── demo_xml_save.cpp │ ├── demofile.txt │ ├── fix_six.cpp │ ├── log_archive.cpp │ ├── log_archive.hpp │ ├── polymorphic_portable_binary_iarchive.cpp │ ├── polymorphic_portable_binary_iarchive.hpp │ ├── polymorphic_portable_binary_oarchive.cpp │ ├── polymorphic_portable_binary_oarchive.hpp │ ├── portable_binary_archive.hpp │ ├── portable_binary_iarchive.cpp │ ├── portable_binary_iarchive.hpp │ ├── portable_binary_oarchive.cpp │ ├── portable_binary_oarchive.hpp │ └── simple_log_archive.hpp ├── include/ │ └── boost/ │ ├── archive/ │ │ ├── archive_exception.hpp │ │ ├── basic_archive.hpp │ │ ├── basic_binary_iarchive.hpp │ │ ├── basic_binary_iprimitive.hpp │ │ ├── basic_binary_oarchive.hpp │ │ ├── basic_binary_oprimitive.hpp │ │ ├── basic_streambuf_locale_saver.hpp │ │ ├── basic_text_iarchive.hpp │ │ ├── basic_text_iprimitive.hpp │ │ ├── basic_text_oarchive.hpp │ │ ├── basic_text_oprimitive.hpp │ │ ├── basic_xml_archive.hpp │ │ ├── basic_xml_iarchive.hpp │ │ ├── basic_xml_oarchive.hpp │ │ ├── binary_iarchive.hpp │ │ ├── binary_iarchive_impl.hpp │ │ ├── binary_oarchive.hpp │ │ ├── binary_oarchive_impl.hpp │ │ ├── binary_wiarchive.hpp │ │ ├── binary_woarchive.hpp │ │ ├── codecvt_null.hpp │ │ ├── detail/ │ │ │ ├── abi_prefix.hpp │ │ │ ├── abi_suffix.hpp │ │ │ ├── archive_serializer_map.hpp │ │ │ ├── auto_link_archive.hpp │ │ │ ├── auto_link_warchive.hpp │ │ │ ├── basic_iarchive.hpp │ │ │ ├── basic_iserializer.hpp │ │ │ ├── basic_oarchive.hpp │ │ │ ├── basic_oserializer.hpp │ │ │ ├── basic_pointer_iserializer.hpp │ │ │ ├── basic_pointer_oserializer.hpp │ │ │ ├── basic_serializer.hpp │ │ │ ├── basic_serializer_map.hpp │ │ │ ├── check.hpp │ │ │ ├── common_iarchive.hpp │ │ │ ├── common_oarchive.hpp │ │ │ ├── decl.hpp │ │ │ ├── helper_collection.hpp │ │ │ ├── interface_iarchive.hpp │ │ │ ├── interface_oarchive.hpp │ │ │ ├── iserializer.hpp │ │ │ ├── oserializer.hpp │ │ │ ├── polymorphic_iarchive_route.hpp │ │ │ ├── polymorphic_oarchive_route.hpp │ │ │ ├── register_archive.hpp │ │ │ └── utf8_codecvt_facet.hpp │ │ ├── dinkumware.hpp │ │ ├── impl/ │ │ │ ├── archive_serializer_map.ipp │ │ │ ├── basic_binary_iarchive.ipp │ │ │ ├── basic_binary_iprimitive.ipp │ │ │ ├── basic_binary_oarchive.ipp │ │ │ ├── basic_binary_oprimitive.ipp │ │ │ ├── basic_text_iarchive.ipp │ │ │ ├── basic_text_iprimitive.ipp │ │ │ ├── basic_text_oarchive.ipp │ │ │ ├── basic_text_oprimitive.ipp │ │ │ ├── basic_xml_grammar.hpp │ │ │ ├── basic_xml_iarchive.ipp │ │ │ ├── basic_xml_oarchive.ipp │ │ │ ├── text_iarchive_impl.ipp │ │ │ ├── text_oarchive_impl.ipp │ │ │ ├── text_wiarchive_impl.ipp │ │ │ ├── text_woarchive_impl.ipp │ │ │ ├── xml_iarchive_impl.ipp │ │ │ ├── xml_oarchive_impl.ipp │ │ │ ├── xml_wiarchive_impl.ipp │ │ │ └── xml_woarchive_impl.ipp │ │ ├── iterators/ │ │ │ ├── base64_exception.hpp │ │ │ ├── base64_from_binary.hpp │ │ │ ├── binary_from_base64.hpp │ │ │ ├── dataflow.hpp │ │ │ ├── dataflow_exception.hpp │ │ │ ├── escape.hpp │ │ │ ├── insert_linebreaks.hpp │ │ │ ├── istream_iterator.hpp │ │ │ ├── mb_from_wchar.hpp │ │ │ ├── ostream_iterator.hpp │ │ │ ├── remove_whitespace.hpp │ │ │ ├── transform_width.hpp │ │ │ ├── unescape.hpp │ │ │ ├── wchar_from_mb.hpp │ │ │ ├── xml_escape.hpp │ │ │ ├── xml_unescape.hpp │ │ │ └── xml_unescape_exception.hpp │ │ ├── polymorphic_binary_iarchive.hpp │ │ ├── polymorphic_binary_oarchive.hpp │ │ ├── polymorphic_iarchive.hpp │ │ ├── polymorphic_oarchive.hpp │ │ ├── polymorphic_text_iarchive.hpp │ │ ├── polymorphic_text_oarchive.hpp │ │ ├── polymorphic_text_wiarchive.hpp │ │ ├── polymorphic_text_woarchive.hpp │ │ ├── polymorphic_xml_iarchive.hpp │ │ ├── polymorphic_xml_oarchive.hpp │ │ ├── polymorphic_xml_wiarchive.hpp │ │ ├── polymorphic_xml_woarchive.hpp │ │ ├── text_iarchive.hpp │ │ ├── text_oarchive.hpp │ │ ├── text_wiarchive.hpp │ │ ├── text_woarchive.hpp │ │ ├── tmpdir.hpp │ │ ├── wcslen.hpp │ │ ├── xml_archive_exception.hpp │ │ ├── xml_iarchive.hpp │ │ ├── xml_oarchive.hpp │ │ ├── xml_wiarchive.hpp │ │ └── xml_woarchive.hpp │ └── serialization/ │ ├── access.hpp │ ├── archive_input_unordered_map.hpp │ ├── archive_input_unordered_set.hpp │ ├── array.hpp │ ├── array_optimization.hpp │ ├── array_wrapper.hpp │ ├── assume_abstract.hpp │ ├── base_object.hpp │ ├── binary_object.hpp │ ├── bitset.hpp │ ├── boost_array.hpp │ ├── boost_unordered_map.hpp │ ├── boost_unordered_set.hpp │ ├── collection_size_type.hpp │ ├── collection_traits.hpp │ ├── collections_load_imp.hpp │ ├── collections_save_imp.hpp │ ├── complex.hpp │ ├── config.hpp │ ├── deque.hpp │ ├── detail/ │ │ ├── is_default_constructible.hpp │ │ ├── shared_count_132.hpp │ │ ├── shared_ptr_132.hpp │ │ ├── shared_ptr_nmt_132.hpp │ │ └── stack_constructor.hpp │ ├── export.hpp │ ├── extended_type_info.hpp │ ├── extended_type_info_no_rtti.hpp │ ├── extended_type_info_typeid.hpp │ ├── factory.hpp │ ├── force_include.hpp │ ├── forward_list.hpp │ ├── hash_collections_load_imp.hpp │ ├── hash_collections_save_imp.hpp │ ├── hash_map.hpp │ ├── hash_set.hpp │ ├── is_bitwise_serializable.hpp │ ├── item_version_type.hpp │ ├── level.hpp │ ├── level_enum.hpp │ ├── library_version_type.hpp │ ├── list.hpp │ ├── map.hpp │ ├── nvp.hpp │ ├── optional.hpp │ ├── priority_queue.hpp │ ├── queue.hpp │ ├── scoped_ptr.hpp │ ├── serialization.hpp │ ├── set.hpp │ ├── shared_ptr.hpp │ ├── shared_ptr_132.hpp │ ├── shared_ptr_helper.hpp │ ├── singleton.hpp │ ├── slist.hpp │ ├── smart_cast.hpp │ ├── split_free.hpp │ ├── split_member.hpp │ ├── stack.hpp │ ├── state_saver.hpp │ ├── static_warning.hpp │ ├── std_variant.hpp │ ├── string.hpp │ ├── strong_typedef.hpp │ ├── throw_exception.hpp │ ├── tracking.hpp │ ├── tracking_enum.hpp │ ├── traits.hpp │ ├── type_info_implementation.hpp │ ├── unique_ptr.hpp │ ├── unordered_collections_load_imp.hpp │ ├── unordered_collections_save_imp.hpp │ ├── unordered_map.hpp │ ├── unordered_set.hpp │ ├── utility.hpp │ ├── valarray.hpp │ ├── variant.hpp │ ├── variant2.hpp │ ├── vector.hpp │ ├── vector_135.hpp │ ├── version.hpp │ ├── void_cast.hpp │ ├── void_cast_fwd.hpp │ ├── weak_ptr.hpp │ └── wrapper.hpp ├── index.html ├── meta/ │ └── libraries.json ├── performance/ │ ├── Jamfile.v2 │ ├── binary_archive.hpp │ ├── binary_warchive.hpp │ ├── peformance_array.cpp │ ├── performance_binary.cpp │ ├── performance_codecvt_null.cpp │ ├── performance_iterators.cpp │ ├── performance_iterators_base64.cpp │ ├── performance_no_rtti.cpp │ ├── performance_polymorphic.cpp │ ├── performance_simple_class.cpp │ ├── performance_utf8_codecvt.cpp │ ├── performance_vector.cpp │ ├── polymorphic_array_binary_archive.hpp │ ├── polymorphic_binary_archive.hpp │ ├── polymorphic_text_archive.hpp │ ├── polymorphic_text_warchive.hpp │ ├── polymorphic_xml_archive.hpp │ ├── polymorphic_xml_warchive.hpp │ ├── portable_binary_archive.hpp │ ├── profile.sh │ ├── text_archive.hpp │ ├── text_warchive.hpp │ ├── xml/ │ │ ├── Jamfile.v2 │ │ ├── harness.hpp │ │ ├── high_resolution_timer.hpp │ │ ├── int16_results.xml │ │ ├── int16_test.cpp │ │ ├── int256_results.xml │ │ ├── int256_test.cpp │ │ ├── int4_results.xml │ │ ├── int4_test.cpp │ │ ├── int64_results.xml │ │ ├── int64_test.cpp │ │ ├── macro.hpp │ │ ├── node.hpp │ │ ├── string16_results.xml │ │ ├── string16_test.cpp │ │ ├── string256_results.xml │ │ ├── string256_test.cpp │ │ ├── string4_results.xml │ │ ├── string4_test.cpp │ │ ├── string64_results.xml │ │ └── string64_test.cpp │ ├── xml_archive.hpp │ └── xml_warchive.hpp ├── src/ │ ├── archive_exception.cpp │ ├── basic_archive.cpp │ ├── basic_iarchive.cpp │ ├── basic_iserializer.cpp │ ├── basic_oarchive.cpp │ ├── basic_oserializer.cpp │ ├── basic_pointer_iserializer.cpp │ ├── basic_pointer_oserializer.cpp │ ├── basic_serializer_map.cpp │ ├── basic_text_iprimitive.cpp │ ├── basic_text_oprimitive.cpp │ ├── basic_text_wiprimitive.cpp │ ├── basic_text_woprimitive.cpp │ ├── basic_xml_archive.cpp │ ├── basic_xml_grammar.ipp │ ├── binary_iarchive.cpp │ ├── binary_oarchive.cpp │ ├── binary_wiarchive.cpp │ ├── binary_woarchive.cpp │ ├── codecvt_null.cpp │ ├── extended_type_info.cpp │ ├── extended_type_info_no_rtti.cpp │ ├── extended_type_info_typeid.cpp │ ├── polymorphic_binary_iarchive.cpp │ ├── polymorphic_binary_oarchive.cpp │ ├── polymorphic_iarchive.cpp │ ├── polymorphic_oarchive.cpp │ ├── polymorphic_text_iarchive.cpp │ ├── polymorphic_text_oarchive.cpp │ ├── polymorphic_text_wiarchive.cpp │ ├── polymorphic_text_woarchive.cpp │ ├── polymorphic_xml_iarchive.cpp │ ├── polymorphic_xml_oarchive.cpp │ ├── polymorphic_xml_wiarchive.cpp │ ├── polymorphic_xml_woarchive.cpp │ ├── stl_port.cpp │ ├── text_iarchive.cpp │ ├── text_oarchive.cpp │ ├── text_wiarchive.cpp │ ├── text_woarchive.cpp │ ├── utf8_codecvt_facet.cpp │ ├── void_cast.cpp │ ├── xml_archive_exception.cpp │ ├── xml_grammar.cpp │ ├── xml_iarchive.cpp │ ├── xml_oarchive.cpp │ ├── xml_wgrammar.cpp │ ├── xml_wiarchive.cpp │ └── xml_woarchive.cpp ├── test/ │ ├── A.cpp │ ├── A.hpp │ ├── A.ipp │ ├── B.hpp │ ├── C.hpp │ ├── D.hpp │ ├── J.hpp │ ├── Jamfile.v2 │ ├── base.hpp │ ├── binary_archive.hpp │ ├── binary_warchive.hpp │ ├── config_test.cpp │ ├── derived2.hpp │ ├── dll_a.cpp │ ├── dll_base.cpp │ ├── dll_derived2.cpp │ ├── dll_polymorphic_base.cpp │ ├── dll_polymorphic_derived2.cpp │ ├── multi_shared1.cpp │ ├── multi_shared2.cpp │ ├── polymorphic_array_binary_archive.hpp │ ├── polymorphic_base.cpp │ ├── polymorphic_base.hpp │ ├── polymorphic_binary_archive.hpp │ ├── polymorphic_derived1.cpp │ ├── polymorphic_derived1.hpp │ ├── polymorphic_derived2.cpp │ ├── polymorphic_derived2.hpp │ ├── polymorphic_text_archive.hpp │ ├── polymorphic_text_warchive.hpp │ ├── polymorphic_xml_archive.hpp │ ├── polymorphic_xml_warchive.hpp │ ├── portable_binary_archive.hpp │ ├── test__helper.cpp │ ├── test_array.cpp │ ├── test_binary.cpp │ ├── test_bitset.cpp │ ├── test_boost_array.cpp │ ├── test_check.cpp │ ├── test_class_info_load.cpp │ ├── test_class_info_save.cpp │ ├── test_codecvt_null.cpp │ ├── test_complex.cpp │ ├── test_const_load_fail1.cpp │ ├── test_const_load_fail1_nvp.cpp │ ├── test_const_load_fail2.cpp │ ├── test_const_load_fail2_nvp.cpp │ ├── test_const_load_fail3.cpp │ ├── test_const_load_fail3_nvp.cpp │ ├── test_const_pass.cpp │ ├── test_const_save_warn1.cpp │ ├── test_const_save_warn1_nvp.cpp │ ├── test_const_save_warn2.cpp │ ├── test_const_save_warn2_nvp.cpp │ ├── test_const_save_warn3.cpp │ ├── test_const_save_warn3_nvp.cpp │ ├── test_const_save_warn4.cpp │ ├── test_const_save_warn4_nvp.cpp │ ├── test_contained_class.cpp │ ├── test_cyclic_ptrs.cpp │ ├── test_delete_pointer.cpp │ ├── test_deque.cpp │ ├── test_derived.cpp │ ├── test_derived_class.cpp │ ├── test_derived_class_ptr.cpp │ ├── test_diamond.cpp │ ├── test_diamond_complex.cpp │ ├── test_dll_exported.cpp │ ├── test_dll_plugin.cpp │ ├── test_dll_simple.cpp │ ├── test_enable_shared_from_this.cpp │ ├── test_exported.cpp │ ├── test_forward_list.cpp │ ├── test_forward_list_ptrs.cpp │ ├── test_helper_support.cpp │ ├── test_inclusion.cpp │ ├── test_inclusion2.cpp │ ├── test_interators.cpp │ ├── test_interrupts.cpp │ ├── test_iterators.cpp │ ├── test_iterators_base64.cpp │ ├── test_list.cpp │ ├── test_list_ptrs.cpp │ ├── test_map.cpp │ ├── test_map_hashed.cpp │ ├── test_mi.cpp │ ├── test_mult_archive_types.cpp │ ├── test_multi_shared_lib.cpp │ ├── test_multiple_inheritance.cpp │ ├── test_multiple_ptrs.cpp │ ├── test_native_array.cpp │ ├── test_new_operator.cpp │ ├── test_no_rtti.cpp │ ├── test_non_default_ctor.cpp │ ├── test_non_default_ctor2.cpp │ ├── test_non_intrusive.cpp │ ├── test_not_serializable.cpp │ ├── test_null_ptr.cpp │ ├── test_nvp.cpp │ ├── test_object.cpp │ ├── test_optional.cpp │ ├── test_p_helper.cpp │ ├── test_pimpl.cpp │ ├── test_polymorphic.cpp │ ├── test_polymorphic2.cpp │ ├── test_polymorphic2.hpp │ ├── test_polymorphic2imp.cpp │ ├── test_polymorphic_A.cpp │ ├── test_polymorphic_A.hpp │ ├── test_primitive.cpp │ ├── test_priority_queue.cpp │ ├── test_private_base.cpp │ ├── test_private_base2.cpp │ ├── test_private_ctor.cpp │ ├── test_queue.cpp │ ├── test_recursion.cpp │ ├── test_registered.cpp │ ├── test_reset_object_address.cpp │ ├── test_set.cpp │ ├── test_set_hashed.cpp │ ├── test_shared_ptr.cpp │ ├── test_shared_ptr_132.cpp │ ├── test_shared_ptr_multi_base.cpp │ ├── test_simple_class.cpp │ ├── test_simple_class_ptr.cpp │ ├── test_singleton.cpp │ ├── test_singleton_inherited.cpp │ ├── test_singleton_plain.cpp │ ├── test_slist.cpp │ ├── test_slist_ptrs.cpp │ ├── test_smart_cast.cpp │ ├── test_split.cpp │ ├── test_stack.cpp │ ├── test_static_warning.cpp │ ├── test_strong_typedef.cpp │ ├── test_tools.hpp │ ├── test_tracking.cpp │ ├── test_traits_fail.cpp │ ├── test_traits_pass.cpp │ ├── test_unique_ptr.cpp │ ├── test_unregistered.cpp │ ├── test_valarray.cpp │ ├── test_variant.cpp │ ├── test_vector.cpp │ ├── test_void_cast.cpp │ ├── test_z.cpp │ ├── text_archive.hpp │ ├── text_warchive.hpp │ ├── xml_archive.hpp │ └── xml_warchive.hpp └── util/ └── test.jam ================================================ FILE CONTENTS ================================================ ================================================ FILE: .drone/drone.sh ================================================ #!/bin/bash # Copyright 2020 Rene Rivera, Sam Darwin # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) set -e export TRAVIS_BUILD_DIR=$(pwd) export DRONE_BUILD_DIR=$(pwd) export TRAVIS_BRANCH=$DRONE_BRANCH export VCS_COMMIT_ID=$DRONE_COMMIT export GIT_COMMIT=$DRONE_COMMIT export REPO_NAME=$DRONE_REPO export PATH=~/.local/bin:/usr/local/bin:$PATH if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then echo '==================================> INSTALL' BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true cd .. git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root cd boost-root git submodule update --init tools/build git submodule update --init libs/config git submodule update --init tools/boostdep cp -r $TRAVIS_BUILD_DIR/* libs/serialization python tools/boostdep/depinst/depinst.py serialization ./bootstrap.sh ./b2 headers echo '==================================> SCRIPT' echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam ./b2 -j 3 libs/serialization/test toolset=$TOOLSET link=${LINK:-shared} fi ================================================ FILE: .drone.star ================================================ # Use, modification, and distribution are # subject to the Boost Software License, Version 1.0. (See accompanying # file LICENSE.txt) # # Copyright Rene Rivera 2020. # For Drone CI we use the Starlark scripting language to reduce duplication. # As the yaml syntax for Drone CI is rather limited. # # globalenv={} linuxglobalimage="cppalliance/droneubuntu1604:1" windowsglobalimage="cppalliance/dronevs2019" def main(ctx): return [ linux_cxx("TOOLSET=gcc LINK=static,shared Job 0", "g++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv), linux_cxx("TOOLSET=gcc LINK=static,shared Job 1", "g++", packages="g++-5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-5', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv), linux_cxx("TOOLSET=gcc LINK=static,shared Job 2", "g++", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-6', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv), linux_cxx("TOOLSET=gcc LINK=static,shared Job 3", "g++", packages="g++-7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'g++-7', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv), linux_cxx("TOOLSET=clang LINK=static,shared Job 4", "clang++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv), linux_cxx("TOOLSET=clang LINK=static,shared Job 5", "clang++", packages="libc++-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++-libc++', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv), osx_cxx("TOOLSET=clang LINK=static,shared Job 6", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv), osx_cxx("TOOLSET=clang LINK=static,shared Job 7", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="10", environment={'TOOLSET': 'clang', 'LINK': 'static,shared', 'TRAVIS_COMPILER': 'clang++', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv), ] # from https://github.com/boostorg/boost-ci load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") ================================================ FILE: .gitattributes ================================================ * text=auto !eol svneol=native#text/plain *.gitattributes text svneol=native#text/plain # Scriptish formats *.bat text svneol=native#text/plain *.bsh text svneol=native#text/x-beanshell *.cgi text svneol=native#text/plain *.cmd text svneol=native#text/plain *.js text svneol=native#text/javascript *.php text svneol=native#text/x-php *.pl text svneol=native#text/x-perl *.pm text svneol=native#text/x-perl *.py text svneol=native#text/x-python *.sh eol=lf svneol=LF#text/x-sh configure eol=lf svneol=LF#text/x-sh # Image formats *.bmp binary svneol=unset#image/bmp *.gif binary svneol=unset#image/gif *.ico binary svneol=unset#image/ico *.jpeg binary svneol=unset#image/jpeg *.jpg binary svneol=unset#image/jpeg *.png binary svneol=unset#image/png *.tif binary svneol=unset#image/tiff *.tiff binary svneol=unset#image/tiff *.svg text svneol=native#image/svg%2Bxml # Data formats *.pdf binary svneol=unset#application/pdf *.avi binary svneol=unset#video/avi *.doc binary svneol=unset#application/msword *.dsp text svneol=crlf#text/plain *.dsw text svneol=crlf#text/plain *.eps binary svneol=unset#application/postscript *.gz binary svneol=unset#application/gzip *.mov binary svneol=unset#video/quicktime *.mp3 binary svneol=unset#audio/mpeg *.ppt binary svneol=unset#application/vnd.ms-powerpoint *.ps binary svneol=unset#application/postscript *.psd binary svneol=unset#application/photoshop *.rdf binary svneol=unset#text/rdf *.rss text svneol=unset#text/xml *.rtf binary svneol=unset#text/rtf *.sln text svneol=native#text/plain *.swf binary svneol=unset#application/x-shockwave-flash *.tgz binary svneol=unset#application/gzip *.vcproj text svneol=native#text/xml *.vcxproj text svneol=native#text/xml *.vsprops text svneol=native#text/xml *.wav binary svneol=unset#audio/wav *.xls binary svneol=unset#application/vnd.ms-excel *.zip binary svneol=unset#application/zip # Text formats .htaccess text svneol=native#text/plain *.bbk text svneol=native#text/xml *.cmake text svneol=native#text/plain *.css text svneol=native#text/css *.dtd text svneol=native#text/xml *.htm text svneol=native#text/html *.html text svneol=native#text/html *.ini text svneol=native#text/plain *.log text svneol=native#text/plain *.mak text svneol=native#text/plain *.qbk text svneol=native#text/plain *.rst text svneol=native#text/plain *.sql text svneol=native#text/x-sql *.txt text svneol=native#text/plain *.xhtml text svneol=native#text/xhtml%2Bxml *.xml text svneol=native#text/xml *.xsd text svneol=native#text/xml *.xsl text svneol=native#text/xml *.xslt text svneol=native#text/xml *.xul text svneol=native#text/xul *.yml text svneol=native#text/plain boost-no-inspect text svneol=native#text/plain CHANGES text svneol=native#text/plain COPYING text svneol=native#text/plain INSTALL text svneol=native#text/plain Jamfile text svneol=native#text/plain Jamroot text svneol=native#text/plain Jamfile.v2 text svneol=native#text/plain Jamrules text svneol=native#text/plain Makefile* text svneol=native#text/plain README text svneol=native#text/plain TODO text svneol=native#text/plain # Code formats *.c text svneol=native#text/plain *.cpp text svneol=native#text/plain *.h text svneol=native#text/plain *.hpp text svneol=native#text/plain *.ipp text svneol=native#text/plain *.tpp text svneol=native#text/plain *.jam text svneol=native#text/plain *.java text svneol=native#text/plain ================================================ FILE: .github/workflows/posix.yml ================================================ # Copyright 2020-2021 Peter Dimov # Copyright 2021 Andrey Semashev # Copyright 2021 Alexander Grund # Copyright 2022 James E. King III # Copyright 2023 Matt Borland # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) name: POSIX on: pull_request: push: branches: - master - develop - feature/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: LIBRARY: serialization UBSAN_OPTIONS: print_stacktrace=1 GIT_FETCH_JOBS: 8 NET_RETRY_COUNT: 5 DEFAULT_BUILD_VARIANT: release jobs: CI: defaults: run: shell: bash strategy: fail-fast: false matrix: include: - toolset: gcc-4.8 cxxstd: "11" address_model: 64 os: ubuntu-latest container: ubuntu:16.04 install: - g++-4.8 sources: - "ppa:ubuntu-toolchain-r/test" - toolset: gcc-4.9 cxxstd: "11" address_model: 64 os: ubuntu-latest container: ubuntu:16.04 install: - g++-4.9 sources: - "ppa:ubuntu-toolchain-r/test" - toolset: gcc-5 cxxstd: "11,14,1z" address_model: 64 os: ubuntu-latest container: ubuntu:16.04 install: - g++-5-multilib - toolset: gcc-5 cxxstd: "11-gnu,14-gnu,1z-gnu" address_model: 64 os: ubuntu-latest container: ubuntu:16.04 install: - g++-5-multilib - toolset: gcc-6 cxxstd: "11,14,1z" address_model: 64 os: ubuntu-latest container: ubuntu:18.04 install: - g++-6-multilib - toolset: gcc-7 cxxstd: "11,14,17" address_model: 64 os: ubuntu-latest container: ubuntu:18.04 install: - g++-7-multilib - toolset: gcc-8 cxxstd: "11,14,17,2a" address_model: 64 os: ubuntu-latest container: ubuntu:18.04 install: - g++-8-multilib - toolset: gcc-9 cxxstd: "11,14,17,2a" address_model: 64 os: ubuntu-20.04 install: - g++-9-multilib - toolset: gcc-9 cxxstd: "11-gnu,14-gnu,17-gnu,2a-gnu" address_model: 64 os: ubuntu-20.04 install: - g++-9-multilib - toolset: gcc-10 cxxstd: "11,14,17,20" address_model: 64 os: ubuntu-20.04 install: - g++-10-multilib - toolset: gcc-11 cxxstd: "11,14,17,20,23" address_model: 64 os: ubuntu-22.04 install: - g++-11-multilib - toolset: gcc-12 cxxstd: "11,14,17,20,23" address_model: 64 os: ubuntu-22.04 install: - g++-12-multilib - toolset: gcc-12 cxxstd: "11-gnu,14-gnu,17-gnu,20-gnu,23-gnu" address_model: 64 os: ubuntu-22.04 install: - g++-12-multilib - name: UBSAN toolset: gcc-12 cxxstd: "11,20" address_model: 64 ubsan: 1 os: ubuntu-22.04 install: - g++-12-multilib # Linux, clang - toolset: clang compiler: clang++-3.7 cxxstd: "11,14" os: ubuntu-latest container: ubuntu:16.04 install: - clang-3.7 - toolset: clang compiler: clang++-3.8 cxxstd: "11,14" os: ubuntu-latest container: ubuntu:16.04 install: - clang-3.8 - toolset: clang compiler: clang++-3.9 cxxstd: "11,14" os: ubuntu-latest container: ubuntu:18.04 install: - clang-3.9 - toolset: clang compiler: clang++-4.0 cxxstd: "11,14" os: ubuntu-latest container: ubuntu:18.04 install: - clang-4.0 - toolset: clang compiler: clang++-5.0 cxxstd: "11,14,1z" os: ubuntu-latest container: ubuntu:18.04 install: - clang-5.0 - toolset: clang compiler: clang++-6.0 cxxstd: "11,14,17" os: ubuntu-latest container: ubuntu:18.04 install: - clang-6.0 - toolset: clang compiler: clang++-7 cxxstd: "11,14,17" os: ubuntu-latest container: ubuntu:18.04 install: - clang-7 # Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode - toolset: clang compiler: clang++-8 cxxstd: "11,14,17,2a" os: ubuntu-latest container: ubuntu:18.04 install: - clang-8 - g++-7 gcc_toolchain: 7 - toolset: clang compiler: clang++-9 cxxstd: "11,14,17,2a" os: ubuntu-20.04 install: - clang-9 - toolset: clang compiler: clang++-10 cxxstd: "11,14,17,20" os: ubuntu-20.04 install: - clang-10 - toolset: clang compiler: clang++-11 cxxstd: "11,14,17,20" os: ubuntu-22.04 install: - clang-11 - toolset: clang compiler: clang++-12 cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: - clang-12 - toolset: clang compiler: clang++-13 cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: - clang-13 - toolset: clang compiler: clang++-14 cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: - clang-14 - toolset: clang compiler: clang++-14 cxxstd: "11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu" os: ubuntu-22.04 install: - clang-14 - toolset: clang compiler: clang++-15 cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: - clang-15 sources: - "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" source_keys: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - toolset: clang compiler: clang++-15 cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: - clang-15 - libc++-15-dev - libc++abi-15-dev sources: - "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" source_keys: - "https://apt.llvm.org/llvm-snapshot.gpg.key" cxxflags: -stdlib=libc++ linkflags: -stdlib=libc++ - toolset: clang cxxstd: "11,14,17,2a" os: macos-11 - toolset: clang cxxstd: "11,14,17,20,2b" os: macos-12 timeout-minutes: 360 runs-on: ${{matrix.os}} container: ${{matrix.container}} steps: - name: Setup environment run: | if [ -f "/etc/debian_version" ] then echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV export DEBIAN_FRONTEND=noninteractive fi if [ -n "${{matrix.container}}" ] then echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV if [ -f "/etc/debian_version" ] then apt-get -o Acquire::Retries=$NET_RETRY_COUNT update if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ] then PYTHON_PACKAGE="python-is-python3" else PYTHON_PACKAGE="python" fi apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake fi fi git config --global pack.threads 0 - uses: actions/checkout@v3 - name: Install packages if: matrix.install run: | declare -a SOURCE_KEYS SOURCES if [ -n "${{join(matrix.source_keys, ' ')}}" ] then SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}") fi if [ -n "${{join(matrix.sources, ' ')}}" ] then SOURCES=("${{join(matrix.sources, '" "')}}") fi for key in "${SOURCE_KEYS[@]}" do for i in {1..$NET_RETRY_COUNT} do echo "Adding key: $key" wget -O - "$key" | sudo apt-key add - && break || sleep 2 done done if [ ${#SOURCES[@]} -gt 0 ] then APT_ADD_REPO_COMMON_ARGS=("-y") APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')" if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ] then APT_ADD_REPO_COMMON_ARGS+=("-n") fi APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)" for source in "${SOURCES[@]}" do for i in {1..$NET_RETRY_COUNT} do APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}") if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ] then case "$source" in "ppa:"*) APT_ADD_REPO_ARGS+=("-P") ;; "deb "*) APT_ADD_REPO_ARGS+=("-S") ;; *) APT_ADD_REPO_ARGS+=("-U") ;; esac fi APT_ADD_REPO_ARGS+=("$source") echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}" sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2 done done fi sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}} - name: Setup GCC Toolchain if: matrix.gcc_toolchain run: | GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" mkdir -p "$GCC_TOOLCHAIN_ROOT" ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" - name: Setup Boost run: | echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY LIBRARY=${GITHUB_REPOSITORY#*/} echo LIBRARY: $LIBRARY echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV echo GITHUB_BASE_REF: $GITHUB_BASE_REF echo GITHUB_REF: $GITHUB_REF REF=${GITHUB_BASE_REF:-$GITHUB_REF} REF=${REF#refs/heads/} echo REF: $REF BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true echo BOOST_BRANCH: $BOOST_BRANCH BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null) echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV DEPINST_ARGS=() GIT_VERSION="$(git --version | sed -e 's/git version //')" GIT_HAS_JOBS=1 if [ -f "/etc/debian_version" ] then if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0) then GIT_HAS_JOBS=0 fi else declare -a GIT_VER=(${GIT_VERSION//./ }) declare -a GIT_MIN_VER=(2 8 0) for ((i=0; i<${#GIT_VER[@]}; i++)) do if [ -z "${GIT_MIN_VER[i]}" ] then GIT_MIN_VER[i]=0 fi if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ] then GIT_HAS_JOBS=0 break fi done fi if [ "$GIT_HAS_JOBS" -ne 0 ] then DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS") fi cd .. git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root" cd boost-root mkdir -p libs/$LIBRARY cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY git submodule update --init tools/boostdep DEPINST_ARGS+=("$LIBRARY") python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}" if [ -z "${{matrix.cmake_tests}}" ] then ./bootstrap.sh ./b2 headers if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ] then echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam if [ -n "$GCC_TOOLCHAIN_ROOT" ] then echo -n " : \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" \"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam fi echo " ;" >> ~/user-config.jam fi fi - name: Run tests if: matrix.cmake_tests == '' run: | cd ../boost-root B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}" "link=static,shared") if [ -n "${{matrix.build_variant}}" ] then B2_ARGS+=("variant=${{matrix.build_variant}}") else B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT") fi if [ -n "${{matrix.threading}}" ] then B2_ARGS+=("threading=${{matrix.threading}}") fi if [ -n "${{matrix.ubsan}}" ] then export UBSAN_OPTIONS="print_stacktrace=1" B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global") fi if [ -n "${{matrix.cxxflags}}" ] then B2_ARGS+=("cxxflags=${{matrix.cxxflags}}") fi if [ -n "${{matrix.linkflags}}" ] then B2_ARGS+=("linkflags=${{matrix.linkflags}}") fi if [ -n "${{matrix.address_model}}" ] then B2_ARGS+=("address-model=${{matrix.address_model}}") fi B2_ARGS+=("libs/$LIBRARY/test") ./b2 "${B2_ARGS[@]}" ================================================ FILE: .github/workflows/windows.yml ================================================ name: Windows on: pull_request: push: branches: - master - develop - feature/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: LIBRARY: serialization jobs: CI: strategy: fail-fast: false matrix: include: - toolset: msvc-14.0 cxxstd: "11,14" addrmd: 32,64 os: windows-2019 - toolset: msvc-14.2 cxxstd: "14,17,latest" addrmd: 32,64 os: windows-2019 - toolset: msvc-14.3 cxxstd: "17,20,latest" addrmd: 32,64 os: windows-2022 - toolset: clang-win cxxstd: "14,17,latest" addrmd: 32,64 os: windows-2022 - toolset: gcc cxxstd: "11,14,17,2a" addrmd: 64 os: windows-2019 runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v3 - name: Setup Boost shell: cmd run: | echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi echo LIBRARY: %LIBRARY% echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% echo GITHUB_BASE_REF: %GITHUB_BASE_REF% echo GITHUB_REF: %GITHUB_REF% if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% set BOOST_BRANCH=develop for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master echo BOOST_BRANCH: %BOOST_BRANCH% cd .. git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root cd boost-root xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ git submodule update --init tools/boostdep python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% cmd /c bootstrap b2 -d0 headers - name: Run tests shell: cmd run: | cd ../boost-root b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=release ================================================ FILE: .gitignore ================================================ ================================================ FILE: .travis.yml ================================================ # Copyright 2016, 2017 Peter Dimov # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) language: cpp sudo: false cache: ccache: true branches: only: - master - develop - /feature\/.*/ env: matrix: - BOGUS_JOB=true matrix: exclude: - env: BOGUS_JOB=true include: - os: linux compiler: g++ env: TOOLSET=gcc LINK=static,shared - os: linux compiler: g++-5 env: TOOLSET=gcc LINK=static,shared addons: apt: packages: - g++-5 sources: - ubuntu-toolchain-r-test - os: linux compiler: g++-6 env: TOOLSET=gcc LINK=static,shared addons: apt: packages: - g++-6 sources: - ubuntu-toolchain-r-test - os: linux compiler: g++-7 env: TOOLSET=gcc LINK=static,shared addons: apt: packages: - g++-7 sources: - ubuntu-toolchain-r-test - os: linux compiler: clang++ env: TOOLSET=clang LINK=static,shared - os: linux compiler: clang++-libc++ env: TOOLSET=clang LINK=static,shared addons: apt: packages: - libc++-dev - os: osx compiler: clang++ env: TOOLSET=clang LINK=static,shared - os: osx osx_image: xcode10 compiler: clang++ env: TOOLSET=clang LINK=static,shared install: - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true - cd .. - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root - cd boost-root - git submodule update --init tools/build - git submodule update --init libs/config - git submodule update --init tools/boostdep - cp -r $TRAVIS_BUILD_DIR/* libs/serialization - python tools/boostdep/depinst/depinst.py serialization - ./bootstrap.sh - ./b2 headers script: - |- echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam - ./b2 -j 3 libs/serialization/test toolset=$TOOLSET link=${LINK:-shared} notifications: email: on_success: always ================================================ FILE: CMake/CMakeLists.txt ================================================ # CMake build control file for Serialization Library tests cmake_minimum_required(VERSION 3.5) if (POLICY CMP0054) cmake_policy (SET CMP0054 NEW) endif (POLICY CMP0054) if (POLICY CMP0063) cmake_policy (SET CMP0063 NEW) endif (POLICY CMP0063) project("serialization") # # Compiler settings # message(STATUS "C++ compiler is ${CMAKE_CXX_COMPILER_ID}" ) add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) message(STATUS "C compiler is ${CMAKE_C_COMPILER_ID}" ) if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) add_definitions( -ftemplate-depth=255 ) # we use gcc to test for C++03 compatibility set(COMPILER_SUPPORTS_CXX11 FALSE) elseif( CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" ) add_definitions( /wd4996 ) set(COMPILER_SUPPORTS_CXX11 TRUE) elseif( CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=300") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0" ) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O3" ) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -dead_strip") set(COMPILER_SUPPORTS_CXX11 TRUE) endif() add_definitions( -std=c++11 ) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # # Locate Project Prerequisites # # Boost # # Project settings # option(BUILD_SHARED_LIBS "Build Shared Libraries" true) find_package(Boost 1.82 REQUIRED COMPONENTS system filesystem) if(NOT Boost_FOUND) message("Boost NOT Found!") else() message(STATUS "Boost Found!") endif() set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(VISIBILITY_INLINES_HIDDEN YES) # enable usage of CHECK_INCLUDE_FILE_CXX include(CheckIncludeFileCXX) # list of archive names for which tests should be generated set(archive_list text_archive text_warchive binary_archive xml_archive xml_warchive) # set(archive_list xml_warchive) # list of tests generated by each function call set(test_list) ########################### # library builds add_library(serialization ../src/archive_exception.cpp ../src/basic_archive.cpp ../src/basic_iarchive.cpp ../src/basic_iserializer.cpp ../src/basic_oarchive.cpp ../src/basic_oserializer.cpp ../src/basic_pointer_iserializer.cpp ../src/basic_pointer_oserializer.cpp ../src/basic_serializer_map.cpp ../src/basic_text_iprimitive.cpp ../src/basic_text_oprimitive.cpp ../src/basic_xml_archive.cpp ../src/binary_iarchive.cpp ../src/binary_oarchive.cpp ../src/extended_type_info.cpp ../src/extended_type_info_typeid.cpp ../src/extended_type_info_no_rtti.cpp ../src/stl_port.cpp ../src/text_iarchive.cpp ../src/text_oarchive.cpp ../src/polymorphic_iarchive.cpp ../src/polymorphic_oarchive.cpp ../src/polymorphic_text_iarchive.cpp ../src/polymorphic_text_oarchive.cpp ../src/polymorphic_binary_iarchive.cpp ../src/polymorphic_binary_oarchive.cpp ../src/polymorphic_xml_iarchive.cpp ../src/polymorphic_xml_oarchive.cpp ../src/void_cast.cpp ../src/xml_grammar.cpp ../src/xml_iarchive.cpp ../src/xml_oarchive.cpp ../src/xml_archive_exception.cpp ../src/codecvt_null.cpp ../src/utf8_codecvt_facet.cpp ../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"' ) target_include_directories(serialization PUBLIC ${Boost_INCLUDE_DIR}) add_library(wserialization ../src/basic_text_wiprimitive.cpp ../src/basic_text_woprimitive.cpp ../src/text_wiarchive.cpp ../src/text_woarchive.cpp ../src/polymorphic_text_wiarchive.cpp ../src/polymorphic_text_woarchive.cpp ../src/xml_wiarchive.cpp ../src/xml_woarchive.cpp ../src/polymorphic_xml_wiarchive.cpp ../src/polymorphic_xml_woarchive.cpp ../src/xml_wgrammar.cpp ../src/basic_xml_grammar.ipp # doesn't show up in "Source Files" in Xcode"' ) target_include_directories(wserialization PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(wserialization PUBLIC serialization) # end library build ########################### ########################### # test targets function( serialization_test test_name) set(arglist) foreach(a IN ITEMS ${ARGN} ) set(arglist ${arglist} ../test/${a}.cpp) endforeach() message(STATUS ${test_name}) add_executable( ${test_name} ../test/${test_name}.cpp ${arglist} ) target_include_directories(${test_name} PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(${test_name} serialization wserialization Boost::filesystem) add_test( ${test_name} ${test_name} ) endfunction(serialization_test) function(archive_test test_name) set(test_listx) set(arglist) foreach(a IN ITEMS ${ARGN} ) set(arglist ${arglist} ../test/${a}.cpp) endforeach() foreach( archive-name IN ITEMS ${archive_list} ) set(amended_test_name ${test_name}_${archive-name}) add_executable(${amended_test_name} ../test/${test_name}.cpp ${arglist}) set_property( TARGET ${amended_test_name} PROPERTY COMPILE_DEFINITIONS BOOST_ARCHIVE_TEST=${archive-name}.hpp ) target_include_directories(${amended_test_name} PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(${amended_test_name} serialization wserialization Boost::filesystem) add_test(${amended_test_name} ${amended_test_name}) set(test_listx ${test_listx} ${amended_test_name}) endforeach() set(test_list ${test_listx} PARENT_SCOPE) endfunction(archive_test) function(polymorphic_archive_test test_name) set(test_listx) set(arglist) foreach(a IN ITEMS ${ARGN} ) set(arglist ${arglist} ../test/${a}.cpp) endforeach() foreach( archive-name IN ITEMS ${archive_list} ) set(amended_archive_name polymorphic_${archive-name}) set(amended_test_name ${test_name}_${amended_archive_name}) add_executable(${amended_test_name} ../test/${test_name}.cpp ${arglist}) set_property( TARGET ${amended_test_name} PROPERTY COMPILE_DEFINITIONS BOOST_ARCHIVE_TEST=${amended_archive_name}.hpp ) message(STATUS ${amended_test_name} " " ${arglist} " " ${amended_archive_name}) target_include_directories(${amended_test_name} PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(${amended_test_name} serialization wserialization Boost::filesystem) add_test(${amended_test_name} ${amended_test_name}) set(test_listx ${test_listx} ${amended_test_name}) endforeach() set(test_list ${test_listx} PARENT_SCOPE) endfunction(polymorphic_archive_test) enable_testing() message(STATUS dll_a) add_library(dll_a SHARED ../test/dll_a.cpp) target_link_libraries(dll_a serialization) message(STATUS dll_polymorphic_base) add_library(dll_polymorphic_base SHARED ../test/dll_polymorphic_base.cpp) target_link_libraries(dll_polymorphic_base serialization) message(STATUS dll_polymorphic_derived2) add_library(dll_polymorphic_derived2 SHARED ../test/dll_polymorphic_derived2.cpp) target_link_libraries(dll_polymorphic_derived2 dll_polymorphic_base serialization) # compile test_dll_plugin.cpp # Running the following test requires that the test know the directory # in which the dll is stored. I don't know how to extract this from bjam # serialization(test_dll_plugin : : dll_polymorphic_derived2_lib) if(BUILD_SHARED_LIBS) # this test can only be made to work if we're linking with shared # libraries. Basically the build systems like to have all shared # or all static so if we're building with static C++ libraries # then linking with a shared one - we need multiple C++ libraries # and things get complex. So just run this test when we're # building with shared libraries (dll in windows speak) serialization_test(test_dll_simple) target_link_libraries(test_dll_simple dll_a serialization) endif() serialization_test(test_private_ctor) serialization_test(test_reset_object_address A) serialization_test(test_void_cast) serialization_test(test_mult_archive_types) serialization_test(test_iterators) serialization_test(test_iterators_base64) serialization_test(test_inclusion) serialization_test(test_inclusion2) serialization_test(test_smart_cast) serialization_test(test_codecvt_null) serialization_test(test_strong_typedef) serialization_test(test_singleton) serialization_test(test_singleton_inherited) serialization_test(test_singleton_plain) archive_test(test_native_array A) archive_test(test_boost_array A) if(COMPILER_SUPPORTS_CXX11) archive_test(test_array A) endif() archive_test(test_binary) archive_test(test_bitset) archive_test(test_class_info_save) archive_test(test_class_info_load) archive_test(test_complex) archive_test(test_contained_class A) archive_test(test_cyclic_ptrs A) archive_test(test_delete_pointer) archive_test(test_deque A) archive_test(test_derived) archive_test(test_derived_class A) archive_test(test_diamond) archive_test(test_diamond_complex) CHECK_INCLUDE_FILE_CXX(forward_list FORWARD_LIST_FOUND) if(FORWARD_LIST_FOUND) message(STATUS "forward_list header found") archive_test(test_forward_list A) archive_test(test_forward_list_ptrs A) else() message(STATUS "forward_list header NOT found") endif() archive_test(test_helper_support) archive_test(test_interrupts) archive_test(test_list A) archive_test(test_list_ptrs A) archive_test(test_map A) CHECK_INCLUDE_FILE_CXX(hash_map HASH_MAP_FOUND) if(HASH_MAP_FOUND) archive_test(test_map_hashed A) endif() archive_test(test_mi) archive_test(test_multiple_ptrs A) archive_test(test_multiple_inheritance) archive_test(test_new_operator A) archive_test(test_non_intrusive) archive_test(test_non_default_ctor) archive_test(test_non_default_ctor2) archive_test(test_null_ptr) archive_test(test_nvp A) archive_test(test_object) archive_test(test_optional) archive_test(test_primitive) archive_test(test_priority_queue A) archive_test(test_private_base) archive_test(test_private_base2) archive_test(test_queue A) archive_test(test_recursion A) archive_test(test_registered) archive_test(test_set A) CHECK_INCLUDE_FILE_CXX(hash_set HASH_SET_FOUND) if(HASH_SET_FOUND) archive_test(test_set_hashed A) endif() archive_test(test_shared_ptr) archive_test(test_shared_ptr_multi_base) archive_test(test_shared_ptr_132) archive_test(test_simple_class A) archive_test(test_simple_class_ptr A) CHECK_INCLUDE_FILE_CXX(slist SLIST_FOUND) if(SLIST_FOUND) message(STATUS "slist header found") archive_test(test_slist A) archive_test(test_slist_ptr A) endif() archive_test(test_stack A) archive_test(test_split) archive_test(test_tracking) archive_test(test_unregistered) archive_test(test_unique_ptr) archive_test(test_valarray) archive_test(test_variant A) archive_test(test_vector A) if(BUILD_SHARED_LIBS) polymorphic_archive_test(test_dll_exported polymorphic_derived1) foreach(test_name IN ITEMS ${test_list} ) target_link_libraries(${test_name} dll_polymorphic_derived2 dll_polymorphic_base serialization wserialization) endforeach() endif() polymorphic_archive_test(test_no_rtti polymorphic_base polymorphic_derived1 polymorphic_derived2) polymorphic_archive_test(test_exported polymorphic_base polymorphic_derived1 polymorphic_derived2) polymorphic_archive_test(test_polymorphic test_polymorphic_A A) polymorphic_archive_test(test_polymorphic2 test_polymorphic2imp) polymorphic_archive_test(test_p_helper) # end test targets #################### #################### # add headers in IDE # for serialization file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/*.hpp" ) add_custom_target(archive SOURCES ${x}) set_property(TARGET archive PROPERTY FOLDER "serialization") file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/detail/*.hpp" ) add_custom_target(archive-detail SOURCES ${x}) set_property(TARGET archive-detail PROPERTY FOLDER "serialization") file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/impl/*.ipp" ) add_custom_target(archive-impl SOURCES ${x}) set_property(TARGET archive-impl PROPERTY FOLDER "serialization") file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/iterators/*.hpp" ) add_custom_target(archive-iterators SOURCES ${x}) set_property(TARGET archive-iterators PROPERTY FOLDER "serialization") file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/serialization/*.hpp" ) add_custom_target(serialization-headers SOURCES ${x}) set_property(TARGET serialization-headers PROPERTY FOLDER "serialization") file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/serialization/detail/*.hpp" ) add_custom_target(serialization-detail SOURCES ${x}) set_property(TARGET serialization-detail PROPERTY FOLDER "serialization") # for wserialization file(GLOB x RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/boost/archive/*_w*.hpp" ) add_custom_target(wserialization_headers SOURCES ${x}) set_property(TARGET wserialization_headers PROPERTY FOLDER "wserialization") # end headers in IDE #################### ##################### # add test project to run misc tests add_executable( test_z ../test/test_z.cpp) target_link_libraries(test_z serialization wserialization ${Boost_LIBRARIES}) # end test project ##################### ================================================ FILE: CMakeLists.txt ================================================ # Copyright 2020, 2021 Peter Dimov # Distributed under the Boost Software License, Version 1.0. # https://www.boost.org/LICENSE_1_0.txt cmake_minimum_required(VERSION 3.5...3.16) project(boost_serialization VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) add_library(boost_serialization src/archive_exception.cpp src/basic_archive.cpp src/basic_iarchive.cpp src/basic_iserializer.cpp src/basic_oarchive.cpp src/basic_oserializer.cpp src/basic_pointer_iserializer.cpp src/basic_pointer_oserializer.cpp src/basic_serializer_map.cpp src/basic_text_iprimitive.cpp src/basic_text_oprimitive.cpp src/basic_xml_archive.cpp src/binary_iarchive.cpp src/binary_oarchive.cpp src/codecvt_null.cpp src/extended_type_info.cpp src/extended_type_info_no_rtti.cpp src/extended_type_info_typeid.cpp src/polymorphic_binary_iarchive.cpp src/polymorphic_binary_oarchive.cpp src/polymorphic_iarchive.cpp src/polymorphic_oarchive.cpp src/polymorphic_text_iarchive.cpp src/polymorphic_text_oarchive.cpp src/polymorphic_xml_iarchive.cpp src/polymorphic_xml_oarchive.cpp src/stl_port.cpp src/text_iarchive.cpp src/text_oarchive.cpp src/utf8_codecvt_facet.cpp src/void_cast.cpp src/xml_archive_exception.cpp src/xml_grammar.cpp src/xml_iarchive.cpp src/xml_oarchive.cpp ) add_library(boost_wserialization src/basic_text_wiprimitive.cpp src/basic_text_woprimitive.cpp src/binary_wiarchive.cpp src/binary_woarchive.cpp src/polymorphic_text_wiarchive.cpp src/polymorphic_text_woarchive.cpp src/polymorphic_xml_wiarchive.cpp src/polymorphic_xml_woarchive.cpp src/text_wiarchive.cpp src/text_woarchive.cpp src/xml_wgrammar.cpp src/xml_wiarchive.cpp src/xml_woarchive.cpp ) add_library(Boost::serialization ALIAS boost_serialization) add_library(Boost::wserialization ALIAS boost_wserialization) target_include_directories(boost_serialization PUBLIC include) target_include_directories(boost_wserialization PUBLIC include) target_link_libraries(boost_serialization PUBLIC Boost::array Boost::assert Boost::config Boost::core Boost::detail Boost::integer Boost::io Boost::iterator Boost::move Boost::mpl Boost::optional Boost::predef Boost::preprocessor Boost::smart_ptr Boost::spirit Boost::type_traits Boost::unordered Boost::utility Boost::variant PRIVATE Boost::function ) target_link_libraries(boost_wserialization PUBLIC boost_serialization) target_compile_definitions(boost_serialization PUBLIC BOOST_SERIALIZATION_NO_LIB # Source files already define BOOST_SERIALIZATION_SOURCE # PRIVATE BOOST_SERIALIZATION_SOURCE ) target_compile_definitions(boost_wserialization PUBLIC BOOST_SERIALIZATION_NO_LIB # Source files already define BOOST_SERIALIZATION_SOURCE # PRIVATE BOOST_SERIALIZATION_SOURCE ) if(BUILD_SHARED_LIBS) target_compile_definitions(boost_serialization PUBLIC BOOST_SERIALIZATION_DYN_LINK) target_compile_definitions(boost_wserialization PUBLIC BOOST_SERIALIZATION_DYN_LINK) else() target_compile_definitions(boost_serialization PUBLIC BOOST_SERIALIZATION_STATIC_LINK) target_compile_definitions(boost_wserialization PUBLIC BOOST_SERIALIZATION_STATIC_LINK) endif() if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13) boost_install(TARGETS boost_serialization boost_wserialization VERSION ${BOOST_SUPERPROJECT_VERSION} HEADER_DIRECTORY include) endif() if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") add_subdirectory(test) endif() ================================================ FILE: appveyor.yml ================================================ # Copyright 2016 Peter Dimov # Copyright 2016 Robert Ramey # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) version: 1.0.{build}-{branch} shallow_clone: true branches: only: - develop # - master environment: matrix: - BUILD_TOOLSET: gcc BUILD_LINK: static - BUILD_TOOLSET: gcc BUILD_LINK: shared - BUILD_TOOLSET: msvc-14.0 BUILD_LINK: static - BUILD_TOOLSET: msvc-14.0 BUILD_LINK: shared install: - cd .. - git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root - cd boost-root - git submodule init libs/align - git submodule init libs/array - git submodule init libs/assert - git submodule init libs/bind - git submodule init libs/compatibility - git submodule init libs/concept_check - git submodule init libs/config - git submodule init libs/container - git submodule init libs/container_hash - git submodule init libs/core - git submodule init libs/detail - git submodule init libs/filesystem - git submodule init libs/function - git submodule init libs/functional - git submodule init libs/integer - git submodule init libs/intrusive - git submodule init libs/io - git submodule init libs/iterator - git submodule init libs/lexical_cast - git submodule init libs/math - git submodule init libs/move - git submodule init libs/mpl - git submodule init libs/numeric/conversion - git submodule init libs/optional - git submodule init libs/predef - git submodule init libs/preprocessor - git submodule init libs/range - git submodule init libs/smart_ptr - git submodule init libs/spirit - git submodule init libs/system - git submodule init libs/throw_exception - git submodule init libs/tuple - git submodule init libs/type_index - git submodule init libs/type_traits - git submodule init libs/unordered - git submodule init libs/utility - git submodule init libs/variant - git submodule init libs/winapi - git submodule init tools/boost_install - git submodule init libs/headers - git submodule init tools/build - git submodule update - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\serialization - set PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%CD%;%PATH% - bootstrap gcc - b2 headers build: off test_script: - cd libs/serialization/test - b2 -j2 toolset=%BUILD_TOOLSET% link=%BUILD_LINK% ================================================ FILE: build/Jamfile.v2 ================================================ # 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. require-b2 5.0.1 ; import-search /boost/config/checks ; import config : requires ; constant boost_dependencies_private : /boost/function//boost_function ; project : source-location ../src : common-requirements $(boost_dependencies) : requirements @include-spirit $(boost_dependencies_private) : usage-requirements BOOST_SERIALIZATION_NO_LIB=1 ; SPIRIT_ROOT = [ modules.peek : SPIRIT_ROOT ] ; rule include-spirit ( properties * ) { local old-compiler ; if borland in $(properties) { if ! 6.1.0 in $(properties) { old-compiler = true ; } } else if msvc in $(properties) { if 6.5 in $(properties) || 7.0 in $(properties) { old-compiler = true ; } } local result ; if $(old-compiler) { if $(SPIRIT_ROOT) { # note - we can't use $(SPIRIT_ROOT) because # it puts -I$(SPIRIT_ROOT) AFTER the "../../.." in the command line. # so use these instead result = -I$(SPIRIT_ROOT) ; } else { echo **** spirit 1.6x required to build library with this compiler **** ; result = no ; } } return $(result) ; } SOURCES = archive_exception 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 extended_type_info extended_type_info_typeid extended_type_info_no_rtti polymorphic_iarchive polymorphic_oarchive stl_port text_iarchive text_oarchive polymorphic_text_iarchive polymorphic_text_oarchive polymorphic_binary_iarchive polymorphic_binary_oarchive polymorphic_xml_iarchive polymorphic_xml_oarchive void_cast xml_grammar xml_iarchive xml_archive_exception codecvt_null ; SOURCES_HAS_STD_WSTREAMBUF = xml_oarchive utf8_codecvt_facet ; WSOURCES = basic_text_wiprimitive basic_text_woprimitive text_wiarchive text_woarchive polymorphic_text_wiarchive polymorphic_text_woarchive xml_wgrammar xml_wiarchive xml_woarchive polymorphic_xml_wiarchive polymorphic_xml_woarchive codecvt_null ; lib boost_serialization : ## sources ## $(SOURCES).cpp : ## requirements ## [ check-target-builds /boost/config/checks//std_wstreambuf : ../src/$(SOURCES_HAS_STD_WSTREAMBUF).cpp ] msvc:/Gy msvc:_SCL_SECURE_NO_WARNINGS msvc:_CRT_SECURE_NO_WARNINGS shared:BOOST_SERIALIZATION_DYN_LINK=1 ; lib boost_wserialization : $(WSOURCES).cpp boost_serialization : [ requires std_wstreambuf ] msvc:/Gy msvc:_SCL_SECURE_NO_WARNINGS msvc:_CRT_SECURE_NO_WARNINGS # note: both serialization and wserialization are conditioned on the this # switch - don't change it to BOOST_WSERIALIZATION_DYN_LINK shared:BOOST_SERIALIZATION_DYN_LINK=1 ; ================================================ FILE: build.jam ================================================ # Copyright René Ferdinand Rivera Morell 2023-2024 # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) require-b2 5.2 ; constant boost_dependencies : /boost/array//boost_array /boost/assert//boost_assert /boost/config//boost_config /boost/core//boost_core /boost/detail//boost_detail /boost/integer//boost_integer /boost/io//boost_io /boost/iterator//boost_iterator /boost/move//boost_move /boost/mp11//boost_mp11 /boost/mpl//boost_mpl /boost/optional//boost_optional /boost/predef//boost_predef /boost/preprocessor//boost_preprocessor /boost/smart_ptr//boost_smart_ptr /boost/spirit//boost_spirit /boost/throw_exception//boost_throw_exception /boost/type_traits//boost_type_traits /boost/utility//boost_utility /boost/variant//boost_variant /boost/variant2//boost_variant2 ; project /boost/serialization : common-requirements include ; explicit [ alias boost_serialization : build//boost_serialization ] [ alias boost_wserialization : build//boost_wserialization ] [ alias all : boost_serialization boost_wserialization example test ] ; call-if : boost-library serialization : install boost_serialization boost_wserialization ; ================================================ FILE: doc/acknowledgments.html ================================================ Serialization - Acknowledgments

C++ Boost

Serialization

Acknowledgments


  • Takatoshi Kondo found and corrected a very obscure and difficult bug in the serialization of virtual base classes.
  • AutoForm Engineering GmbH supported development efforts to extend correct serialization to objects stored in DLLS.
  • Cadence Israel supported enhancement and testing of the portable binary archive.
  • 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".
  • Mattias Troyer enhanced the implementation of native binary archives. This includes enhancement and generalization of the library itself including generalization of the wrapper concept.
  • Markus Schöpflin tracked down issues with TRU64 compiler resulting in 100% passing.
  • Troy D. Straszheim made the initial version of variant serialization.
  • Tonko Juricic helped refine and complete project files for VC 7.1 ide
  • Rene Rivera tracked down several issues related to Code Warrior, toolset configuration and bjam and much else.
  • Martin Ecker detected (and fixed!) a number of subtle errors regarding cyclic pointers, shared pointers. He also built the library as a DLL and raised some issues
  • 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 platforms including VC 6.0, Intel, and especially Borland.
  • Jens Maurer and Beman Dawes who got the boost serialization ball rolling. It was one or both of these two that invented the much beloved & syntax used to implement both save and load in one function specification.
  • Vladimir Prus for evaluating an early draft and contributing the diamond inheritance example.
  • William E. Kempf who made the templates for this and other boost manuals. This relieved me of much aggravation.
  • Vahan Margaryan and Fredrik Blomqvist for their contributions to my understanding of the subtle issues of exception safety in this context.
  • all other boost members who responded with feedback during the development of this library. Almost all comments resulted in tangible changes in the library which made it much better.
  • boosters who helped out in porting to other platforms:, Fernando Cacciola (Borland), Jeff Flinn (VC 7.1), Vladimir Prus (gcc 3.3), Christoph Ludwig(gcc 3.4), Rob Lievaart(mingw), Marshal Clow(gcc-darwin) among others.
  • all boost members who participated in the first formal review in November 2002. Many of these members invested quite an effort to evaluate the library and suggest changes. They are Matthias Troyer, Pavel Vozenilek, Vladimir Prus, Fredrik Blomqvist, Jeff Garland, Gennadiy Rozental, Alberto Barbati, Dave Harris. Mr. Rozenthal in particular wrote an incredibly insightful analysis that has driven all subsequent development that has resulted in the current package.
  • Dave Harris proposal and spirited defense of it led to a re-thinking of the overrides for serialization of pointers. This resulted in a simpler and more effective method of accounting for non-default constructors required by serialization of pointers and STL collections.
  • Bryce Lelbach rewrote the XML Serialization grammar using Boost.Spirit 2.x.

© Copyright Robert Ramey 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)

================================================ FILE: doc/archive_reference.html ================================================ Serialization - More on Archives

C++ Boost

Serialization

Archive Class Reference


Trivial Archive
More Useful Archive Classes
Usage
Testing
Polymorphic Archives

Trivial Archive

The Archive concept specifies the functions that a class must implement in order to be used to serialize Serializable types. Our discussion will focus on archives used for saving as the hierarchy is exactly analogous for archives used for loading data.

Minimum Requirements

The simplest class which will model the Archive concept specifies the functions that a class will look like:

#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){};
};
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.

This archive will compile and execute with any types which implement the Serializable concept. For an example see demo_trivial_archive.cpp. 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 simple log archive to how this has been done.

More Useful Archive Classes

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.

Our archives have been factored into a tree of classes in order to minimize repetition of code. This is shown in the accompanying class diagram. Any class which fulfills the following requirements will fit into this hierarchy and implement all the features we require. Deriving from the base class common_oarchive.hpp provides all features we desire which are missing from trivial_oarchive above.



#include <cstddef> // std::size_t
#include <boost/archive/detail/common_oarchive.hpp>

/////////////////////////////////////////////////////////////////////////
// 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
    template<class T>
    void save(T & t);

public:
    //////////////////////////////////////////////////////////
    // public interface used by programs that use the
    // serialization library

    // archives are expected to support this function
    void save_binary(void *address, std::size_t count);
};
Given a suitable definitions of save and save_binary, any program using serialization with a conforming C++ compiler should compile and run with this archive class.

Optional Overrides

The detail::common_oarchive 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.

void save_start(char const *)

Default:Does nothing.
Purpose:To inject/retrieve an object name into the archive. Used by XML archive to inject "<name>" before data.

void save_end(char const *)

Default:Does nothing.
Purpose:To inject/retrieve an object name into the archive. Used by XML archive to inject "</name>" after data.

void end_preamble()

Default:Does nothing.
Purpose:Called each time 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 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 void end_preamble() 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 void end_preamble() is a no-op thereby permitting it to be optimised away for archive classes that don't use it.

template<class T> void save_override(T & t, int);

Default:Invokes archive::save(Archive & ar, t)
This is the main entry into the serialization library.
Purpose:This can be specialized in cases where the data is to be written to the archive in some special way. For example, XML archives implement special handling for name-value pairs by overriding this function template for name-value pairs. This replaces the default name-value pair handling, which is just to throw away the name, with one appropriate for XML which writes out the start of an XML tag with the correct object name.

Types used by the serialization library

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 void save_override(T & t, int);. 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 boost::archive namespace used internally by the serialization library:

typedefault
serialized as
version_typeunsigned int
object_id_typeunsigned int
object_id_reference_typeunsigned int
class_id_typeint
class_id_optional_typenothing
class_id_reference_typeint
tracking_typebool
classname_typestring

All of these are associated with a default serialization defined in terms of primitive types so it isn't a requirement to define save_override for these types.

These are defined in basic_archive.hpp. All of these types have been assigned an implementation level of primitive and are convertible to types such as int, unsigned int, etc. so that they have default implementations. This is illustrated by basic_text_iarchive.hpp. which relies upon the default. However, in some cases, overrides will have to be explicitly provided for these types. For an example see basic_xml_iarchive.hpp.

In real practice, we probably won't be quite done. One or more of the following issues may need to be addressed:

  • Even if we are using a conforming compiler, we might want our new archive class to be portable to non-conforming compilers.
  • Our archive format might require extra information inserted into it. For example, XML archives need <name ... >...</name> surrounding all data objects.
  • Addressing any of the above may generate more issues to be addressed.
  • The archives included with the library are all templates which use a stream or streambuf as a template parameter rather than simple classes. Combined with the above, even more issues arise with non-conforming compilers.
The attached class diagram shows the relationships between classes used to implement the serialization library.

A close examination of the archives included with the library illustrate what it takes to make a portable archive that covers all data types.

Usage

The newly created archive will usually be stored in its own header module. All that is necessary is to include the header and construct an instance of the new archive. EXCEPT for one special case.
  • Instances of a derived class are serialized through a base class pointer.
  • Such instances are not "registered" neither implicitly nor explicitly. That is, the macro BOOST_CLASS_EXPORT is used to instantiate the serialization code for the included archives.
To make this work, the following should be included after the archive class definition.

BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)
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 will throw an unregistered_class exception.

Testing

Exhaustive testing of the library requires testing the different aspects of object serialization with each archive. There are 46 different tests that can run with any archive. There are 5 "standard archives" included with the system. (3 in systems that don't support wide character i/o).

In addition, there are 28 other tests which aren't related to any particular archive class.

The default bjam 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.

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 BOOST_ARCHIVE_TEST to the name of the header. Here is the header file test_archive.hpp . Test header files for other archives are similar.


// text_archive test header
// include output archive header
#include <boost/archive/text_oarchive.hpp>
// set name of test output archive
typedef boost::archive::text_oarchive test_oarchive;
// set name of test output stream
typedef std::ofstream test_ostream;

// repeat the above for input archive
#include <boost/archive/text_iarchive.hpp>
typedef boost::archive::text_iarchive test_iarchive;
typedef std::ifstream test_istream;

// define open mode for streams
//   binary archives should use std::ios_base::binary
#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
To test a new archive, for example, portable binary archives, with the gcc compiler, make a header file portable_binary_archive.hpp and invoke bjam with
 
-sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
This process in encapsulated in the shell or cmd script library_test whose command line is

library_test --toolset=gcc -sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp

Polymorphic Archives

Motivation

All archives described so far are implemented as templates. Code to save and load data to archives is regenerated for each combination of archive class and data type. Under these circumstances, a good optimizing compiler that can expand inline functions to enough depth will generate fast code. However:
  • Much inline code may be replicated.
  • If there are several archive classes, code will be regenerated for each archive class.
  • If serialization code is placed in a library, that library must be rebuilt each time a new archive class is created.
  • If serialization code is placed in a DLL,
    • The DLL will contain versions of code for each known archive type. This would result in loading of DLLs which contain much code that is not used - basically defeating one of the main motivations for choosing to use a DLL in the first place.
    • If a new archive is created and an application shipped, all DLLs have to be rebuilt, and reshipped along with the application which uses the new archive. Thus the other main motivation for using a DLL is defeated.

Implementation

The solution is the pair polymorphic_oarchive and polymorphic_iarchive. They present a common interface of virtual functions - no templates - that is equivalent to the standard templated one. This is shown in the accompanying class diagram

The accompanying demo program in files demo_polymorphic.cpp, demo_polymorphic_A.hpp, and demo_polymorphic_A show how polymorphic archives are to be used. Note the following:

  • demo_polymorphic_A.hpp and demo_polymorphic_A.cpp 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 created in the future.
  • The main program demo_polymorphic.cpp specifies a specific archive implementation.
As can be seen in the class diagram 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 polymorphic_iarchive_route.hpp and polymorphic_oarchive_route.hpp which redirect calls to the polymorphic archives to the specific archive. As these contain no code specific to the particular implementation archive, they can be used to create a polymorphic archive implementation from any functioning templated archive implementation.

As a convenience, small header files have been included which contain a typedef for a polymorphic implementation for each corresponding templated one. For example, the headers polymorphic_text_iarchive.hpp and polymorphic_text_oarchive.hpp. contain the typedef for the polymorphic implementation of the standard text archive classes text_iarchive.hpp and text_oarchive.hpp respectively. All included polymorphic archives use the same naming scheme.

Usage

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 inline archive functions. This will result in a detectable degradation in performance for saving and loading archives.

Note that the concept of polymorphic archives is fundamentally incompatible with the serialization of new types that are marked "primitive" by the user with:

 
BOOST_CLASS_IMPLEMENTATION(my_primitive_type, boost::serialization::primitive_type)
Code to implement serialization for these types is instantiated "on the fly" in the user's program. But this conflicts with the whole purpose of the polymorphic archive. An attempt to serialize such a primitive type will result in a compilation error since the common polymorphic interface is static and cannot instantiate code for a new type.

The main utility of polymorphic archives will be to permit the building of class DLLs that will include serialization code for all present and future archives with no redundant code.


© Copyright Robert Ramey 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)

================================================ FILE: doc/archives.html ================================================ Serialization - Archives

C++ Boost

Serialization

Archive Concepts


Saving Archive Concept
Loading Archive Concept
Models
Exceptions
Character Sets

Notation

In the following descriptions
  • SA is an type modeling the Saving Archive Concept.
  • sa is an instance of type SA.
  • LA is an type modeling the Loading Archive Concept.
  • la is an instance of type LA.
  • T is an Serializable Type.
  • x is an instance of type T Type.
  • u,v is a pointer to a an instance of type T.
  • count is an instance of a type that can be converted to std::size_t.

Saving Archive Concept

Associated Types

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 Loading Archive Concept(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 serializable.

Valid Expressions

SA::is_saving

Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>

SA::is_loading

Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>

sa << x
sa & x

These expressions must perform exactly the same function. They append the value of x along with other information to sa. 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 x.

Returns a reference to sa.

sa.save_binary(u, count)

Appends to the archive size_t(count) bytes found at u.

sa.register_type<T>()
sa.register_type(u)

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 Special Considerations - Derived Pointers. The second syntax is included to permit this function to be called on non-conforming compilers when sa is a template argument. For more information, see Template Invocation syntax

sa.get_library_version()

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.

sa.get_helper<Helper>(void * const helper_instance_id = 0)

See la.get_helper<Helper>(void * const helper_instance_id = 0) below.

Loading Archive Concept

Associated Types

Each model of this concept presumes the existence of a corresponding type modeling the Saving Archive Concept. 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.

Valid Expressions

LA::is_saving

Returns the Boost MPL Integral Constant type boost::mpl::bool_<false>

LA::is_loading

Returns the Boost MPL Integral Constant type boost::mpl::bool_<true>

la >> x
la & x

These expressions must perform exactly the same function. Sets x to a value retrieved from la.

Returns a reference to la.

la.load_binary(u, count)

Retrieves from la size_t(count) bytes and stores them in memory starting at u.

la.register_type<T>()
la.register_type(u)

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 Special Considerations - Derived Pointers. The second syntax is included to permit this function to be called on non-conforming compilers when la is a template argument. For more information, see Template Invocation syntax

la.get_library_version()

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.

la.get_helper<Helper>(void * const helper_instance_id)

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 la.get_helper<Helper>(void * const helper_instance_id) is invoked for a given helper_instance_id, Helper, a default-constructed Helper object is created, attached to la and a reference to it is returned. Subsequent invocations of la.get_helper<Helper>(void * const helper_instance_id) with the same id value return a reference to the formerly constructed object. All objects created in this manner are destroyed upon la destruction time. The purpose of helper objects is discussed in Special Considerations - Helper Support.

la.reset_object_address(v, u)

Communicates to the archive that the object originally at address u has been moved to address v.

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.

la.delete_created_pointers()

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.
There are archives based on text, binary and XML file formats but all have the above interface. Given that all archives present the same public interface, specification of serialization is exactly the same for all archives. Archive classes have other members not mentioned here. However they are related to the internal functioning of the library and are not meant to be called by users of an archive. Implementation of new archives is discussed in New Archives - Implementation.

The existence of the << and >> suggests a relationship between archives and C++ i/o streams. Archives are not C++ i/o streams. 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. 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.

Archive Models

This library includes various implementations of the Archive concept. An archive is defined by two complementary classes. One is for saving data while the other is for loading it. 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.

// a portable text archive
boost::archive::text_oarchive // saving
boost::archive::text_iarchive // loading

// a portable text archive using a wide character stream
boost::archive::text_woarchive // saving
boost::archive::text_wiarchive // loading

// a portable XML archive
boost::archive::xml_oarchive // saving
boost::archive::xml_iarchive // loading

// a portable XML archive which uses wide characters - use for utf-8 output
boost::archive::xml_woarchive // saving
boost::archive::xml_wiarchive // loading

// a non-portable native binary archive
boost::archive::binary_oarchive // saving
boost::archive::binary_iarchive // loading



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.

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 - ignored on saving
};

} // archive
} // boost

namespace boost {
namespace archive {

class text_oarchive : ...
{
    ...
public:
    ... // implementation of the Saving Archive concept
    text_oarchive(std::ostream & os, unsigned int flags = 0);
    ~text_oarchive();
};

} // archive
} // boost

text_oarchive(std::ostream & os, unsigned int flags = 0);

Constructs an archive given an open stream as an argument and optional flags. For most applications there will be no need to use flags. Flags are defined by enum archive_flags enumerator. Multiple flags can be combined with the | 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 endianness to gracefully handle the case where it has been erroneously assumed that such an archive is portable across platforms. In some cases, where this extra overhead might be considered objectionable, it can be suppressed with the no_header flag.

In some cases, an archive may alter (and later restore) the codecvt facet of the stream locale. To suppress this action, include the no_codecvt flag.

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 no_xml_tag_checking flag.

~text_oarchive();

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.

namespace boost {
namespace archive {

class text_iarchive : ...
{
    ...
public:
    ... // implementation of the Loading Archive concept
    text_iarchive(std::istream & is, unsigned int flags = 0);
    ~text_iarchive();
};

} //namespace archive
) //namespace boost

text_iarchive(std::istream & is, unsigned int flags = 0);

Constructs an archive given an open stream 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.

~text_iarchive();

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.

The binary_oarchive and binary_iarchive classes are implemented in terms of the more basic std::streambuf. So, in addition to the common class interface described above, they include the following constructors:

binary_oarchive(std::streambuf & bsb, unsigned int flags = 0);

and

binary_iarchive(std::streambuf & bsb, unsigned int flags = 0);

Exceptions

All of the archive classes included may throw exceptions. The list of exceptions that might be thrown can be found in section Archive Exceptions of this documentation.

Character Sets

This library includes two archive classes for XML. The wide character version (xml_w?archive) renders its output as UTF-8 which can handle any wide character without loss of information. std::string data is converted from multi-byte format to wide character format using the current locale. Hence this version should give a fair rendering of all C++ data for all cases. This could result in some unexpected behavior. Suppose an std::string is created with the locale character set to hebrew characters. On output this is converted to wide characters. On input however, there could be a problem if the locale is not set the same as when the archive is created.

The normal character version (xml_?archive) renders std::string output without any conversion. Though this may work fine for serialization, it may create difficulties if the XML archive is used for some other purpose.


© Copyright Robert Ramey 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)

================================================ FILE: doc/bibliography.html ================================================ Serialization - Bibliography

C++ Boost

Serialization

Bibliography


  1. David Sugar and Daniel Silverstone, "CommonC++ Libraries", http://www.gnu.org/software/commoncpp/
  2. Nicola Santi, "Eternity", www.sourceforge.net/projects/eternity-it/
  3. Allen Holub, "Roll Your Own Persistence", Microsoft Systems Journal vol 11, no 6 Jun 1996
  4. Code Farms, Inc.
  5. Tasos Kontogiorgos & Michael Kim, "A C++ Template-Based Application Architecture", C++ Report
  6. Scott Meyers, Effective C++, Addison-Wesley, 1992
  7. Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley, 1997
  8. Alexandrescu, Andrei, Modern C++ Design, Addison-Wesley, 2001
  9. Jim Hyslop, and Herb Sutter, "Factory Redux, Part2", C/C++ User's Journal, vol 21, No. 8, August 2003
  10. David Vandevoorde and Nicolai M. Josuttis, C++ Templates - The Complete Guide, Addison-Wesley, 2003
  11. Herb Sutter, "Pimpls--Beauty Marks You Can Depend On", C++ Report, from More C++ Gems, Cambridge University Press, 2000
  12. James Coplien, "Curiously Recurring Template Patterns", C++ Report, from C++ Gems, Cambridge University Press, 1998
  13. Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Design Patterns, Addison-Wesley Publishing Company, 1995
  14. Stephan Beal, "s11n serialization library", www.s11n.net
  15. Vandevoorde and Josuttis, C++ Templates - A Complete Guide, Addison-Wesley, 2003

© Copyright Robert Ramey 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)

================================================ FILE: doc/class_diagram.html ================================================ Serialization - Archive Class Diagram

C++ Boost

Serialization

Text Archive Class Diagram





basic_oarchive ->
      |
      |
      |      interface_oarchive<text_oarchive> ->
      |                     /
      |                   /
      |        _________/
      |      /
      |    /
      |  /
common_oarchive<text_oarchive> ->
      |
      |
basic_text_oarchive<text_oarchive> ->
      |
      |
      |     basic_text_oprimitive<basic_ostream> ->
      |                    /
      |                  /
      |       _________/                  interface_oarchive<polymorphic_oarchive> ->
      |     /                                                |
      |   /                                                  |
      | /                                                    |
text_oarchive_impl<text_oarchive> ->              polymorphic_oarchive_impl ->
      | \                                                    |
      |   \                                                  |
      |     \_____________________________________    polymorphic_oarchive ->
      |                                           \         /
      |                                             \     /
      |                                               \ /  
text_oarchive ->                 polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> > ->
                                                       |
                                                       |
                                                       |
                                             polymorphic_text_oarchive ->


This diagram shows the relationship between the various classes that implement saving (output serialization) for text archives. The hierarchy and organization is similar for loading and for other types of archives as well. In the diagram, classes written in blue implement saving for a given archive type. (in this case it's text archives). Users include classes in red to save their data from a particular type of archive. Other classes whose names are in black implement the library and should never change. They are in namespace boost::archive::detail
basic_oarchive
Implements the core library functions for class export, versioning, and object tracking. It is compiled into the library as it has no template parameters.

interface_oarchive<text_oarchive>
A class that declares the standard archive interface. This has been factored out so that it can be used as a base class for polymorphic_oarchive as well as for archive implementations.

common_oarchive<text_oarchive>
The function of this class is to make the connection between the virtual function interface used by basic_oarchive and the template interface used by archive class implementations.

basic_text_oarchive<text_oarchive>
Implements the basic functionality for simple text archives. The primitive save functions have been factored out so it can be used in other text based archives like XML archives.

basic_text_oprimitive<basic_ostream>
Implements the save oversaves for all primitive types. This is a template with a parameter which describes the stream.

text_oarchive_impl<text_oarchive>
Inherits from the above two classes to implement text archives.

text_oarchive
This is just a short hand for text_oarchive_impl<text_oarchive> . We can't use typedef because a typedef can't refer to it self in its definition. This is the class name that is used to serialize to a text archive.

interface_oarchive<polymorphic_oarchive>
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 common_oarchive uses.

polymorphic_oarchive
A class with a list of virtual save(T &t) 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.

polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> >

This class implements the polymorphic_oarchive 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.

polymorphic_text_oarchive
this is just a typedef so we can write polymorphic_text_archive rather than polymorphic_oarchive_route<text_oarchive_impl<text_oarchive> >

© Copyright Robert Ramey 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)

================================================ FILE: doc/codecvt.html ================================================ UTF-8 Codecvt Facet C++ Boost

utf8_codecvt_facet

template<
    typename InternType = wchar_t, 
    typename ExternType = char
> utf8_codecvt_facet

Rationale

UTF-8 is a method of encoding Unicode text in environments where data is stored as 8-bit characters and some ascii characters are considered special (i.e. Unix filesystem filenames) and tend to appear more commonly than other characters. While UTF-8 is convenient and efficient for storing data on filesystems, it was not meant to be manipulated in memory by applications. While some applications (such as Unix's 'cat') can simply ignore the encoding of data, others should convert from UTF-8 to UCS-4 (the more canonical representation of Unicode) on reading from file, and reversing the process on writing out to file.

The C++ Standard IOStreams provides the std::codecvt facet to handle specifically these cases. On reading from or writing to a file, the std::basic_filebuf can call out to the codecvt facet to convert data representations from external format (ie. UTF-8) to internal format (ie. UCS-4) and vice-versa. utf8_codecvt_facet is a specialization of std::codecvt specifically designed to handle the case of translating between UTF-8 and UCS-4.

Template Parameters

ParameterDescriptionDefault
InternType The internal type used to represent UCS-4 characters. wchar_t
ExternType The external type used to represent UTF-8 octets. char_t

Requirements

utf8_codecvt_facet defaults to using char as its external data type and wchar_t as its internal datatype, but on some architectures wchar_t is not large enough to hold UCS-4 characters. In order to use another internal type.You must also specialize std::codecvt to handle your internal and external types. (std::codecvt<char,wchar_t,std::mbstate_t> is required to be supplied by any standard-conforming compiler).

Example Use

The following is a simple example of using this facet:
  //...
  // My encoding type
  typedef wchar_t ucs4_t;

  std::locale old_locale;
  std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);

  // Set a New global locale
  std::locale::global(utf8_locale);

  // Send the UCS-4 data out, converting to UTF-8
  {
    std::wofstream ofs("data.ucd");
    ofs.imbue(utf8_locale);
    std::copy(ucs4_data.begin(),ucs4_data.end(),
          std::ostream_iterator<ucs4_t,ucs4_t>(ofs));
  }

  // Read the UTF-8 data back in, converting to UCS-4 on the way in
  std::vector<ucs4_t> from_file;
  {
    std::wifstream ifs("data.ucd");
    ifs.imbue(utf8_locale);
    ucs4_t item = 0;
    while (ifs >> item) from_file.push_back(item);
  }
  //...

History

This code was originally written as an iterator adaptor over containers for use with UTF-8 encoded strings in memory. Dietmar Kuehl suggested that it would be better provided as a codecvt facet.

Resources



Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
Andrew Lumsdaine, Indiana University (lums@osl.iu.edu)

© Copyright Robert Ramey 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)

================================================ FILE: doc/configuration.html ================================================ Serialization - Configuration ================================================ FILE: doc/contents.html ================================================ Serialization

Contents

Release Notes
Overview
Tutorial
Reference
Archive Concepts
Serializable Concept
Special Considerations
Archive Class Reference
Implementation Notes
Case Studies
Other Classes
Tips and Tricks
Rationale
To Do
History
Bibliography
Acknowledgments
================================================ FILE: doc/dataflow.html ================================================ Serialization - Dataflow Iterators

C++ Boost

Serialization

Dataflow Iterators


Motivation

Consider the problem of translating an arbitrary length sequence of 8 bit bytes to base64 text. Such a process can be summarized as:

source => 8 bit bytes => 6 bit integers => encode to base64 characters => insert line breaks => destination

We would prefer the solution that is:

  • Decomposable. so we can code, test, verify and use each (simple) stage of the conversion independently.
  • Composable. so we can use this composite as a new component somewhere else.
  • Efficient, so we're not required to re-implement it again.
  • Scalable, so that it works well for short and arbitrarily long sequences.
The approach that comes closest to meeting these requirements is that described and implemented with Iterator Adaptors. The fundamental feature of an Iterator Adaptor template that makes it interesting to us is that it takes as a parameter a base iterator from which it derives its input. This suggests that something like the following might be possible.

typedef 
    insert_linebreaks<         // insert line breaks every 76 characters
        base64_from_binary<    // convert binary values to base64 characters
            transform_width<   // retrieve 6 bit integers from a sequence of 8 bit bytes
                const char *,
                6,
                8
            >
        > 
        ,76
    > 
    base64_text; // compose all the above operations in to a new iterator

std::copy(
    base64_text(address),
    base64_text(address + count),
    ostream_iterator<CharType>(os)
);
Indeed, this seems to be exactly the kind of problem that iterator adaptors are intended to address. The Iterator Adaptor library already includes modules which can be configured to implement some of the operations above. For example, included is transform_iterator, which can be used to implement 6 bit integer => base64 code.

Dataflow Iterators

Unfortunately, not all iterators which inherit from Iterator Adaptors are guaranteed to meet the composability goals stated above. To accomplish this purpose, they have to be written with some additional considerations in mind. We define a Dataflow Iterator as an class inherited from iterator_adaptor which fulfills a small set of additional requirements.

Templated Constructors

Templated constructor have the form:


template<class T>
dataflow_iterator(T start) :
    iterator_adaptor(Base(start))
{}
When these constructors are applied to our example of above, the following code is generated:

std::copy(
    insert_linebreaks(
        base64_from_binary(
            transform_width(
                address
            ),
        )
    ),
    insert_linebreaks(
        base64_from_binary(
            transform_width(
                address + count
            )
        )
    )
    ostream_iterator<char>(os)
);
The recursive application of this template is what automatically generates the constructor base64_text(const char *) in our example above. The original Iterator Adaptors include a make_xxx_iterator to fulfill this function. However, I believe these are unwieldy to use compared to the above solution using Templated constructors.

Dereferencing

Dereferencing some iterators can cause problems. For example, a natural way to write a remove_whitespace iterator is to increment past the initial whitespaces when the iterator is constructed. This will fail if the iterator passed to the constructor "points" to the end of a string. The filter_iterator is implemented in this way so it can't be used in our context. So, for implementation of this iterator, space removal is deferred until the iterator actually is dereferenced.

Comparison

The default implementation of iterator equality of iterator_adaptor just invokes the equality operator on the base iterators. Generally this is satisfactory. However, this implies that other operations (E. G. dereference) do not prematurely increment the base iterator. Avoiding this can be surprisingly tricky in some cases. (E.G. transform_width)

Iterators which fulfill the above requirements should be composable and the above sample code should implement our binary to base64 conversion.

Iterators Included in the Library

Dataflow iterators for the serialization library are all defined in the namespace boost::archive::iterators included here are:
base64_from_binary
transforms a sequence of integers to base64 text
binary_from_base64
transforms a sequence of base64 characters to a sequence of integers
insert_linebreaks
given a sequence, creates a sequence with newline characters inserted
mb_from_wchar
transforms a sequence of wide characters to a sequence of multi-byte characters
remove_whitespace
given a sequence of characters, returns a sequence with the white characters removed. This is a derivation from the boost::filter_iterator
transform_width
transforms a sequence of x bit elements into a sequence of y bit elements. This is a key component in iterators which translate to and from base64 text.
wchar_from_mb
transform a sequence of multi-byte characters in the current locale to wide characters.
xml_escape
escapes xml meta-characters from xml text
xml_unescape
unescapes xml escape sequences to create a sequence of normal text

The standard stream iterators don't quite work for us. On systems which implement wchar_t 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 boost::archive::interators to avoid conflicts with the standard library versions.

istream_iterator
ostream_iterator

© Copyright Robert Ramey 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)

================================================ FILE: doc/definitions.html ================================================ Serialization - Definitions ================================================ FILE: doc/derivation.html ================================================ Serialization - Derivation from an Existing Archive

C++ Boost

Serialization

Derivation from an Existing Archive


Log Archive

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 demo_log.cpp.

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.

To this end it is derived from the included xml archive and the save functions for some types are specialized for this application.

The serialization library is implemented using the Curiously Recurring Template Pattern (CRTP). 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.

This example illustrates several issues that have to be addressed when doing something like this

  1. It is derived from xml_oarchive_impl NOT xml_oarchive
    As described in the comments in xml_oarchive.hpp. xml_oarchive really a shorthand name for xml_oarchive_impl<xml_oarchive>. So we should derive from xml_oarchive_impl<log_archive> rather than xml_oarchive.
    
    class log_archive :
        // don't derive from xml_oarchive !!!
        public xml_oarchive_impl<log_archive>
    {
    ...
    
  2. Note the log_archive between the <> This is required so that base classes can downcast their this pointer to the most derived class. This is referred to as Curiously Recurring Template Pattern (CRTP) [11]. It is used to implement static polymorphism.
  3. Base classes need to be explicitly given access to the derived class. This can be done by making members public or by including friend declarations for the base classes.
    
        friend class detail::common_oarchive<log_archive>;
        friend class basic_xml_oarchive<log_archive>;
        friend class boost::serialization::save_access;
    
  4. Reread Archive Internals. This describes the class hierarchy so that you know what to override.
  5. Base class functions will usually need to be explicitly invoked. We commonly specialize the function name save_override for saving primitives. Usage of a function name in a derived class "hides" similarly named functions of the base class. That is, function name overloading doesn't automatically include base classes. To address this, we can use:
    
        using xml_oarchive_impl<derived_t>::save;
        void save(const unsigned int t);
        ...
    
    which should work on conforming compilers. However, I have found 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);
        }
        void save(const unsigned int t);
        ...
    
    so it's what I use.
  6. Template definitions of base classes may have to be explicitly instantiated. The demo includes
    
    // explicitly instantiate for this type of binary stream
    #include <boost/archive/basic_binary_oprimitive.ipp>
    
    for just this purpose. Failure to include required template definitions will result in undefined symbol errors when the program is linked.
  7. Without alteration, this class cannot be further derived from.
    Base classes using CRTP 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 xml_oarchive. Specifically, it would look something like:
    
    template<class Archive>
    class log_archive_impl :
        // don't derive from xml_oarchive !!!
        public xml_oarchive_impl<Archive>
    {
        ...
    };
    
    // do not derive from this class !!!
    class log_archive : 
        public log_archive_impl<log_archive>
    {
    public:
        log_archive(std::ostream & os, unsigned int flags = 0) :
            log_archive_impl<xml_oarchive>(os, flags)
        {}
    };
    

© Copyright Robert Ramey 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)

================================================ FILE: doc/exception_safety.html ================================================ Serialization - Reference

C++ Boost

Serialization

Exception Safety


The process of loading an archive may result in the creation of new objects. That same process may throw an exception at some point. In order to prevent memory leaks and invalid pointers, these situations must be considered. Unfortunately, there is no simple universal solution to this problem. The manner of addressing this must depend on the design of the data structures to be serialized. Below, we discuss varying scenarios in increasing order of difficulty. This discussion presumes that the class member functions are exception safe before considering serialization. That is, the destructor could be called at anytime without referencing an invalid pointer, or creating a memory leak.
  1. class contains no pointers

    No problem here.

  2. class contains only owned pointers

    From here on, we have to make a distinction between pointers used to manage heap storage (owned pointers) and pointers used to refer to related objects (referenced pointers). Programs containing owned pointers must contain code for deleting these objects and returning the deallocated storage to the heap. Programs containing referenced pointers must be designed to ensure that no such referenced pointers are de-referenced after the object pointed to has been destroyed and its storage returned to the heap. If a pointer is stored in only one place, it must be an owned pointer.

    The load function traps any exceptions that occur between the time an object is created and its pointer is stored. Should an exception occur while reading an archive, the created object is deleted and the de-serialized pointer is set to NULL. This ensures that there are no memory leaks. The fact that there are no other copies of this pointer ensures that no pointers are left invalid. The object's destructor should be able to delete any other existing objects in the normal manner without problem. test_delete_pointer.cpp illustrates this case.

  3. class contains one or more referenced pointers

    This situation can be further subdivided into two cases

    1. owned pointers are always serialized before referenced pointers

      Object tracking will ensure that no new objects will be created by the loading of a referenced pointer. If an exception occurs, referenced 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. Owned pointers are handled exactly as described above.

    2. class contains referenced pointers which might be created by load

      If a referenced pointer is loaded before its corresponding owned pointer, the object will be allocated on the heap. In certain cases it cannot be known which pointers were created by their owners and which were created by the load function. To address this:
      • Trap exceptions with a try/catch block.
      • Within the catch part, invoke the archive function delete_created_pointers() to delete any pointers created by the class load. Without other action, objects created in this way would end up as memory leaks as they are not considered owned pointers and hence aren't destroyed.
      • The object's destructor won't try to delete referenced pointers so any dangling references will cause no harm.
      demo_exception.cpp is a program that illustrates this case.

  4. Other cases

    Situations not covered above are pointers for which the classifications of referenced and owned are not applicable. This might occur where pointers are created by one class but consumed and deleted by another. These may be addressed with an ad hoc analysis similar to the above. As the situation becomes more complex this becomes more difficult and error prone. Eventually, it will be have to addressed by building heap management into the pointer itself - that is into boost::shared_ptr. The library includes serialization of boost::shared_ptr. As previously mentioned, this required a tiny alteration in one of the boost::shared_ptr implementation files in order to permit access by the serialization system.

© Copyright Robert Ramey 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)

================================================ FILE: doc/exceptions.html ================================================ Serialization - Archive Exceptions

C++ Boost

Serialization

Archive Exceptions


unregistered_class
invalid_signature
unsupported_version
unsupported_class_version
pointer_conflict
incompatible_native_format
array_size_too_short
input_stream_error
output_stream_error
invalid_class_name
unregistered_class
multiple_code_instantiation
xml_archive_parsing_error
xml_archive_tag_mismatch
xml_archive_tag_name_error
Archive operators can throw a boost::archive_exception object which can be caught by an application program. These exceptions are defined in the files archive_exception.hpp and basic_xml_archive.hpp.

namespace boost {
namespace archive {

class archive_exception  : public std::exception
{
public:
    typedef enum {
        unregistered_class,     // attempt to serialize a pointer of
                                // an unregistered class
        invalid_signature,      // first line of archive does not contain
                                // expected string
        unsupported_version,    // archive created with library version subsequent
                                // to this one
        pointer_conflict        // an attempt has been made to directly 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.
        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 program
                            // needs to be rebuilt.
        multiple_code_instantiation, // code for implementing serialization for some
                            // type has been instantiated in more than one module.
        output_stream_error     // error on stream output
    } exception_code;
    exception_code code;
    archive_exception(exception_code c) : code(c) {}
    virtual const char *what( ) const throw();
};

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

    } exception_code;
    xml_archive_exception(exception_code c){}
    virtual const char *what( ) const throw();
};

} // archive
} // boost

unregistered_class

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 BOOST_ARCHIVE_CUSTOM_ARCHIVE_TYPES macro.

invalid_signature

Archives are initiated with a known string. If this string is not found when the archive is opened, It is presumed that this file is not a valid archive and this exception is thrown.

unsupported_version

This system records the current library version number to all archives created. Note that this is in no way related to version number of classes used by application programs. This refers to the version of the serialization system used to create the archive. Future versions of this serialization system will be able to identify archives created under a previous (i.e. this) system and alter the loading procedure accordingly. Hence, future enhancements to this serialization system should not obsolete any existing archive files. It is only necessary to increment this version number when the newer system creates archives incompatible in format with the current one.

Should it ever occur that an older program attempts to read newer archives whose format has changed, this exception is thrown.

unsupported_class_version

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.

pointer_conflict

To understand what this exception means consider the following scenario

template<class Archive>
void T::save(Archive &ar) const
{
    const A * aptr = &a;
    ar << aptr;          // save an instance of object of class A through a pointer
    ...
    ar << a;             // save an instance of an object of class A
    assert(aptr == &a);  // this must be true
}

template<class Archive>
void T::load(Archive &ar)
{
    A * aptr;
    ar >> aptr;          // create and initialize a new instance of class A
    ...
    ar >> a;             // restore state of on object of class A
    assert(aptr == &a);  // this won't be true
}
An object is saved first through a pointer then directly. Upon loading back in the same sequence, we first create an new object and load in its data. Then we load the data into another existing object. Where we started with one object during save, we have two objects after restore. In a more realistic situation, it could be very difficult to find this error. Fortunately, these situations can be detected when the archive is created. When this occurs, this exception is thrown.

incompatible_native_format

The library currently supports char text, wide char text and native binary archive files. At the beginning of every archive, a signature is written indicating the type of archive. This exception is thrown when an attempt is made to read an archive written in a different format.

array_size_too_short

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.

input_stream_error
output_stream_error

An error has occurred during stream input or ouput. Aside from the common situations such as a corrupted or truncated input file, there are several less obvious ones that sometimes occur.

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 is destroyed before opening an input archive on that same stream. That is, rather than using something like:


std::stringstream ss;
std::vector<V> v;
boost::archive::text_oarchive oa(ss);
oa << v;
boost::archive::text_iarchive ia(ss);
ia >> v;
use

std::stringstream ss;
std::vector<V> v;
{
    boost::archive::text_oarchive oa(ss);
    oa << v;
}
{
    boost::archive::text_iarchive ia(ss);
    ia >> v;
}

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.

invalid_class_name

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.

unregistered_cast

In order to support casting between pointers of base and derived classes 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 Runtime Casting. This exception is thrown if an attempt is made to convert between two pointers whose relationship has not been registered,

multiple_code_instantiation

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.

xml_archive_parsing_error

The XML generated by the serialization process is intimately coupled to the C++ class structure, relationships between objects and the serialization specifications. If these become out of sync in any way, the XML may not map to the loading serialization and this exception might be thrown. This might occur for one of the following reasons:
  • 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 archive unreadable by the serialization library.
  • 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 properly deserialize previously created archives.

xml_archive_tag_mismatch

This exception will be thrown if the start or end tag of an XML element doesn't match the name specified for the object in the program.

xml_archive_tag_name_error

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).

© Copyright Robert Ramey 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)

================================================ FILE: doc/extended_type_info.html ================================================ Serialization - extended_type_info

C++ Boost

Serialization

extended_type_info


Motivation
Runtime Interface
Requirements
Models
Example

Motivation

The serialization library needs a system like type_info/typeid() to perform the following functions
  1. given a pointer to a type T discover the true type pointed to.
  2. given an "external" key - determine what type of object to create.

The problem with std::type_info

  • The main function we require - std::typeid() is not available in all environments. Support for this function depends upon runtime typing(RTTI) support from the compiler. This may be non-existent or not enabled for reasons such as a perceived inefficiency.
  • std::type_info 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.
  • 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.
  • 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.

Features

extended_type_info is an implementation of std::type_info functionality with the following features:
  • Builds a set of extended_type_info records - one for each type serialized.
  • 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"
  • permits the "mixing" of type info systems. For example, one class might use typeid() to find the external identifier of a class while another might not.
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.

Runtime Interface


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

Generally, there will be one and only one extended_type_info instance created for each type. However, this is enforced only at the executable module level. That is, if a program includes some shared libraries or DLLS, there may be more than one instance of this class corresponding to a particular type. For this reason the comparison functions below can't just compare the addresses of this instance but rather must be programmed to compare the actual information the instances contain.


extended_type_info(unsigned int type_info_key, const char *key);

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.

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 Global Unique IDentifier. 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.


void key_register();
void key_unregister();

This system maintains a global table which relates external strings to extended_type_info 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 extended_type_info to use for creating a new object.

These functions are called by constructors and destructors of classes which implement extended_type_info to add and remove entries from this table.


const char *get_key() const;

Retrieves the key for extended_type_info instance. If no key has been associated with the instance, then a NULL is returned.


bool operator<(const extended_type_info & rhs) const;
bool operator==(const extended_type_info & rhs) const;
bool operator!=(const extended_type_info & rhs) const;

These functions are used to compare extended_type_info objects. They impose a strict total ordering on all extended_type_info records.


virtual void * construct(unsigned int count = 0, ...) const;

Construct a new instance of the type to which this extended_type_info 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 GUID 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 plugins.


virtual void destroy(void const * const p) const;

Destroy an instance created by the above constructor.


static const extended_type_info * find(const char *key);

Given a character string key or GUID, return the address of a corresponding extended_type_info object.

Requirements for an Implementation

In order to be used by the serialization library, an implementation of extended_type_info, (referred to as ETI here), must be derived from extended_type_info and also implement the following:

template<class ETI>
const extended_type_info *
ETI::get_derived_extended_type_info(const T & t) const;

Return a pointer to the extended_type_info 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 extended_type_info implementation.

virtual bool ETI::is_less_than(const extended_type_info &rhs) const;

Compare this instance to another one using the same extended_type_info implementation.

virtual bool ETI::is_equal(const extended_type_info &rhs) const;

Compare this instance to another one using the same extended_type_info implementation. Return true if the types referred to are the same. Otherwise return false

const char ETI::get_key() const;

Retrieve the external key (aka GUID) for this class.

virtual void * construct(unsigned int count, ...) const;

Construct an instance of the corresponding type with the include argument list.

virtual void * destroy(void const * const ptr ) const;

Destroy an instance of this type. This calls the proper destructor and recovers allocated memory.

Models

The serialization library includes two distinct extended_type_info implementations.

extended_type_info_typeid

is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled by the compiler.

extended_type_info_no_rtti

is implemented in a way that doesn't rely on the existence RTTI. Instead, it requires that all polymorphic types be explicitly exported. In addition, if the export facility is to be used to serialize types through base class pointers, those types are required to implement a virtual function with the signature:
virtual const char * get_key();
which returns a unique string the most derived object this class. This function must be virtual in order to implement the functionality required by ETI::get_derived_extended_type_info as described above.

Example

The test program test_no_rtti implements this function in terms of the extended_type_info 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 extended_type_info.

Requirements for Each Type

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:
namespace boost {
namespace serialization {
template
struct extended_type_info_typeid<T>;
template
struct extended_type_info_typeid<const T>;
} // serialization
} // boost
For those using the serialization library, this step can be skipped as it is done automatically. The serialization library includes the macro:
BOOST_CLASS_TYPE_INFO(
    my_type, 
    extended_type_info_typeid<my_class>
)
which is used to specify which extended_type_info system is to be used for a given type.

extended_type_info includes a facility for constructing instances of types without knowing what the exact types are. This is done with the function virtual void * extended_type_info::construct(unsigned int count = 0, ...) const; . For example:

struct base {
...
};
struct derived : public base {
...
};
...
extended_type_info *eti = extended_type_info::find("my_class")
base * b = eti->construct(...);

The construct 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 here

© Copyright Robert Ramey 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)

================================================ FILE: doc/faq.html ================================================ Serialization - Tips and Tricks

C++ Boost

Serialization

Tips and Tricks


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 "TRAK" item which includes the text you want to add to this list.

© Copyright Robert Ramey 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)

================================================ FILE: doc/headers.html ================================================ Serialization - Code Structure

C++ Boost

Serialization

Code Structure


Files Included by User Programs
Archive Implementations
Serialization Declarations
Serialization Implementations
Files Which Implement the Library
Archive Development
Archive Internals
Archive Library Code Modules
Dataflow Iterators
This library includes a large number of files. They are organized and classified according to the purposes listed in the above index.

namespace of classes and templates is synchronized with the directory in which the file is found. For example, the class declaration


boost::archive::text_oarchive
is included with the following declaration

#include <boost/archive/text_oarchive.hpp>

Files Included by User Programs

Using this library entails including headers listed in this section. It should not be necessary to explicitly include any other header files.

Archive Implementations

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.
boost/archive/archive_exception.hpp
Exceptions which might be invoked by the library.
boost/archive/binary_iarchive.hpp
native binary input archive used for loading.
boost/archive/binary_oarchive.hpp
native binary output archive used for saving.
boost/archive/text_iarchive.hpp
text input archive used for loading.
boost/archive/text_oarchive.hpp
text output archive used for saving.
boost/archive/text_wiarchive.hpp
wide character text input archive used for loading.
boost/archive/text_woarchive.hpp
wide character text input archive used for saving.
boost/archive/xml_iarchive.hpp
xml input archive used for loading.
boost/archive/xml_oarchive.hpp
xml output archive used for saving.
boost/archive/xml_wiarchive.hpp
wide character xml input archive used for loading.
boost/archive/xml_woarchive.hpp
wide character xml output archive used for saving.

Serialization Declarations

To specify how a type is serialized, one codes templates for serialization functions. In the simplest cases, this does not require the inclusion of any header files for this purpose. In most cases one or more of the following header files will have to be included in order to complete or refine the description of the serializaition implementation for a given class.
boost/serialization/base_object.hpp
For serialization of base classes.
boost/serialization/nvp.hpp
To associate a name tag with a serializable object. This is necessary to properly render an xml archive which includes the object name.
boost/serialization/split_free.hpp
To divide implementation of non-intrusive serialization into separate save and load functions.
boost/serialization/split_member.hpp
To divide implementation of intrusive serialization into separate save and load functions.
boost/serialization/export.hpp
For serialization of pointers to derived classes via key export.
boost/serialization/assume_abstract.hpp
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.
This group will be required less frequently. The are used to override aspects of the default implementation of the serialization process for specified types.
boost/serialization/version.hpp
To override the default version index (0) assigned to a class.
boost/serialization/level.hpp
To override the default implementation level trait for a type.
boost/serialization/tracking.hpp
To override the default tracking trait for a type.
boost/serialization/type_info_implementation.hpp
By default, the library uses RTTI, to identify types at runtime. In some cases, E.G. such as a platform which doesn't implement RTTI, this header can be included to permit the override of the default runtime type identification system.

Serialization Implementations

This group of headers includes templates which implement serialization for Standard 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.

By convention these header files are named: boost/serialization/xxx.hpp where xxx is the name of the header file which contains the type to be serialized. For example, the declaration


#include <boost/serialization/list.hpp>
includes the code to implement serialization of the STL std::list type. While

#include <boost/serialization/shared_ptr.hpp>
includes code to implement serialization of the BOOST boost::shared_ptr type. Note that including the serialization header for a type automatically includes the appropriate header of the type to be serialized. As of this writing, the library includes templates of all STL library templates as well as templates for boost::optional, boost::shared_ptr, and boost::scoped_ptr. Presumably, this list will expand with the passage of time.

Files Which Implement the Library

Archive Development

These header files contain declarations for basic types used to create concrete archive types that are made available to users above. Users wishing to make their own type of archive may want to examine these headers to see how the archives included with the libary have been constructed.
boost/archive/basic_archive.hpp
This file includes declarations for certain types that have to be accounted for in all archive implementations. The serialization system relies on certain special types such as class_id_type 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 text files, or with special code as they are in xml archives.
boost/archive/basic_text_oprimitive.hpp
boost/archive/basic_text_iprimitive.hpp
Implementation of serialization of primitive types in terms of character or wide character text streams. This is used in the implementation of text and xml archives. Presumably this would be useful for implementations of other variations of text archives such as user friendly text or windows ini files.
boost/archive/basic_binary_oprimitive.hpp
boost/archive/basic_binary_iprimitive.hpp
Implementation of serialization of primitive types in terms of character or wide character binary streams.
boost/archive/basic_binary_oarchive.hpp
boost/archive/basic_binary_iarchive.hpp
Implementation of serialization of all types in terms of character or wide character binary streams. This is factored out separately from the implementation of binary primitives above. This may facilitate the creation of other types of binary archives in the future. It also preserves analogy and symmetry with the rest of the library which aids in understanding.
boost/archive/basic_text_oarchive.hpp
boost/archive/basic_text_iarchive.hpp
boost/archive/basic_xml_oarchive.hpp
boost/archive/basic_xml_iarchive.hpp
Implementation of serialization of all types in terms of character or wide character text streams. These classes specify archive type specific behavior on a type by type basis. For example, basic_xml_oarchive.hpp includes code to guarantee that any object not attached to a name will trap during compile time. On the other hand, basic_text_oarchive.hpp contains code to strip out and ignore any names attached to objects.

boost/archive/detail/common_iarchive.hpp
boost/archive/detail/common_oarchive.hpp
All archive implementations are derived from these header files. They provide the interface to the internal implementation details of the library.

Archive Internals

The interface (see
Archive Concepts) and implementation are factored out into separate classes to minimize code duplication. These files are found in the directory boost/archive/detail. These are included as necessary by the archive class implementations listed above. This has the unfortunate side effect of making the implementation less transparent. Users should never find it necessary to change these files.

The following discussion is based on the class diagram.

boost/archive/detail/interface_iarchive.hpp
boost/archive/detail/interface_iarchive.hpp
Here are the declarations and definitions for the archive_concept. This class redirects calls to the archive interface to a function named save_override in the most derived archive class.
save_override is declared and implemented in each class in the archive hierarchy.

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
Note the usage of Partial Function Template Ordering to permit the correct save implementation to be selected.

Archive Library Code Modules

Parts of the library are implemented as library code. All of this code is to be found in
libs/serialization/src. in the form of *.cpp. The directory boost/archive/impl contains *.ipp files which implement templates. These templates are instantiated only by archive implementation so are generally not included in user code modules.

The trade offs related to library implementation via pre-compiled code and templated headers are well known. This library uses both. It uses templated headers to generate code to serialize user and primitive types and it uses pre-compiled 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.

  • Serialization of user and primitive types runs at top speed. This is a noticeable difference with a previous version of the library which did not use templates for archives.
  • Library implementation code that never changes need only be compiled once rather than each time a user's program is recompiled. This can save much development time.
  • Headers which solely related to implementation need only be included in the library code modules. This prevents a user program from accidentally depending on an implementation feature of the serialization library.
  • In building the library I came to the conclusions that there can arise situations regarding static code/data instantiation that could not be satisfactorily addressed without a code module. Unfortunately, I've forgotten the circumstances which led me to this conclusion.
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 program which uses xml serialization.

Dataflow Iterators

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 others.

This is a ripe topic in itself. It's touched upon by the boost iterator libraries, View Template Library, and others.

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 local to the serialization library: boost/archive/iterators. These iterators are described in Dataflow Iterators.


© Copyright Robert Ramey 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)

================================================ FILE: doc/history.html ================================================ Serialization - History

C++ Boost

Serialization

History


  1. 26 Feb 2002 initial version uploaded to boost
  2. 27 Feb 2002
    • divide interface from implementation for class serialization to permit compilation on gcc
    • improved template instantantation for type templates
  3. 18 Mar 2002 - draft #2 uploaded to boost
    • elminated locale effects on archives
    • added signature and library version to archive header
    • improved detection of errors when objects are serialized as pointers and subsequently serialized as objects
    • permit non-portable binary archives
    • implement workaround for systems such as MSVC 6.0 that don't support partial ordering
  4. 16 May 2002 - draft #3 uploaded to boost
    • Ability to specify serialization of other templates in a non-intrusive way.
    • Included an example which uses boost::shared_ptr.
    • improved documentation
    • More test cases
    • More testing and documentation of obscure situtations
    • Better code organization for transparency
    • Wide character support implemented and tested with unicode.
  5. 28 Jun 2002 - #4 library submission
    • minor corrections
    • replaced erroneous shared_ptr example with std::auto_ptr example
    • prevention of memory leaks when exceptions are invoked
  6. 30 Aug 2002 - #5 library submission
    • minor corrections
    • Additions to documentation to explicitly address issues of exception safety.
    • More test cases/demos to illustrate handling of the above issues.
    • Additions to documentation to include rationale for not depending on type_id
    • Implementation of serialization of boost::shared_ptr. This is included as a demo as it depends upon a minor alteration of boost::shared_count.
  7. 08 Nov 2002 - #6 library submission
    • minor corrections
    • corrected error which manifested itself when serializing polymorphic pointers to obects derived from multiple base classes
    • minor adjustments to support plug-ins via virtual save/load/version functions
    • test cases to support the above
  8. 08 September 2003- version # 12 library submission
    • attempts to address all issues raised during the November 2002 review
  9. November 2003 - draft #13 uploaded
    • corrections, enhancements, change in api for pointer overload
  10. 28 December 2003
    • implementation of save/loadbinary
    • enhancements included archives to permit derivation
  11. 1 March 2004 - draft # 17 upload
    • portability to intel 8.0, and VC 6.0
    • Alter archive implementation to permit derivation. Make tests.
    • Implement serialize/save/load binary for text and XML archives using base64 character encoding.
    • Added documentation and test for serialization of large binary objects.
    • Added "Derivation from an Existing Archive Class" to documentation along with example program.
    • Added PIMPL example
    • certain special situations are now detected and addressed at compile time to generate all in-line code. For example, for types serialized without class information, and without memory tracking, the serialization process can be reduced to a minimal amount of inline code.
    • All tests have been run in release as well as debug mode
    • Many improvements in code and documentation to improve accuracy and completeness.
  12. 11 April 2004 - draft # 18 upload
    • Reorganization of header and template files.
    • Enhanced documentation to help explain implementation issues.
    • Adjustments to improve support for less conformant compilers.
    • A few bug fixes.
  13. 31 May 2004 - draft # 20 upload
    • Polymorphic archives.
    • A few bug fixes.
  14. 1 November 2004 - final changes for first boost official release 1.32 .
    • Adjustments to address package compatible with two-phase lookup.
    • Many small adjustments to accommodate quirks of various compilers.
    • A few bug fixes.

© Copyright Robert Ramey 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)

================================================ FILE: doc/implementation.html ================================================ Serialization - Implementation Notes

C++ Boost

Serialization

Implementation Notes


Character Encoding
Specific Compiler/Library Issues
44.X
Intel 8.0
Visual C++ 8.0
Visual C++ 7.1
Comeau 4.3.3
Code Warrior 9.x
Code Warrior 8.3
TRU64
Dinkumware Library
STLPort 4.5.3

Character Encoding

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 a rather long consideration of all these factors has been to set default encoding according to the following rules.
  • All text archives (i.e. text_?archive) will produce text output in the current stream locale. Generally this will produce no changes in string data.
  • To produce binary output with Microsoft compilers, the stream will have to be opened with mode ios::binary. Failure to do so will result in 0x0d characters (carriage-return) characters being removed from the input stream if they are followed by a 0x0a character (line-feed). This could corrupt the input and make the file unreadable. On UNIX systems the ios::binary is not required and is ignored if used.
  • character XML archives (i.e. xml_oarchive) will produce XML output with characters encoded according to the current stream locale.
  • wide character XML archives (i.e. xml_woarchive) will produce files encoded in UTF-8.
This character encoding is implemented by changing the locale 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 by specifying boost::archive::no_codecvt when the archive is opened. In this case, the stream locale will not be changed by the serialization library.

Note that the code conversion included for wide character text and XML archives could alter std::string data stored in archives. Suppose a normal (multi-byte) character string is written to a wide character stream. Our system uses the current locale to translate it to a wide character string before writing it out. Upon reading, it is translated back to a (multi-byte)string. If the locale on the platform that reads the archive is different than the locale on the platform that wrote the stream, the actual string data may be altered by the serialization process. To avoid this, either avoid usage of locale dependent multi-byte strings or be sure that the locale is set correctly before reading the archive.

To produce wide character text output (i.e. 16 bit characters on Win32 systems), do the following.

  • Open a wide character stream.
  • Alter the stream locale to use boost::archive::codecvt_null<OStream::char_type>
  • Create the archive with the flag no_codecvt.
Naturally, the input process has to be symmetrical.

Specific Compiler/Library Issues

GCC 4.X

  • 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.
  • 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:
    
        -Wno-non-virtual-dtor
        -Wno-ctor-dtor-privacy
        

Intel C++ 8.0

No known issues. All tests compile and run in debug and release modes.

Visual C++ 8.0

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:

    /wd4996
    

Visual C++ 7.1

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 demo_portable_iarchive.cpp would have to be reformulated as a library or dll similar to the pre-defined archives in order to function.

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.

This compiler can treat wchar_t as either a short integer or an intrinsic type. If /Zc:wchar_t is specified on the compile command line, wchar_t 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 - BUT - both the library AND the application must be compiled with the same switch settings. Note that BJAM includes this switch by default. So if want to use the libraries that BJAM builds, you should include this switch when you compile your own applications.

Using the Visual C++ IDE
The library includes a VC++ 7.1 "Solution" - BoostSerializationLibrary along with a set of project files - one for each demo and test. Consider the following if you decide to use these configurations.
  • The projects assume that the tests have been built with bjam using the default locations. This will result in a bin 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.
  • There are project configurations for all the combinations of build variants that boost supports. That is for release, debug, static, static multi-threading, etc..
  • If you want to use/debug the DLL versions of libraries and corresponding tests, alter the project file to define BOOST_ALL_DYN_LINK=1. Note that for the executables to run, the PATH environmental variable will have to include the directories that contain the DLL versions of the boost libraries.
  • 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.
  • 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.
  • To test that boost libraries are built correctly, one can build and test them the way we do. This entails:
    1. downloading a copy of bjam.exe
    2. building process_jam_log
    3. building compiler_status
    4. invoking runtest.bat
    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.

Comeau 4.3.3

  • This compiler fails to make a DLL with export under windows.
  • The associated library - libcomo fails when using a codecvt facet. This generates a failure with all wide character archives.
  • the test_set fails by going into an infinite memory leak.

Code Warrior 9.x

  • Some tests and demos fail - still under investigation

Code Warrior 8.3

all the above issues for Code Warrior 9.x plus:
  • This compiler only supports templated streams with the static library version.
  • The above inhibits the build of DLL versions of the library.
  • Some demos fail - still under investigation

TRU64

All tests and demos pass except for test_variant. Boost Variant doesn't function wih this compiler

Dinkumware Library

Several compilers, including Visual C++ 6.0, use an older dinkumware library. These platforms have several issues:
  • The dinkumware library shipped with this compiler does not change the locale facet of an i/o stream unless the imbue function is called before the stream is opened. In order to use this library with this environment to generate UTF-8 files, one cannot depend on the "automatic" setting of locale that archives implement. The stream locale must be set explicitly on the stream before an archive is opened on it. The archive should be opened with the no_codecvt flag. Note this problem will occur on all compilers shipped with this library.
  • Other issues have been worked around in the file. dinkumware.hpp

STLPort 4.5.3

  • when built to use the dynamic linking versions of the C++ runtime code (dynamic) all tests fail to link. This is due to a missing symbol in the stlport library related to custom codecvt facets.
  • 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.

Revised 1 November, 2004

© Copyright Robert Ramey 2002-2015. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

================================================ FILE: doc/index.html ================================================ Serialization <a href="overview.html"</a> ================================================ FILE: doc/new_case_studies.html ================================================  Serialization - Proposed Case Studies

C++ Boost

Serialization

Proposed Case Studies


Serializing a Function Object
Archive Adaptors
Archive Helpers
These are not part of the library itself, but rather techniques on how to use the library to address specific situations.

Serializing a Function Object

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.

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.

This case study would show how to do this.

Archive Adaptors

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.

This case study would show how to make a useful archive adaptor.

Archive Helpers

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.

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.


Revised 1 November, 2008

© Copyright Robert Ramey 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)

================================================ FILE: doc/overview.html ================================================ Serialization - Overview

C++ Boost

Serialization

Overview


Requirements
Other Implementations

Here, we use the term "serialization" 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 parameter passing or other facility. In this system we use the term "archive" to refer to a specific rendering of this stream of bytes. This could be a file of binary data, text data, XML, or some other created by the user of this library.

Our goals for such a system are:

  1. Code portability - depend only on ANSI C++ facilities.
  2. Code economy - exploit features of C++ such as RTTI, templates, and multiple inheritance, etc. where appropriate to make code shorter and simpler to use.
  3. Independent versioning for each class definition. That is, when a class definition changed, older files can still be imported to the new version of the class.
  4. Deep pointer save and restore. That is, save and restore of pointers saves and restores the data pointed to.
  5. Proper restoration of pointers to shared data.
  6. Serialization of STL containers and other commonly used templates.
  7. Data Portability - Streams of bytes created on one platform should be readable on any other.
  8. Orthogonal specification of class serialization and archive format. That is, any file format should be able to store serialization of any arbitrary set of C++ data structures without having to alter the serialization of any class.
  9. Non-intrusive. Permit serialization to be applied to unaltered classes. That is, don't require that classes to be serialized be derived from a specific base class or implement specified member functions. This is necessary to easily permit serialization to be applied to classes from class libraries that we cannot or don't want to have to alter.
  10. The archive interface must be simple enough to easily permit creation of a new type of archive.
  11. The archive interface must be rich enough to permit the creation of an archive that presents serialized data as XML in a useful manner.

Other implementations

Before getting started I searched around for current implementations. I found several.
  • MFC This is the one that I am very familiar with. I have used it for several years and have found it very useful. However it fails requirements 1, 2, 3, 6, 7, and 9. In spite of all the requirements not fulfilled, this is the most useful implementation I've found. It turns out that class versioning - partially implemented in MFC - really is indispensable for my applications. Inevitably, version 1.x of a shipping program needs to store more information in files than was originally provided for. MFC is the only one of these implementations that supports this - though only for the most derived class. Still it's better than nothing and does the job. MFC doesn't implement serialization of STL collections. Though it does so for MFC collections.
  • CommonC++ libraries [1] As far as I can tell, this closely follows the MFC implementation but does address a few of the issues. It is portable and creates portable archives but skips versioning. It does support proper and complete restoration of pointers and STL collections. It does address compression though not in the way that I would prefer. The package would also benefit from having better documentation. So it fails to address 2, 3, 7, 8, and 9.
  • Eternity [2] This is a bare bones package. It seems well coded but it really needs documentation and examples. It's not obvious how to use it without time consuming study of the source code. Recent versions do support files in XML format. This Fails 3, 6, 7?, 8, and 9.
  • Holub's implementation [3] This is the article that first got me thinking about my own requirements for a serialization implementation. Interesting and worth the read if you can overlook the arrogant tone of the prose. This implementation fails 2, 3, 4, 5, and 6.
  • s11n [13] This library has similar goals to this one. Some aspects of the implemenation are also similar. As of this writing, it would seem that:
    • Portability(1) is guaranteed only for recent versions of GCC.
    • Versioning(3) of class definitions is not explicitly supported by the library.
    • it doesn't seem to automatically account for shared pointers(5). I concluded this from the documentation as well as the statement that serialization of graph like structures is not supported.
    Its has lots of differences - and lots in common with this implementation.

Revised 1 November, 2004

© Copyright Robert Ramey 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)

================================================ FILE: doc/performance_status.html ================================================ Boost Library Status Automatic Test

Library Status: serialization

Run Date: 02:42:48 UTC, Tuesday 10 June 2008

Test Name gcc-3.4.4
profile
peformance_array_binary_archivePass Profile
peformance_array_text_archivePass Profile
peformance_array_text_warchiveMissing
peformance_array_xml_archivePass Profile
peformance_array_xml_warchiveMissing
performance_iteratorsPass Profile
performance_iterators_base64Pass Profile
================================================ FILE: doc/pimpl.html ================================================ Serialization - PIMPL

C++ Boost

Serialization

PIMPL


PIMPL is a C++ programming idiom described by Herb Sutter [10] which stands for "Private Implementation". It is also referred to as the "Handle Body Idiom". Included in this library is a program called demo_pimpl.cpp which illustrates how this is used. The file demo_pimpl_A.hpp 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.

// class whose declaration is hidden by a pointer
struct B;

struct A {
    // class a contains a pointer to a "hidden" declaration
    B *pimpl;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int file_version);
    A();
};
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: demo_pimpl_A.cpp by:

#include "demo_pimpl_A.hpp"

// "hidden" definition of class B
struct B {
    int b;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int file_version){
        ar & b;
    }
};

A::A() :
    pimpl(new B)
{}

A::~A(){
    delete pimpl;
}

// now we can define the serialization for class A
template<class Archive>
void A::serialize(Archive & ar, const unsigned int file_version){
    ar & pimpl;
}
As described in [10] this brings the following advantages:
  • type "B" can be used without using its header.
  • implementation of B can be changed without generating a cascade of recompilations.
So, we compile the modules and everything is fine. However when we link, we get an error. Two symbols are undefined:

void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
The problem is that when compiling the above code, there is no instantiation of the serialize template. There can't be as it's not "known" what types of archives the serialization is going to be used with. So these functions are "missing" when an attempt to link is made. The solution is to explicitly instantiate serialization code for those archives which are going to be used. In this example, including the the following code in any *.cpp file does just that:

#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
);
template void A::serialize<boost::archive::text_oarchive>(
    boost::archive::text_oarchive & ar, 
    const unsigned int file_version
);
The program should now link as well as compile.

The downside of this is that one has to know which archives are going to be used with hidden serializations. This is an effect of using template driven code. One can invoke explicitly instantiation for all known templates and presume that the linker will exclude unreferenced code. This should work but is platform dependent.


© Copyright Robert Ramey 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)

================================================ FILE: doc/private_base.html ================================================ Serialization - Private Base Classes

C++ Boost

Serialization

Private Base Classes


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.

/////////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;
}
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 BOOST_SERIALIZATION_BASE_OBJECT_NVP is code which links derived and base class definitions in tables used to serialize derived classes through pointers to a polymorphic base class. This code requires the ability to invoke static_cast<Base &>(Derived &) 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.

In order for this code compiler the following alteration must be made:


    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)
        );
    }
With this change the program will now compile.

If we made one of the functions of Base virtual 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.


© Copyright Robert Ramey 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)

================================================ FILE: doc/profile1.txt ================================================ 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 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 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 `' 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 int&, unsigned long const&) [7] __divdi3 [6] std::ostream::operator<<(void const*) [5] _pei386_runtime_relocator ================================================ FILE: doc/profile2.txt ================================================ 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::fill() 0.00 0.01 0.00 36 0.00 0.00 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator > >, 8, 6, char>::fill() 0.00 0.01 0.00 30 0.00 0.00 std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, char const&) 0.00 0.01 0.00 11 0.00 0.00 boost::archive::iterators::xml_escape::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::drain() 0.00 0.01 0.00 5 0.00 0.00 boost::archive::iterators::xml_unescape::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*, unsigned int) 0.00 0.01 0.00 1 0.00 0.00 void test_xml_unescape(char const*, char const*, unsigned int) 0.00 0.01 0.00 1 0.00 0.00 void test_stream_iterators(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*, std::allocator const&, std::forward_iterator_tag) 0.00 0.01 0.00 1 0.00 0.00 std::basic_string, std::allocator >::basic_string(char*, char*, std::allocator 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 [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::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 > >, 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 >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, char const&) [7] ----------------------------------------------- 0.00 0.00 11/11 void test_xml_escape(char const*, char const*, unsigned int) [13] [8] 0.0 0.00 0.00 11 boost::archive::iterators::xml_escape::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::fill() [5] 0.00 0.00 36/36 boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator > >, 8, 6, char>::fill() [6] 0.00 0.00 30/30 std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, char const&) [7] ----------------------------------------------- 0.00 0.00 9/9 void test_xml_unescape(char const*, char const*, unsigned int) [14] [10] 0.0 0.00 0.00 9 boost::archive::iterators::xml_unescape::drain() [10] 0.00 0.00 5/5 boost::archive::iterators::xml_unescape::drain_residue(char const*) [11] ----------------------------------------------- 0.00 0.00 5/5 boost::archive::iterators::xml_unescape::drain() [10] [11] 0.0 0.00 0.00 5 boost::archive::iterators::xml_unescape::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*, unsigned int) [13] 0.00 0.00 11/11 boost::archive::iterators::xml_escape::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*, unsigned int) [14] 0.00 0.00 9/9 boost::archive::iterators::xml_unescape::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 const*, unsigned int) [15] 0.00 0.00 1/1 std::basic_string, std::allocator >::basic_string(char*, char*, std::allocator 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*, unsigned int) [13] 0.00 0.00 1/1 void test_xml_unescape(char const*, char const*, unsigned int) [14] 0.00 0.00 1/1 void test_stream_iterators(char const*, unsigned int) [15] ----------------------------------------------- 0.00 0.00 1/1 std::basic_string, std::allocator >::basic_string(char*, char*, std::allocator const&) [18] [17] 0.0 0.00 0.00 1 char* std::string::_S_construct(char*, char*, std::allocator const&, std::forward_iterator_tag) [17] ----------------------------------------------- 0.00 0.00 1/1 void test_stream_iterators(char const*, unsigned int) [15] [18] 0.0 0.00 0.00 1 std::basic_string, std::allocator >::basic_string(char*, char*, std::allocator const&) [18] 0.00 0.00 1/1 char* std::string::_S_construct(char*, char*, std::allocator 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 `' 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*, unsigned int) [16] test_main(int, char**) [5] boost::archive::iterators::transform_width::fill() [14] void test_xml_unescape(char const*, char const*, unsigned int) [8] boost::archive::iterators::xml_escape::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::drain_residue(char const*) [17] char* std::string::_S_construct(char*, char*, std::allocator const&, std::forward_iterator_tag) [15] void test_stream_iterators(char const*, unsigned int) [10] boost::archive::iterators::xml_unescape::drain() [18] std::basic_string, std::allocator >::basic_string(char*, char*, std::allocator const&) [12] __static_initialization_and_destruction_0(int, int) (performance_iterators.cpp) [6] boost::archive::iterators::transform_width<__gnu_cxx::__normal_iterator > >, 8, 6, char>::fill() [7] std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, char const&) ================================================ FILE: doc/profile3.txt ================================================ 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::fill() 0.00 0.00 0.00 150 0.00 0.00 boost::archive::iterators::transform_width >, 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() 0.00 0.00 0.00 1 0.00 0.00 std::_List_base >::_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() [7] [4] 0.0 0.00 0.00 200 boost::archive::iterators::transform_width::fill() [4] ----------------------------------------------- 0.00 0.00 150/150 void test_base64() [7] [5] 0.0 0.00 0.00 150 boost::archive::iterators::transform_width >, 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() [7] 0.00 0.00 200/200 boost::archive::iterators::transform_width::fill() [4] 0.00 0.00 150/150 boost::archive::iterators::transform_width >, char>, 8, 6, char>::fill() [5] 0.00 0.00 1/1 std::_List_base >::_M_clear() [8] ----------------------------------------------- 0.00 0.00 1/1 void test_base64() [7] [8] 0.0 0.00 0.00 1 std::_List_base >::_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 `' 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() [5] boost::archive::iterators::transform_width >, char>, 8, 6, char>::fill() [8] std::_List_base >::_M_clear() [6] __static_initialization_and_destruction_0(int, int) (performance_iterators_base64.cpp) [4] boost::archive::iterators::transform_width::fill() ================================================ FILE: doc/rationale.html ================================================ Serialization - Rationale

C++ Boost

Serialization

Rationale


The term "serialization" is preferred to "persistence"
Archives are not streams
Strings are treated specially in text archives
typeid information is not included in archives

The term "serialization" is preferred to "persistence"

I found that persistence is often used to refer to something quite different. Examples are storage of class instances (objects) in database schema [4] This library will be useful in other contexts besides implementing persistence. The most obvious case is that of marshalling data for transmission to another system.

Archives are not streams

Archive classes are NOT derived from streams even though they have similar syntax rules.

  • Archive classes are not kinds of streams though they are implemented in terms of streams. This distinction is addressed in [5] item number 41.
  • We don't want users to insert/extract data directly into/from  the stream .  This could create a corrupted archive. Were archives derived from streams, it would possible to accidentally do this. So archive classes only define operations which are safe and necessary.
  • The usage of streams to implement the archive classes that are included in the library is merely convenient - not necessary. Library users may well want to define their own archive format which doesn't use streams at all.

Archive Members are Templates Rather than Virtual Functions

The previous version of this library defined virtual functions for all primitive types. These were overridden by each archive class. There were two issues related to this:
  • Some disliked virtual functions because of the added execution time overhead.
  • This caused implementation difficulties since the set of primitive data types varies between platforms. Attempting to define the correct set of virtual functions, (think long long, __int64, etc.) resulted in messy and fragile code. Replacing this with templates and letting the compiler generate the code for the primitive types actually used, resolved this problem. Of course, the ripple effects of this design change were significant, but in the end led to smaller, faster, more maintainable code.

    std::strings are treated specially in text files

    Treating strings as STL vectors would result in minimal code size. This was not done because:

    • In text archives it is convenient to be able to view strings. Our text implementation stores single characters as integers. Storing strings as a vector of characters would waste space and render the archives inconvenient for debugging.
    • Stream implementations have special functions for std::string and std::wstring. Presumably they optimize appropriately.
    • Other specializations of std::basic_string are in fact handled as vectors of the element type.

    typeid information is not included in archives

    I originally thought that I had to save the name of the class specified by std::type_of::name() in the archive. This created difficulties as std::type_of::name() is not portable and not guaranteed to return the class name. This makes it almost useless for implementing archive portability. This topic is explained in much more detail in [7] page 206. It turned out that it was not necessary. As long as objects are loaded in the exact sequence as they were saved, the type is available when loading. The only exception to this is the case of polymorphic pointers never before loaded/saved. This is addressed with the register_type() and/or export facilities described in the reference. In effect, export generates a portable equivalent to typeid information.


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/reference.html ================================================  Serialization - Serialization of Classes

    C++ Boost

    Serialization

    Serializable Concept


    Archive Concepts
    Serializable Concept
    Special Considerations
    Archive Class Reference
    Implementation Notes

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/release.html ================================================ Serialization - Release Notes

    C++ Boost

    Serialization

    Release Notes


    Differences from version 1.58
    Differences from version 1.48
    Differences from version 1.45
    Differences from version 1.43
    Differences from version 1.42
    Differences from version 1.41
    Differences from version 1.40
    Differences from version 1.39
    Differences from version 1.37
    Differences from version 1.35
    Differences from version 1.34
    Differences from version 1.33
    Differences from version 1.32
    Pending Issues
    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.

    Differences from Boost 1.58

    • Eliminated support for Borland compilers and Microsoft compilers prior to version 7.1.
    • Eliminated support for compilers which do not support Partial Function Template Ordering (pfto).
    • 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.

    Differences from Boost 1.48

    • Added support for C++11 types such as std::shared_ptr, std::array, and others.
    • Implemented the concept of a "Helper" which can be used to implement serialization of types which are otherwise not serializable."
    • Made library compatible with C++11, Compatibility with C++03 has been maintained.

    Differences from Boost 1.45

    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.

    Differences from Boost 1.43

    • fixed bug in the serialization of virtual base classes. Due to heroic efforts by Takatoshi Kondo.
    • 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.

      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

          fix_six <file name>
          
      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.

    Differences from Boost 1.42

    • fixed failure of shared_ptr serialization when serializing pointers created from enable_shared_from_this.
    • 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.
    • 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.
    • 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.
    • Some memory leaks associated with void_cast have been fixed.

    Differences from Boost 1.41

    • adjustments have been made to minimize compile time warnings.
    • 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.
    • Some memory leaks associated with void_cast have been fixed.

    Differences from Boost 1.40

    This library has been tested against Boost version 1.39 and 1.40.

    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.

    Old Code:
    ...
    #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> ;
    
    should be replaced with this new code:
    #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> ;
    

    Differences from Boost 1.39

    • It is now possible to serialize an object through a pointer to a class which implements its own new/delete operators. This functionaly is not available on some compilers.
    • serialization of polymorphic objects has been sped up considerably.
    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 Pending Issues.

    Differences from Boost 1.37

    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 Pending Issues.

    Differences from Boost 1.36

    There are no new features in this version. As of this writing, all bug reports filed as TRAK tickets have been addressed.

    Differences from Boost 1.35

    • 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.
    • 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.
    • 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.
    • All bug reports filed as TRAK tickets have been addressed.
    • 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.

    Differences from Boost 1.34

    • Enhanced support for fast serialization for native binary archives. By Mattias Troyer.
    • Improved implementation of "export" functionality. Removes header ordering requirement and eliminates the maintenance of a pre-determined list of "known archives" By David Abrahams.
    • Improved support for STLPort.

    Differences from Boost 1.33

    • Native Binary archives use the std::streambuf interface. This should result in noticeably faster execution in many cases.

    Differences from Boost 1.32

    • Dynamic Linking Library (DLLs and shared libraries) for platforms which support them. See Automatic Linking on Windows.
    • Implementation of auto-link for compilers which can support this.
    • Better support for Argument Dependent Lookup and two-phase lookup. This results in simpler rules regarding the placing of serialization specializations namespaces.
    • Enhanced documentation to help explain usage of the above.
    • Adjustments to improve support for less conformant compilers.
    • Improved const 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 here.
    • A new implementation of serialization for shared_ptr<T>. This is compatible with public interface of shared_ptr<T> so it should be more robust and not have to change in the future. The implementation optionally includes code to load shared_ptr<T> stored in archives created with boost 1.32. This code is stored in 'he header: boost/serialization/shared_ptr_132.hpp. If your application needs to load archives created with boost 1.32 libraries, include the above header before each inclusion of boost/serialization/shared_ptr.hpp.
    • More compilers tested and supported.
    • Miscellaneous bug fixes.

    Pending issues

    • Rvalues cannot be serialized. It would be possible to implement this for untracked types, but this has not been done.
    • Pointers to pointers cannot currently be serialized
    • It's possible that std::string and std::wstring 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.
    • A subtle error in the implementation of serializaton of std::map is fixed in this version. Unfortunately, the fix breaks serialization of std::map for those compilers which do not support partial template specialization. Also, types which contain pointers or tracked types might not work correctly.
    • Serialization of virtual base classes relies upon RTTI. It will fail when used on systems which don't have RTTI enabled.

    Aside from the above, there are a number of issues related to specific platforms. These are listed in Specific Compiler/Library Issues.


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/serialization.html ================================================ Serialization - Serialization of Classes

    C++ Boost

    Serialization

    Serializable Concept


    Primitive Types
    Class Types
    Member Function
    Free Function
    Namespaces for Free Function Overrides
    Class Members
    Base Classes
    const Members
    Templates
    Versioning
    Splitting serialize into save/load
    Member Functions
    Free Functions
    Pointers
    Non-Default Constructors
    Pointers to Objects of Derived Classes
    Registration
    Export
    Instantiation
    Selective Tracking
    Runtime Casting
    References
    Arrays
    Class Serialization Traits
    Serialization Wrappers
    Models - Serialization Implementations Included in the Library
    A type T is Serializable if and only if one of the following is true:
    • it is a primitive type.
      By primitive type we mean a C++ built-in type and ONLY a C++ built-in type. Arithmetic (including characters), bool, enum are primitive types. Below in serialization traits, we define a "primitive" implementation level in a different way for a different purpose. This can be a source of confusion.
    • It is a class type and one of the following has been declared according to the prototypes detailed below:
      • a class member function serialize
      • a global function serialize
    • it is a pointer to a Serializable type.
    • it is a reference to a Serializable type.
    • it is a native C++ Array of Serializable type.

    Primitive Types

    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.

    Class Types

    For class/struct types, the template operators &, <<, and >> will generate code that invokes the programmer's serialization code for the particular data type. There is no default. An attempt to serialize a class/struct for which no serialization has been explicitly specified will result in a compile time error. The serialization of a class can be specified via either a class member function or a free function which takes a reference to an instance of the class as an argument.

    Member Function

    The serialization library invokes the following code to save or load a class instance to/from and archive.
    
    template<class Archive, class T>
    inline void serialize(
        Archive & ar, 
        T & t, 
        const unsigned int file_version
    ){
        // invoke member function for class T
        t.serialize(ar, file_version);
    }
    
    That is, the default definition of template serialize presumes the existence of a class member function template of the following signature:
    
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version){
        ...
    }
    
    If such a member function is not declared, a compile time error will occur. In order that the member function generated by this template can be called to append the data to an archive, it either must be public or the class must be made accessible to the serialization library by including:
    
    friend class boost::serialization::access;
    
    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 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.

    It may not be immediately obvious how this one template serves for both saving data to an archive as well as loading data from the archive. The key is that the & operator is defined as << for output archives and as >> input archives. The "polymorphic" behavior of the & permits the same template to be used for both save and load operations. This is very convenient in that it saves a lot of typing and guarantees that the saving and loading of class data members are always in sync. This is the key to the whole serialization system.

    Free Function

    Of course we're not restricted to using the default implementation described above. We can override the default one with our own. Doing this will permit us to implement serialization of a class without altering the class definition itself. We call this non-intrusive serialization. Suppose our class is named my_class, the override would be specified as:
    
    // namespace selection
    
    template<class Archive>
    inline void serialize(
        Archive & ar, 
        my_class & t, 
        const unsigned int file_version
    ){
        ...
    }
    
    Note that we have called this override "non-intrusive". This is slightly inaccurate. It does not require that the class have special functions, that it be derived from some common base class or any other fundamental design changes. However, it will require access to the class members that are to be saved and loaded. If these members are private, it won't be possible to serialize them. So in some instances, minor modifications to the class to be serialized will be necessary even when using this "non-intrusive" method. In practice this may not be such a problem as many libraries (E.G. STL) expose enough information to permit implementation of non-intrusive serialization with absolutely no changes to the library.

    Namespaces for Free Function Overrides

    For maximum portability, include any free functions templates and definitions in the namespace boost::serialization. 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:
    • boost::serialization
    • namespace of the archive class
    • namespace of the type being serialized

    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 serialization.hpp

    Serialization of Class Members

    Regardless of which of the above methods is used, the body of the serialize function must specify the data to be saved/loaded by sequential application of the archive operator & to all the data members of the class.
    
    {
        // save/load class member variables
        ar & member1;
        ar & member2;
    }
    

    Base Classes

    The header file base_object.hpp includes the template:
    
    template<class Base, class Derived>
    Base & base_object(Derived &d);
    
    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 Serializable type T the base class state should be serialized like this:
    
    {
        // invoke serialization of the base class 
        ar & boost::serialization::base_object<base_class_of_T>(*this);
        // save/load class member variables
        ar & member1;
        ar & member2;
    }
    
    Resist the temptation to just cast *this to the base class. This might seem to work but may fail to invoke code necessary for proper serialization.

    Note that this is NOT the same as calling the serialize 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 serialize member functions should be private.

    const Members

    Saving const members to an archive requires no special considerations. Loading const members can be addressed by using a const_cast:
    
        ar & const_cast<T &>(t);
    
    Note that this violates the spirit and intention of the const keyword. const members are initialized when a class instance is constructed and not changed thereafter. However, this may be most appropriate in many cases. Ultimately, it comes down to the question about what const means in the context of serialization.

    Templates

    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 boost::shared_ptr<T> and for std::list<T>. If I have defined serialization for my own class my_t, then serialization for std::list< boost::shared_ptr< my_t> > is already available for use.

    For an example that shows how this idea might be implemented for your own class templates, see demo_auto_ptr.cpp. This shows how non-intrusive serialization for the template auto_ptr from the standard library can be implemented.

    A somewhat trickier addition of serialization to a standard template can be found in the example shared_ptr.hpp

    In the specification of serialization for templates, its common to split serialize into a load/save pair. Note that the convenience macro described above isn't helpful in these cases as the number and kind of template class arguments won't match those used when splitting serialize for a simple class. Use the override syntax instead.

    Versioning

    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 is loaded from the archive, the original version number is passed as an argument to the loading function. This permits the load function to include logic to accommodate older definitions for the class and reconcile them with latest version. Save functions always save the current version. So this results in automatically converting older format archives to the newest versions. Version numbers are maintained independently for each class. This results in a simple system for permitting access to older files and conversion of same. The current version of the class is assigned as a Class Serialization Trait described later in this manual.
    
    {
        // invoke serialization of the base class 
        ar & boost::serialization::base_object<base_class_of_T>(*this);
        // save/load class member variables
        ar & member1;
        ar & member2;
        // if its a recent version of the class
        if(1 < file_version)
            // save load recently added class members
            ar & member3;
    }
    

    Splitting serialize into Save/Load

    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.

    Splitting Member Functions

    For member functions this can be addressed by including the header file boost/serialization/split_member.hpp including code like this in the class:
    
    template<class Archive>
    void save(Archive & ar, const unsigned int version) const
    {
        // invoke serialization of the base class 
        ar << boost::serialization::base_object<const base_class_of_T>(*this);
        ar << member1;
        ar << member2;
        ar << member3;
    }
    
    template<class Archive>
    void load(Archive & ar, const unsigned int version)
    {
        // invoke serialization of the base class 
        ar >> boost::serialization::base_object<base_class_of_T>(*this);
        ar >> member1;
        ar >> member2;
        if(version > 0)
            ar >> member3;
    }
    
    template<class Archive>
    void serialize(
        Archive & ar,
        const unsigned int file_version 
    ){
        boost::serialization::split_member(ar, *this, file_version);
    }
    
    This splits the serialization into two separate functions save and load. Since the new serialize template is always the same it can be generated by invoking the macro BOOST_SERIALIZATION_SPLIT_MEMBER() defined in the header file boost/serialization/split_member.hpp . So the entire serialize function above can be replaced with:
    
    BOOST_SERIALIZATION_SPLIT_MEMBER()
    

    Splitting Free Functions

    The situation is same for non-intrusive serialization with the free serialize function template. To use save and load function templates rather than serialize:
    
    namespace boost { namespace serialization {
    template<class Archive>
    void save(Archive & ar, const my_class & t, unsigned int version)
    {
        ...
    }
    template<class Archive>
    void load(Archive & ar, my_class & t, unsigned int version)
    {
        ...
    }
    }}
    
    include the header file
    boost/serialization/split_free.hpp . and override the free serialize function template:
    
    namespace boost { namespace serialization {
    template<class Archive>
    inline void serialize(
        Archive & ar,
        my_class & t,
        const unsigned int file_version
    ){
        split_free(ar, t, file_version); 
    }
    }}
    
    To shorten typing, the above template can be replaced with the macro:
    
    BOOST_SERIALIZATION_SPLIT_FREE(my_class)
    
    Note that although the functionality to split the serialize function into save/load has been provided, the usage of the serialize function with the corresponding & operator is preferred. The key to the serialization implementation is that objects are saved and loaded in exactly the same sequence. Using the & operator and serialize function guarantees that this is always the case and will minimize the occurrence of hard to find errors related to synchronization of save and load functions.

    Also note that BOOST_SERIALIZATION_SPLIT_FREE must be used outside of any namespace.

    Pointers

    A pointer to any class instance can be serialized with any of the archive save/load operators.

    To properly save and restore an object through a pointer the following situations must be addressed:

    1. If the same object is saved multiple times through different pointers, only one copy of the object need be saved.
    2. 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.
    3. 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.
    4. 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.
    5. NULL pointers must be detected when saved and restored to NULL when deserialized.
    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:

    Saving a pointer:

    1. determine the true type of the object being pointed to.
    2. write a special tag to the archive
    3. if the object pointed to has not already been written to the archive, do so now
    Loading a pointer:
    1. read a tag from the archive.
    2. determine the type of object to be created
    3. if the object has already been loaded, return its address.
    4. otherwise, create a new instance of the object
    5. read the data back in using the operators described above
    6. return the address of the newly created object.
    Given that class instances are saved/loaded to/from the archive only once, regardless of how many times they are serialized with the << and >> operators
    • Loading the same pointer object multiple times results in only one object being created, thereby replicating the original pointer configuration.
    • Structures, such as collections of polymorphic pointers, are handled with no special effort on the part of users of this library.
    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 Class Serialization Traits as described in another section of this manual

    Non-Default Constructors

    Serialization of pointers is implemented in the library with code similar to the following:
    
    // load data required for construction and invoke constructor in place
    template<class Archive, class T>
    inline void load_construct_data(
        Archive & ar, T * t, const unsigned int file_version
    ){
        // default just uses the default constructor to initialize
        // previously allocated memory. 
        ::new(t)T();
    }
    
    The default load_construct_data invokes the default constructor "in-place" to initialize the memory.

    If there is no such default constructor, the function templates load_construct_data and perhaps save_construct_data 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
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version){
            ar & m_state;
        }
    public:
        // no default construct guarantees that no invalid object
        // ever exists
        my_class(int attribute) :
            m_attribute(attribute),
            m_state(0)
        {}
    };
    
    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
    ){
        // save data required to construct instance
        ar << t->m_attribute;
    }
    
    template<class Archive>
    inline void load_construct_data(
        Archive & ar, my_class * t, const unsigned int file_version
    ){
        // retrieve data from archive required to construct new instance
        int attribute;
        ar >> attribute;
        // invoke inplace constructor to initialize instance of my_class
        ::new(t)my_class(attribute);
    }
    }} // namespace ...
    
    In addition to the deserialization of pointers, these overrides are used in the deserialization of STL containers whose element type has no default constructor.

    Pointers to Objects of Derived Classes

    Registration

    Consider the following:
    
    class base {
        ...
    };
    class derived_one : public base {
        ...
    };
    class derived_two : public base {
        ...
    };
    int main(){
        ...
        base *b;
        ...
        ar & b; 
    }
    
    When saving b what kind of object should be saved? When loading b what kind of object should be created? Should it be an object of class derived_one, derived_two, or maybe base?

    It turns out that the kind of object serialized depends upon whether the base class (base in this case) is polymorphic or not. If base is not polymorphic, that is if it has no virtual functions, then an object of the type base 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.

    If the base class is polymorphic, an object of the most derived type (derived_one or derived_two in this case) will be serialized. The question of which type of object is to be serialized is (almost) automatically handled by the library.

    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".

    Expanding our previous example:

    
    int 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; 
    }
    
    When b is read it is preceded by a unique (to the archive) class identifier which has previously been related to class derived_one or derived_two.

    If a derived class has NOT been automatically "registered" as described above, an unregistered_class exception will be thrown when serialization is invoked.

    This can be addressed by registering the derived class explicitly. All archives are derived from a base class which implements the following template:

    
    template<class T>
    register_type(T * = NULL);
    
    So our problem could just as well be addressed by writing:
    
    int main(){
        ...
        ar.template register_type<derived_one>();
        ar.template register_type<derived_two>();
        base *b;
        ...
        ar & b; 
    }
    
    Note that if the serialization function is split between save and load, both functions must include the registration. This is required to keep the save and corresponding load in synchronization.

    Export

    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.

    So we have another method:

    
    #include <boost/serialization/export.hpp>
    ...
    BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
    BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
    
    int main(){
        ...
        base *b;
        ...
        ar & b; 
    }
    
    The macro BOOST_CLASS_EXPORT_GUID 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 - Export Key.

    Instantiation

    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 template<class Archive, class T>. This means that serialization code must be instantiated for each combination of archive and data type that is serialized in the program.

    Polymorphic pointers of derived classes may never be referred to explicitly by the program so normally code to serialize such classes would never be instantiated. So in addition to including export key strings in an archive, BOOST_CLASS_EXPORT_GUID explicitly instantiates the class serialization code for all archive classes used by the program.

    Selective Tracking

    Whether or not an object is tracked is determined by its object tracking trait. The default setting for user defined types is track_selectively. 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 export a class identifier by specifying BOOST_CLASS_EXPORT 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 track_never in those programs.

    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, track_never can be used.

    Runtime Casting

    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 boost::serialization::base_object<Base>(Derived &) is to ensure that the base/derived pair is added to the table before the main 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 base_object and specify an empty function for the base class serialization. The alternative is to "register" the Base/Derived relationship explicitly by invoking the template void_cast_register<Derived, Base>();. 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:
    
    #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")
    
    int main(){
        //...
        std::stringstream ss;
        boost::archive::text_iarchive ar(ss);
        base *b;
        ar >> b; 
    }
    

    In order for this template to be invoked in code compiled by non-conforming compilers, the following syntax may be used:

    
    boost::serialization::void_cast_register(
        static_cast<Derived *>(NULL),
        static_cast<Base *>(NULL)
    );
    
    For more information, see Template Invocation syntax

    References

    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 is slightly more complex if the class has reference members. This raises the question of how and where the objects being referred to are stored and how are they created. Also there is the question about references to polymorphic base classes. Basically, these are the same questions that arise regarding pointers. This is no surprise as references are really a special kind of pointer. We address these questions by serializing references as though they were pointers.
    
    class object;
    class my_class {
    private:
        friend class boost::serialization::access;
        int member1;
        object & member2;
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version);
    public:
        my_class(int m, object & o) :
            member1(m), 
            member2(o)
        {}
    };
    
    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
    ){
        // save data required to construct instance
        ar << t.member1;
        // serialize reference to object as a pointer
        ar << & t.member2;
    }
    
    template<class Archive>
    inline void load_construct_data(
        Archive & ar, my_class * t, const unsigned int file_version
    ){
        // retrieve data from archive required to construct new instance
        int m;
        ar >> m;
        // create and load data through pointer to object
        // tracking handles issues of duplicates.
        object * optr;
        ar >> optr;
        // invoke inplace constructor to initialize instance of my_class
        ::new(t)my_class(m, *optr);
    }
    }} // namespace ...
    

    Arrays

    If T is a serializable type, then any native C++ array of type T is a serializable type. That is, if T is a serializable type, then the following is automatically available and will function as expected:
    
    T t[4];
    ar << t;
        ...
    ar >> t;
    

    Class Serialization Traits

    Serialization Wrappers

    Models - Serialization Implementations Included in the Library

    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 the included serialization code for std::list, use:
    
    #include <boost/serialization/list.hpp>
    
    rather than
    
    #include <list>
    
    Since the former includes the latter, this is all that is necessary. The same holds true for all STL collections as well as templates required to support them (e.g. std::pair).

    As of this writing, the library contains serialization of the following boost classes:

    • optional
    • variant
    • scoped_ptr
    • shared_ptr
    • auto_ptr (demo)
    C++17 std::variant is supported as well. Others are being added to the list so check the boost files section and headers for new implementations!

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/shared_ptr.html ================================================ Template serialization - shared_ptr

    C++ Boost

    Serialization

    Template serialization - shared_ptr<class T>


    All the code snippets included below are defined within the boost::serialization namespace.

    shared_ptr<T> is defined in shared_ptr.hpp.

    The general class outline for a shared_ptr<T> is:

    shared_ptr<T> contains:
    T *px;
    shared_count pn; which contains a pointer to:
    sp_counted_base_impl<T, ...> which is derived from the polymorphic abstract class
    sp_counted_base
    The serialization process proceeds down the tree above.

    The first cut at implementing serialization for shared_ptr just serializes the relevant members of shared_ptr. It's almost trivial:

    
    template<class Archive, class T>
    inline void serialize(
        Archive & ar,
        shared_ptr<T> & t,
        const unsigned int file_version,
        int
    ){
        ar & t.px; // save the raw pointer
        ar & t.pn; // save the shared reference count
    }
    
    So far so good. Now for the serialization of shared_count:
    
    template<class Archive>
    inline void save(
        Archive & ar,
        const boost::detail::shared_count & t,
        const unsigned int file_version
    ){
        ar << t.pi_;
    }
    
    template<class Archive>
    inline void load(
        Archive & ar,
        boost::detail::shared_count & t,
        const unsigned int file_version
    ){
        ar >> t.pi_;
    }
    
    A key feature of this library is the ability to specify serialization of a class or template without changing the class or template declaration or definition. This is referred to as non-intrusive serialization.

    The pi_member of shared count is a pointer to an instance of sp_counted_base_impl. Since this class doesn't have a default constructor, serialization requires specification of the following overload:

    
    template<class Archive, class P, class D>
    inline void save_construct_data(
        Archive & ar,
        const boost::detail::sp_counted_base_impl<P, D> * t, 
        const unsigned int file_version
    ){
        // variables used for construction
        ar << t->ptr;
        ar << *t;
    }
    
    template<class Archive, class P, class D>
    inline void load_construct_data(
        Archive & ar,
        boost::detail::sp_counted_base_impl<P, D> * t, 
        const unsigned int file_version
    ){
        P ptr_;
        ar >> ptr_;
        // placement new
        ::new(t)boost::detail::sp_counted_base_impl<P, D>(ptr_,  D());
        ar >> *t;
    }
    
    The statement ar >> ptr_ is key. This deserializes the same pointer deserialized above. Default object tracking will ensure that no more than one instance of the object is created and that the pointer returned by multiple deserializations are all the same. Hence, regardless of how many instances of shared_ptr/shared_count corresponding to a particular object are created, they will all point to the same object.

    Since sp_counted_base_impl<P, D> is derived from sp_counted_base, the following is needed:

    
    template<class Archive, class P, class D>
    inline void serialize(
        Archive & ar,
        boost::detail::sp_counted_base_impl<P, D> & t,
        const unsigned int file_version,
        int
    ){
        ar & boost::serialization::base_object<
    	boost::detail::sp_counted_base
        >(*this);
    }
    
    which will in turn require serialization of its base class:
    
    inline void serialize(
        Archive & ar,
        boost::detail::sp_counted & t,
        const unsigned int file_version,
        int
    ){
    }
    
    It would seem we're done, but running the test program, demo_shared_ptr.cpp , with this code produces the following output.
    
    a = 0x003017A0 use count = 2
    a1 = 0x003017A0 use count = 2
    unique element count = 1
    a = 0x00000000 use count = 0
    a1 = 0x00000000 use count = 0
    unique element count = 0
    a = 0x00303060 use count = 1
    a1 = 0x00303060 use count = 1
    unique element count = 1
    
    This indicates that we're not quite done. Due to default object tracking, sp_counted_base_impl<P, D> is only created once regardless of how many shared pointers point to the same object. Of course, it has to be this way. The reference count starts at 1 and is never incremented. Code must be added to the serialization functions to maintain the proper reference count.

    The process of serialization of an empty base class - sp_counted_base - seems like additional overhead. Examination of code in base_object.hpp reveals that base_object.hpp provides two functions:

    • invokes serialization of the base class data
    • as a side effect, "registers" the fact base/derived relationship so that conversions of pointers between base and derived classes can be made at runtime.
    In this case we need only the latter function so we can replace the base object serialization with:
    
    // register the relationship between each derived class
    // and its polymorphic base
    void_cast_register<
        boost::detail::sp_counted_base_impl<P, D>
        boost::detail::sp_counted_base, 
    >();
    
    and we don't have to include a trivial serializer for sp_counted_base.

    Finally we need to specify name-value pair wrappers if we want to be able to use this serialization with XML archives.

    Actually, even this is really just a start. Among the issues not addressed in this implementation are:

    • weak_ptr is not addressed. I haven't even looked into this.
    • Other smart pointers that might interact with shared_ptr haven't been addressed at all. To be confident that the implementation is complete and correct, all these should be addressed as well.
    • Exception handling hasn't been exhaustively considered.
    • Other issues yet to be discovered.
    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:
    BOOST_SHARED_POINTER_EXPORT(T)
    BOOST_SHARED_POINTER_EXPORT_GUID(T, K)
    
    These are specialized versions of the macros used for exporting classes serialized through raw pointers.

    Clear, complete, correct and exception safe serialization of smart pointers is going to be a challenge. I hope that this implementation provides a useful starting point for such an effort.


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/shared_ptr2.html ================================================  Template serialization - shared_ptr

    C++ Boost

    Serialization

    shared_ptr<class T> Revisited


    The previously described serialization of shared_ptr illustrates the straightforward way of serializing a moderately complicated class structure. Unfortunately, this way of doing it suffered from some undesirable features
    • It was dependent on the Boost implementation of shared_ptr. The shared_ptr interface has been included in std::tr1 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 shared_ptr.
    • It required extra macros for export.
    
    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.
        ...
    }
    
    In principle, this is very much simpler than the original implementation. Completion of this code requires:
    1. Filling in the "To Do". This required making an extra map for shared_ptr instances.
    2. A method for identifying pointers to the same objects from pointers to their base classes.
    3. Backward compatibility with pointers serialized by the previous method. This exploits the serialization class versioning.
    4. Proper handling of weak_ptr.
    The result of this effort can be found in boost::serialization::shared_ptr.hpp

    Note that if your code needs to read archives created under boost version 1.32, you will have to include the following

    
    #include <boost/serialization/shared_ptr_132.hpp>
    #include <boost/serialization/shared_ptr.hpp>
    
    rather than just
    
    #include <boost/serialization/shared_ptr.hpp>
    

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/simple_log.html ================================================ Serialization - Derivation from an Existing Archive

    C++ Boost

    Serialization

    A Simple Logging Archive Class


    The purpose of this example is to help clarify the usage of the Archive Concept so that one can implement his own archive classes. simple_log_archive.hpp 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:
    
    #include "simple_log_archive.hpp"
    ...
    // display the complete schedule
    simple_log_archive log(std::cout);
    log << schedule;
    
    and it produces the following output
    
    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
    ...
    
    The complete example is demo_simple_log.cpp. Look at Trivial Archive to get a better understanding of how this works. Also, note the following:
    • Only 160 lines of code.
    • Header only - linking with the serialization library not required.
    • Displays ALL Serializable types.
    • Lacks some features.
      • 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.
      • doesn't display information serialized as binary data

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/singleton.html ================================================ Serialization - singleton

    C++ Boost

    Serialization

    singleton


    Motivation
    Features
    Class Interface
    Requirements
    Examples
    Multi-Threading

    Motivation

    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:
    • Some static data variable and constant entries refer to others. The sequence of initialization cannot be arbitrary but must be in proper sequence.
    • A number of static variables aren't referred to explicitly and, without special precautions, will be stripped by most code optimizers
    • Many of these variables are created by templates and special care must be taken to be sure that they are instantiated
    • In a multi-threading system, its possible that these static variables will be accessed concurrently by separate threads. This would create a race condition with unpredictable behavior
    This singleton class addresses all of the above issues.

    Features

    This singleton implementation has the following features:
    • Any instance will be constructed before any attempt is made to access it.
    • Any instance created with a template is guaranteed to be instantiated.
    • 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.
    • All instances are constructed before main 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.
    • The above implies that any const instances are thread-safe during the whole program. Again, no thread locking is required.
    • 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 main 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.

    Class Interface

    
    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
    

    
    static const T & get_const_instance();
    

    Retrieve a constant reference to the singleton for this type.

    
    static T & get_mutable_instance();
    

    Retrieve a mutable reference to the singleton for this type.

    
    static bool is_destroyed();
    

    Return true if the destructor on this singleton has been called. Otherwise, return false.

    Requirements

    In order to be used as singleton<T> , the type T must be default constructible. It doesn't require static variables - though it may have them. Since the library guarantees that only one instance of singleton<T> exists and all access is through the above static interface functions, common member functions of T become the functional equivalent of static functions.

    Examples

    There are at least two different ways to use this class template. Both are used in the serialization library.

    The first way is illustrated by an excerpt from the file extended_type_info.cpp. which contains the following 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);
        ...
    }
    
    Just by referring to the singleton instance anywhere in the program will guarantee that one and only one instance for the specified type (ktmap in this example) will exist throughout the program. There is no need for any other declaration or definition.

    A second way is to use singleton<T> as one of the base classes of the type. This is illustrated by a simplified excerpt from extended_type_info_typeid.hpp

    
    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(){}
        ...
    };
    
    This usage will permit a more natural syntax to be used:
    
    extended_type_info_typeid<T>::get_const_instance()
    
    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.

    Multi-Threading

    This singleton CAN be safely used in multi-threading applications if one is careful follow a simple rule:

    Do not call get_mutable_instance when more than one thread is running! 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.

    
    void boost::serialization::singleton_module::lock();
    void boost::serialization::singleton_module::unlock();
    bool boost::serialization::singleton_module::is_locked();
    
    In a program compiled for debug, any invocation of get_mutable_instance() 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 main is called. The lock() and unlock() are "global" in that they affect ALL the singletons defined by this template. All serialization tests invoke lock() at the start of the program. For programs compiled in release mode these functions have no effect.

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/smart_cast.html ================================================ Serialization - BOOST_STATIC_WARNING

    C++ Boost

    Serialization

    smart_cast


    Motivation

    To cast from one type to another related type, C++ provides the following operators:
    static_cast<T *>(U *)
    static_cast<T &>(U &)
    • required if neither T nor U are polymorphic
    • permitted in other cases.
    • fails to detect erroneous casts of polymorphic pointers/references at runtime.
    • does not permit "cross casting"
    • inline function calls can be optimized away during compile time.

    dynamic_cast<T *>(U *)
    dynamic_cast<T &>(U &)
    • permitted if either T or U are polymorphic
    • prohibited in other cases.
    • throws exception on detecting erroneous casts of polymorphic pointers/references at runtime.
    • permits "cross casting"
    • cannot optimise inline virtual functions at compile time.
    These rules can make it difficult to use casting with a function template argument. Consider the following example:
    
    #include <boost/serialization/smart_cast.hpp>
    
    struct top {
    };
    
    struct base1 : public top {
        bool is_storable() const {
            return true;
        }
        virtual ~base1();
    };
    
    struct base2 {
        virtual ~base2();
    };
    
    struct derived1 :
        public base1
    {
        derived1();
    };
    
    struct derived2 :
        public base1, 
        public base2
    {
        derived2();
    };
    
    template<class T>
    bool is_storable(T &t){
        // what type of cast to use here?
    
        // this fails at compile time when T == base2
        // return static_cast<base1 &>(t).is_storable();
    
        // this fails at compile time when T == top
        // otherwise it works but cannot optimize inline function call
        // return dynamic_cast<base1 &>(t).is_storable();
    
        // this always works - and is guaranteed to generate the fastest code !
        return (boost::smart_cast_reference<base1 &>(t)).is_storable();
    }
    
    int main(){
        derived1 d1;
        top & t1 = d1;
        derived2 d2;
        base2 & b2 = d2;
    
        bool result;
        result = is_storable(d1);   
        result = is_storable(d2);   
        result = is_storable(b2);
        result = is_storable(b2);
        result = is_storable(t1);
        return 0;
    }
    
    The serialization library includes a mix of classes which use both static polymorphism (CRTP) and dynamic polymorphism via virtual functions. smart_cast was written to address the more problematic manifestations of the situation exemplified above.

    Usage

    The following syntax is supported:
    
    smart_cast<Target *, Source *>(Source * s);
    smart_cast<Target *>(Source * s);
    smart_cast<Target &, Source &>(Source & s);
    
    Note that the above syntax doesn't include
    
    smart_cast<Target & >(Source & s)
    
    but the same functionality is supported with the following special syntax
    
    smart_cast_reference<Target &>(Source & s)
    

    Requirements

    smart_cast can be used only on compilers that support partial template specialization or on types for which the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(<type>) has been applied.

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/special.html ================================================ Serialization - Special Considerations

    C++ Boost

    Serialization

    Special Considerations


    Object Tracking
    Class Information
    Helper Support
    Archive Portability
    Numerics
    Traits
    Binary Archives
    XML Archives
    Exporting Class Serialization
    Static Libraries and Serialization
    DLLS - Serialization and Runtime Linking
    Plugins
    Multi-Threading
    Optimizations
    Archive Exceptions
    Exception Safety

    Object Tracking

    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.

    This could cause problems in programs where the copies of different objects are saved from the same address.

    
    template<class Archive>
    void save(boost::basic_oarchive & ar, const unsigned int version) const
    {
        for(int i = 0; i < 10; ++i){
            A x = a[i];
            ar << x;
        }
    }
    
    In this case, the data to be saved exists on the stack. Each iteration of the loop updates the value on the stack. So although the data changes each iteration, the address of the data doesn't. If a[i] is an array of objects being tracked by memory address, the library will skip storing objects after the first as it will be assumed that objects at the same address are really the same object.

    To help detect such cases, output archive operators expect to be passed const reference arguments.

    Given this, the above code will invoke a compile time assertion. The obvious fix in this example is to use

    
    template<class Archive>
    void save(boost::basic_oarchive & ar, const unsigned int version) const
    {
        for(int i = 0; i < 10; ++i){
            ar << a[i];
        }
    }
    
    which will compile and run without problem. The usage of const 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.

    Unfortunately, implementation issues currently prevent the detection of this kind of error when the data item is wrapped as a name-value pair.

    A similar problem can occur when different objects are loaded to an address which is different from the final location:

    
    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);
        }
    }
    
    In this case, the address of x 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:
    
    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);
        }
    }
    
    This will adjust the tracking information to reflect the final resting place of the moved variable and thereby rectify the above problem.

    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.

    By default, data types designated primitive by the Implementation Level class serialization trait are never tracked. If it is desired to track a shared primitive object through a pointer (e.g. a long used as a reference count), It should be wrapped in a class/struct so that it is an identifiable type. The alternative of changing the implementation level of a long would affect all longs serialized in the whole program - probably not what one would intend.

    It is possible that we may want to track addresses even though the object is never serialized through a pointer. For example, a virtual base class need be saved/loaded only once. By setting this serialization trait to track_always, we can suppress redundant save/load operations.

    
    BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
    

    Helper Support

    Some types, specially those with complicated lifetime behavior or limited access to their internal state, might need or benefit from elaborate serialization algorithms. The principle motivating case is that of shared_ptr. As instances are loaded, they have to be "matched up" with any other instances which have already been loaded. Thus, a table of previously loaded instances has to be maintained while the archive containing the shared_ptr instances is being loaded. Without maintaining such a table, the shared_ptr would be a serializable type.

    To implement this facility, one declares a helper object associated to the current archive that can be used to store contextual information relevant to the particular type serialization algorithm.

    
    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
    
    get_helper<shared_ptr_serialization_helper>(); 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 hlp can effectively be used to store contextual information persisting through the serialization of different complex_type objects on the same archive.

    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.

    Class Information

    By default, for each class serialized, class information is written to the archive. This information includes version number, implementation level and tracking behavior. This is necessary so that the archive can be correctly deserialized even if a subsequent version of the program changes some of the current trait values for a class. The space overhead for this data is minimal. There is a little bit of runtime overhead since each class has to be checked to see if it has already had its class information included in the archive. In some cases, even this might be considered too much. This extra overhead can be eliminated by setting the implementation level class trait to: boost::serialization::object_serializable.

    Turning off tracking and class information serialization will result in pure template inline code that in principle could be optimised down to a simple stream write/read. Elimination of all serialization overhead 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 declared in a header like this:

    
    #include <boost/serialization/serialization.hpp>
    #include <boost/serialization/level.hpp>
    #include <boost/serialization/tracking.hpp>
    
    // a pixel is a light weight struct which is used in great numbers.
    struct pixel
    {
        unsigned char red, green, blue;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int /* version */){
            ar << red << green << blue;
        }
    };
    
    // elminate serialization overhead at the cost of
    // never being able to increase the version.
    BOOST_CLASS_IMPLEMENTATION(pixel, boost::serialization::object_serializable);
    
    // eliminate object tracking (even if serialized through a pointer)
    // at the risk of a programming error creating duplicate objects.
    BOOST_CLASS_TRACKING(pixel, boost::serialization::track_never)
    

    Archive Portability

    Several archive classes create their data in the form of text or a portable binary format. It should be possible to save such a class on one platform and load it on another. This is subject to a couple of conditions.

    Numerics

    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 wchar_t 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 fairly obvious situation and easily handled by using the numeric types in <boost/cstdint.hpp>

    A special integral type is std::size_t 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 collection_size_type 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.

    Traits

    Another potential problem is illustrated by the following example:
    
    template<class T>
    struct my_wrapper {
        template<class Archive>
        Archive & serialize ...
    };
    
    ...
    
    class my_class {
        wchar_t a;
        short unsigned b;
        template<class Archive>
        Archive & serialize(Archive & ar, unsigned int version){
            ar & my_wrapper(a);
            ar & my_wrapper(b);
        }
    };
    
    If my_wrapper uses default serialization traits there could be a problem. With the default traits, each time a new type is added to the archive, bookkeeping information is added. So in this example, the archive would include such bookkeeping information for my_wrapper<wchar_t> and for my_wrapper<short_unsigned>. Or would it? What about compilers that treat wchar_t as a synonym for unsigned short? In this case there is only one distinct type - not two. If archives are passed between programs with compilers that differ in their treatment of wchar_t the load operation will fail in a catastrophic way.

    One remedy for this is to assign serialization traits to the template my_template such that class information for instantiations of this template is never serialized. This process is described above and has been used for Name-Value Pairs. Wrappers would typically be assigned such traits.

    Another way to avoid this problem is to assign serialization traits to all specializations of the template my_wrapper for all primitive types so that class information is never saved. This is what has been done for our implementation of serializations for STL collections.

    Binary Archives

    Standard stream i/o on some systems will expand linefeed characters to carriage-return/linefeed on output. This creates a problem for binary archives. The easiest way to handle this is to open streams for binary archives in "binary mode" by using the flag ios::binary. If this is not done, the archive generated will be unreadable.

    Unfortunately, no way has been found to detect this error before loading the archive. Debug builds will assert when this is detected so that may be helpful in catching this error.

    XML Archives

    XML archives present a somewhat special case. XML format has a nested structure that maps well to the "recursive class member visitor" pattern used by the serialization system. However, XML differs from other formats in that it requires a name for each data member. Our goal is to add this information to the class serialization specification while still permiting the the serialization code to be used with any archive. This is archived by requiring that all data serialized to an XML archive be serialized as a name-value pair. The first member is the name to be used as the XML tag for the data item while the second is a reference to the data item itself. Any attempt to serialize data not wrapped in a in a name-value pair will 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 name-value pairs, it will be guaranteed that all data can be serialized to all archive classes with maximum efficiency.

    Exporting Class Serialization

    Elsewhere in this manual, we have described BOOST_CLASS_EXPORT. Export implies two things:
    • Instantiates code which is not otherwise referred to.
    • Associates an external identifier with the class to be serialized. The fact that the class isn't explicitly referred to implies this requirement.
    In C++, usage of code not explicitly referred to is implemented via virtual functions. Hence, the need for export is implied by the usage of a derived class that is manipulated via a pointer or reference to its base class.

    BOOST_CLASS_EXPORT 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.

    Note that the implemenation of this functionality requires that the BOOST_CLASS_EXPORT macro appear after the inclusion of any archive class headers for which code is to be instantiated. So, code that uses BOOST_CLASS_EXPORT will look like the following:

    
    #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
    
    This will be true regardless of whether the code is part of a stand alone executable, a static library or a dynamic or shared library.

    Including BOOST_CLASS_EXPORT 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 BOOST_CLASS_EXPORT is invoked. This can best be addressed by using BOOST_CLASS_EXPORT_KEY in the header declarations and BOOST_CLASS_EXPORT_IMPLEMENT in the class definition file.

    This system has certain implications for placing code in static or shared libraries. Placing BOOST_CLASS_EXPORT 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 Polymorphic Archives.

    Strictly speaking, export should not be necessary if all pointer serialization occurs through the most derived class. However, in order to detect what would be a catastrophic error, the library traps ALL serializations through a pointer to a polymorphic class which are not exported or otherwise registered. So, in practice, be prepared to register or export all classes with one or more virtual functions which are serialized through a pointer.

    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.

    Static Libraries and Serialization

    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.
    • Only compile serialization definitions in the library.
    • Explicitly instantiate serialization code for ALL archive classes you intend to use in the library.
    • For exported types, only use BOOST_CLASS_EXPORT_KEY in headers.
    • For exported types, only use BOOST_CLASS_EXPORT_IMPLEMENT in definitions compiled in the library. For any particular type, there should be only one file which contains BOOST_CLASS_EXPORT_IMPLEMENT 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 BOOST_CLASS_EXPORT_IMPLEMENT in multiple files could result in a failure to link due to duplicated symbols or the throwing of a runtime exception.
    • Code for serialization should be only in the library,
    • Familiarize yourself with the PIMPL idiom.
    This is illustrated by demo_pimpl.cpp , demo_pimpl_A.cpp and demo_pimpl_A.hpp where implementation of serialization is in a static library completely separate from the main program.

    DLLS - Serialization and Runtime Linking

    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:

    test_dll_simple , and dll_a.cpp where implementation of serialization is also completely separate from the main program but the code is loaded at runtime. In this example, this code is loaded automatically when the program which uses it starts up, but it could just as well be loaded and unloaded with an OS dependent API call.

    Also included are test_dll_exported.cpp , and polymorphic_derived2.cpp which are similar to the above but include tests of the export and no_rtti facilities in the context of DLLS.

    For best results, write your code to conform to the following guidelines:

    • Don't include inline code in classes used in DLLS. This will generate duplicate code in the DLLS and mainline. This needlessly duplicates code. Worse, it makes is possible for different versions of the same code to exist simultaneously. This type of error turns out to be excruciatingly difficult to debug. Finally, it opens the possibility that a module being referred to might be explicitly unloaded which would (hopefully) result in a runtime error. This is another bug that is not always reproducible or easy to find. For class member templates use something like
      
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version);
      
      in the header, and
      
      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.
      
      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.
    • If DLLS are to be loaded and unloaded explicitly (e.g. using dlopen in *nix or LoadLibrary 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.

    Plugins

    In order to implement the library, various facilities for runtime manipulation of types at runtime were required. These are extended_type_info for associating classes with external identifying strings (GUID) and void_cast for casting between pointers of related types. To complete the functionality of extended_type_info 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:
    
    #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
    
    With this in place, one can construct, serialize and destroy a class about which is known only the GUID and a base class.

    Multi-Threading

    The fundamental purpose of serialization would conflict with multiple threads concurrently writing/reading from/to a single open archive instance. The library implementation presumes that the application avoids such a situation.

    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 singleton described elsewhere in this documentation.

    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:

    • Accessing the same archive instance from different tasks.
    • Loading/Unloading DLLS or shared libraries while any archive instances are open.
    The library should be thread safe.

    Optimizations

    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 array wrapper. Serialization functions for data types containing contiguous arrays of homogeneous types, such as for std::vector, std::valarray or boost::multiarray should serialize them using an array 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 array wrapper, as is done for the binary archives.

    Archive Exceptions

    Exception Safety


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/state_saver.html ================================================ Serialization - <code style="white-space: normal">state_saver</code>

    C++ Boost

    Serialization

    state_saver


    Sometimes a certain value has to change only for a limited scope. This class wrapper saves a copy of the current state of some object, and resets the object's state at destruction time, undoing any change the object may have gone through. Here is the interface:

    
    template<class T>
    // T requirements:
    //  - POD or object semantic (cannot be reference, function, ...)
    //  - copy constructor
    //  - operator = (no-throw one preferred)
    class state_saver : private boost::noncopyable
    {
    private:
        ... // implementation
    
    public:
        state_saver(T & object);
        ~state_saver();
    };
    
    The complete implementation can be found here The following illustrates how this is expected to be used.
    
    #include <boost/state_saver.hpp>
    
    void func(A & a)
        boost::state_saver<A> s(a);
        ... // alter state of a by calling non-const functions
        ... // call other functions
        // original state of a automatically restored on exit
    }
    

    History

    This is a generalization of Daryle Walker's io_state_saver library.

    Robert Ramey made an initial version for the serialization library.

    Pavel Vozenilek made several non-obvious refinements to make it more secure and boost friendly


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/static_warning.html ================================================ Serialization - BOOST_STATIC_WARNING

    C++ Boost

    Serialization

    BOOST_STATIC_WARNING


    The header <boost/serialization/static_warning.hpp> supplies a single macro BOOST_STATIC_WARNING(x), which generates a compile time warning message if the integral-constant-expression x is not true.

    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.

    It is intended that the functioning of BOOST_STATIC_WARNING(x) be identical to that of BOOST_STATIC_ASSERT(x) 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 BOOST_STATIC_WARNING(x) consult the documentation for BOOST_STATIC_ASSERT(x) here.


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/strong_typedef.html ================================================ Serialization - BOOST_STATIC_WARNING

    C++ Boost

    Serialization

    BOOST_STRONG_TYPEDEF


    Motivation

    typedef creates an alias for an existing type. It does not create a new type that can be used for matching either function or template parameters. This can be shown by trying to compile the following example.
    
    typedef int a;
    void f(int x);  // (1) function to handle simple integers
    void f(a x);    // (2) special function to handle integers of type a 
    int main(){
        int x = 1;
        a y;
        y = x;      // other operations permitted as a is converted as necessary
        f(x);       // chooses (1)
        f(y);       // chooses (2)
    }
    
    Since typedef doesn't create a new type, this program can't compile to code that implements its obvious intention.

    Usage of BOOST_STRONG_TYPEDEF addresses this.

    
    
    #include <boost/serialization/strong_typedef.hpp>
    
    
    BOOST_STRONG_TYPEDEF(int, a)
    void f(int x);  // (1) function to handle simple integers
    void f(a x);    // (2) special function to handle integers of type a 
    int main(){
        int x = 1;
        a y;
        y = x;      // other operations permitted as a is converted as necessary
        f(x);       // chooses (1)
        f(y);       // chooses (2)
    }
    
    The program will now compile and run as expected.

    Usage

    Syntax of BOOST_STRONG_TYPEDEF has been designed to be similar to the standard typedef. So
    
    BOOST_STRONG_TYPEDEF(primitive type, name)
    
    will create a new type "name" which will be substitutable for the original type but still of distinct type.

    Implemenation

    BOOST_STRONG_TYPEDEF is a macro which generates a class named "name" which wraps an instance of its primitive type and provides appropriate conversion operators in order to make the new type substitutable for the one that it wraps.

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/style.css ================================================ 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; } /* (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) */ ================================================ FILE: doc/todo.html ================================================ Serialization - To Do

    C++ Boost

    Serialization

    To Do


    Portable Binary Archives
    Performance Testing and Profiling
    Back Versioning
    Testing for Environments with No RTTI
    Additional Case Studies
    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.

    Portable Binary Archives

    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.

    It's missing the following:

    • 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.
    • Integration into the Boost testing regimen similar to the other archive classes.

    Performance Testing and Profiling

    I've managed to setup performance profiling using the following:
    • current (as I write this) Boost.Build tools.
    • the gcc compiler.
    • and a shell script - profile.sh
    • library_status program from the tools/regression/src directory
    Invoking profile script produces a table which shows the results of each test and links to the actual profile.

    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.

    Back Versioning

    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.

    Environments without RTTI

    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 extended_typeinfo 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.

    Revised 1 November, 2008

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/traits.html ================================================ Serialization - Class Serialization Traits

    C++ Boost

    Serialization

    Class Serialization Traits


    Version
    Implementation Level
    Object Tracking
    Export Key
    Abstract
    Type Information Implementation
    Wrappers
    Bitwise Serialization
    Template Serialization Traits
    Compile Time Warnings and Errors
    Serialization of data depends on the type of the data. For example, for primitive types such as int, 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 be saved/loaded more than once in any case. Details of serialization for a particular data type will vary depending on the type, the way it is used and specifications of the programmer.

    One can alter the manner in which a particular data type is serialized by specifying one or more class serialization traits. It is not generally necessary for the programmer to explicitly assign traits to his classes as there are default values for all traits. If the default values are not appropriate they can be assigned by the programmer. A template is used to associate a typename with a constant. For example see version.hpp.

    Version

    This header file includes the following code:
    
    namespace boost { 
    namespace serialization {
    template<class T>
    struct version
    {
        BOOST_STATIC_CONSTANT(unsigned int, value = 0);
    };
    } // namespace serialization
    } // namespace boost
    
    For any class T, The default definition of boost::serialization::version<T>::value is 0. If we want to assign a value of 2 as the version for class my_class we specialize the version template:
    
    namespace boost { 
    namespace serialization {
    struct version<my_class>
    {
        BOOST_STATIC_CONSTANT(unsigned int, value = 2);
    };
    } // namespace serialization
    } // namespace boost
    
    Now whenever the version number for class my_class is required, the value 2 will be returned rather than the default value of 0.

    To diminish typing and enhance readability, a macro is defined so that instead of the above, we could write:

    
    BOOST_CLASS_VERSION(my_class, 2)
    
    which expands to the code above.

    Implementation Level

    In the same manner as the above, the "level" of implementation of serialization is specified. The header file level.hpp defines the following.
    
    // names for each level
    enum level_type
    {
        // Don't serialize this type. An attempt to do so should
        // invoke a compile time assertion.
        not_serializable = 0,
        // write/read this type directly to the archive. In this case
        // serialization code won't be called.  This is the default
        // case for fundamental types.  It presumes a member function or
        // template in the archive class that can handle this type.
        // there is no runtime overhead associated reading/writing
        // instances of this level
        primitive_type = 1,
        // Serialize the objects of this type using the objects "serialize"
        // function or template. This permits values to be written/read
        // to/from archives but includes no class or version information. 
        object_serializable = 2,
        ///////////////////////////////////////////////////////////////////
        // once an object is serialized at one of the above levels, the
        // corresponding archives cannot be read if the implementation level
        // for the archive object is changed.  
        ///////////////////////////////////////////////////////////////////
        // Add class information to the archive.  Class information includes
        // implementation level, class version and class name if available.
        object_class_info = 3,
    };
    
    Using a macro defined in level.hpp we can specify that my_class should be serialized along with its version number:
    
    BOOST_CLASS_IMPLEMENTATION(my_class, boost::serialization::object_class_info)
    
    If implementation level is not explicitly assigned, the system uses a default according to the following rules.
    • if the data type is volatile assign not_serializable
    • else if it's an enum or fundamental type assign primitive_type
    • else assign object_class_info
    That is, for most user defined types, objects will be serialized along with class version information. This will permit one to maintain backward compatibility with archives which contain previous versions. However, with this ability comes a small runtime cost. For types whose definition will "never" change, efficiency can be gained by specifying object_serializable to override the default setting of object_class_info. For example, this has been done for the binary_object wrapper

    Object Tracking

    Depending on the way a type is used, it may be necessary or convenient to track the address of objects saved and loaded. For example, this is generally necessary while serializing objects through a pointer in order to be sure that multiple identical objects are not created when an archive is loaded. This "tracking behavior" is controlled by the type trait defined in the header file tracking.hpp which defines the following:
    
    // names for each tracking level
    enum tracking_type
    {
        // never track this type
        track_never = 0,
        // track objects of this type if the object is serialized through a 
        // pointer.
        track_selectively = 1,
        // always track this type
        track_always = 2
    };
    
    A corresponding macro is defined so that we can use:
    
    BOOST_CLASS_TRACKING(my_class, boost::serialization::track_never)
    
    Default tracking traits are:
    • For primitive, track_never.
    • For pointers, track_never. That is, addresses of addresses are not tracked by default.
    • All current serialization wrappers such as boost::serialization::nvp, track_never.
    • For all other types, track_selectively. That is addresses of serialized objects are tracked if and only if one or more of the following is true:
      • an object of this type is anywhere in the program serialized through a pointer.
      • the class is explicitly "exported" - see below.
      • the class is explicitly "registered" in the archive

    The default behavior is almost always the most convenient one. However, there a few cases where it would be desirable to override the default. One case is that of a virtual base class. In a diamond inheritance structure with a virtual base class, object tracking will prevent redundant save/load invocations. So here is one case where it might be convenient to override the default tracking trait. (Note: in a future version the default will be reimplemented to automatically track classes used as virtual bases). This situation is demonstrated by test_diamond.cpp included with the library.

    Export Key

    When serializing a derived class through a virtual base class pointer, two issues may arise.
    • The code in the derived class might never be explicitly referred to. Such code will never be instantiated.

      This is addressed by invoking BOOST_CLASS_EXPORT_IMPLEMENT(T) in the file which defines (implements) the class T. This ensures that code for the derived class T will be explicitly instantiated.

    • There needs to be some sort of identifier which can be used to select the code to be invoked when the object is loaded. Standard C++ does implement typeid() which can be used to return a unique string for the class. This is not entirely satisfactory for our purposes for the following reasons:
      • There is no guarantee that the string is the same across platforms. This would then fail to support portable archives.
      • In using code modules from various sources, classes may have to be wrapped in different namespaces in different programs.
      • There might be classes locally defined in different code modules that have the same name.
      • There might be classes with different names that we want to consider equivalent for purposes of serialization.

      So in the serialization library, this is addressed by invoking BOOST_CLASS_EXPORT_KEY2(my_class, "my_class_external_identifier") in the header file which declares the class. In a large majority of applications, the class name works just fine for the external identifier string so the following short cut is defined - BOOST_CLASS_EXPORT_KEY(my_class).

    For programs which consist of only one module - that is programs which do not use DLLS, one can specify BOOST_CLASS_EXPORT(my_class) or BOOST_CLASS_EXPORT_GUID(my_class, "my_class_external_identifier") in either the declaration header or definition. These macros expand to invocation of both of the macros described above. (GUID stands for Globally Unique IDentifier.)

    (Elsewhere in this manual, the serialization of derived classes is addressed in detail.)

    The header file export.hpp contains all macro definitions described here. The library will throw a runtime exception if

    • A type not explicitly referred to is not exported.
    • Serialization code for the same type is instantiated in more than one module (or DLL).

    Abstract

    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 BOOST_IS_ABSTRACT(T) to do this. Not all compilers support this type trait and corresponding macro. To address this, the macro BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) has been implemented to permit one to explicitly indicate that a specified type is in fact abstract. This will guarentee that BOOST_IS_ABSTRACT will return the correct value for all compilers.

    Type Information Implementation

    This last trait is also related to the serialization of objects through a base class pointer. The implementation of this facility requires the ability to determine at run time the true type of the object that a base class pointer points to. Different serialization systems do this in different ways. In our system, the default method is to use the function typeid(...) which is available in systems which support RTTI (Run Time Type Information). This will be satisfactory in almost all cases and most users of this library will lose nothing in skipping this section of the manual.

    However, there are some cases where the default type determination system is not convenient. Some platforms might not support RTTI or it may have been disabled in order to speed execution or for some other reason. Some applications, E.G. runtime linking of plug-in modules, can't depend on C++ RTTI to determine the true derived class. RTTI only returns the correct type for polymorphic classes - classes with at least one virtual function. If any of these situations applies, one may substitute his own implementation of extended_type_info

    The interface to facilities required to implement serialization is defined in extended_type_info.hpp. Default implementation of these facilities based on typeid(...) is defined in extended_type_info_typeid.hpp. An alternative implementation based on exported class identifiers is defined in extended_type_info_no_rtti.hpp.

    By invoking the macro:

    
    BOOST_CLASS_TYPE_INFO(
        my_class, 
        extended_type_info_no_rtti<my_class>
    )
    
    we can assign the type information implementation to each class on a case by case basis. There is no requirement that all classes in a program use the same implementation of extended_type_info. This supports the concept that serialization of each class is specified "once and for all" in a header file that can be included in any project without change.

    This is illustrated by the test program test_no_rtti.cpp. Other implementations are possible and might be necessary for certain special cases.

    Wrappers

    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 wrapper.hpp includes the following code:
    
    namespace boost { 
    namespace serialization {
    template<class T>
    struct is_wrapper
     : public mpl::false_
    {};
    } // namespace serialization
    } // namespace boost
    
    For any class T, The default definition of boost::serialization::is_wrapper<T>::value is thus false. If we want to declare that a class my_class is a wrapper we specialize the version template:
    
    namespace boost { 
    namespace serialization {
    struct is_wrapper<my_class>
     : mpl::true_
    {};
    } // namespace serialization
    } // namespace boost
    

    To diminish typing and enhance readability, a macro is defined so that instead of the above, we could write:

    
    BOOST_CLASS_IS_WRAPPER(my_class)
    
    which expands to the code above.

    Bitwise Serialization

    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 is_bitwise_serializable.hpp is used:
    
    namespace boost { namespace serialization {
        template<class T>
        struct is_bitwise_serializable
         : public is_arithmetic<T>
        {};
    } }
    
    is used, and can be specialized for other classes. The specialization is made easy by the corresponding macro:
    
    BOOST_IS_BITWISE_SERIALIZABLE(my_class)
    

    Template Serialization Traits

    In some instances it might be convenient to assign serialization traits to a whole group of classes at once. Consider, the name-value pair wrapper
    
    template<class T>
    struct nvp : public std::pair<const char *, T *>
    {
        ...
    };
    
    used by XML archives to associate a name with a data variable of type T. These data types are never tracked and never versioned. So one might want to specify:
    
    BOOST_CLASS_IMPLEMENTATION(nvp<T>, boost::serialization::level_type::object_serializable)
    BOOST_CLASS_TRACKING(nvp<T>, boost::serialization::track_never)
    
    Examination of the definition of these macros reveals that they won't expand to sensible code when used with a template argument. So rather than using the 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;
        BOOST_STATIC_CONSTANT(
            int,
            value = implementation_level::type::value
        );
    };
    
    // nvp objects are generally created on the stack and are never tracked
    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
        );
    };
    
    to assign serialization traits to all classes generated by the template nvp<T>

    Note that it is only possible to use the above method to assign traits to templates when using compilers which correctly support Partial Template Specialization. One's first impulse might be to do something like:

    
    #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    template<class T>
    struct implementation_level<nvp<T> >
    {
       ... // see above
    };
    
    // nvp objects are generally created on the stack and are never tracked
    template<class T>
    struct tracking_level<nvp<T> >
    {
       ... // see above
    };
    #endif
    
    This can be problematic when one wants to make his code and archives portable to other platforms. It means the objects will be serialized differently depending on the platform used. This implies that objects saved from one platform won't be loaded properly on another. In other words, archives won't be portable.

    This problem is addressed by creating another method of assigning serialization traits to user classes. This is illustrated by the serialization for a name-value pair.

    Specifically, this entails deriving the template from a special class boost::serialization::traits which is specialized for a specific combination of serialization traits. When looking up the serialization traits, the library first checks to see if this class has been used as a base class. If so, the corresponding traits are used. Otherwise, the standard defaults are used. By deriving from a serialization traits class rather than relying upon Partial Template Specializaton, one can a apply serialization traits to a template and those traits will be the same across all known platforms.

    The signature for the traits template is:

    
    template<
        class T,       
        int Level, 
        int Tracking,
        unsigned int Version = 0,
        class ETII = BOOST_SERIALIZATION_DEFAULT_TYPE_INFO(T),
        class IsWrapper = mpl::false_
    >
    struct traits
    
    and template parameters should be assigned according to the following table:

    parameterdescriptionpermitted valuesdefault value
    Ttarget classclass namenone
    Levelimplementation levelnot_serializable
    primitive_type
    object_serializable
    object_class_info
    none
    Trackingtracking leveltrack_never
    track_selectivly
    track_always
    none
    Versionclass versionunsigned integer0
    ETTItype_info implementationextended_type_info_typeid
    extended_type_info_no_rtti
    default type_info implementation
    IsWrapperis the type a wrapper?mpl::false_
    mpl::true_
    mpl::false_

    Compile Time Warnings and Errors

    Some serialization traits can conflict with other ones. Sometimes these conflicts will result in erroneous behavior (E.G. creating of archives which could not be read) and other times they represent a probable misconception on the part of the library user which could result in surprising behavior. To the extent possible, these conflicts are detected at compile time and errors (BOOST_STATIC_ASSERT) or warnings (BOOST_STATIC_WARNING) are generated. They are generated in a compiler dependent manner which should show a chain of instantiation to the point where the error/warning is detected. Without this capability, it would be very hard to track down errors or unexpected behavior in library usage. Here is a list of the conflicts trapped:

    object_level - error

    This error traps attempts to serialize types whose implementation level is set to non_serializable.

    object_versioning - error

    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.

    object_tracking - warning

    The following code will display a message when compiled:
    T t;
    ar << t;
    
    unless the tracking_level serialization trait is set to "track_never". The following will compile without problem:
    const T t
    ar << t;
    
    Likewise, the following code will trap at compile time:
    T * t;
    ar >> t;
    
    if the tracking_level serialization trait is set to "track_never".

    The following case illustrates the function of this message. It was originally used as an example in the mailing list by Peter Dimov.

    class construct_from 
    { 
        ... 
    }; 
    
    void main(){ 
        ... 
        Y y; 
        construct_from x(y); 
        ar << x; 
    } 
    
    Suppose that the above message is not displayed and the code is used as is.
    1. 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.
      void main(){ 
          ... 
          Y y; 
          construct_from x(y); 
          ar << x; 
          ... 
          x.f(); // change x in some way 
         ... 
          ar << x 
      } 
      

      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.

    2. 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:
      class K { 
          shared_ptr <construct_from> z; 
          template <class Archive> 
          void serialize(Archive & ar, const unsigned version){ 
              ar << z; 
          } 
      }; 
      

      He builds and runs the program and tests his new functionality. It works great and he's delighted.

    3. Things continue smoothly as before. A month goes by and it's discovered that when loading the archives made in the last month (reading the log). Things don't work. The second log entry is always the same as the first. After a series of very long and increasingly acrimonious email exchanges, it's discovered that programmer(3) accidentally broke programmer(2)'s code .This is because by serializing via a pointer, the "log" object is now being tracked. This is because the default tracking behavior is "track_selectively". This means that class instances are tracked only if they are serialized through pointers anywhere in the program. Now multiple saves from the same address result in only the first one being written to the archive. Subsequent saves only add the address - even though the data might have been changed. When it comes time to load the data, all instances of the log record show the same data. In this way, the behavior of a functioning piece of code is changed due the side effect of a change in an otherwise disjoint module. Worse yet, the data has been lost and cannot be recovered from the archives. People are really upset and disappointed with boost (at least the serialization system).

    4. 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:
      BOOST_CLASS_TRACKING(construct_from, track_never) 
      
    5. Now everything works again. Or - so it seems.

    6. shared_ptr<construct_from> is not going to have a single raw pointer shared amongst the instances. Each loaded shared_ptr<construct_from> is going to have its own distinct raw pointer. This will break shared_ptr 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.

    Now consider what happens when the message is displayed:

    1. Right away, the program traps at
      ar << x; 
      

    2. The programmer curses (another %^&*&* hoop to jump through). He's in a hurry (and who isn't) and would prefer not to const_cast - because it looks bad. So he'll just make the following change an move on.
      Y y; 
      const construct_from x(y); 
      ar << x; 
      

      Things work fine and he moves on.

    3. Now programmer (2) wants to make his change - and again another annoying const issue;
      Y y; 
      const construct_from x(y); 
      ... 
      x.f(); // change x in some way ; compile error f() is not const 
      ... 
      ar << x 
      

      He's mildly annoyed now he tries the following:

      • 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

      • He removes the const from const construct_from above - damn now he gets the trap. If he looks at the comment code where the BOOST_STATIC_ASSERT occurs, he'll do one of two things

        1. This is just crazy. Its making my life needlessly difficult and flagging code that is just fine. So I'll fix this with a const_cast and fire off a complaint to the list and maybe they will fix it. In this case, the story branches off to the previous scenario.

        2. 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.
          BOOST_CLASS_TRACKING(construct_from, track_never) 
          

    4. Now programmer (3) comes along and make his change. The behavior of the original (and distant module) remains unchanged because the construct_from trait has been set to "track_never" so he should always get copies and the log should be what we expect.

    5. 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 BOOST_CLASS_TRACKING 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 construct_from are reconciled.
    Note that in this second scenario
    • all errors are trapped at compile time.
    • no invalid archives are created.
    • no data is lost.
    • no runtime errors occur.
    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.

    pointer_level - warning

    This trap addresses the following situation when serializing a pointer:
    • A type doesn't save class information in the archive. That is, the serialization trait implementation level <= object_serializable.
    • 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.

      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.

      Though this situation is unlikely for several reasons, it is possible - hence this warning.

    So if your program traps here, consider changing the tracking or implementation level traits - or not serializing via a pointer.

    pointer_tracking - warning

    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.

    const_loading - error

    One cannot load data into a "const" object unless it's a wrapper around some other non-const object.

    © Copyright Robert Ramey 2002-2004 and Matthias Troyer 2006. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    ================================================ FILE: doc/tutorial.html ================================================ Serialization - Tutorial

    C++ Boost

    Serialization

    Tutorial


    A Very Simple Case
    Non Intrusive Version
    Serializable Members
    Derived Classes
    Pointers
    Arrays
    STL Collections
    Class Versioning
    Splitting serialize into save/load
    Archives
    List of examples
    An output archive is similar to an output data stream. Data can be saved to the archive with either the << or the & operator:
    
    ar << data;
    ar & data;
    
    An input archive is similar to an input datastream. Data can be loaded from the archive with either the >> or the & operator.
    
    ar >> data;
    ar & data;
    

    When these operators are invoked for primitive data types, the data is simply saved/loaded to/from the archive. When invoked for class data types, the class serialize function is invoked. Each serialize function is uses the above operators to save/load its data members. This process will continue in a recursive manner until all the data contained in the class is saved/loaded.

    A Very Simple Case

    These operators are used inside the serialize function to save and load class data members.

    Included in this library is a program called demo.cpp which illustrates how to use this system. Below we excerpt code from this program to illustrate with the simplest possible case how this library is intended to be used.

    
    #include <fstream>
    
    // include headers that implement a archive in simple text format
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    
    /////////////////////////////////////////////////////////////
    // gps coordinate
    //
    // illustrates serialization for a simple type
    //
    class gps_position
    {
    private:
        friend class boost::serialization::access;
        // When the class Archive corresponds to an output archive, the
        // & operator is defined similar to <<.  Likewise, when the class Archive
        // is a type of input archive the & operator is defined similar to >>.
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & degrees;
            ar & minutes;
            ar & seconds;
        }
        int degrees;
        int minutes;
        float seconds;
    public:
        gps_position(){};
        gps_position(int d, int m, float s) :
            degrees(d), minutes(m), seconds(s)
        {}
    };
    
    int main() {
        // create and open a character archive for output
        std::ofstream ofs("filename");
    
        // 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
        }
    
        // ... some time later restore the class instance to its orginal state
        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
        }
        return 0;
    }
    
    

    For each class to be saved via serialization, there must exist a function to save all the class members which define the state of the class. For each class to be loaded via serialization, there must exist a function to load these class members in the same sequence as they were saved. In the above example, these functions are generated by the template member function serialize.

    Non Intrusive Version

    The above formulation is intrusive. That is, it requires that classes whose instances are to be serialized be altered. This can be inconvenient in some cases. An equivalent alternative formulation permitted by the system would be:

    
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    
    class gps_position
    {
    public:
        int degrees;
        int minutes;
        float seconds;
        gps_position(){};
        gps_position(int d, int m, float s) :
            degrees(d), minutes(m), seconds(s)
        {}
    };
    
    namespace boost {
    namespace serialization {
    
    template<class Archive>
    void serialize(Archive & ar, gps_position & g, const unsigned int version)
    {
        ar & g.degrees;
        ar & g.minutes;
        ar & g.seconds;
    }
    
    } // namespace serialization
    } // namespace boost
    

    In this case the generated serialize functions are not members of the gps_position class. The two formulations function in exactly the same way.

    The main application of non-intrusive serialization is to permit serialization to be implemented for classes without changing the class definition. In order for this to be possible, the class must expose enough information to reconstruct the class state. In this example, we presumed that the class had public members - not a common occurrence. Only classes which expose enough information to save and restore the class state will be serializable without changing the class definition.

    Serializable Members

    A serializable class with serializable members would look like this:

    
    class bus_stop
    {
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & latitude;
            ar & longitude;
        }
        gps_position latitude;
        gps_position longitude;
    protected:
        bus_stop(const gps_position & lat_, const gps_position & long_) :
        latitude(lat_), longitude(long_)
        {}
    public:
        bus_stop(){}
        // See item # 14 in Effective C++ by Scott Meyers.
        // re non-virtual destructors in base classes.
        virtual ~bus_stop(){}
    };
    

    That is, members of class type are serialized just as members of primitive types are.

    Note that saving an instance of the class bus_stop with one of the archive operators will invoke the serialize function which saves latitude and longitude. Each of these in turn will be saved by invoking serialize in the definition of gps_position. In this manner the whole data structure is saved by the application of an archive operator to just its root item.

    Derived Classes

    Derived classes should include serializations of their base classes.

    
    #include <boost/serialization/base_object.hpp>
    
    class bus_stop_corner : public bus_stop
    {
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            // serialize base class information
            ar & boost::serialization::base_object<bus_stop>(*this);
            ar & street1;
            ar & street2;
        }
        std::string street1;
        std::string street2;
        virtual std::string description() const
        {
            return street1 + " and " + 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_)
        {}
    };
    
    

    Note the serialization of the base classes from the derived class. Do NOT directly call the base class serialize functions. Doing so might seem to work but will bypass the code that tracks instances written to storage to eliminate redundancies. It will also bypass the writing of class version information into the archive. For this reason, it is advisable to always make member serialize functions private. The declaration friend boost::serialization::access will grant to the serialization library access to private member variables and functions.

    Pointers

    Suppose we define a bus route as an array of bus stops. Given that
    1. we might have several types of bus stops (remember bus_stop is a base class)
    2. a given bus_stop might appear in more than one route.
    it's convenient to represent a bus route with an array of pointers to bus_stop.
    
    class bus_route
    {
        friend class boost::serialization::access;
        bus_stop * stops[10];
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            int i;
            for(i = 0; i < 10; ++i)
                ar & stops[i];
        }
    public:
        bus_route(){}
    };
    
    
    Each member of the array stops will be serialized. 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 not sufficient to save the value of the pointer, rather the 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.

    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

    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 demo.cpp, 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 here.

    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.

    Arrays

    The above formulation is in fact more complex than necessary. The serialization library detects when the object being serialized is an array and emits code equivalent to the above. So the above can be shortened to:
    
    class bus_route
    {
        friend class boost::serialization::access;
        bus_stop * stops[10];
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & stops;
        }
    public:
        bus_route(){}
    };
    
    

    STL Collections

    The above example uses an array of members. More likely such an application would use an STL collection for such a purpose. The serialization library contains code for serialization of all STL classes. Hence, the reformulation below will also work as one would expect.
    
    #include <boost/serialization/list.hpp>
    
    class bus_route
    {
        friend class boost::serialization::access;
        std::list<bus_stop *> stops;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & stops;
        }
    public:
        bus_route(){}
    };
    
    

    Class Versioning

    Suppose we're satisfied with our bus_route class, build a program that uses it and ship the product. Some time later, it's decided that the program needs enhancement and the bus_route class is altered to include the name of the driver of the route. So the new version looks like:

    
    #include <boost/serialization/list.hpp>
    #include <boost/serialization/string.hpp>
    
    class bus_route
    {
        friend class boost::serialization::access;
        std::list<bus_stop *> stops;
        std::string driver_name;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & driver_name;
            ar & stops;
        }
    public:
        bus_route(){}
    };
    
    
    Great, we're all done. Except... what about people using our application who now have a bunch of files created under the previous program. How can these be used with our new program version?

    In general, the serialization library stores a version number in the archive for each class serialized. By default this version number is 0. When the archive is loaded, the version number under which it was saved is read. The above code can be altered to exploit this

    
    #include <boost/serialization/list.hpp>
    #include <boost/serialization/string.hpp>
    #include <boost/serialization/version.hpp>
    
    class bus_route
    {
        friend class boost::serialization::access;
        std::list<bus_stop *> stops;
        std::string driver_name;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            // only save/load driver_name for newer archives
            if(version > 0)
                ar & driver_name;
            ar & stops;
        }
    public:
        bus_route(){}
    };
    
    BOOST_CLASS_VERSION(bus_route, 1)
    
    
    By application of versioning to each class, there is no need to try to maintain a versioning of files. That is, a file version is the combination of the versions of all its constituent classes. This system permits programs to be always compatible with archives created by all previous versions of a program with no more effort than required by this example.

    Splitting serialize into save/load

    The serialize function is simple, concise, and guarantees that class members are saved and loaded in the same sequence - the key to the serialization system. However, there are cases where the load and save operations are not as similar as the examples used here. For example, this could occur with a class that has evolved through multiple versions. The above class can be reformulated as:
    
    #include <boost/serialization/list.hpp>
    #include <boost/serialization/string.hpp>
    #include <boost/serialization/version.hpp>
    #include <boost/serialization/split_member.hpp>
    
    class bus_route
    {
        friend class boost::serialization::access;
        std::list<bus_stop *> stops;
        std::string driver_name;
        template<class Archive>
        void save(Archive & ar, const unsigned int version) const
        {
            // note, version is always the latest when saving
            ar  & driver_name;
            ar  & stops;
        }
        template<class Archive>
        void load(Archive & ar, const unsigned int version)
        {
            if(version > 0)
                ar & driver_name;
            ar  & stops;
        }
        BOOST_SERIALIZATION_SPLIT_MEMBER()
    public:
        bus_route(){}
    };
    
    BOOST_CLASS_VERSION(bus_route, 1)
    
    
    The macro BOOST_SERIALIZATION_SPLIT_MEMBER() generates code which invokes the save or load depending on whether the archive is used for saving or loading.

    Archives

    Our discussion here has focused on adding serialization capability to classes. The actual rendering of the data to be serialized is implemented in the archive class. Thus the stream of serialized data is a product of the serialization of the class and the archive selected. It is a key design decision that these two components be independent. This permits any serialization specification to be usable with any archive.

    In this tutorial, we have used a particular archive class - text_oarchive for saving and text_iarchive 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.

    If the current set of archive classes doesn't provide the attributes, format, or behavior needed for a particular application, one can either make a new archive class or derive from an existing one. This is described later in the manual.

    List of Examples

    demo.cpp
    This is the completed example used in this tutorial. It does the following:
    1. Creates a structure of differing kinds of stops, routes and schedules
    2. Displays it
    3. Serializes it to a file named "testfile.txt" with one statement
    4. Restores to another structure
    5. Displays the restored structure
    Output of this program is sufficient to verify that all the originally stated requirements for a serialization system are met with this system. The contents of the archive file can also be displayed as serialization files are ASCII text.
    demo_xml.cpp
    This is a variation the original demo which supports xml archives in addition to the others. The extra wrapping macro, BOOST_SERIALIZATION_NVP(name), is needed to associate a data item name with the corresponding xml tag. It is important that 'name' be a valid xml tag, else it will be impossible to restore the archive. For more information see Name-Value Pairs. Here is what an xml archive looks like.
    demo_xml_save.cpp and demo_xml_load.cpp
    Note also that though our examples save and load the program data to an archive within the same program, this merely a convenience for purposes of illustration. In general, the archive may or may not be loaded by the same program that created it.

    The astute reader might notice that these examples contain a subtle but important flaw. They leak memory. The bus stops are created in the main 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 new_schedule 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.

    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 shared_ptr rather than raw pointers. Along with serialization implementations for the Standard Library, the serialization library includes implementation of serialization for boost::shared ptr. Given this, it should be easy to alter any of these examples to eliminate the memory leak. This is left as an exercise for the reader.


    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/void_cast.html ================================================  Serialization - BOOST_STATIC_WARNING

    C++ Boost

    Serialization

    void_cast


    Motivation

    C++ includes the operator dynamic_cast<T>(U * u) for casting a pointer at runtime between two related types. However, this can only be used for polymorphic classes. That is, it can only be used with related classes which have at least one virtual function. Limiting the serialization of pointers to only such classes would diminish the applicability of the library.

    Usage

    The following functions are defined in the header void_cast.hpp. They are declared in the namespace boost::serialization.

    
    template<class Derived, class Base>
    const void_cast_detail::void_caster &
    void_cast_register(
        Derived const * derived = NULL, 
        Base * const base = NULL
    );
    

    This function "registers" a pair of related types. It stores the fact that Derived is immediately derived from Base in a global table.
    • This "registration" can be invoked anywhere in the program. The table is built at pre-runtime and is available anywhere else in the program.
    • only adjacent base/derived pairs need be registered. That is,
      
        void_cast_register<A, B>();
        void_cast_register<B, C>();
        
      automatically derives the fact that A can be upcast to C and vice-versa.

    
    void *
    void_upcast(
        extended_type_info const & derived_type,
        extended_type_info const & base_type,
        void * const t 
    );
    

    
    void *
    void_downcast(
        extended_type_info const & derived_type,
        extended_type_info const & base_type,
        void * const t 
    );
    

    These functions cast a void pointer from one type to another. The source and definition types are specified by passing references to the corresponding extended_type_info records. An attempt to cast between types not "registered" with void_cast_register will throw a boost::archive::archive_exception with value equal to unregistered_cast

    © Copyright Robert Ramey 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)

    ================================================ FILE: doc/wrappers.html ================================================  Serialization - Serialization Wrappers

    C++ Boost

    Serialization

    Serialization Wrappers


    Binary Objects
    Arrays
    BOOST_STRONG_TYPEDEF
    Collection Sizes
    Name-Value Pairs
    Composition
    Sometimes it convenient to create a temporary object just to support serialization 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.

    Wrappers need to be treated in a special way by some archives, and hence the is_wrapper trait for these wrapper classes is set to true.

    Binary Objects

    A binary object is just a sequence of bytes stored as raw binary data. This would most likely be used for a large amount of "light weight" data such as a pixel map or embedded binary file. The header file binary_object.hpp includes the constructors:
    
    boost::serialization::binary_object(void * t, size_t size);
    boost::serialization::make_binary_object(void * t, size_t size);
    
    which will construct a temporary binary object that can be serialized just like any other object. Its default serialization is to use archive class primitives save_binary and load_binary. 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.

    Arrays

    An array is a contiguous sequence of homogeneous data types, such as a builtin C-array, a boost::array<T> or a std::vector<T>. 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 array.hpp includes the function
    
    template <T>
    boost::serialization::make_array(T* t, std::size_t size);
    
    which will construct a temporary array object
    
    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;
    };
    
    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 array.

    BOOST_STRONG_TYPEDEF

    Another example of a serialization wrapper is the BOOST_STRONG_TYPEDEF template. The serialization libraries uses these to pass particular kinds of integers such as object_id, version, etc. to an archive class. Given that these integers are now distinguishable according to their type, XML archives can apply special handling to these types. For example, a version number is rendered as an XML attribute in the form "version=12". In the absence of any specific override, these types are automatically converted to the underlying integer type so the special overrides used for XML archives aren't needed for other archives.

    Collection Sizes

    An example of a strong typedef is the collection_size_type in the header file collection_size_type.hpp . This type should be used for serializing the size of a C++ collection, so that the archive can pick the best integral representation for the serialization of collection sizes. This is necessary since, although std::size_t 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 collection_size_type might be serialized as a variable length integer in a portable binary archive.

    Name-Value Pairs

    XML archives present a somewhat special case. XML format has a nested structure that maps well to the "recursive class member visitor" pattern used by the serialization system. However, XML differs from other formats in that it requires a name for each class data member. Our goal is to add this information to the class serialization specification while still permiting the the serialization code to be used with any archive.

    Our solution is to wrap class members to be serialized in a name-value-pair. This structure is defined in nvp.hpp. It is just a reference to the data member coupled with a pointer to to a const char * 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.

    The xml archive classes contain code similar to:

    
    // special treatment for name-value pairs.
    template<class T>
    xml_oarchive & operator&(const boost::serialization::nvp<T> & t)
    {
        // write an xml start tag
        start_tag(t.name());
    
        // serialize the data as usual
        *this & t.value();
    
        // write an xml end tag
        end_tag(t.name());
    }
    
    The most obvious and convenient name to assign to as the XML data item name is - surprise! - the name of the C++ class data member. So our serialization code will look like:
    
    ar & make_nvp("my_variable", my_variable);
    
    To simplify typing and enhance readability a macro is defined so we can write:
    
    ar & BOOST_SERIALIZATION_NVP(my_variable);
    
    Similarly there exists a macro definition that permits us to write:
    
    BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class)
    
    Note that these macros must be used in the namespace of the class, and without qualifying the namespace in the argument.

    demo_gps.hpp includes NVP wrappers or all data members. demo_xml.cpp saves and loads data to an XML archive. Here is example of the XML Archive corresponding to our tutorial example.

    Composition

    Wrappers should be designed so that they can be composed as necessary. For example, to pass binary data as a name value pair use:
    
    ar & make_nvp("named_binary_object", make_binary_object(address, size));
    

    © Copyright Robert Ramey 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)

    ================================================ FILE: example/Jamfile.v2 ================================================ # 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 ../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-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 : : : demo_xml_save ] ; ================================================ FILE: example/demo.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo.cpp // // (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 // NULL #include #include #include #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////// // The intent of this program is to serve as a tutorial for // users of the serialization package. An attempt has been made // to illustrate most of the facilities of the package. // // The intent is to create an example sufficiently complete to // illustrate the usage and utility of the package while // including a minimum of other code. // // This illustration models the bus system of a small city. // This includes, multiple bus stops, bus routes and schedules. // There are different kinds of stops. Bus stops in general // will appear on multiple routes. A schedule will include // multiple trips on the same route. ///////////////////////////////////////////////////////////// // gps coordinate // // illustrates serialization for a simple type // class gps_position { friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); friend class boost::serialization::access; int degrees; int minutes; float seconds; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & degrees & minutes & 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; friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); virtual std::string description() const = 0; gps_position latitude; gps_position longitude; template void serialize(Archive &ar, const unsigned int version) { ar & latitude; ar & longitude; } protected: bus_stop(const gps_position & _lat, const gps_position & _long) : latitude(_lat), longitude(_long) {} public: bus_stop(){} 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 void serialize(Archive &ar, const unsigned int version) { // save/load base class information ar & boost::serialization::base_object(*this); ar & street1 & 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 void serialize(Archive &ar, const unsigned int version) { ar & boost::serialization::base_object(*this) & name; } public: bus_stop_destination(){} bus_stop_destination( const gps_position & _lat, const gps_position & _long, const std::string & _name ) : bus_stop(_lat, _long), name(_name) { } }; ///////////////////////////////////////////////////////////// // a bus route is a collection of bus stops // // illustrates serialization of STL collection templates. // // illustrates serialization of polymorphic pointer (bus stop *); // // illustrates storage and recovery of shared pointers is correct // and efficient. That is objects pointed to by more than one // pointer are stored only once. In such cases only one such // object is restored and pointers are restored to point to it // class bus_route { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_route &br); typedef bus_stop * bus_stop_pointer; std::list stops; template 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(); ar.register_type(static_cast(NULL)); //ar.template register_type(); ar.register_type(static_cast(NULL)); // serialization of stl collections is already defined // in the header ar & 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::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<< >(ar, pair) and others in // serialization.hpp // // illustrates nesting of serializable classes // // illustrates use of version number to automatically grandfather older // versions of the same class. class bus_schedule { public: // note: this structure was made public. because the friend declarations // didn't seem to work as expected. struct trip_info { template void serialize(Archive &ar, const unsigned int file_version) { // in versions 2 or later if(file_version >= 2) // read the drivers name ar & driver; // all versions have the following info ar & hour & 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) {} }; private: friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs); friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti); std::list > schedule; template void serialize(Archive &ar, const unsigned int version) { ar & 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, 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 >::const_iterator it; for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ os << it->first << *(it->second); } return os; } void save_schedule(const bus_schedule &s, const char * filename){ // make an archive std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << s; } void restore_schedule(bus_schedule &s, const char * filename) { // open the archive std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); // restore the schedule from the archive ia >> s; } int main(int argc, char *argv[]) { // make the schedule bus_schedule original_schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule original_schedule.append("bob", 6, 24, &route0); original_schedule.append("bob", 9, 57, &route0); original_schedule.append("alice", 11, 02, &route0); // make another route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule original_schedule.append("ted", 7, 17, &route1); original_schedule.append("ted", 9, 38, &route1); original_schedule.append("alice", 11, 47, &route1); // display the complete schedule std::cout << "original schedule"; std::cout << original_schedule; std::string filename(boost::archive::tmpdir()); filename += "/demofile.txt"; // save the schedule save_schedule(original_schedule, filename.c_str()); // ... some time later // make a new schedule bus_schedule new_schedule; restore_schedule(new_schedule, filename.c_str()); // and display std::cout << "\nrestored schedule"; std::cout << new_schedule; // should be the same as the old one. (except for the pointer values) delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demo_auto_ptr.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_auto_ptr.cpp // (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 #include #include #include #include // remove, std::autoptr inteface wrong in dinkumware #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::remove; } #endif #include #include #include #include namespace boost { namespace serialization { ///////////////////////////////////////////////////////////// // implement serialization for auto_ptr< T > // note: this must be added to the boost namespace in order to // be called by the library template inline void save( Archive & ar, 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; } template inline void load( Archive & ar, std::auto_ptr< T > &t, const unsigned int file_version ){ T *pTarget; ar >> pTarget; // note that the reset automagically maintains the reference count #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) t.release(); t = std::auto_ptr< T >(pTarget); #else t.reset(pTarget); #endif } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::auto_ptr< T > &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost ///////////////////////////////////////////////////////////// // test auto_ptr serialization class A { private: friend class boost::serialization::access; int x; template void serialize(Archive &ar, const unsigned int /* file_version */){ ar & x; } public: A(){} // default constructor ~A(){} // default destructor }; void save(const std::auto_ptr & spa, const char *filename) { std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << spa; } void load(std::auto_ptr & spa, const char *filename) { // open the archive std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); // restore the schedule from the archive ia >> spa; } int main(int argc, char *argv[]) { std::string filename = boost::archive::tmpdir(); filename += "/testfile"; // create a new auto pointer to ta new object of type A std::auto_ptr spa(new A); // serialize it save(spa, filename.c_str()); // reset the auto pointer to NULL // thereby destroying the object of type A // note that the reset automagically maintains the reference count #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) spa.release(); #else spa.reset(); #endif // restore state to one equivalent to the original // creating a new type A object load(spa, filename.c_str()); // obj of type A gets destroyed // as auto_ptr goes out of scope std::remove(filename.c_str()); return 0; } ================================================ FILE: example/demo_dll_a.hpp ================================================ #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 #include // for rand() #include // for fabs() #include // size_t #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::rand; using ::fabs; using ::size_t; } #endif //#include #include #include #include #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #include #include #include 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 void serialize( Archive &ar, const unsigned int /* file_version */ ){ ar & BOOST_SERIALIZATION_NVP(b); #ifndef BOOST_NO_INT64_T ar & BOOST_SERIALIZATION_NVP(f); ar & BOOST_SERIALIZATION_NVP(g); #endif #if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x551 ) int i; if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){ i = l; ar & BOOST_SERIALIZATION_NVP(i); } else{ ar & BOOST_SERIALIZATION_NVP(i); l = i; } #else ar & BOOST_SERIALIZATION_NVP(l); #endif ar & BOOST_SERIALIZATION_NVP(m); ar & BOOST_SERIALIZATION_NVP(n); ar & BOOST_SERIALIZATION_NVP(o); ar & BOOST_SERIALIZATION_NVP(p); ar & BOOST_SERIALIZATION_NVP(q); #ifndef BOOST_NO_CWCHAR ar & BOOST_SERIALIZATION_NVP(r); #endif ar & BOOST_SERIALIZATION_NVP(c); ar & BOOST_SERIALIZATION_NVP(s); ar & BOOST_SERIALIZATION_NVP(t); ar & BOOST_SERIALIZATION_NVP(u); ar & BOOST_SERIALIZATION_NVP(v); ar & BOOST_SERIALIZATION_NVP(w); ar & BOOST_SERIALIZATION_NVP(x); ar & BOOST_SERIALIZATION_NVP(y); #ifndef BOOST_NO_STD_WSTRING ar & BOOST_SERIALIZATION_NVP(z); #endif } bool b; #ifndef BOOST_NO_INT64_T boost::int64_t f; boost::uint64_t g; #endif enum h { i = 0, j, k } l; std::size_t m; signed long n; unsigned long o; signed short p; unsigned short q; #ifndef BOOST_NO_CWCHAR wchar_t r; #endif char c; signed char s; unsigned char t; signed int u; unsigned int v; float w; double x; std::string y; #ifndef BOOST_NO_STD_WSTRING std::wstring z; #endif public: A(); bool operator==(const A &rhs) const; bool operator!=(const A &rhs) const; bool operator<(const A &rhs) const; // used by less // hash function for class A operator std::size_t () const; friend std::ostream & operator<<(std::ostream & os, A const & a); friend std::istream & operator>>(std::istream & is, A & a); }; //BOOST_TEST_DONT_PRINT_LOG_VALUE(A); template void randomize(S &x) { assert(0 == x.size()); for(;;){ unsigned int i = std::rand() % 27; if(0 == i) break; x += static_cast('a' - 1 + i); } } template 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(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 ================================================ FILE: example/demo_dll_a.ipp ================================================ #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 #include // for rand() #include // for fabs() #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::rand; using ::fabs; using ::size_t; } #endif //#include #include #include #include #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #include #include #include 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 void serialize( Archive &ar, const unsigned int /* file_version */ ){ ar & BOOST_SERIALIZATION_NVP(b); #ifndef BOOST_NO_INT64_T ar & BOOST_SERIALIZATION_NVP(f); ar & BOOST_SERIALIZATION_NVP(g); #endif #if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x551 ) int i; if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){ i = l; ar & BOOST_SERIALIZATION_NVP(i); } else{ ar & BOOST_SERIALIZATION_NVP(i); l = i; } #else ar & BOOST_SERIALIZATION_NVP(l); #endif ar & BOOST_SERIALIZATION_NVP(m); ar & BOOST_SERIALIZATION_NVP(n); ar & BOOST_SERIALIZATION_NVP(o); ar & BOOST_SERIALIZATION_NVP(p); ar & BOOST_SERIALIZATION_NVP(q); #ifndef BOOST_NO_CWCHAR ar & BOOST_SERIALIZATION_NVP(r); #endif ar & BOOST_SERIALIZATION_NVP(c); ar & BOOST_SERIALIZATION_NVP(s); ar & BOOST_SERIALIZATION_NVP(t); ar & BOOST_SERIALIZATION_NVP(u); ar & BOOST_SERIALIZATION_NVP(v); ar & BOOST_SERIALIZATION_NVP(w); ar & BOOST_SERIALIZATION_NVP(x); ar & BOOST_SERIALIZATION_NVP(y); #ifndef BOOST_NO_STD_WSTRING ar & BOOST_SERIALIZATION_NVP(z); #endif } bool b; #ifndef BOOST_NO_INT64_T boost::int64_t f; boost::uint64_t g; #endif enum h { i = 0, j, k } l; std::size_t m; signed long n; unsigned long o; signed short p; unsigned short q; #ifndef BOOST_NO_CWCHAR wchar_t r; #endif char c; signed char s; unsigned char t; signed int u; unsigned int v; float w; double x; std::string y; #ifndef BOOST_NO_STD_WSTRING std::wstring z; #endif public: A(); bool operator==(const A &rhs) const; bool operator!=(const A &rhs) const; bool operator<(const A &rhs) const; // used by less // hash function for class A operator std::size_t () const; friend std::ostream & operator<<(std::ostream & os, A const & a); friend std::istream & operator>>(std::istream & is, A & a); }; //BOOST_TEST_DONT_PRINT_LOG_VALUE(A); template void randomize(S &x) { assert(0 == x.size()); for(;;){ unsigned int i = std::rand() % 27; if(0 == i) break; x += static_cast('a' - 1 + i); } } template 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(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 ================================================ FILE: example/demo_dll_b.hpp ================================================ #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 // for rand() #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::rand; } #endif #include #include #include #include "A.hpp" /////////////////////////////////////////////////////// // Derived class test class B : public A { private: friend class boost::serialization::access; template 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 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 ================================================ FILE: example/demo_dll_b.ipp ================================================ #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 // for rand() #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::rand; } #endif #include #include #include #include "A.hpp" /////////////////////////////////////////////////////// // Derived class test class B : public A { private: friend class boost::serialization::access; template 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 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 ================================================ FILE: example/demo_exception.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_exception.cpp // (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Example of safe exception handling for pointer de-serialization // // This example was prepared by Robert Ramey to demonstrate and test // safe exception handling during the de-serialization of pointers in // a non-trivial example. // // Hopefully, this addresses exception issues raised by // Vahan Margaryan who spent considerable time and effort // in the analysis and testing of issues of exception safety // of the serialization library. #include #include #include // NULL #include #include #include // remove #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::remove; } #endif #include #ifndef BOOST_NO_EXCEPTIONS #include #endif #include #include #include #include template struct deleter { void operator()(TPTR t){ delete t; } }; class Course; class Student; class Student { public: static int count; Student(){ count++; } ~Student(){ some_courses.clear(); count--; } std::list some_courses; private: friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & some_courses; } }; int Student::count = 0; class Course { public: static int count; Course(){ count++; } ~Course(){ // doesnt delete pointers in list // since it doesn't "own" them some_students.clear(); count--; } std::list some_students; private: friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & some_students; } }; int Course::count = 0; class School { public: ~School(){ // must delete all the students because // it "owns" them std::for_each(all_students.begin(), all_students.end(), deleter()); all_students.clear(); // as well as courses std::for_each(all_courses.begin(), all_courses.end(), deleter()); all_courses.clear(); } std::list all_students; std::list all_courses; private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER() template void save(Archive & ar, const unsigned int file_version) const; template void load(Archive & ar, const unsigned int file_version); }; #if 0 // case 1: template void School::serialize(Archive & ar, const unsigned int /* file_version */){ // if an exception occurs while loading courses // the structure courses may have some courses each // with students ar & all_courses; // while all_students will have no members. ar & all_students; // create students that have no courses // so ~School() will delete all members of courses // but this will NOT delete any students - see above // a memory leak will be the result. } // switching the order of serialization doesn't help in this case // case 2: template void School::serialize(Archive & ar, const unsigned int /* file_version */){ ar & all_students; ar >> all_courses; // create any courses that have no students } #endif template void School::save(Archive & ar, const unsigned int /* file_version */) const { ar << all_students; ar << all_courses; } template void School::load(Archive & ar, const unsigned int /* file_version */){ // if an exception occurs while loading courses // the structure courses may have some courses each // with students try{ // deserialization of a Course * will in general provoke the // deserialization of Student * which are added to the list of // students for a class. That is, this process will result // in the copying of a pointer. ar >> all_courses; ar >> all_students; // create students that have no courses } catch(std::exception){ // eliminate any dangling references all_courses.clear(); all_students.clear(); throw; } } void init(School *school){ Student *bob = new Student(); Student *ted = new Student(); Student *carol = new Student(); Student *alice = new Student(); school->all_students.push_back(bob); school->all_students.push_back(ted); school->all_students.push_back(carol); school->all_students.push_back(alice); Course *math = new Course(); Course *history = new Course(); Course *literature = new Course(); Course *gym = new Course(); school->all_courses.push_back(math); school->all_courses.push_back(history); school->all_courses.push_back(literature); school->all_courses.push_back(gym); bob->some_courses.push_back(math); math->some_students.push_back(bob); bob->some_courses.push_back(literature); literature->some_students.push_back(bob); ted->some_courses.push_back(math); math->some_students.push_back(ted); ted->some_courses.push_back(history); history->some_students.push_back(ted); alice->some_courses.push_back(literature); literature->some_students.push_back(alice); alice->some_courses.push_back(history); history->some_students.push_back(alice); // no students signed up for gym // carol has no courses } void save(const School * const school, const char *filename){ std::ofstream ofile(filename); boost::archive::text_oarchive ar(ofile); ar << school; } void load(School * & school, const char *filename){ std::ifstream ifile(filename); boost::archive::text_iarchive ar(ifile); try{ ar >> school; } catch(std::exception){ // eliminate dangling reference school = NULL; } } int main(int argc, char *argv[]){ std::string filename(boost::archive::tmpdir()); filename += "/demofile.txt"; School *school = new School(); std::cout << "1. student count = " << Student::count << std::endl; std::cout << "2. class count = " << Course::count << std::endl; init(school); std::cout << "3. student count = " << Student::count << std::endl; std::cout << "4. class count = " << Course::count << std::endl; save(school, filename.c_str()); delete school; school = NULL; std::cout << "5. student count = " << Student::count << std::endl; std::cout << "6. class count = " << Course::count << std::endl; load(school, filename.c_str()); std::cout << "7. student count = " << Student::count << std::endl; std::cout << "8. class count = " << Course::count << std::endl; delete school; std::cout << "9. student count = " << Student::count << std::endl; std::cout << "10. class count = " << Course::count << std::endl; std::remove(filename.c_str()); return Student::count + Course::count; } ================================================ FILE: example/demo_fast_archive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_fast_binary_archive.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // should pass compilation and execution #include #include #include #define BOOST_ARCHIVE_SOURCE #include #include #include // include template definitions for base classes used. Otherwise // you'll get link failure with undefined symbols #include #include #include #include using namespace boost::archive; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // "Fast" output binary archive. This is a variation of the native binary class fast_binary_oarchive : // don't derive from binary_oarchive !!! public binary_oarchive_impl< fast_binary_oarchive, std::ostream::char_type, std::ostream::traits_type > { typedef fast_binary_oarchive derived_t; typedef binary_oarchive_impl< fast_binary_oarchive, std::ostream::char_type, std::ostream::traits_type > base_t; #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else friend class boost::archive::detail::interface_oarchive; friend class basic_binary_oarchive; friend class basic_binary_oprimitive< derived_t, std::ostream::char_type, std::ostream::traits_type >; friend class boost::archive::save_access; #endif // add base class to the places considered when matching // save function to a specific set of arguments. Note, this didn't // work on my MSVC 7.0 system using // binary_oarchive_impl::load_override; // so we use the sure-fire method below. This failed to work as well template void save_override(T & t){ base_t::save_override(t); // verify that this program is in fact working by making sure // that arrays are getting passed here BOOST_STATIC_ASSERT(! (boost::is_array::value) ); } template void save_override(const int (& t)[N]){ save_binary(t, sizeof(t)); } template void save_override(const unsigned int (& t)[N]){ save_binary(t, sizeof(t)); } template void save_override(const long (& t)[N]){ save_binary(t, sizeof(t)); } template void save_override(const unsigned long (& t)[N]){ 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) {} }; // 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 > { 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; friend class basic_binary_iarchive; friend class basic_binary_iprimitive< derived_t, std::ostream::char_type, std::ostream::traits_type >; friend class boost::archive::load_access; #endif // add base class to the places considered when matching // save function to a specific set of arguments. Note, this didn't // work on my MSVC 7.0 system using // binary_oarchive_impl::load_override; // so we use the sure-fire method below. This failed to work as well template void load_override(T & t){ base_t::load_override(t); BOOST_STATIC_ASSERT(! (boost::is_array::value) ); } template void load_override(int (& t)[N]){ load_binary(t, sizeof(t)); } template void load_override(unsigned int (& t)[N]){ load_binary(t, sizeof(t)); } template void load_override(long (& t)[N]){ load_binary(t, sizeof(t)); } template void load_override(unsigned long (& t)[N]){ 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) {} }; // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_iarchive) int main( int argc, char* argv[] ) { const int a[3] = {1, 2, 3}; int a1[3] = {4, 5, 6}; std::stringstream ss; { fast_binary_oarchive pboa(ss); pboa << a; } { fast_binary_iarchive pbia(ss); pbia >> a1; } return (a[0] != a1[0]) || (a[1] != a1[1]) || (a[2] != a1[2]); } ================================================ FILE: example/demo_gps.hpp ================================================ #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 #include #include #include #include #include #include #include #include // This illustration models the bus system of a small city. // This includes, multiple bus stops, bus routes and schedules. // There are different kinds of stops. Bus stops in general // will appear on multiple routes. A schedule will include // multiple trips on the same route. ///////////////////////////////////////////////////////////// // gps coordinate // // illustrates serialization for a simple type // class gps_position { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); int degrees; int minutes; float seconds; template 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 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 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 void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop) & BOOST_SERIALIZATION_NVP(name); } public: bus_stop_destination(){} bus_stop_destination( const gps_position & _lat, const gps_position & _long, const std::string & _name ) : bus_stop(_lat, _long), name(_name) { } }; ///////////////////////////////////////////////////////////// // a bus route is a collection of bus stops // // illustrates serialization of STL collection templates. // // illustrates serialization of polymorphic pointer (bus stop *); // // illustrates storage and recovery of shared pointers is correct // and efficient. That is objects pointed to by more than one // pointer are stored only once. In such cases only one such // object is restored and pointers are restored to point to it // class bus_route { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_route &br); typedef bus_stop * bus_stop_pointer; std::list stops; template 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(); ar.register_type(static_cast(NULL)); //ar.template register_type(); ar.register_type(static_cast(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::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<< >(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 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 void serialize(Archive &ar, const unsigned int file_version) { // in versions 2 or later if(file_version >= 2) // read the drivers name ar & BOOST_SERIALIZATION_NVP(driver); // all versions have the following info ar & BOOST_SERIALIZATION_NVP(hour) & BOOST_SERIALIZATION_NVP(minute); } // starting time int hour; int minute; // only after system shipped was the driver's name added to the class std::string driver; trip_info(){} trip_info(int _h, int _m, const std::string &_d) : hour(_h), minute(_m), driver(_d) {} ~trip_info(){ } }; // friend std::ostream & operator<<(std::ostream &os, const trip_info &ti); private: std::list > 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 >::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 ================================================ FILE: example/demo_log.cpp ================================================ /////////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 #include #include "demo_gps.hpp" #include "log_archive.hpp" int main(int argc, char *argv[]){ // make the schedule bus_schedule schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule schedule.append("bob", 6, 24, &route0); schedule.append("bob", 9, 57, &route0); schedule.append("alice", 11, 02, &route0); // make another route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule schedule.append("ted", 7, 17, &route1); schedule.append("ted", 9, 38, &route1); schedule.append("alice", 11, 47, &route1); // display the complete schedule log_archive oa(std::cout); oa << BOOST_SERIALIZATION_NVP(schedule); oa << schedule; delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demo_output.txt ================================================ original schedule 6:24 bob 0x003265C8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x00326768 35136'15.456" 13332'15.3" White House 9:57 bob 0x003265C8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x00326768 35136'15.456" 13332'15.3" White House 11:2 alice 0x003265C8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x00326768 35136'15.456" 13332'15.3" White House 7:17 ted 0x003267D0 35134'48.789" 13332'16.23" Lincoln Memorial 0x00326768 35136'15.456" 13332'15.3" White House 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 9:38 ted 0x003267D0 35134'48.789" 13332'16.23" Lincoln Memorial 0x00326768 35136'15.456" 13332'15.3" White House 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 11:47 alice 0x003267D0 35134'48.789" 13332'16.23" Lincoln Memorial 0x00326768 35136'15.456" 13332'15.3" White House 0x00326648 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane restored schedule 6:24 0x0032A2F8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x0032A628 35136'15.456" 13332'15.3" White House 9:57 0x0032A2F8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x0032A628 35136'15.456" 13332'15.3" White House 11:2 0x0032A2F8 34135'52.56" 13422'78.3" 24th Street and 10th Avenue 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 0x0032A628 35136'15.456" 13332'15.3" White House 7:17 0x0032A8C0 35134'48.789" 13332'16.23" Lincoln Memorial 0x0032A628 35136'15.456" 13332'15.3" White House 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 9:38 0x0032A8C0 35134'48.789" 13332'16.23" Lincoln Memorial 0x0032A628 35136'15.456" 13332'15.3" White House 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane 11:47 0x0032A8C0 35134'48.789" 13332'16.23" Lincoln Memorial 0x0032A628 35136'15.456" 13332'15.3" White House 0x0032A508 35137'23.456" 13335'54.12" State street and Cathedral Vista Lane *** No errors detected ================================================ FILE: example/demo_pimpl.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_pimpl.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // should pass compilation and execution #include #include #include #include "demo_pimpl_A.hpp" int main(int argc, char* argv[]) { std::stringstream ss; const A a; { boost::archive::text_oarchive oa(ss); oa << a; } A a1; { boost::archive::text_iarchive ia(ss); ia >> a1; } return 0; } ================================================ FILE: example/demo_pimpl_A.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_pimpl_A.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include "demo_pimpl_A.hpp" // "hidden" definition of class B struct B { int b; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & b; } }; A::A() : pimpl(new B) {} A::~A(){ delete pimpl; } // now we can define the serialization for class A template void A::serialize(Archive & ar, const unsigned int /* file_version */){ ar & pimpl; } // without the explicit instantiation below, the program will // fail to link for lack of instantiation of the above function // note: the following failed to fix link errors for vc 7.0 ! template void A::serialize( boost::archive::text_iarchive & ar, const unsigned int file_version ); template void A::serialize( boost::archive::text_oarchive & ar, const unsigned int file_version ); ================================================ FILE: example/demo_pimpl_A.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP #define BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_pimpl_A.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) // class whose declaration is hidden by a pointer struct B; struct A { // class a contains a pointer to a "hidden" declaration B *pimpl; template void serialize(Archive & ar, const unsigned int file_version); A(); ~A(); }; #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP ================================================ FILE: example/demo_polymorphic.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_polymorphic.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // should pass compilation and execution #include #include #include #include #include #include "demo_polymorphic_A.hpp" int main(int argc, char* argv[]) { const A a; A a1; { // test with a text archive std::stringstream ss; { // instantiate archive which inherits polymorphic interface // and the normal text archive implementation boost::archive::polymorphic_text_oarchive oa(ss); boost::archive::polymorphic_oarchive & oa_interface = oa; // we can just just the interface for saving oa_interface << a; } { // or we can use the implementation directly boost::archive::polymorphic_text_iarchive ia(ss); ia >> a1; } } if(! (a == a1)) return 1; { //test with a binary archive std::stringstream ss; { // instantiate archive which inherits polymorphic interface // and the normal binary archive implementation boost::archive::polymorphic_binary_oarchive oa(ss); oa << a; } { // see above boost::archive::polymorphic_binary_iarchive ia(ss); boost::archive::polymorphic_iarchive & ia_interface = ia; // use just the polymorphic interface for loading. ia_interface >> a1; } } if(! (a == a1)) return 1; return 0; } ================================================ FILE: example/demo_polymorphic_A.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_polymorphic_A.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include "demo_polymorphic_A.hpp" // explicitly instantiate templates for polymorphic archives // used by this demo. template void A::serialize( boost::archive::polymorphic_iarchive &, const unsigned int ); template void A::serialize( boost::archive::polymorphic_oarchive &, const unsigned int ); ================================================ FILE: example/demo_polymorphic_A.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP #define BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // demo_polymorphic_A.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) namespace boost { namespace archive { class polymorphic_iarchive; class polymorphic_oarchive; } // namespace archive } // namespace boost struct A { // class a contains a pointer to a "hidden" declaration template void serialize( Archive & ar, const unsigned int file_version ){ ar & data; } int data; bool operator==(const A & rhs) const { return data == rhs.data; } A() : data(0) {} }; #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP ================================================ FILE: example/demo_portable_archive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_portable_archive.cpp // // (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) // 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 #include "portable_binary_oarchive.hpp" #include "portable_binary_iarchive.hpp" #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::rand; } #endif 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 void serialize(Archive & ar, const unsigned int /* version */){ ar & c & i & i2 & ui & l & ul ; } public: bool operator==(const A & rhs) const { return c == rhs.c && i == rhs.i && i2 == rhs.i2 && ui == rhs.ui && l == rhs.l && ul == rhs.ul ; } A() : c(0xFF & std::rand()), pa(0), i(std::rand()), i2(0x80), ui(std::rand()), l(std::rand() * std::rand()), ul(std::rand()) {} }; int main( int /* argc */, char* /* argv */[] ) { const A a; A a1; std::stringstream ss; { portable_binary_oarchive pboa(ss); pboa << a; } { 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); } ================================================ FILE: example/demo_save.xml ================================================ 6 bob 6 24 3 34 135 52.560001 134 22 78.300003 24th Street 10th Avenue 35 137 23.455999 133 35 54.119999 State street Cathedral Vista Lane 35 136 15.456 133 32 15.3 White House bob 9 57 alice 11 2 ted 7 17 3 35 134 48.789001 133 32 16.23 Lincoln Memorial ted 9 38 alice 11 47 ================================================ FILE: example/demo_shared_ptr.cpp ================================================ // demo_shared_ptr.cpp : demonstrates adding serialization to a template // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . Polymorphic // derived pointer example by David Tonge. // 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 #include #include // NULL #include #include #include // remove #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::remove; } #endif #include #include #include #include /////////////////////////// // test shared_ptr serialization class A { private: friend class boost::serialization::access; int x; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & x; } public: static int count; A(){++count;} // default constructor virtual ~A(){--count;} // default destructor }; BOOST_SERIALIZATION_SHARED_PTR(A) ///////////////// // ADDITION BY DT class B : public A { private: friend class boost::serialization::access; int x; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & boost::serialization::base_object(*this); } public: static int count; B() : A() {}; virtual ~B() {}; }; BOOST_SERIALIZATION_SHARED_PTR(B) ///////////////// int A::count = 0; void display(boost::shared_ptr &spa, boost::shared_ptr &spa1) { std::cout << "a = 0x" << std::hex << spa.get() << " "; if (spa.get()) std::cout << "is a " << typeid(*(spa.get())).name() << "* "; std::cout << "use count = " << std::dec << spa.use_count() << std::endl; std::cout << "a1 = 0x" << std::hex << spa1.get() << " "; if (spa1.get()) std::cout << "is a " << typeid(*(spa1.get())).name() << "* "; std::cout << "use count = " << std::dec << spa1.use_count() << std::endl; std::cout << "unique element count = " << A::count << std::endl; } int main(int /* argc */, char * /*argv*/[]) { std::string filename(boost::archive::tmpdir()); filename += "/testfile"; // create a new shared pointer to ta new object of type A boost::shared_ptr spa(new A); boost::shared_ptr spa1; spa1 = spa; display(spa, spa1); // serialize it { std::ofstream ofs(filename.c_str()); boost::archive::text_oarchive oa(ofs); oa << spa; oa << spa1; } // reset the shared pointer to NULL // thereby destroying the object of type A spa.reset(); spa1.reset(); display(spa, spa1); // restore state to one equivalent to the original // creating a new type A object { // open the archive std::ifstream ifs(filename.c_str()); boost::archive::text_iarchive ia(ifs); // restore the schedule from the archive ia >> spa; ia >> spa1; } display(spa, spa1); spa.reset(); spa1.reset(); std::cout << std::endl; std::cout << std::endl; std::cout << "New tests" << std::endl; ///////////////// // ADDITION BY DT // create a new shared pointer to ta new object of type A spa = boost::shared_ptr(new B); spa1 = spa; display(spa, spa1); // serialize it { std::ofstream ofs(filename.c_str()); boost::archive::text_oarchive oa(ofs); oa.register_type(static_cast(NULL)); oa << spa; oa << spa1; } // reset the shared pointer to NULL // thereby destroying the object of type B spa.reset(); spa1.reset(); display(spa, spa1); // restore state to one equivalent to the original // creating a new type B object { // open the archive std::ifstream ifs(filename.c_str()); boost::archive::text_iarchive ia(ifs); // restore the schedule from the archive ia.register_type(static_cast(NULL)); ia >> spa; ia >> spa1; } display(spa, spa1); /////////////// std::remove(filename.c_str()); // obj of type A gets destroyed // as smart_ptr goes out of scope return 0; } ================================================ FILE: example/demo_simple_log.cpp ================================================ /////////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 #include #include "demo_gps.hpp" #include "simple_log_archive.hpp" int main(int argc, char *argv[]) { // make the schedule bus_schedule schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule schedule.append("bob", 6, 24, &route0); schedule.append("bob", 9, 57, &route0); schedule.append("alice", 11, 02, &route0); // make another route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule schedule.append("ted", 7, 17, &route1); schedule.append("ted", 9, 38, &route1); schedule.append("alice", 11, 47, &route1); // display the complete schedule simple_log_archive log(std::cout); log << schedule; delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demo_trivial_archive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_trivial_archive.cpp // // (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include // std::size_t #include ///////////////////////////////////////////////////////////////////////// // class trivial_oarchive class trivial_oarchive { public: ////////////////////////////////////////////////////////// // public interface used by programs that use the // serialization library typedef boost::mpl::bool_ is_saving; typedef boost::mpl::bool_ is_loading; template void register_type(){} template trivial_oarchive & operator<<(const T & t){ return *this; } template trivial_oarchive & operator&(const T & t){ return *this << t; } void save_binary(void *address, std::size_t count){}; }; #include "demo_gps.hpp" int main(int argc, char *argv[]) { // make the schedule bus_schedule schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule schedule.append("bob", 6, 24, &route0); schedule.append("bob", 9, 57, &route0); schedule.append("alice", 11, 02, &route0); // make another route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule schedule.append("ted", 7, 17, &route1); schedule.append("ted", 9, 38, &route1); schedule.append("alice", 11, 47, &route1); // display the complete schedule trivial_oarchive ta; ta << schedule; delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demo_xml.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_xml.cpp // // (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 #include #include #include #include // remove #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::remove; } #endif #include #include #include #include "demo_gps.hpp" void save_schedule(const bus_schedule &s, const char * filename){ // make an archive std::ofstream ofs(filename); assert(ofs.good()); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(s); } void restore_schedule(bus_schedule &s, const char * filename) { // open the archive std::ifstream ifs(filename); assert(ifs.good()); boost::archive::xml_iarchive ia(ifs); // restore the schedule from the archive ia >> BOOST_SERIALIZATION_NVP(s); } int main(int argc, char *argv[]) { // make the schedule bus_schedule original_schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule original_schedule.append("bob", 6, 24, &route0); original_schedule.append("bob", 9, 57, &route0); original_schedule.append("alice", 11, 02, &route0); // make another route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule original_schedule.append("ted", 7, 17, &route1); original_schedule.append("ted", 9, 38, &route1); original_schedule.append("alice", 11, 47, &route1); // display the complete schedule std::cout << "original schedule"; std::cout << original_schedule; std::string filename(boost::archive::tmpdir()); filename += "/demo.xml"; // save the schedule save_schedule(original_schedule, filename.c_str()); // ... some time later // make a new schedule bus_schedule new_schedule; restore_schedule(new_schedule, filename.c_str()); // and display std::cout << "\nrestored schedule"; std::cout << new_schedule; // should be the same as the old one. (except for the pointer values) std::remove(filename.c_str()); delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demo_xml.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP #define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_xml.hpp // // (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include // This illustration models the bus system of a small city. // This includes, multiple bus stops, bus routes and schedules. // There are different kinds of stops. Bus stops in general // will appear on multiple routes. A schedule will include // multiple trips on the same route. ///////////////////////////////////////////////////////////// // gps coordinate // // illustrates serialization for a simple type // class gps_position { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); int degrees; int minutes; float seconds; template 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 void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(latitude); ar & BOOST_SERIALIZATION_NVP(longitude); } protected: bus_stop(const gps_position & _lat, const gps_position & _long) : latitude(_lat), longitude(_long) {} public: bus_stop(){} friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); virtual ~bus_stop(){} }; BOOST_IS_ABSTRACT(bus_stop) std::ostream & operator<<(std::ostream &os, const bus_stop &bs) { return os << bs.latitude << bs.longitude << ' ' << bs.description(); } ///////////////////////////////////////////////////////////// // Several kinds of bus stops // // illustrates serialization of derived types // class bus_stop_corner : public bus_stop { friend class boost::serialization::access; std::string street1; std::string street2; virtual std::string description() const { return street1 + " and " + street2; } template 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 void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop) & BOOST_SERIALIZATION_NVP(name); } public: bus_stop_destination(){} bus_stop_destination( const gps_position & _lat, const gps_position & _long, const std::string & _name ) : bus_stop(_lat, _long), name(_name) { } }; ///////////////////////////////////////////////////////////// // a bus route is a collection of bus stops // // illustrates serialization of STL collection templates. // // illustrates serialization of polymorphic pointer (bus stop *); // // illustrates storage and recovery of shared pointers is correct // and efficient. That is objects pointed to by more than one // pointer are stored only once. In such cases only one such // object is restored and pointers are restored to point to it // class bus_route { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_route &br); typedef bus_stop * bus_stop_pointer; std::list stops; template 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(); ar.register_type(static_cast(NULL)); //ar.template register_type(); ar.register_type(static_cast(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::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<< >(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 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 void serialize(Archive &ar, const unsigned int file_version) { // in versions 2 or later if(file_version >= 2) // read the drivers name ar & BOOST_SERIALIZATION_NVP(driver); // all versions have the following info ar & BOOST_SERIALIZATION_NVP(hour) & BOOST_SERIALIZATION_NVP(minute); } // starting time int hour; int minute; // only after system shipped was the driver's name added to the class std::string driver; trip_info(){} trip_info(int _h, int _m, const std::string &_d) : hour(_h), minute(_m), driver(_d) {} ~trip_info(){ } }; // friend std::ostream & operator<<(std::ostream &os, const trip_info &ti); private: std::list > 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 >::const_iterator it; for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ os << it->first << *(it->second); } return os; } #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP ================================================ FILE: example/demo_xml_load.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_xml_load.cpp // // (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 #include #include #include #include "demo_gps.hpp" void restore_schedule(bus_schedule &s, const char * filename) { // open the archive std::ifstream ifs(filename); assert(ifs.good()); boost::archive::xml_iarchive ia(ifs); // restore the schedule from the archive ia >> BOOST_SERIALIZATION_NVP(s); } int main(int argc, char *argv[]) { // make a new schedule bus_schedule new_schedule; std::string filename(boost::archive::tmpdir()); filename += "/demo_save.xml"; restore_schedule(new_schedule, filename.c_str()); // and display std::cout << "\nrestored schedule"; std::cout << new_schedule; return 0; } ================================================ FILE: example/demo_xml_save.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_xml_save.cpp // // (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 #include #include #include #include "demo_gps.hpp" void save_schedule(const bus_schedule &s, const char * filename){ // make an archive std::ofstream ofs(filename); assert(ofs.good()); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(s); } int main(int argc, char *argv[]) { // make the schedule bus_schedule original_schedule; // fill in the data // make a few stops bus_stop *bs0 = new bus_stop_corner( gps_position(34, 135, 52.560f), gps_position(134, 22, 78.30f), "24th Street", "10th Avenue" ); bus_stop *bs1 = new bus_stop_corner( gps_position(35, 137, 23.456f), gps_position(133, 35, 54.12f), "State street", "Cathedral Vista Lane" ); bus_stop *bs2 = new bus_stop_destination( gps_position(35, 136, 15.456f), gps_position(133, 32, 15.300f), "White House" ); bus_stop *bs3 = new bus_stop_destination( gps_position(35, 134, 48.789f), gps_position(133, 32, 16.230f), "Lincoln Memorial" ); // make a route bus_route route0; route0.append(bs0); route0.append(bs1); route0.append(bs2); // add trips to schedule original_schedule.append("bob", 6, 24, &route0); original_schedule.append("bob", 9, 57, &route0); original_schedule.append("alice", 11, 02, &route0); // make an other route bus_route route1; route1.append(bs3); route1.append(bs2); route1.append(bs1); // add trips to schedule original_schedule.append("ted", 7, 17, &route1); original_schedule.append("ted", 9, 38, &route1); original_schedule.append("alice", 11, 47, &route1); // display the complete schedule std::cout << "original schedule"; std::cout << original_schedule; std::string filename(boost::archive::tmpdir()); filename += "/demo_save.xml"; // save the schedule save_schedule(original_schedule, filename.c_str()); delete bs0; delete bs1; delete bs2; delete bs3; return 0; } ================================================ FILE: example/demofile.txt ================================================ 22 serialization::archive 3 0 2 0 0 6 0 0 0 0 6 24 4 1 0 0 0 0 3 5 1 0 1 0 0 0 0 34 135 52.560001 134 22 78.300003 11 24th Street 11 10th Avenue 5 2 35 137 23.455999 133 35 54.119999 12 State street 20 Cathedral Vista Lane 6 1 0 3 35 136 15.456 133 32 15.3 11 White House 9 57 4 0 11 2 4 0 7 17 4 4 3 6 5 35 134 48.789001 133 32 16.23 16 Lincoln Memorial 6 3 5 2 9 38 4 4 11 47 4 4 ================================================ FILE: example/fix_six.cpp ================================================ #include #include #include #include #include void usage(const char * program_name){ std::cout << "usage:"; std::cout << program_name << " filename" << std::endl; } int main(int argc, char *argv[]){ if(argc != 2){ std::cout << "invalid number of arguments" << std::endl; usage(argv[0]); return 1; } std::filebuf fb; fb.open( argv[1], std::ios_base::binary | std::ios_base::in | std::ios_base::out ); if(!fb.is_open()){ std::cout << argv[1] << " failed to open" << std::endl; return 1; } boost::archive::binary_iarchive ia(fb); boost::archive::library_version_type lvt = ia.get_library_version(); if(boost::archive::library_version_type(6) != lvt){ std::cout << "library version not equal to six" << std::endl; return 1; } lvt = boost::archive::library_version_type(7); fb.pubseekpos(26, std::ios_base::out); fb.sputn(reinterpret_cast(& lvt), sizeof(lvt)); fb.close(); } ================================================ FILE: example/log_archive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // log_archive.cpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #if (defined _MSC_VER) && (_MSC_VER == 1200) # pragma warning (disable : 4786) // too long name, harmless warning #endif //#define BOOST_ARCHIVE_SOURCE #include "log_archive.hpp" #include // explicitly instantiate for this type of xml stream #include #include #include namespace boost { namespace archive { template class detail::archive_serializer_map; template class basic_xml_oarchive ; template class xml_oarchive_impl ; } // namespace archive } // namespace boost ================================================ FILE: example/log_archive.hpp ================================================ #ifndef LOG_ARCHIVE_HPP #define LOG_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // log_archive.hpp // (C) Copyright 2010 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail } // namespace archive } // boost ///////////////////////////////////////////////////////////////////////// // log data to an output stream. This illustrates a simpler implementation // of text output which is useful for getting a formatted display of // any serializable class. Intended to be useful as a debugging aid. class log_archive : /* protected ? */ public boost::archive::xml_oarchive_impl { typedef boost::archive::xml_oarchive_impl base; // give serialization implementation access to this class friend class boost::archive::detail::interface_oarchive; friend class boost::archive::basic_xml_oarchive; friend class boost::archive::save_access; ///////////////////////////////////////////////////////////////////// // Override functions defined in basic_xml_oarchive // Anything not an attribute and not a name-value pair is an // error and should be trapped here. template void save_override(T & t){ // make it a name-value pair and pass it on. // this permits this to be used even with data types which // are not wrapped with the name base::save_override(boost::serialization::make_nvp(NULL, t)); } template void save_override(const boost::serialization::nvp< T > & t){ // this is here to remove the "const" requirement. Since // this class is to be used only for output, it's not required. base::save_override(t); } // specific overrides for attributes - not name value pairs so we // want to trap them before the above "fall through" // since we don't want to see these in the output - make them no-ops. void save_override(const boost::archive::object_id_type & t){} void save_override(const boost::archive::object_reference_type & t){} void save_override(const boost::archive::version_type & t){} void save_override(const boost::archive::class_id_type & t){} void save_override(const boost::archive::class_id_optional_type & t){} void save_override(const boost::archive::class_id_reference_type & t){} void save_override(const boost::archive::class_name_type & t){} void save_override(const boost::archive::tracking_type & t){} public: log_archive(std::ostream & os, unsigned int flags = 0) : boost::archive::xml_oarchive_impl( os, flags | boost::archive::no_header ) {} }; #endif // LOG_ARCHIVE_HPP ================================================ FILE: example/polymorphic_portable_binary_iarchive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_portable_binary_iarchive.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #define BOOST_ARCHIVE_SOURCE #include "polymorphic_portable_binary_iarchive.hpp" // explicitly instantiate for this type of text stream #include #include #include namespace boost { namespace archive { template class binary_iarchive_impl< polymorphic_portable_binary_iarchive, std::istream::char_type, std::istream::traits_type >; template class detail::archive_pointer_iserializer< polymorphic_portable_binary_iarchive > ; } // namespace archive } // namespace boost ================================================ FILE: example/polymorphic_portable_binary_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_portable_binary_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include "portable_binary_iarchive.hpp" typedef boost::archive::detail::polymorphic_iarchive_dispatch< portable_binary_iarchive > polymorphic_portable_binary_iarchive; #include #if BOOST_VERSION > 103401 // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( polymorphic_portable_binary_iarchive ) #endif #endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP ================================================ FILE: example/polymorphic_portable_binary_oarchive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_portable_binary_oarchive.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #define BOOST_ARCHIVE_SOURCE #include "polymorphic_portable_binary_oarchive.hpp" // explicitly instantiate for this type of text stream #include #include #include namespace boost { namespace archive { // explicitly instantiate for this type of binary stream template class binary_oarchive_impl< polymorphic_portable_binary_oarchive, std::ostream::char_type, std::ostream::traits_type >; template class detail::archive_pointer_oserializer< polymorphic_portable_binary_oarchive > ; } // namespace archive } // namespace boost ================================================ FILE: example/polymorphic_portable_binary_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_portable_binary_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include "portable_binary_oarchive.hpp" typedef boost::archive::detail::polymorphic_oarchive_dispatch< portable_binary_oarchive > polymorphic_portable_binary_oarchive; #include #if BOOST_VERSION > 103401 // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( polymorphic_portable_binary_oarchive ) #endif #endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP ================================================ FILE: example/portable_binary_archive.hpp ================================================ #ifndef PORTABLE_BINARY_ARCHIVE_HPP #define PORTABLE_BINARY_ARCHIVE_HPP // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #if CHAR_BIT != 8 #error This code assumes an eight-bit byte. #endif #include #include enum portable_binary_archive_flags { endian_big = 0x4000, endian_little = 0x8000 }; //#if ( endian_big <= boost::archive::flags_last ) //#error archive flags conflict //#endif inline void reverse_bytes(char size, char *address){ char * first = address; char * last = first + size - 1; for(;first < last;++first, --last){ char x = *last; *last = *first; *first = x; } } #endif // PORTABLE_BINARY_ARCHIVE_HPP ================================================ FILE: example/portable_binary_iarchive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // portable_binary_iarchive.cpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include "portable_binary_iarchive.hpp" void portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){ char size; l = 0; this->primitive_base_t::load(size); if(0 == size){ return; } bool negative = (size < 0); if(negative) size = -size; if(size > maxsize) boost::serialization::throw_exception( portable_binary_iarchive_exception() ); char * cptr = reinterpret_cast(& l); #if BOOST_ENDIAN_BIG_BYTE cptr += (sizeof(boost::intmax_t) - size); #endif this->primitive_base_t::load_binary(cptr, size); #if BOOST_ENDIAN_BIG_BYTE if(m_flags & endian_little) #else if(m_flags & endian_big) #endif reverse_bytes(size, cptr); if(negative) l = -l; } void portable_binary_iarchive::load_override( boost::archive::class_name_type & t ){ std::string cn; cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); load_override(cn); if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::invalid_class_name) ); std::memcpy(t, cn.data(), cn.size()); // borland tweak t.t[cn.size()] = '\0'; } void portable_binary_iarchive::init(unsigned int flags){ if(0 == (flags & boost::archive::no_header)){ // read signature in an archive version independent manner std::string file_signature; * this >> file_signature; if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE()) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::invalid_signature ) ); // make sure the version of the reading archive library can // support the format of the archive being read boost::archive::library_version_type input_library_version; * this >> input_library_version; // extra little .t is to get around borland quirk if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::unsupported_version ) ); #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) this->set_library_version(input_library_version); //#else //#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200) //detail:: //#endif boost::archive::detail::basic_iarchive::set_library_version( input_library_version ); #endif } unsigned char x; load(x); m_flags = x << CHAR_BIT; } #include #include namespace boost { namespace archive { namespace detail { template class archive_serializer_map; } template class basic_binary_iprimitive< portable_binary_iarchive, std::istream::char_type, std::istream::traits_type > ; } // namespace archive } // namespace boost ================================================ FILE: example/portable_binary_iarchive.hpp ================================================ #ifndef PORTABLE_BINARY_IARCHIVE_HPP #define PORTABLE_BINARY_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 ) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // portable_binary_iarchive.hpp // (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include #include "portable_binary_archive.hpp" /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // exception to be thrown if integer read from archive doesn't fit // variable being loaded class portable_binary_iarchive_exception : public boost::archive::archive_exception { public: enum exception_code { incompatible_integer_size } m_exception_code ; portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) : boost::archive::archive_exception(boost::archive::archive_exception::other_exception), m_exception_code(c) {} virtual const char *what( ) const throw( ) { const char *msg = "programmer error"; switch(m_exception_code){ case incompatible_integer_size: msg = "integer cannot be represented"; break; default: msg = boost::archive::archive_exception::what(); assert(false); break; } return msg; } }; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // "Portable" input binary archive. It addresses integer size and endianness so // that binary archives can be passed across systems. Note:floating point types // not addressed here class portable_binary_iarchive : public boost::archive::basic_binary_iprimitive< portable_binary_iarchive, std::istream::char_type, std::istream::traits_type >, public boost::archive::detail::common_iarchive< portable_binary_iarchive > { typedef boost::archive::basic_binary_iprimitive< portable_binary_iarchive, std::istream::char_type, std::istream::traits_type > primitive_base_t; typedef boost::archive::detail::common_iarchive< portable_binary_iarchive > archive_base_t; #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else friend archive_base_t; friend primitive_base_t; // since with override load below friend class boost::archive::detail::interface_iarchive< portable_binary_iarchive >; friend class boost::archive::load_access; protected: #endif unsigned int m_flags; void load_impl(boost::intmax_t & l, char maxsize); // default fall through for any types not specified here template void load(T & t){ boost::intmax_t l; load_impl(l, sizeof(T)); // use cast to avoid compile time warning //t = static_cast< T >(l); t = T(l); } void load(boost::serialization::item_version_type & t){ boost::intmax_t l; load_impl(l, sizeof(boost::serialization::item_version_type)); // use cast to avoid compile time warning t = boost::serialization::item_version_type(l); } void load(boost::archive::version_type & t){ boost::intmax_t l; load_impl(l, sizeof(boost::archive::version_type)); // use cast to avoid compile time warning t = boost::archive::version_type(l); } void load(boost::archive::class_id_type & t){ boost::intmax_t l; load_impl(l, sizeof(boost::archive::class_id_type)); // use cast to avoid compile time warning t = boost::archive::class_id_type(static_cast(l)); } void load(std::string & t){ this->primitive_base_t::load(t); } #ifndef BOOST_NO_STD_WSTRING void load(std::wstring & t){ this->primitive_base_t::load(t); } #endif void load(float & t){ this->primitive_base_t::load(t); // floats not supported //BOOST_STATIC_ASSERT(false); } void load(double & t){ this->primitive_base_t::load(t); // doubles not supported //BOOST_STATIC_ASSERT(false); } void load(char & t){ this->primitive_base_t::load(t); } void load(unsigned char & t){ this->primitive_base_t::load(t); } typedef boost::archive::detail::common_iarchive detail_common_iarchive; template void load_override(T & t){ this->detail_common_iarchive::load_override(t); } void load_override(boost::archive::class_name_type & t); // binary files don't include the optional information void load_override(boost::archive::class_id_optional_type &){} void init(unsigned int flags); public: portable_binary_iarchive(std::istream & is, unsigned flags = 0) : primitive_base_t( * is.rdbuf(), 0 != (flags & boost::archive::no_codecvt) ), archive_base_t(flags), m_flags(0) { init(flags); } portable_binary_iarchive( std::basic_streambuf< std::istream::char_type, std::istream::traits_type > & bsb, unsigned int flags ) : primitive_base_t( bsb, 0 != (flags & boost::archive::no_codecvt) ), archive_base_t(flags), m_flags(0) { init(flags); } }; // required by export in boost version > 1.34 #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive) #endif // required by export in boost <= 1.34 #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive #if defined(_MSC_VER) #pragma warning( pop ) #endif #endif // PORTABLE_BINARY_IARCHIVE_HPP ================================================ FILE: example/portable_binary_oarchive.cpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // portable_binary_oarchive.cpp // (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include "portable_binary_oarchive.hpp" void portable_binary_oarchive::save_impl( const boost::intmax_t l, const char maxsize ){ char size = 0; if(l == 0){ this->primitive_base_t::save(size); return; } boost::intmax_t ll; bool negative = (l < 0); if(negative) ll = -l; else ll = l; do{ ll >>= CHAR_BIT; ++size; }while(ll != 0); this->primitive_base_t::save( static_cast(negative ? -size : size) ); if(negative) ll = -l; else ll = l; char * cptr = reinterpret_cast(& ll); #if BOOST_ENDIAN_BIG_BYTE cptr += (sizeof(boost::intmax_t) - size); if(m_flags & endian_little) reverse_bytes(size, cptr); #else if(m_flags & endian_big) reverse_bytes(size, cptr); #endif this->primitive_base_t::save_binary(cptr, size); } void portable_binary_oarchive::init(unsigned int flags) { if(m_flags == (endian_big | endian_little)){ boost::serialization::throw_exception( portable_binary_oarchive_exception() ); } if(0 == (flags & boost::archive::no_header)){ // write signature in an archive version independent manner const std::string file_signature( boost::archive::BOOST_ARCHIVE_SIGNATURE() ); * this << file_signature; // write library version const boost::archive::library_version_type v( boost::archive::BOOST_ARCHIVE_VERSION() ); * this << v; } save(static_cast(m_flags >> CHAR_BIT)); } #include #include namespace boost { namespace archive { namespace detail { template class archive_serializer_map; } template class basic_binary_oprimitive< portable_binary_oarchive, std::ostream::char_type, std::ostream::traits_type > ; } // namespace archive } // namespace boost ================================================ FILE: example/portable_binary_oarchive.hpp ================================================ #ifndef PORTABLE_BINARY_OARCHIVE_HPP #define PORTABLE_BINARY_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 ) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // portable_binary_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // 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 #include #include #include #include #include #include "portable_binary_archive.hpp" /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // exception to be thrown if integer read from archive doesn't fit // variable being loaded class portable_binary_oarchive_exception : public boost::archive::archive_exception { public: typedef enum { invalid_flags } exception_code; portable_binary_oarchive_exception(exception_code c = invalid_flags ) {} virtual const char *what( ) const throw( ) { const char *msg = "programmer error"; switch(code){ case invalid_flags: msg = "cannot be both big and little endian"; default: boost::archive::archive_exception::what(); } return msg; } }; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // "Portable" output binary archive. This is a variation of the native binary // archive. it addresses integer size and endianness so that binary archives can // be passed across systems. Note:floating point types not addressed here class portable_binary_oarchive : public boost::archive::basic_binary_oprimitive< portable_binary_oarchive, std::ostream::char_type, std::ostream::traits_type >, public boost::archive::detail::common_oarchive< portable_binary_oarchive > { typedef boost::archive::basic_binary_oprimitive< portable_binary_oarchive, std::ostream::char_type, std::ostream::traits_type > primitive_base_t; typedef boost::archive::detail::common_oarchive< portable_binary_oarchive > archive_base_t; #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else friend archive_base_t; friend primitive_base_t; // since with override save below friend class boost::archive::detail::interface_oarchive< portable_binary_oarchive >; friend class boost::archive::save_access; protected: #endif unsigned int m_flags; void save_impl(const boost::intmax_t l, const char maxsize); // add base class to the places considered when matching // save function to a specific set of arguments. Note, this didn't // work on my MSVC 7.0 system so we use the sure-fire method below // using archive_base_t::save; // default fall through for any types not specified here template void save(const T & t){ save_impl(t, sizeof(T)); } void save(const std::string & t){ this->primitive_base_t::save(t); } #ifndef BOOST_NO_STD_WSTRING void save(const std::wstring & t){ this->primitive_base_t::save(t); } #endif void save(const float & t){ this->primitive_base_t::save(t); // floats not supported //BOOST_STATIC_ASSERT(false); } void save(const double & t){ this->primitive_base_t::save(t); // doubles not supported //BOOST_STATIC_ASSERT(false); } void save(const char & t){ this->primitive_base_t::save(t); } void save(const unsigned char & t){ this->primitive_base_t::save(t); } // default processing - kick back to base class. Note the // extra stuff to get it passed borland compilers typedef boost::archive::detail::common_oarchive detail_common_oarchive; template void save_override(T & t){ this->detail_common_oarchive::save_override(t); } // explicitly convert to char * to avoid compile ambiguities void save_override(const boost::archive::class_name_type & t){ const std::string s(t); * this << s; } // binary files don't include the optional information void save_override( const boost::archive::class_id_optional_type & /* t */ ){} void init(unsigned int flags); public: portable_binary_oarchive(std::ostream & os, unsigned flags = 0) : primitive_base_t( * os.rdbuf(), 0 != (flags & boost::archive::no_codecvt) ), archive_base_t(flags), m_flags(flags & (endian_big | endian_little)) { init(flags); } portable_binary_oarchive( std::basic_streambuf< std::ostream::char_type, std::ostream::traits_type > & bsb, unsigned int flags ) : primitive_base_t( bsb, 0 != (flags & boost::archive::no_codecvt) ), archive_base_t(flags), m_flags(0) { init(flags); } }; // required by export in boost version > 1.34 #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive) #endif // required by export in boost <= 1.34 #define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive #if defined(_MSC_VER) #pragma warning( pop ) #endif #endif // PORTABLE_BINARY_OARCHIVE_HPP ================================================ FILE: example/simple_log_archive.hpp ================================================ #ifndef BOOST_SIMPLE_LOG_ARCHIVE_HPP #define BOOST_SIMPLE_LOG_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // simple_log_archive.hpp // (C) Copyright 2010 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // std::size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////////////////// // log data to an output stream. This illustrates a simpler implementation // of text output which is useful for getting a formatted display of // any serializable class. Intended to be useful as a debugging aid. class simple_log_archive { std::ostream & m_os; unsigned int m_depth; template struct save_enum_type { template static void invoke(Archive &ar, const T &t){ ar.m_os << static_cast(t); } }; template struct save_primitive { template static void invoke(Archive & ar, const T & t){ ar.m_os << t; } }; template struct save_only { template static void invoke(Archive & ar, const T & t){ // make sure call is routed through the highest interface that might // be specialized by the user. boost::serialization::serialize_adl( ar, const_cast(t), ::boost::serialization::version< T >::value ); } }; template void save(const T &t){ typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if, boost::mpl::identity >, //else BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< // if its primitive boost::mpl::equal_to< boost::serialization::implementation_level< T >, boost::mpl::int_ >, boost::mpl::identity >, // else boost::mpl::identity > > >::type typex; typex::invoke(*this, t); } #ifndef BOOST_NO_STD_WSTRING void save(const std::wstring &ws){ m_os << "wide string types not supported in log archive"; } #endif public: /////////////////////////////////////////////////// // Implement requirements for archive concept typedef boost::mpl::bool_ is_loading; typedef boost::mpl::bool_ is_saving; // this can be a no-op since we ignore pointer polymorphism template void register_type(const T * = NULL){} unsigned int get_library_version(){ return 0; } void save_binary(const void *address, std::size_t count){ m_os << "save_binary not implemented"; } // the << operators template simple_log_archive & operator<<(T const & t){ m_os << ' '; save(t); return * this; } template simple_log_archive & operator<<(T * const t){ m_os << " ->"; if(NULL == t) m_os << " null"; else *this << * t; return * this; } template simple_log_archive & operator<<(const T (&t)[N]){ return *this << boost::serialization::make_array( static_cast(&t[0]), N ); } template simple_log_archive & operator<<(const boost::serialization::nvp< T > & t){ m_os << '\n'; // start line with each named object // indent according to object depth for(unsigned int i = 0; i < m_depth; ++i) m_os << ' '; ++m_depth; m_os << t.name(); // output the name of the object * this << t.const_value(); --m_depth; return * this; } // the & operator template simple_log_archive & operator&(const T & t){ return * this << t; } /////////////////////////////////////////////// simple_log_archive(std::ostream & os) : m_os(os), m_depth(0) {} }; #endif // BOOST_SIMPLE_LOG_ARCHIVE_HPP ================================================ FILE: include/boost/archive/archive_exception.hpp ================================================ #ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP #define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // archive/archive_exception.hpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // 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 #include #include #include #include // note: the only reason this is in here is that windows header // includes #define exception_code _exception_code (arrrgghhhh!). // the most expedient way to address this is be sure that this // header is always included whenever this header file is included. #if defined(BOOST_WINDOWS) #include #endif #include // must be the last header namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // exceptions thrown by archives // class BOOST_SYMBOL_VISIBLE archive_exception : public virtual std::exception { private: char m_buffer[128]; protected: BOOST_ARCHIVE_DECL unsigned int append(unsigned int l, const char * a); BOOST_ARCHIVE_DECL archive_exception() BOOST_NOEXCEPT; public: typedef enum { no_exception, // initialized without code other_exception, // any exception not listed below unregistered_class, // attempt to serialize a pointer of // an unregistered class invalid_signature, // first line of archive does not contain // expected string unsupported_version,// archive created with library version // subsequent to this one pointer_conflict, // an attempt has been made to directly // serialize an object which has // already been serialized through a pointer. // Were this permitted, the archive load would result // in the creation of an extra copy of the object. incompatible_native_format, // attempt to read native binary format // on incompatible platform array_size_too_short,// array being loaded doesn't fit in array allocated input_stream_error, // error on input stream invalid_class_name, // class name greater than the maximum permitted. // most likely a corrupted archive or an attempt // to insert virus via buffer overrun method. unregistered_cast, // base - derived relationship not registered with // void_cast_register unsupported_class_version, // type saved with a version # greater than the // one used by the program. This indicates that the program // needs to be rebuilt. multiple_code_instantiation, // code for implementing serialization for some // type has been instantiated in more than one module. output_stream_error // error on input stream } exception_code; exception_code code; BOOST_ARCHIVE_DECL archive_exception( exception_code c, const char * e1 = NULL, const char * e2 = NULL ) BOOST_NOEXCEPT; BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT; BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE; BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE; }; }// namespace archive }// namespace boost #include // pops abi_suffix.hpp pragmas #endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP ================================================ FILE: include/boost/archive/basic_archive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_archive.hpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // count #include #include #include #include #include #include #include // must be the last header namespace boost { namespace archive { #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 4267 ) #endif BOOST_ARCHIVE_DECL boost::serialization::library_version_type BOOST_ARCHIVE_VERSION(); // create alias in boost::archive for older user code. typedef boost::serialization::library_version_type library_version_type; class version_type { private: typedef uint_least32_t base_type; base_type t; public: // should be private - but MPI fails if it's not!!! version_type(): t(0) {} explicit version_type(const unsigned int & t_) : t(t_){ BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } version_type(const version_type & t_) : t(t_.t) {} version_type & operator=(const version_type & rhs){ t = rhs.t; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type & (){ return t; } bool operator==(const version_type & rhs) const { return t == rhs.t; } bool operator<(const version_type & rhs) const { return t < rhs.t; } }; class class_id_type { private: typedef int_least16_t base_type; base_type t; public: // should be private - but then can't use BOOST_STRONG_TYPE below class_id_type() : t(0) {} explicit class_id_type(const int t_) : t(t_){ BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } explicit class_id_type(const std::size_t t_) : t(t_){ // BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } class_id_type(const class_id_type & t_) : t(t_.t) {} class_id_type & operator=(const class_id_type & rhs){ t = rhs.t; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type &() { return t; } bool operator==(const class_id_type & rhs) const { return t == rhs.t; } bool operator<(const class_id_type & rhs) const { return t < rhs.t; } }; #define BOOST_SERIALIZATION_NULL_POINTER_TAG boost::archive::class_id_type(-1) class object_id_type { private: typedef uint_least32_t base_type; base_type t; public: object_id_type(): t(0) {} // note: presumes that size_t >= unsigned int. // use explicit cast to silence useless warning explicit object_id_type(const std::size_t & t_) : t(static_cast(t_)){ // make quadruple sure that we haven't lost any real integer // precision BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } object_id_type(const object_id_type & t_) : t(t_.t) {} object_id_type & operator=(const object_id_type & rhs){ t = rhs.t; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type & () { return t; } bool operator==(const object_id_type & rhs) const { return t == rhs.t; } bool operator<(const object_id_type & rhs) const { return t < rhs.t; } }; #if defined(_MSC_VER) #pragma warning( pop ) #endif struct tracking_type { bool t; explicit tracking_type(const bool t_ = false) : t(t_) {} tracking_type(const tracking_type & t_) : t(t_.t) {} operator bool () const { return t; } operator bool & () { return t; } tracking_type & operator=(const bool t_){ t = t_; return *this; } bool operator==(const tracking_type & rhs) const { return t == rhs.t; } bool operator==(const bool & rhs) const { return t == rhs; } tracking_type & operator=(const tracking_type & rhs){ t = rhs.t; return *this; } }; struct class_name_type : private boost::noncopyable { char *t; operator const char * & () const { return const_cast(t); } operator char * () { return t; } std::size_t size() const { return std::strlen(t); } explicit class_name_type(const char *key_) : t(const_cast(key_)){} explicit class_name_type(char *key_) : t(key_){} class_name_type & operator=(const class_name_type & rhs){ t = rhs.t; return *this; } }; enum archive_flags { no_header = 1, // suppress archive header info no_codecvt = 2, // suppress alteration of codecvt facet no_xml_tag_checking = 4, // suppress checking of xml tags no_tracking = 8, // suppress ALL tracking flags_last = 8 }; BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_SIGNATURE(); /* NOTE : Warning : Warning : Warning : Warning : Warning * If any of these are changed to different sized types, * binary_iarchive won't be able to read older archives * unless you rev the library version and include conditional * code based on the library version. There is nothing * inherently wrong in doing this - but you have to be super * careful because it's easy to get wrong and start breaking * old archives !!! */ #define BOOST_ARCHIVE_STRONG_TYPEDEF(T, D) \ class D : public T { \ public: \ explicit D(const T tt) : T(tt){} \ }; \ /**/ BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_reference_type) BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_optional_type) BOOST_ARCHIVE_STRONG_TYPEDEF(object_id_type, object_reference_type) }// namespace archive }// namespace boost #include // pops abi_suffix.hpp pragmas #include // set implementation level to primitive for all types // used internally by the serialization library BOOST_CLASS_IMPLEMENTATION(boost::serialization::library_version_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::version_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_reference_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_optional_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::class_name_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type) BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type) #include // set types used internally by the serialization library // to be bitwise serializable BOOST_IS_BITWISE_SERIALIZABLE(boost::serialization::library_version_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::version_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_reference_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_optional_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_name_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_id_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_reference_type) BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::tracking_type) #endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_binary_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_iarchive.hpp // // archives stored as native binary - this should be the fastest way // to archive the state of a group of objects. It makes no attempt to // convert to any canonical form. // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE // ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON // (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 #include #include #include #include #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif #include // must be the last header namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail ///////////////////////////////////////////////////////////////////////// // class basic_binary_iarchive - read serialized objects from a input binary stream template class BOOST_SYMBOL_VISIBLE basic_binary_iarchive : public detail::common_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_iarchive; #else friend class detail::interface_iarchive; #endif #endif // intermediate level to support override of operators // fot templates in the absence of partial function // template ordering. If we get here pass to base class // note extra nonsense to sneak it pass the borland compilers typedef detail::common_iarchive detail_common_iarchive; template void load_override(T & t){ this->detail_common_iarchive::load_override(t); } // include these to trap a change in binary format which // isn't specifically handled // upto 32K classes BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); // upto 2G objects BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); // binary files don't include the optional information void load_override(class_id_optional_type & /* t */){} void load_override(tracking_type & t, int /*version*/){ boost::serialization::library_version_type lv = this->get_library_version(); if(boost::serialization::library_version_type(6) < lv){ int_least8_t x=0; * this->This() >> x; t = boost::archive::tracking_type(x); } else{ bool x=0; * this->This() >> x; t = boost::archive::tracking_type(x); } } void load_override(class_id_type & t){ boost::serialization::library_version_type lv = this->get_library_version(); /* * library versions: * boost 1.39 -> 5 * boost 1.43 -> 7 * boost 1.47 -> 9 * * * 1) in boost 1.43 and inferior, class_id_type is always a 16bit value, with no check on the library version * --> this means all archives with version v <= 7 are written with a 16bit class_id_type * 2) in boost 1.44 this load_override has disappeared (and thus boost 1.44 is not backward compatible at all !!) * 3) recent boosts reintroduced load_override with a test on the version : * - v > 7 : this->detail_common_iarchive::load_override(t, version) * - v > 6 : 16bit * - other : 32bit * --> which is obviously incorrect, see point 1 * * the fix here decodes class_id_type on 16bit for all v <= 7, which seems to be the correct behaviour ... */ if(boost::serialization::library_version_type (7) < lv){ this->detail_common_iarchive::load_override(t); } else{ int_least16_t x=0; * this->This() >> x; t = boost::archive::class_id_type(x); } } void load_override(class_id_reference_type & t){ load_override(static_cast(t)); } void load_override(version_type & t){ boost::serialization::library_version_type lv = this->get_library_version(); if(boost::serialization::library_version_type(7) < lv){ this->detail_common_iarchive::load_override(t); } else if(boost::serialization::library_version_type(6) < lv){ uint_least8_t x=0; * this->This() >> x; t = boost::archive::version_type(x); } else if(boost::serialization::library_version_type(5) < lv){ uint_least16_t x=0; * this->This() >> x; t = boost::archive::version_type(x); } else if(boost::serialization::library_version_type(2) < lv){ // upto 255 versions unsigned char x=0; * this->This() >> x; t = version_type(x); } else{ unsigned int x=0; * this->This() >> x; t = boost::archive::version_type(x); } } void load_override(boost::serialization::item_version_type & t){ boost::serialization::library_version_type lv = this->get_library_version(); // if(boost::serialization::library_version_type(7) < lvt){ if(boost::serialization::library_version_type(6) < lv){ this->detail_common_iarchive::load_override(t); } else if(boost::serialization::library_version_type(6) < lv){ uint_least16_t x=0; * this->This() >> x; t = boost::serialization::item_version_type(x); } else{ unsigned int x=0; * this->This() >> x; t = boost::serialization::item_version_type(x); } } void load_override(serialization::collection_size_type & t){ if(boost::serialization::library_version_type(5) < this->get_library_version()){ this->detail_common_iarchive::load_override(t); } else{ unsigned int x=0; * this->This() >> x; t = serialization::collection_size_type(x); } } BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(class_name_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); basic_binary_iarchive(unsigned int flags) : detail::common_iarchive(flags) {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_binary_iprimitive.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP #define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #if defined(_MSC_VER) #pragma warning( disable : 4800 ) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_iprimitive.hpp // // archives stored as native binary - this should be the fastest way // to archive the state of a group of objects. It makes no attempt to // convert to any canonical form. // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE // ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON // (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 #include #include #include // std::memcpy #include // std::size_t #include // basic_streambuf #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include #include #include // must be the last header namespace boost { namespace archive { ///////////////////////////////////////////////////////////////////////////// // class binary_iarchive - read serialized objects from a input binary stream template class BOOST_SYMBOL_VISIBLE basic_binary_iprimitive { #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS friend class load_access; protected: #else public: #endif std::basic_streambuf & m_sb; // return a pointer to the most derived class Archive * This(){ return static_cast(this); } #ifndef BOOST_NO_STD_LOCALE // note order! - if you change this, libstd++ will fail! // a) create new locale with new codecvt facet // b) save current locale // c) change locale to new one // d) use stream buffer // e) change locale back to original // f) destroy new codecvt facet boost::archive::codecvt_null codecvt_null_facet; basic_streambuf_locale_saver locale_saver; std::locale archive_locale; #endif // main template for serialization of primitive types template void load(T & t){ load_binary(& t, sizeof(T)); } ///////////////////////////////////////////////////////// // fundamental types that need special treatment // trap usage of invalid uninitialized boolean void load(bool & t){ load_binary(& t, sizeof(t)); int i = t; BOOST_ASSERT(0 == i || 1 == i); (void)i; // warning suppression for release builds. } BOOST_ARCHIVE_OR_WARCHIVE_DECL void load(std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_OR_WARCHIVE_DECL void load(std::wstring &ws); #endif BOOST_ARCHIVE_OR_WARCHIVE_DECL void load(char * t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void load(wchar_t * t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_iprimitive( std::basic_streambuf & sb, bool no_codecvt ); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_binary_iprimitive(); public: // we provide an optimized load for all fundamental types // typedef serialization::is_bitwise_serializable // use_array_optimization; struct use_array_optimization { template #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) struct apply { typedef typename boost::serialization::is_bitwise_serializable< T >::type type; }; #else struct apply : public boost::serialization::is_bitwise_serializable< T > {}; #endif }; // the optimized load_array dispatches to load_binary template void load_array(serialization::array_wrapper& a, unsigned int) { load_binary(a.address(),a.count()*sizeof(ValueType)); } void load_binary(void *address, std::size_t count); }; template inline void basic_binary_iprimitive::load_binary( void *address, std::size_t count ){ // note: an optimizer should eliminate the following for char files BOOST_ASSERT( static_cast(count / sizeof(Elem)) <= boost::integer_traits::const_max ); std::streamsize s = static_cast(count / sizeof(Elem)); std::streamsize scount = m_sb.sgetn( static_cast(address), s ); if(scount != s) boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); // note: an optimizer should eliminate the following for char files BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits::const_max); s = static_cast(count % sizeof(Elem)); if(0 < s){ // if(is.fail()) // boost::serialization::throw_exception( // archive_exception(archive_exception::stream_error) // ); Elem t; scount = m_sb.sgetn(& t, 1); if(scount != 1) boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); std::memcpy(static_cast(address) + (count - s), &t, static_cast(s)); } } } // namespace archive } // namespace boost #include // pop pragmas #endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP ================================================ FILE: include/boost/archive/basic_binary_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. // archives stored as native binary - this should be the fastest way // to archive the state of a group of objects. It makes no attempt to // convert to any canonical form. // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE // ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON #include #include #include #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail ////////////////////////////////////////////////////////////////////// // class basic_binary_oarchive - write serialized objects to a binary output stream // note: this archive has no pretensions to portability. Archive format // may vary across machine architectures and compilers. About the only // guarantee is that an archive created with this code will be readable // by a program built with the same tools for the same machine. This class // does have the virtue of building the smallest archive in the minimum amount // of time. So under some circumstances it may be he right choice. template class BOOST_SYMBOL_VISIBLE basic_binary_oarchive : public detail::common_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_oarchive; #else friend class detail::interface_oarchive; #endif #endif // any datatype not specified below will be handled by base class typedef detail::common_oarchive detail_common_oarchive; template void save_override(const T & t){ this->detail_common_oarchive::save_override(t); } // include these to trap a change in binary format which // isn't specifically handled BOOST_STATIC_ASSERT(sizeof(tracking_type) == sizeof(bool)); // upto 32K classes BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); // upto 2G objects BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); // binary files don't include the optional information void save_override(const class_id_optional_type & /* t */){} // enable this if we decide to support generation of previous versions #if 0 void save_override(const boost::archive::version_type & t){ library_version_type lvt = this->get_library_version(); if(boost::serialization::library_version_type(7) < lvt){ this->detail_common_oarchive::save_override(t); } else if(boost::serialization::library_version_type(6) < lvt){ const boost::uint_least16_t x = t; * this->This() << x; } else{ const unsigned int x = t; * this->This() << x; } } void save_override(const boost::serialization::item_version_type & t){ library_version_type lvt = this->get_library_version(); if(boost::serialization::library_version_type(7) < lvt){ this->detail_common_oarchive::save_override(t); } else if(boost::serialization::library_version_type(6) < lvt){ const boost::uint_least16_t x = t; * this->This() << x; } else{ const unsigned int x = t; * this->This() << x; } } void save_override(class_id_type & t){ library_version_type lvt = this->get_library_version(); if(boost::serialization::library_version_type(7) < lvt){ this->detail_common_oarchive::save_override(t); } else if(boost::serialization::library_version_type(6) < lvt){ const boost::int_least16_t x = t; * this->This() << x; } else{ const int x = t; * this->This() << x; } } void save_override(class_id_reference_type & t){ save_override(static_cast(t)); } #endif // explicitly convert to char * to avoid compile ambiguities void save_override(const class_name_type & t){ const std::string s(t); * this->This() << s; } #if 0 void save_override(const serialization::collection_size_type & t){ if (get_library_version() < boost::serialization::library_version_type(6)){ unsigned int x=0; * this->This() >> x; t = serialization::collection_size_type(x); } else{ * this->This() >> t; } } #endif BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); basic_binary_oarchive(unsigned int flags) : detail::common_oarchive(flags) {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_binary_oprimitive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP #define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_oprimitive.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. // archives stored as native binary - this should be the fastest way // to archive the state of a group of objects. It makes no attempt to // convert to any canonical form. // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE // ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON #include #include #include #include // basic_streambuf #include #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include #include #include #include // must be the last header namespace boost { namespace archive { ///////////////////////////////////////////////////////////////////////// // class basic_binary_oprimitive - binary output of primitives template class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive { #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS friend class save_access; protected: #else public: #endif std::basic_streambuf & m_sb; // return a pointer to the most derived class Archive * This(){ return static_cast(this); } #ifndef BOOST_NO_STD_LOCALE // note order! - if you change this, libstd++ will fail! // a) create new locale with new codecvt facet // b) save current locale // c) change locale to new one // d) use stream buffer // e) change locale back to original // f) destroy new codecvt facet boost::archive::codecvt_null codecvt_null_facet; basic_streambuf_locale_saver locale_saver; std::locale archive_locale; #endif // default saving of primitives. template void save(const T & t) { save_binary(& t, sizeof(T)); } ///////////////////////////////////////////////////////// // fundamental types that need special treatment // trap usage of invalid uninitialized boolean which would // otherwise crash on load. void save(const bool t){ BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); save_binary(& t, sizeof(t)); } BOOST_ARCHIVE_OR_WARCHIVE_DECL void save(const std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_OR_WARCHIVE_DECL void save(const std::wstring &ws); #endif BOOST_ARCHIVE_OR_WARCHIVE_DECL void save(const char * t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save(const wchar_t * t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_oprimitive( std::basic_streambuf & sb, bool no_codecvt ); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_binary_oprimitive(); public: // we provide an optimized save for all fundamental types // typedef serialization::is_bitwise_serializable // use_array_optimization; // workaround without using mpl lambdas struct use_array_optimization { template #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) struct apply { typedef typename boost::serialization::is_bitwise_serializable< T >::type type; }; #else struct apply : public boost::serialization::is_bitwise_serializable< T > {}; #endif }; // the optimized save_array dispatches to save_binary template void save_array(boost::serialization::array_wrapper const& a, unsigned int) { save_binary(a.address(),a.count()*sizeof(ValueType)); } void save_binary(const void *address, std::size_t count); }; template inline void basic_binary_oprimitive::save_binary( const void *address, std::size_t count ){ // BOOST_ASSERT(count <= std::size_t(boost::integer_traits::const_max)); // note: if the following assertions fail // a likely cause is that the output stream is set to "text" // mode where by cr characters receive special treatment. // be sure that the output stream is opened with ios::binary //if(os.fail()) // boost::serialization::throw_exception( // archive_exception(archive_exception::output_stream_error) // ); // figure number of elements to output - round up count = ( count + sizeof(Elem) - 1) / sizeof(Elem); std::streamsize scount = m_sb.sputn( static_cast(address), static_cast(count) ); if(count != static_cast(scount)) boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); //os.write( // static_cast(address), // count //); //BOOST_ASSERT(os.good()); } } //namespace boost } //namespace archive #include // pop pragmas #endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP ================================================ FILE: include/boost/archive/basic_streambuf_locale_saver.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP #define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_streambuf_locale_saver.hpp // (C) Copyright 2005 Robert Ramey - http://www.rrsd.com // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. // note derived from boost/io/ios_state.hpp // Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution // are subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or a copy at .) // See for the library's home page. #ifndef BOOST_NO_STD_LOCALE #include // for std::locale #include #include // for std::basic_streambuf #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost{ namespace archive{ template < typename Ch, class Tr > class basic_streambuf_locale_saver : private boost::noncopyable { public: explicit basic_streambuf_locale_saver(std::basic_streambuf &s) : m_streambuf(s), m_locale(s.getloc()) {} ~basic_streambuf_locale_saver(){ m_streambuf.pubsync(); m_streambuf.pubimbue(m_locale); } private: std::basic_streambuf & m_streambuf; std::locale const m_locale; }; template < typename Ch, class Tr > class basic_istream_locale_saver : private boost::noncopyable { public: explicit basic_istream_locale_saver(std::basic_istream &s) : m_istream(s), m_locale(s.getloc()) {} ~basic_istream_locale_saver(){ // libstdc++ crashes without this m_istream.sync(); m_istream.imbue(m_locale); } private: std::basic_istream & m_istream; std::locale const m_locale; }; template < typename Ch, class Tr > class basic_ostream_locale_saver : private boost::noncopyable { public: explicit basic_ostream_locale_saver(std::basic_ostream &s) : m_ostream(s), m_locale(s.getloc()) {} ~basic_ostream_locale_saver(){ m_ostream.flush(); m_ostream.imbue(m_locale); } private: std::basic_ostream & m_ostream; std::locale const m_locale; }; } // archive } // boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_NO_STD_LOCALE #endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP ================================================ FILE: include/boost/archive/basic_text_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. // archives stored as text - note these ar templated on the basic // stream templates to accommodate wide (and other?) kind of characters // // note the fact that on libraries without wide characters, ostream is // is not a specialization of basic_ostream which in fact is not defined // in such cases. So we can't use basic_istream but rather // use two template parameters #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail ///////////////////////////////////////////////////////////////////////// // class basic_text_iarchive - read serialized objects from a input text stream template class BOOST_SYMBOL_VISIBLE basic_text_iarchive : public detail::common_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile error // on msvc 7.1 friend detail::interface_iarchive; #else friend class detail::interface_iarchive; #endif #endif // intermediate level to support override of operators // fot templates in the absence of partial function // template ordering typedef detail::common_iarchive detail_common_iarchive; template void load_override(T & t){ this->detail_common_iarchive::load_override(t); } // text file don't include the optional information void load_override(class_id_optional_type & /*t*/){} BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(class_name_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); basic_text_iarchive(unsigned int flags) : detail::common_iarchive(flags) {} ~basic_text_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_text_iprimitive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP #define BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_iprimitive.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. // archives stored as text - note these are templated on the basic // stream templates to accommodate wide (and other?) kind of characters // // Note the fact that on libraries without wide characters, ostream is // not a specialization of basic_ostream which in fact is not defined // in such cases. So we can't use basic_ostream but rather // use two template parameters #include #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) using ::locale; #endif } // namespace std #endif #include #include #include #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #include #include #include #include #include // must be the last header namespace boost { namespace archive { ///////////////////////////////////////////////////////////////////////// // class basic_text_iarchive - load serialized objects from a input text stream #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 4267 ) #endif template class BOOST_SYMBOL_VISIBLE basic_text_iprimitive { protected: IStream &is; io::ios_flags_saver flags_saver; io::ios_precision_saver precision_saver; #ifndef BOOST_NO_STD_LOCALE // note order! - if you change this, libstd++ will fail! // a) create new locale with new codecvt facet // b) save current locale // c) change locale to new one // d) use stream buffer // e) change locale back to original // f) destroy new codecvt facet boost::archive::codecvt_null codecvt_null_facet; std::locale archive_locale; basic_istream_locale_saver< typename IStream::char_type, typename IStream::traits_type > locale_saver; #endif template void load(T & t) { if(is >> t) return; boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); } void load(char & t) { short int i; load(i); t = i; } void load(signed char & t) { short int i; load(i); t = i; } void load(unsigned char & t) { unsigned short int i; load(i); t = i; } #ifndef BOOST_NO_INTRINSIC_WCHAR_T void load(wchar_t & t) { BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); int i; load(i); t = i; } #endif BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_iprimitive(IStream &is, bool no_codecvt); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_text_iprimitive(); public: BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_binary(void *address, std::size_t count); }; #if defined(_MSC_VER) #pragma warning( pop ) #endif } // namespace archive } // namespace boost #include // pop pragmas #endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP ================================================ FILE: include/boost/archive/basic_text_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. // archives stored as text - note these ar templated on the basic // stream templates to accommodate wide (and other?) kind of characters // // note the fact that on libraries without wide characters, ostream is // is not a specialization of basic_ostream which in fact is not defined // in such cases. So we can't use basic_ostream but rather // use two template parameters #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail ///////////////////////////////////////////////////////////////////////// // class basic_text_oarchive template class BOOST_SYMBOL_VISIBLE basic_text_oarchive : public detail::common_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_oarchive; #else friend class detail::interface_oarchive; #endif #endif enum { none, eol, space } delimiter; BOOST_ARCHIVE_OR_WARCHIVE_DECL void newtoken(); void newline(){ delimiter = eol; } // default processing - kick back to base class. Note the // extra stuff to get it passed borland compilers typedef detail::common_oarchive detail_common_oarchive; template void save_override(T & t){ this->detail_common_oarchive::save_override(t); } // start new objects on a new line void save_override(const object_id_type & t){ this->This()->newline(); this->detail_common_oarchive::save_override(t); } // text file don't include the optional information void save_override(const class_id_optional_type & /* t */){} void save_override(const class_name_type & t){ const std::string s(t); * this->This() << s; } BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); basic_text_oarchive(unsigned int flags) : detail::common_oarchive(flags), delimiter(none) {} ~basic_text_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_text_oprimitive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP #define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_oprimitive.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. // archives stored as text - note these ar templated on the basic // stream templates to accommodate wide (and other?) kind of characters // // note the fact that on libraries without wide characters, ostream is // is not a specialization of basic_ostream which in fact is not defined // in such cases. So we can't use basic_ostream but rather // use two template parameters #include #include #include // size_t #include #include #include #include #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) using ::locale; #endif } // namespace std #endif #include #include #include #include #include #include #include #include #include #include // must be the last header namespace boost { namespace archive { ///////////////////////////////////////////////////////////////////////// // class basic_text_oprimitive - output of primitives to stream template class BOOST_SYMBOL_VISIBLE basic_text_oprimitive { protected: OStream &os; io::ios_flags_saver flags_saver; io::ios_precision_saver precision_saver; #ifndef BOOST_NO_STD_LOCALE // note order! - if you change this, libstd++ will fail! // a) create new locale with new codecvt facet // b) save current locale // c) change locale to new one // d) use stream buffer // e) change locale back to original // f) destroy new codecvt facet boost::archive::codecvt_null codecvt_null_facet; std::locale archive_locale; basic_ostream_locale_saver< typename OStream::char_type, typename OStream::traits_type > locale_saver; #endif ///////////////////////////////////////////////////////// // fundamental types that need special treatment void save(const bool t){ // trap usage of invalid uninitialized boolean which would // otherwise crash on load. BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); if(os.fail()) boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); os << t; } void save(const signed char t) { save(static_cast(t)); } void save(const unsigned char t) { save(static_cast(t)); } void save(const char t) { save(static_cast(t)); } #ifndef BOOST_NO_INTRINSIC_WCHAR_T void save(const wchar_t t) { BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); save(static_cast(t)); } #endif ///////////////////////////////////////////////////////// // saving of any types not listed above template void save_impl(const T &t, boost::mpl::bool_ &){ if(os.fail()) boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); os << t; } ///////////////////////////////////////////////////////// // floating point types need even more special treatment // the following determines whether the type T is some sort // of floating point type. Note that we then assume that // the stream << operator is defined on that type - if not // we'll get a compile time error. This is meant to automatically // support synthesized types which support floating point // operations. Also it should handle compiler dependent types // such long double. Due to John Maddock. template struct is_float { typedef typename mpl::bool_< boost::is_floating_point::value || (std::numeric_limits::is_specialized && !std::numeric_limits::is_integer && !std::numeric_limits::is_exact && std::numeric_limits::max_exponent) >::type type; }; template void save_impl(const T &t, boost::mpl::bool_ &){ // must be a user mistake - can't serialize un-initialized data if(os.fail()){ boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); } // The formulae for the number of decimal digits required is given in // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf // which is derived from Kahan's paper: // www.eecs.berkeley.edu/~wkahan/ieee754status/ieee754.ps // const unsigned int digits = (std::numeric_limits::digits * 3010) / 10000; // note: I've commented out the above because I didn't get good results. e.g. // in one case I got a difference of 19 units. const unsigned int digits = #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS std::numeric_limits::max_digits10; #else std::numeric_limits::digits10 + 2; #endif os << std::setprecision(digits) << std::scientific << t; } template void save(const T & t){ typename is_float::type tf; save_impl(t, tf); } BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_oprimitive(OStream & os, bool no_codecvt); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_text_oprimitive(); public: // unformatted append of one character void put(typename OStream::char_type c){ if(os.fail()) boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); os.put(c); } // unformatted append of null terminated string void put(const char * s){ while('\0' != *s) os.put(*s++); } BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_binary(const void *address, std::size_t count); }; } //namespace boost } //namespace archive #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP ================================================ FILE: include/boost/archive/basic_xml_archive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_archive.hpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include // must be the last header namespace boost { namespace archive { // constant strings used in xml i/o extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_OBJECT_ID(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_OBJECT_REFERENCE(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_CLASS_ID(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_CLASS_NAME(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_TRACKING(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_VERSION(); extern BOOST_ARCHIVE_DECL const char * BOOST_ARCHIVE_XML_SIGNATURE(); }// namespace archive }// namespace boost #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_xml_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail ///////////////////////////////////////////////////////////////////////// // class basic_xml_iarchive - read serialized objects from a input text stream template class BOOST_SYMBOL_VISIBLE basic_xml_iarchive : public detail::common_iarchive { unsigned int depth; #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_iarchive; #endif BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_start(const char *name); BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_end(const char *name); // Anything not an attribute and not a name-value pair is an // should be trapped here. template void load_override(T & t) { // If your program fails to compile here, its most likely due to // not specifying an nvp wrapper around the variable to // be serialized. BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); this->detail_common_iarchive::load_override(t); } // Anything not an attribute - see below - should be a name value // pair and be processed here typedef detail::common_iarchive detail_common_iarchive; template void load_override( const boost::serialization::nvp< T > & t ){ this->This()->load_start(t.name()); this->detail_common_iarchive::load_override(t.value()); this->This()->load_end(t.name()); } // specific overrides for attributes - handle as // primitives. These are not name-value pairs // so they have to be intercepted here and passed on to load. // although the class_id is included in the xml text file in order // to make the file self describing, it isn't used when loading // an xml archive. So we can skip it here. Note: we MUST override // it otherwise it will be loaded as a normal primitive w/o tag and // leaving the archive in an undetermined state BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(class_id_type & t); void load_override(class_id_optional_type & /* t */){} BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(object_id_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(version_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void load_override(tracking_type & t); // class_name_type can't be handled here as it depends upon the // char type used by the stream. So require the derived implementation // handle this. // void load_override(class_name_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_iarchive(unsigned int flags); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_xml_iarchive() BOOST_OVERRIDE; }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP ================================================ FILE: include/boost/archive/basic_xml_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail ////////////////////////////////////////////////////////////////////// // class basic_xml_oarchive - write serialized objects to a xml output stream template class BOOST_SYMBOL_VISIBLE basic_xml_oarchive : public detail::common_oarchive { // special stuff for xml output unsigned int depth; bool pending_preamble; #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_oarchive; #endif bool indent_next; BOOST_ARCHIVE_OR_WARCHIVE_DECL void indent(); BOOST_ARCHIVE_OR_WARCHIVE_DECL void init(); BOOST_ARCHIVE_OR_WARCHIVE_DECL void windup(); BOOST_ARCHIVE_OR_WARCHIVE_DECL void write_attribute( const char *attribute_name, int t, const char *conjunction = "=\"" ); BOOST_ARCHIVE_OR_WARCHIVE_DECL void write_attribute( const char *attribute_name, const char *key ); // helpers used below BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_start(const char *name); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_end(const char *name); BOOST_ARCHIVE_OR_WARCHIVE_DECL void end_preamble(); // Anything not an attribute and not a name-value pair is an // error and should be trapped here. template void save_override(T & t) { // If your program fails to compile here, its most likely due to // not specifying an nvp wrapper around the variable to // be serialized. BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); this->detail_common_oarchive::save_override(t); } // special treatment for name-value pairs. typedef detail::common_oarchive detail_common_oarchive; template void save_override( const ::boost::serialization::nvp< T > & t ){ this->This()->save_start(t.name()); this->detail_common_oarchive::save_override(t.const_value()); this->This()->save_end(t.name()); } // specific overrides for attributes - not name value pairs so we // want to trap them before the above "fall through" BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const class_id_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const class_id_optional_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const class_id_reference_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const object_id_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const object_reference_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const version_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const class_name_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL void save_override(const tracking_type & t); BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_oarchive(unsigned int flags); BOOST_ARCHIVE_OR_WARCHIVE_DECL ~basic_xml_oarchive() BOOST_OVERRIDE; }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP ================================================ FILE: include/boost/archive/binary_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_HPP #define BOOST_ARCHIVE_BINARY_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { // do not derive from this class. If you want to extend this functionality // via inheritance, derived from binary_iarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE binary_iarchive : public binary_iarchive_impl< boost::archive::binary_iarchive, std::istream::char_type, std::istream::traits_type >{ public: binary_iarchive(std::istream & is, unsigned int flags = 0) : binary_iarchive_impl< binary_iarchive, std::istream::char_type, std::istream::traits_type >(is, flags) { init(flags); } binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : binary_iarchive_impl< binary_iarchive, std::istream::char_type, std::istream::traits_type >(bsb, flags) { init(flags); } }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive) BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP ================================================ FILE: include/boost/archive/binary_iarchive_impl.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP #define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_iarchive_impl.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE binary_iarchive_impl : public basic_binary_iprimitive, public basic_binary_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_iarchive; friend basic_binary_iarchive; friend load_access; #else friend class detail::interface_iarchive; friend class basic_binary_iarchive; friend class load_access; #endif #endif template void load_override(T & t){ this->basic_binary_iarchive::load_override(t); } void init(unsigned int flags){ if(0 != (flags & no_header)){ return; } #if ! defined(__MWERKS__) this->basic_binary_iarchive::init(); this->basic_binary_iprimitive::init(); #else basic_binary_iarchive::init(); basic_binary_iprimitive::init(); #endif } binary_iarchive_impl( std::basic_streambuf & bsb, unsigned int flags ) : basic_binary_iprimitive( bsb, 0 != (flags & no_codecvt) ), basic_binary_iarchive(flags) {} binary_iarchive_impl( std::basic_istream & is, unsigned int flags ) : basic_binary_iprimitive( * is.rdbuf(), 0 != (flags & no_codecvt) ), basic_binary_iarchive(flags) {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP ================================================ FILE: include/boost/archive/binary_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_HPP #define BOOST_ARCHIVE_BINARY_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { // do not derive from this class. If you want to extend this functionality // via inheritance, derived from binary_oarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE binary_oarchive : public binary_oarchive_impl< binary_oarchive, std::ostream::char_type, std::ostream::traits_type > { public: binary_oarchive(std::ostream & os, unsigned int flags = 0) : binary_oarchive_impl< binary_oarchive, std::ostream::char_type, std::ostream::traits_type >(os, flags) { init(flags); } binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : binary_oarchive_impl< binary_oarchive, std::ostream::char_type, std::ostream::traits_type >(bsb, flags) { init(flags); } }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive) BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_oarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP ================================================ FILE: include/boost/archive/binary_oarchive_impl.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP #define BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_oarchive_impl.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE binary_oarchive_impl : public basic_binary_oprimitive, public basic_binary_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_oarchive; friend basic_binary_oarchive; friend save_access; #else friend class detail::interface_oarchive; friend class basic_binary_oarchive; friend class save_access; #endif #endif template void save_override(T & t){ this->basic_binary_oarchive::save_override(t); } void init(unsigned int flags) { if(0 != (flags & no_header)){ return; } #if ! defined(__MWERKS__) this->basic_binary_oarchive::init(); this->basic_binary_oprimitive::init(); #else basic_binary_oarchive::init(); basic_binary_oprimitive::init(); #endif } binary_oarchive_impl( std::basic_streambuf & bsb, unsigned int flags ) : basic_binary_oprimitive( bsb, 0 != (flags & no_codecvt) ), basic_binary_oarchive(flags) {} binary_oarchive_impl( std::basic_ostream & os, unsigned int flags ) : basic_binary_oprimitive( * os.rdbuf(), 0 != (flags & no_codecvt) ), basic_binary_oarchive(flags) {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP ================================================ FILE: include/boost/archive/binary_wiarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP #define BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_wiarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include // wistream #include #include namespace boost { namespace archive { class binary_wiarchive : public binary_iarchive_impl< binary_wiarchive, std::wistream::char_type, std::wistream::traits_type > { public: binary_wiarchive(std::wistream & is, unsigned int flags = 0) : binary_iarchive_impl< binary_wiarchive, std::wistream::char_type, std::wistream::traits_type >(is, flags) {} binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : binary_iarchive_impl< binary_wiarchive, std::wistream::char_type, std::wistream::traits_type >(bsb, flags) {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP ================================================ FILE: include/boost/archive/binary_woarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP #define BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_woarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include #include namespace boost { namespace archive { // do not derive from this class. If you want to extend this functionality // via inheritance, derived from binary_oarchive_impl instead. This will // preserve correct static polymorphism. class binary_woarchive : public binary_oarchive_impl< binary_woarchive, std::wostream::char_type, std::wostream::traits_type > { public: binary_woarchive(std::wostream & os, unsigned int flags = 0) : binary_oarchive_impl< binary_woarchive, std::wostream::char_type, std::wostream::traits_type >(os, flags) {} binary_woarchive(std::wstreambuf & bsb, unsigned int flags = 0) : binary_oarchive_impl< binary_woarchive, std::wostream::char_type, std::wostream::traits_type >(bsb, flags) {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP ================================================ FILE: include/boost/archive/codecvt_null.hpp ================================================ #ifndef BOOST_ARCHIVE_CODECVT_NULL_HPP #define BOOST_ARCHIVE_CODECVT_NULL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // codecvt_null.hpp: // (C) Copyright 2004 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 #include // NULL, size_t #ifndef BOOST_NO_CWCHAR #include // for mbstate_t #endif #include #include #include //#include // must be the last header #if defined(BOOST_NO_STDC_NAMESPACE) namespace std { // For STLport on WinCE, BOOST_NO_STDC_NAMESPACE can get defined if STLport is putting symbols in its own namespace. // In the case of codecvt, however, this does not mean that codecvt is in the global namespace (it will be in STLport's namespace) # if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) using ::codecvt; # endif using ::mbstate_t; using ::size_t; } // namespace #endif #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { template class codecvt_null; template<> class codecvt_null : public std::codecvt { bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return true; } public: explicit codecvt_null(std::size_t no_locale_manage = 0) : std::codecvt(no_locale_manage) {} ~codecvt_null() BOOST_OVERRIDE {} }; template<> class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt { BOOST_SYMBOL_EXPORT std::codecvt_base::result do_out( std::mbstate_t & state, const wchar_t * first1, const wchar_t * last1, const wchar_t * & next1, char * first2, char * last2, char * & next2 ) const BOOST_OVERRIDE; BOOST_SYMBOL_EXPORT std::codecvt_base::result do_in( std::mbstate_t & state, const char * first1, const char * last1, const char * & next1, wchar_t * first2, wchar_t * last2, wchar_t * & next2 ) const BOOST_OVERRIDE; BOOST_SYMBOL_EXPORT int do_encoding( ) const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return sizeof(wchar_t) / sizeof(char); } BOOST_SYMBOL_EXPORT bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return false; } BOOST_SYMBOL_EXPORT int do_max_length( ) const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return do_encoding(); } public: BOOST_SYMBOL_EXPORT explicit codecvt_null(std::size_t no_locale_manage = 0); BOOST_SYMBOL_EXPORT ~codecvt_null() BOOST_OVERRIDE ; }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC # pragma warning(pop) #endif //#include // pop pragmas #endif //BOOST_ARCHIVE_CODECVT_NULL_HPP ================================================ FILE: include/boost/archive/detail/abi_prefix.hpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // abi_prefix.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 // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275) #endif ================================================ FILE: include/boost/archive/detail/abi_suffix.hpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // abi_suffix.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. #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas ================================================ FILE: include/boost/archive/detail/archive_serializer_map.hpp ================================================ #ifndef BOOST_ARCHIVE_SERIALIZER_MAP_HPP #define BOOST_ARCHIVE_SERIALIZER_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // archive_serializer_map.hpp: extension of type_info required for // serialization. // (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) // See http://www.boost.org for updates, documentation, and revision history. // note: this is nothing more than the thinnest of wrappers around // basic_serializer_map so we can have a one map / archive type. #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_serializer; template class BOOST_SYMBOL_VISIBLE archive_serializer_map { public: static BOOST_ARCHIVE_OR_WARCHIVE_DECL bool insert(const basic_serializer * bs); static BOOST_ARCHIVE_OR_WARCHIVE_DECL void erase(const basic_serializer * bs); static BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * find( const boost::serialization::extended_type_info & type_ ); }; } // namespace detail } // namespace archive } // namespace boost #include // must be the last header #endif //BOOST_ARCHIVE_SERIALIZER_MAP_HPP ================================================ FILE: include/boost/archive/detail/auto_link_archive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // auto_link_archive.hpp // // (c) Copyright Robert Ramey 2004 // 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 library home page at http://www.boost.org/libs/serialization //----------------------------------------------------------------------------// // This header implements separate compilation features as described in // http://www.boost.org/more/separate_compilation.html // enable automatic library variant selection ------------------------------// #include #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ && !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ && !defined(BOOST_SERIALIZATION_SOURCE) // Set the name of our library, this will get undef'ed by auto_link.hpp // once it's done with it: // #define BOOST_LIB_NAME boost_serialization // // If we're importing code from a dll, then tell auto_link.hpp about it: // #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) # define BOOST_DYN_LINK #endif // // And include the header that does the work: // #include #endif // auto-linking disabled #endif // BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/auto_link_warchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // auto_link_warchive.hpp // // (c) Copyright Robert Ramey 2004 // 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 library home page at http://www.boost.org/libs/serialization //----------------------------------------------------------------------------// // This header implements separate compilation features as described in // http://www.boost.org/more/separate_compilation.html // enable automatic library variant selection ------------------------------// #include #if !defined(BOOST_WARCHIVE_SOURCE) \ && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) // Set the name of our library, this will get undef'ed by auto_link.hpp // once it's done with it: // #define BOOST_LIB_NAME boost_wserialization // // If we're importing code from a dll, then tell auto_link.hpp about it: // #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) # define BOOST_DYN_LINK #endif // // And include the header that does the work: // #include #endif // auto-linking disabled #endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/basic_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_iarchive.hpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. // can't use this - much as I'd like to as borland doesn't support it #include #include #include #include #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_iarchive_impl; class basic_iserializer; class basic_pointer_iserializer; ////////////////////////////////////////////////////////////////////// // class basic_iarchive - read serialized objects from a input stream class BOOST_SYMBOL_VISIBLE basic_iarchive : private boost::noncopyable, public boost::archive::detail::helper_collection { friend class basic_iarchive_impl; // hide implementation of this class to minimize header conclusion boost::scoped_ptr pimpl; virtual void vload(version_type &t) = 0; virtual void vload(object_id_type &t) = 0; virtual void vload(class_id_type &t) = 0; virtual void vload(class_id_optional_type &t) = 0; virtual void vload(class_name_type &t) = 0; virtual void vload(tracking_type &t) = 0; protected: BOOST_ARCHIVE_DECL basic_iarchive(unsigned int flags); boost::archive::detail::helper_collection & get_helper_collection(){ return *this; } public: // some msvc versions require that the following function be public // otherwise it should really protected. virtual BOOST_ARCHIVE_DECL ~basic_iarchive(); // note: NOT part of the public API. BOOST_ARCHIVE_DECL void next_object_pointer(void *t); BOOST_ARCHIVE_DECL void register_basic_serializer( const basic_iserializer & bis ); BOOST_ARCHIVE_DECL void load_object( void *t, const basic_iserializer & bis ); BOOST_ARCHIVE_DECL const basic_pointer_iserializer * load_pointer( void * & t, const basic_pointer_iserializer * bpis_ptr, const basic_pointer_iserializer * (*finder)( const boost::serialization::extended_type_info & eti ) ); // real public API starts here BOOST_ARCHIVE_DECL void set_library_version(boost::serialization::library_version_type archive_library_version); BOOST_ARCHIVE_DECL boost::serialization::library_version_type get_library_version() const; BOOST_ARCHIVE_DECL unsigned int get_flags() const; BOOST_ARCHIVE_DECL void reset_object_address(const void * new_address, const void * old_address); BOOST_ARCHIVE_DECL void delete_created_pointers(); }; } // namespace detail } // namespace archive } // namespace boost #include // pops abi_suffix.hpp pragmas #endif //BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/basic_iserializer.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP #define BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_iserializer.hpp: extension of type_info required for serialization. // (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 // NULL #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace serialization { class extended_type_info; } // namespace serialization // forward declarations namespace archive { namespace detail { class basic_iarchive; class basic_pointer_iserializer; class BOOST_SYMBOL_VISIBLE basic_iserializer : public basic_serializer { private: basic_pointer_iserializer *m_bpis; protected: explicit BOOST_ARCHIVE_DECL basic_iserializer( const boost::serialization::extended_type_info & type ); virtual BOOST_ARCHIVE_DECL ~basic_iserializer(); public: bool serialized_as_pointer() const { return m_bpis != NULL; } void set_bpis(basic_pointer_iserializer *bpis){ m_bpis = bpis; } const basic_pointer_iserializer * get_bpis_ptr() const { return m_bpis; } virtual void load_object_data( basic_iarchive & ar, void *x, const unsigned int file_version ) const = 0; // returns true if class_info should be saved virtual bool class_info() const = 0 ; // returns true if objects should be tracked virtual bool tracking(const unsigned int) const = 0 ; // returns class version virtual version_type version() const = 0 ; // returns true if this class is polymorphic virtual bool is_polymorphic() const = 0; virtual void destroy(/*const*/ void *address) const = 0 ; }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/basic_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_OARCHIVE_HPP #define BOOST_ARCHIVE_BASIC_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_oarchive.hpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // NULL #include #include #include #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_oarchive_impl; class basic_oserializer; class basic_pointer_oserializer; ////////////////////////////////////////////////////////////////////// // class basic_oarchive - write serialized objects to an output stream class BOOST_SYMBOL_VISIBLE basic_oarchive : private boost::noncopyable, public boost::archive::detail::helper_collection { friend class basic_oarchive_impl; // hide implementation of this class to minimize header conclusion boost::scoped_ptr pimpl; // overload these to bracket object attributes. Used to implement // xml archives virtual void vsave(const version_type t) = 0; virtual void vsave(const object_id_type t) = 0; virtual void vsave(const object_reference_type t) = 0; virtual void vsave(const class_id_type t) = 0; virtual void vsave(const class_id_optional_type t) = 0; virtual void vsave(const class_id_reference_type t) = 0; virtual void vsave(const class_name_type & t) = 0; virtual void vsave(const tracking_type t) = 0; protected: BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0); BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection & get_helper_collection(); virtual BOOST_ARCHIVE_DECL ~basic_oarchive(); public: // note: NOT part of the public interface BOOST_ARCHIVE_DECL void register_basic_serializer( const basic_oserializer & bos ); BOOST_ARCHIVE_DECL void save_object( const void *x, const basic_oserializer & bos ); BOOST_ARCHIVE_DECL void save_pointer( const void * t, const basic_pointer_oserializer * bpos_ptr ); void save_null_pointer(){ vsave(BOOST_SERIALIZATION_NULL_POINTER_TAG); } // real public interface starts here BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing BOOST_ARCHIVE_DECL boost::serialization::library_version_type get_library_version() const; BOOST_ARCHIVE_DECL unsigned int get_flags() const; }; } // namespace detail } // namespace archive } // namespace boost #include // pops abi_suffix.hpp pragmas #endif //BOOST_ARCHIVE_BASIC_OARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/basic_oserializer.hpp ================================================ #ifndef BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP #define BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_oserializer.hpp: extension of type_info required for serialization. // (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 // NULL #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace serialization { class extended_type_info; } // namespace serialization // forward declarations namespace archive { namespace detail { class basic_oarchive; class basic_pointer_oserializer; class BOOST_SYMBOL_VISIBLE basic_oserializer : public basic_serializer { private: basic_pointer_oserializer *m_bpos; protected: explicit BOOST_ARCHIVE_DECL basic_oserializer( const boost::serialization::extended_type_info & type_ ); virtual BOOST_ARCHIVE_DECL ~basic_oserializer(); public: bool serialized_as_pointer() const { return m_bpos != NULL; } void set_bpos(basic_pointer_oserializer *bpos){ m_bpos = bpos; } const basic_pointer_oserializer * get_bpos() const { return m_bpos; } virtual void save_object_data( basic_oarchive & ar, const void * x ) const = 0; // returns true if class_info should be saved virtual bool class_info() const = 0; // returns true if objects should be tracked virtual bool tracking(const unsigned int flags) const = 0; // returns class version virtual version_type version() const = 0; // returns true if this class is polymorphic virtual bool is_polymorphic() const = 0; }; } // namespace detail } // namespace serialization } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/basic_pointer_iserializer.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP #define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_pointer_oserializer.hpp: extension of type_info required for // serialization. // (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 #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace serialization { class extended_type_info; } // namespace serialization // forward declarations namespace archive { namespace detail { class basic_iarchive; class basic_iserializer; class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer : public basic_serializer { protected: explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer( const boost::serialization::extended_type_info & type_ ); virtual BOOST_ARCHIVE_DECL ~basic_pointer_iserializer(); public: virtual void * heap_allocation() const = 0; virtual const basic_iserializer & get_basic_serializer() const = 0; virtual void load_object_ptr( basic_iarchive & ar, void * x, const unsigned int file_version ) const = 0; }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/basic_pointer_oserializer.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP #define BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_pointer_oserializer.hpp: extension of type_info required for // serialization. // (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 #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_oarchive; class basic_oserializer; class BOOST_SYMBOL_VISIBLE basic_pointer_oserializer : public basic_serializer { protected: explicit BOOST_ARCHIVE_DECL basic_pointer_oserializer( const boost::serialization::extended_type_info & type_ ); public: virtual BOOST_ARCHIVE_DECL ~basic_pointer_oserializer(); virtual const basic_oserializer & get_basic_serializer() const = 0; virtual void save_object_ptr( basic_oarchive & ar, const void * x ) const = 0; }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/basic_serializer.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_SERIALIZER_HPP #define BOOST_ARCHIVE_BASIC_SERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_serializer.hpp: extension of type_info required for serialization. // (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 #include // NULL #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { class basic_serializer : private boost::noncopyable { const boost::serialization::extended_type_info * m_eti; protected: explicit basic_serializer( const boost::serialization::extended_type_info & eti ) : m_eti(& eti) {} public: inline bool operator<(const basic_serializer & rhs) const { // can't compare address since there can be multiple eti records // for the same type in different execution modules (that is, DLLS) // leave this here as a reminder not to do this! // return & lhs.get_eti() < & rhs.get_eti(); return get_eti() < rhs.get_eti(); } const char * get_debug_info() const { return m_eti->get_debug_info(); } const boost::serialization::extended_type_info & get_eti() const { return * m_eti; } }; class basic_serializer_arg : public basic_serializer { public: basic_serializer_arg(const serialization::extended_type_info & eti) : basic_serializer(eti) {} }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_BASIC_SERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/basic_serializer_map.hpp ================================================ #ifndef BOOST_SERIALIZER_MAP_HPP #define BOOST_SERIALIZER_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_serializer_map.hpp: extension of type_info required for serialization. // (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 #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } namespace archive { namespace detail { class basic_serializer; class BOOST_SYMBOL_VISIBLE basic_serializer_map : public boost::noncopyable { struct type_info_pointer_compare { bool operator()( const basic_serializer * lhs, const basic_serializer * rhs ) const ; }; typedef std::set< const basic_serializer *, type_info_pointer_compare > map_type; map_type m_map; public: BOOST_ARCHIVE_DECL bool insert(const basic_serializer * bs); BOOST_ARCHIVE_DECL void erase(const basic_serializer * bs); BOOST_ARCHIVE_DECL const basic_serializer * find( const boost::serialization::extended_type_info & type_ ) const; private: // cw 8.3 requires this basic_serializer_map& operator=(basic_serializer_map const&); }; } // namespace detail } // namespace archive } // namespace boost #include // must be the last header #endif // BOOST_SERIALIZER_MAP_HPP ================================================ FILE: include/boost/archive/detail/check.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_CHECK_HPP #define BOOST_ARCHIVE_DETAIL_CHECK_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #if !defined(__clang__) #pragma inline_depth(255) #pragma inline_recursion(on) #endif #endif #if defined(__MWERKS__) #pragma inline_depth(255) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // check.hpp: interface for serialization system. // (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) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace archive { namespace detail { // checks for objects template inline void check_object_level(){ typedef typename mpl::greater_equal< serialization::implementation_level< T >, mpl::int_ >::type typex; // trap attempts to serialize objects marked // not_serializable BOOST_STATIC_ASSERT(typex::value); } template inline void check_object_versioning(){ typedef typename mpl::or_< typename mpl::greater< serialization::implementation_level< T >, mpl::int_ >, typename mpl::equal_to< serialization::version< T >, mpl::int_<0> > > typex; // trap attempts to serialize with objects that don't // save class information in the archive with versioning. BOOST_STATIC_ASSERT(typex::value); } template inline void check_object_tracking(){ // presume it has already been determined that // T is not a const BOOST_STATIC_ASSERT(! boost::is_const< T >::value); typedef typename mpl::equal_to< serialization::tracking_level< T >, mpl::int_ >::type typex; // saving an non-const object of a type not marked "track_never) // may be an indicator of an error usage of the // serialization library and should be double checked. // See documentation on object tracking. Also, see the // "rationale" section of the documentation // for motivation for this checking. BOOST_STATIC_WARNING(typex::value); } // checks for pointers template inline void check_pointer_level(){ // we should only invoke this once we KNOW that T // has been used as a pointer!! typedef typename mpl::or_< typename mpl::greater< serialization::implementation_level< T >, mpl::int_ >, typename mpl::not_< typename mpl::equal_to< serialization::tracking_level< T >, mpl::int_ > > > typex; // Address the following when serializing to a pointer: // a) This type doesn't save class information in the // archive. That is, the serialization trait implementation // level <= object_serializable. // b) 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 // but rather the existence of the operation ar >> T * is used to // infer that an object of this type should be tracked. So, if // you save via a pointer but don't load via a pointer the operation // will fail on load without given any valid reason for the failure. // So if your program traps here, consider changing the // tracking or implementation level traits - or not // serializing via a pointer. BOOST_STATIC_WARNING(typex::value); } template void inline check_pointer_tracking(){ typedef typename mpl::greater< serialization::tracking_level< T >, mpl::int_ >::type typex; // serializing an object of a type marked "track_never" through a pointer // could result in creating more objects than were saved! BOOST_STATIC_WARNING(typex::value); } template inline void check_const_loading(){ typedef typename mpl::or_< typename boost::serialization::is_wrapper< T >, typename mpl::not_< typename boost::is_const< T > > >::type typex; // cannot load data into a "const" object unless it's a // wrapper around some other non-const object. BOOST_STATIC_ASSERT(typex::value); } } // detail } // archive } // boost #endif // BOOST_ARCHIVE_DETAIL_CHECK_HPP ================================================ FILE: include/boost/archive/detail/common_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // common_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { class extended_type_info; // note: referred to as Curiously Recurring Template Patter (CRTP) template class BOOST_SYMBOL_VISIBLE common_iarchive : public basic_iarchive, public interface_iarchive { friend class interface_iarchive; friend class basic_iarchive; private: void vload(version_type & t) BOOST_OVERRIDE { * this->This() >> t; } void vload(object_id_type & t) BOOST_OVERRIDE { * this->This() >> t; } void vload(class_id_type & t) BOOST_OVERRIDE { * this->This() >> t; } void vload(class_id_optional_type & t) BOOST_OVERRIDE { * this->This() >> t; } void vload(tracking_type & t) BOOST_OVERRIDE { * this->This() >> t; } void vload(class_name_type &s) BOOST_OVERRIDE { * this->This() >> s; } protected: // default processing - invoke serialization library template void load_override(T & t){ archive::load(* this->This(), t); } // default implementations of functions which emit start/end tags for // archive types that require them. void load_start(const char * /*name*/){} void load_end(const char * /*name*/){} // default archive initialization common_iarchive(unsigned int flags = 0) : basic_iarchive(flags), interface_iarchive() {} }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/common_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // common_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { // note: referred to as Curiously Recurring Template Patter (CRTP) template class BOOST_SYMBOL_VISIBLE common_oarchive : public basic_oarchive, public interface_oarchive { friend class interface_oarchive; friend class basic_oarchive; private: void vsave(const version_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const object_id_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const object_reference_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const class_id_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const class_id_reference_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const class_id_optional_type t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const class_name_type & t) BOOST_OVERRIDE { * this->This() << t; } void vsave(const tracking_type t) BOOST_OVERRIDE { * this->This() << t; } protected: // default processing - invoke serialization library template void save_override(T & t){ archive::save(* this->This(), t); } void save_start(const char * /*name*/){} void save_end(const char * /*name*/){} common_oarchive(unsigned int flags = 0) : basic_oarchive(flags), interface_oarchive() {} }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/decl.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP #define BOOST_ARCHIVE_DETAIL_DECL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 // decl.hpp // // (c) Copyright Robert Ramey 2004 // 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 library home page at http://www.boost.org/libs/serialization //----------------------------------------------------------------------------// // This header implements separate compilation features as described in // http://www.boost.org/more/separate_compilation.html #include #if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) #if defined(BOOST_ARCHIVE_SOURCE) #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT #else #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT #endif #if defined(BOOST_WARCHIVE_SOURCE) #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT #else #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT #endif #if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE) #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT #else #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT #endif #endif #if ! defined(BOOST_ARCHIVE_DECL) #define BOOST_ARCHIVE_DECL #endif #if ! defined(BOOST_WARCHIVE_DECL) #define BOOST_WARCHIVE_DECL #endif #if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) #define BOOST_ARCHIVE_OR_WARCHIVE_DECL #endif #endif // BOOST_ARCHIVE_DETAIL_DECL_HPP ================================================ FILE: include/boost/archive/detail/helper_collection.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP #define BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // helper_collection.hpp: archive support for run-time helpers // (C) Copyright 2002-2008 Robert Ramey and Joaquin M Lopez Munoz // 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 // NULL #include #include #include #include #include #include #include namespace boost { namespace archive { namespace detail { class helper_collection { helper_collection(const helper_collection&); // non-copyable helper_collection& operator = (const helper_collection&); // non-copyable // note: we dont' actually "share" the function object pointer // we only use shared_ptr to make sure that it get's deleted typedef std::pair< const void *, boost::shared_ptr > helper_value_type; template boost::shared_ptr make_helper_ptr(){ // use boost::shared_ptr rather than std::shared_ptr to maintain // c++03 compatibility return boost::make_shared(); } typedef std::vector collection; collection m_collection; struct predicate { BOOST_DEFAULTED_FUNCTION(predicate(const predicate& rhs), : m_ti(rhs.m_ti) {}) BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs)) public: const void * const m_ti; bool operator()(helper_value_type const &rhs){ return m_ti == rhs.first; } predicate(const void * ti) : m_ti(ti) {} }; protected: helper_collection(){} ~helper_collection(){} public: template Helper& find_helper(void * const id = 0) { collection::const_iterator it = std::find_if( m_collection.begin(), m_collection.end(), predicate(id) ); void * rval = 0; if(it == m_collection.end()){ m_collection.push_back( std::make_pair(id, make_helper_ptr()) ); rval = m_collection.back().second.get(); } else{ rval = it->second.get(); } return *static_cast(rval); } }; } // namespace detail } // namespace serialization } // namespace boost #endif // BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP ================================================ FILE: include/boost/archive/detail/interface_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // interface_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // NULL #include #include #include #include #include #include #include // must be the last header namespace boost { namespace archive { namespace detail { class basic_pointer_iserializer; template class interface_iarchive { protected: interface_iarchive() {} public: ///////////////////////////////////////////////////////// // archive public interface typedef mpl::bool_ is_loading; typedef mpl::bool_ is_saving; // return a pointer to the most derived class Archive * This(){ return static_cast(this); } template const basic_pointer_iserializer * register_type(T * = NULL){ const basic_pointer_iserializer & bpis = boost::serialization::singleton< pointer_iserializer >::get_const_instance(); this->This()->register_basic_serializer(bpis.get_basic_serializer()); return & bpis; } template Helper & get_helper(void * const id = 0){ helper_collection & hc = this->This()->get_helper_collection(); return hc.template find_helper(id); } template Archive & operator>>(T & t){ this->This()->load_override(t); return * this->This(); } // the & operator template Archive & operator&(T & t){ return *(this->This()) >> t; } }; } // namespace detail } // namespace archive } // namespace boost #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/interface_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP #define BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // interface_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // NULL #include #include #include #include #include #include // must be the last header #include namespace boost { namespace archive { namespace detail { class basic_pointer_oserializer; template class interface_oarchive { protected: interface_oarchive() {} public: ///////////////////////////////////////////////////////// // archive public interface typedef mpl::bool_ is_loading; typedef mpl::bool_ is_saving; // return a pointer to the most derived class Archive * This(){ return static_cast(this); } template const basic_pointer_oserializer * register_type(const T * = NULL){ const basic_pointer_oserializer & bpos = boost::serialization::singleton< pointer_oserializer >::get_const_instance(); this->This()->register_basic_serializer(bpos.get_basic_serializer()); return & bpos; } template Helper & get_helper(void * const id = 0){ helper_collection & hc = this->This()->get_helper_collection(); return hc.template find_helper(id); } template Archive & operator<<(const T & t){ this->This()->save_override(t); return * this->This(); } // the & operator template Archive & operator&(const T & t){ return * this ->This() << t; } }; } // namespace detail } // namespace archive } // namespace boost #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP ================================================ FILE: include/boost/archive/detail/iserializer.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP #define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(BOOST_MSVC) # pragma once #if !defined(__clang__) #pragma inline_depth(255) #pragma inline_recursion(on) #endif #endif #if defined(__MWERKS__) #pragma inline_depth(255) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // iserializer.hpp: interface for serialization system. // (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 // for placement new #include // size_t, NULL #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO #include #endif #include #include #include #include #include #include #include #include #include #include #if !defined(BOOST_MSVC) && \ (BOOST_WORKAROUND(__IBMCPP__, < 1210) || \ defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590)) #define BOOST_SERIALIZATION_DONT_USE_HAS_NEW_OPERATOR 1 #else #define BOOST_SERIALIZATION_DONT_USE_HAS_NEW_OPERATOR 0 #endif #if ! BOOST_SERIALIZATION_DONT_USE_HAS_NEW_OPERATOR #include #endif #include #include #include #include #include #include #include #include #include #include #include // the following is need only for dynamic cast of polymorphic pointers #include #include #include #include #include #include #include namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { // an accessor to permit friend access to archives. Needed because // some compilers don't handle friend templates completely class load_access { public: template static void load_primitive(Archive &ar, T &t){ ar.load(t); } }; namespace detail { #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif template class iserializer : public basic_iserializer { private: void destroy(/*const*/ void *address) const BOOST_OVERRIDE { boost::serialization::access::destroy(static_cast(address)); } public: explicit iserializer() : basic_iserializer( boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance() ) {} BOOST_DLLEXPORT void load_object_data( basic_iarchive & ar, void *x, const unsigned int file_version ) const BOOST_OVERRIDE BOOST_USED; bool class_info() const BOOST_OVERRIDE { return boost::serialization::implementation_level< T >::value >= boost::serialization::object_class_info; } bool tracking(const unsigned int /* flags */) const BOOST_OVERRIDE { return boost::serialization::tracking_level< T >::value == boost::serialization::track_always || ( boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively && serialized_as_pointer()); } version_type version() const BOOST_OVERRIDE { return version_type(::boost::serialization::version< T >::value); } bool is_polymorphic() const BOOST_OVERRIDE { return boost::is_polymorphic< T >::value; } ~iserializer() BOOST_OVERRIDE {} }; #ifdef BOOST_MSVC # pragma warning(pop) #endif template BOOST_DLLEXPORT void iserializer::load_object_data( basic_iarchive & ar, void *x, const unsigned int file_version ) const { // note: we now comment this out. Before we permitted archive // version # to be very large. Now we don't. To permit // readers of these old archives, we have to suppress this // code. Perhaps in the future we might re-enable it but // permit its suppression with a runtime switch. #if 1 // trap case where the program cannot handle the current version if(file_version > static_cast(version())) boost::serialization::throw_exception( archive::archive_exception( boost::archive::archive_exception::unsupported_class_version, get_debug_info() ) ); #endif // make sure call is routed through the highest interface that might // be specialized by the user. boost::serialization::serialize_adl( boost::serialization::smart_cast_reference(ar), * static_cast(x), file_version ); } #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif // the purpose of this code is to allocate memory for an object // without requiring the constructor to be called. Presumably // the allocated object will be subsequently initialized with // "placement new". // note: we have the boost type trait has_new_operator but we // have no corresponding has_delete_operator. So we presume // that the former being true would imply that the a delete // operator is also defined for the class T. template struct heap_allocation { // boost::has_new_operator< T > doesn't work on these compilers #if BOOST_SERIALIZATION_DONT_USE_HAS_NEW_OPERATOR // This doesn't handle operator new overload for class T static T * invoke_new(){ return static_cast(operator new(sizeof(T))); } static void invoke_delete(T *t){ (operator delete(t)); } #else // note: we presume that a true value for has_new_operator // implies the existence of a class specific delete operator as well // as a class specific new operator. struct has_new_operator { static T * invoke_new() { return static_cast((T::operator new)(sizeof(T))); } static void invoke_delete(T * t) { // if compilation fails here, the likely cause that the class // T has a class specific new operator but no class specific // delete operator which matches the following signature. // note that this solution addresses the issue that two // possible signatures. But it doesn't address the possibility // that the class might have class specific new with NO // class specific delete at all. Patches (compatible with // C++03) welcome! (operator delete)(t); } }; struct doesnt_have_new_operator { static T* invoke_new() { return static_cast(operator new(sizeof(T))); } static void invoke_delete(T * t) { // Note: I'm reliance upon automatic conversion from T * to void * here (operator delete)(t); } }; static T * invoke_new() { typedef typename mpl::eval_if< boost::has_new_operator< T >, mpl::identity, mpl::identity >::type typex; return typex::invoke_new(); } static void invoke_delete(T *t) { typedef typename mpl::eval_if< boost::has_new_operator< T >, mpl::identity, mpl::identity >::type typex; typex::invoke_delete(t); } #endif explicit heap_allocation(){ m_p = invoke_new(); } ~heap_allocation(){ if (0 != m_p) invoke_delete(m_p); } T* get() const { return m_p; } T* release() { T* p = m_p; m_p = 0; return p; } private: T* m_p; }; template class pointer_iserializer : public basic_pointer_iserializer { private: void * heap_allocation() const BOOST_OVERRIDE { detail::heap_allocation h; T * t = h.get(); h.release(); return t; } const basic_iserializer & get_basic_serializer() const BOOST_OVERRIDE { return boost::serialization::singleton< iserializer >::get_const_instance(); } BOOST_DLLEXPORT void load_object_ptr( basic_iarchive & ar, void * x, const unsigned int file_version ) const BOOST_OVERRIDE BOOST_USED; public: // this should always be a singleton so make the constructor protected pointer_iserializer(); ~pointer_iserializer() BOOST_OVERRIDE; }; #ifdef BOOST_MSVC # pragma warning(pop) #endif // note: BOOST_DLLEXPORT is so that code for polymorphic class // serialized only through base class won't get optimized out template BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( basic_iarchive & ar, void * t, const unsigned int file_version ) const { Archive & ar_impl = boost::serialization::smart_cast_reference(ar); // note that the above will throw std::bad_alloc if the allocation // fails so we don't have to address this contingency here. // catch exception during load_construct_data so that we don't // automatically delete the t which is most likely not fully // constructed BOOST_TRY { // this addresses an obscure situation that occurs when // load_constructor de-serializes something through a pointer. ar.next_object_pointer(t); boost::serialization::load_construct_data_adl( ar_impl, static_cast(t), file_version ); } BOOST_CATCH(...){ // if we get here the load_construct failed. The heap_allocation // will be automatically deleted so we don't have to do anything // special here. BOOST_RETHROW; } BOOST_CATCH_END ar_impl >> boost::serialization::make_nvp(NULL, * static_cast(t)); } template pointer_iserializer::pointer_iserializer() : basic_pointer_iserializer( boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance() ) { boost::serialization::singleton< iserializer >::get_mutable_instance().set_bpis(this); archive_serializer_map::insert(this); } template pointer_iserializer::~pointer_iserializer(){ archive_serializer_map::erase(this); } template struct load_non_pointer_type { // note this bounces the call right back to the archive // with no runtime overhead struct load_primitive { template static void invoke(Archive & ar, T & t){ load_access::load_primitive(ar, t); } }; // note this bounces the call right back to the archive // with no runtime overhead struct load_only { template static void invoke(Archive & ar, const T & t){ // short cut to user's serializer // make sure call is routed through the highest interface that might // be specialized by the user. boost::serialization::serialize_adl( ar, const_cast(t), boost::serialization::version< T >::value ); } }; // note this save class information including version // and serialization level to the archive struct load_standard { template static void invoke(Archive &ar, const T & t){ void * x = boost::addressof(const_cast(t)); ar.load_object( x, boost::serialization::singleton< iserializer >::get_const_instance() ); } }; struct load_conditional { template static void invoke(Archive &ar, T &t){ //if(0 == (ar.get_flags() & no_tracking)) load_standard::invoke(ar, t); //else // load_only::invoke(ar, t); } }; template static void invoke(Archive & ar, T &t){ typedef typename mpl::eval_if< // if its primitive mpl::equal_to< boost::serialization::implementation_level< T >, mpl::int_ >, mpl::identity, // else typename mpl::eval_if< // class info / version mpl::greater_equal< boost::serialization::implementation_level< T >, mpl::int_ >, // do standard load mpl::identity, // else typename mpl::eval_if< // no tracking mpl::equal_to< boost::serialization::tracking_level< T >, mpl::int_ >, // do a fast load mpl::identity, // else // do a fast load only tracking is turned off mpl::identity > > >::type typex; check_object_versioning< T >(); check_object_level< T >(); typex::invoke(ar, t); } }; template struct load_pointer_type { struct abstract { template static const basic_pointer_iserializer * register_type(Archive & /* ar */){ // it has? to be polymorphic BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); return static_cast(NULL); } }; struct non_abstract { template static const basic_pointer_iserializer * register_type(Archive & ar){ return ar.register_type(static_cast(NULL)); } }; template static const basic_pointer_iserializer * register_type(Archive &ar, const T* const /*t*/){ // there should never be any need to load an abstract polymorphic // class pointer. Inhibiting code generation for this // permits abstract base classes to be used - note: exception // virtual serialize functions used for plug-ins typedef typename mpl::eval_if< boost::serialization::is_abstract, boost::mpl::identity, boost::mpl::identity >::type typex; return typex::template register_type< T >(ar); } template static T * pointer_tweak( const boost::serialization::extended_type_info & eti, void const * const t, const T & ) { // tweak the pointer back to the base class void * upcast = const_cast( boost::serialization::void_upcast( eti, boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance(), t ) ); if(NULL == upcast) boost::serialization::throw_exception( archive_exception(archive_exception::unregistered_class) ); return static_cast(upcast); } template static void check_load(T * const /* t */){ check_pointer_level< T >(); check_pointer_tracking< T >(); } static const basic_pointer_iserializer * find(const boost::serialization::extended_type_info & type){ return static_cast( archive_serializer_map::find(type) ); } template static void invoke(Archive & ar, Tptr & t){ check_load(t); const basic_pointer_iserializer * bpis_ptr = register_type(ar, t); const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( // note major hack here !!! // I tried every way to convert Tptr &t (where Tptr might // include const) to void * &. This is the only way // I could make it work. RR (void * & )t, bpis_ptr, find ); // if the pointer isn't that of the base class if(newbpis_ptr != bpis_ptr){ t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); } } }; template struct load_enum_type { template static void invoke(Archive &ar, T &t){ // convert integers to correct enum to load int i; ar >> boost::serialization::make_nvp(NULL, i); t = static_cast< T >(i); } }; template struct load_array_type { template static void invoke(Archive &ar, T &t){ typedef typename remove_extent< T >::type value_type; // convert integers to correct enum to load // determine number of elements in the array. Consider the // fact that some machines will align elements on boundaries // other than characters. std::size_t current_count = sizeof(t) / ( static_cast(static_cast(&t[1])) - static_cast(static_cast(&t[0])) ); boost::serialization::collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(static_cast(count) > current_count) boost::serialization::throw_exception( archive::archive_exception( boost::archive::archive_exception::array_size_too_short ) ); // explicit template arguments to pass intel C++ compiler ar >> serialization::make_array< value_type, boost::serialization::collection_size_type >( static_cast(&t[0]), count ); } }; } // detail template inline void load(Archive & ar, T &t){ // if this assertion trips. It means we're trying to load a // const object with a compiler that doesn't have correct // function template ordering. On other compilers, this is // handled below. detail::check_const_loading< T >(); typedef typename mpl::eval_if, mpl::identity > ,//else typename mpl::eval_if, mpl::identity > ,//else typename mpl::eval_if, mpl::identity > ,//else mpl::identity > > > >::type typex; typex::invoke(ar, t); } } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/oserializer.hpp ================================================ #ifndef BOOST_ARCHIVE_OSERIALIZER_HPP #define BOOST_ARCHIVE_OSERIALIZER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #if !defined(__clang__) #pragma inline_depth(255) #pragma inline_recursion(on) #endif #endif #if defined(__MWERKS__) #pragma inline_depth(255) #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // oserializer.hpp: interface for serialization system. // (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 #include // NULL #include #include #include #include #include #include #include #include #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { // an accessor to permit friend access to archives. Needed because // some compilers don't handle friend templates completely class save_access { public: template static void end_preamble(Archive & ar){ ar.end_preamble(); } template static void save_primitive(Archive & ar, const T & t){ ar.end_preamble(); ar.save(t); } }; namespace detail { #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif template class oserializer : public basic_oserializer { private: // private constructor to inhibit any existence other than the // static one public: explicit BOOST_DLLEXPORT oserializer() : basic_oserializer( boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance() ) {} BOOST_DLLEXPORT void save_object_data( basic_oarchive & ar, const void *x ) const BOOST_OVERRIDE BOOST_USED; bool class_info() const BOOST_OVERRIDE { return boost::serialization::implementation_level< T >::value >= boost::serialization::object_class_info; } bool tracking(const unsigned int /* flags */) const BOOST_OVERRIDE { return boost::serialization::tracking_level< T >::value == boost::serialization::track_always || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively && serialized_as_pointer()); } version_type version() const BOOST_OVERRIDE { return version_type(::boost::serialization::version< T >::value); } bool is_polymorphic() const BOOST_OVERRIDE { return boost::is_polymorphic< T >::value; } ~oserializer() BOOST_OVERRIDE {} }; #ifdef BOOST_MSVC # pragma warning(pop) #endif template BOOST_DLLEXPORT void oserializer::save_object_data( basic_oarchive & ar, const void *x ) const { // make sure call is routed through the highest interface that might // be specialized by the user. BOOST_STATIC_ASSERT(boost::is_const< T >::value == false); boost::serialization::serialize_adl( boost::serialization::smart_cast_reference(ar), * static_cast(const_cast(x)), version() ); } #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif template class pointer_oserializer : public basic_pointer_oserializer { private: const basic_oserializer & get_basic_serializer() const BOOST_OVERRIDE { return boost::serialization::singleton< oserializer >::get_const_instance(); } BOOST_DLLEXPORT void save_object_ptr( basic_oarchive & ar, const void * x ) const BOOST_OVERRIDE BOOST_USED; public: pointer_oserializer(); ~pointer_oserializer() BOOST_OVERRIDE; }; #ifdef BOOST_MSVC # pragma warning(pop) #endif template BOOST_DLLEXPORT void pointer_oserializer::save_object_ptr( basic_oarchive & ar, const void * x ) const { BOOST_ASSERT(NULL != x); // make sure call is routed through the highest interface that might // be specialized by the user. T * t = static_cast(const_cast(x)); const unsigned int file_version = boost::serialization::version< T >::value; Archive & ar_impl = boost::serialization::smart_cast_reference(ar); boost::serialization::save_construct_data_adl( ar_impl, t, file_version ); ar_impl << boost::serialization::make_nvp(NULL, * t); } template pointer_oserializer::pointer_oserializer() : basic_pointer_oserializer( boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance() ) { // make sure appropriate member function is instantiated boost::serialization::singleton< oserializer >::get_mutable_instance().set_bpos(this); archive_serializer_map::insert(this); } template pointer_oserializer::~pointer_oserializer(){ archive_serializer_map::erase(this); } template struct save_non_pointer_type { // note this bounces the call right back to the archive // with no runtime overhead struct save_primitive { template static void invoke(Archive & ar, const T & t){ save_access::save_primitive(ar, t); } }; // same as above but passes through serialization struct save_only { template static void invoke(Archive & ar, const T & t){ // make sure call is routed through the highest interface that might // be specialized by the user. boost::serialization::serialize_adl( ar, const_cast(t), ::boost::serialization::version< T >::value ); } }; // adds class information to the archive. This includes // serialization level and class version struct save_standard { template static void invoke(Archive &ar, const T & t){ ar.save_object( boost::addressof(t), boost::serialization::singleton< oserializer >::get_const_instance() ); } }; // adds class information to the archive. This includes // serialization level and class version struct save_conditional { template static void invoke(Archive &ar, const T &t){ //if(0 == (ar.get_flags() & no_tracking)) save_standard::invoke(ar, t); //else // save_only::invoke(ar, t); } }; template static void invoke(Archive & ar, const T & t){ typedef typename mpl::eval_if< // if its primitive mpl::equal_to< boost::serialization::implementation_level< T >, mpl::int_ >, mpl::identity, // else typename mpl::eval_if< // class info / version mpl::greater_equal< boost::serialization::implementation_level< T >, mpl::int_ >, // do standard save mpl::identity, // else typename mpl::eval_if< // no tracking mpl::equal_to< boost::serialization::tracking_level< T >, mpl::int_ >, // do a fast save mpl::identity, // else // do a fast save only tracking is turned off mpl::identity > > >::type typex; check_object_versioning< T >(); typex::invoke(ar, t); } template static void invoke(Archive & ar, T & t){ check_object_level< T >(); check_object_tracking< T >(); invoke(ar, const_cast(t)); } }; template struct save_pointer_type { struct abstract { template static const basic_pointer_oserializer * register_type(Archive & /* ar */){ // it has? to be polymorphic BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); return NULL; } }; struct non_abstract { template static const basic_pointer_oserializer * register_type(Archive & ar){ return ar.register_type(static_cast(NULL)); } }; template static const basic_pointer_oserializer * register_type(Archive &ar, T* const /*t*/){ // there should never be any need to save an abstract polymorphic // class pointer. Inhibiting code generation for this // permits abstract base classes to be used - note: exception // virtual serialize functions used for plug-ins typedef typename mpl::eval_if< boost::serialization::is_abstract< T >, mpl::identity, mpl::identity >::type typex; return typex::template register_type< T >(ar); } struct non_polymorphic { template static void save( Archive &ar, T & t ){ const basic_pointer_oserializer & bpos = boost::serialization::singleton< pointer_oserializer >::get_const_instance(); // save the requested pointer type ar.save_pointer(& t, & bpos); } }; struct polymorphic { template static void save( Archive &ar, T & t ){ typename boost::serialization::type_info_implementation< T >::type const & i = boost::serialization::singleton< typename boost::serialization::type_info_implementation< T >::type >::get_const_instance(); boost::serialization::extended_type_info const * const this_type = & i; // retrieve the true type of the object pointed to // if this assertion fails its an error in this library BOOST_ASSERT(NULL != this_type); const boost::serialization::extended_type_info * true_type = i.get_derived_extended_type_info(t); // note:if this exception is thrown, be sure that derived pointer // is either registered or exported. if(NULL == true_type){ boost::serialization::throw_exception( archive_exception( archive_exception::unregistered_class, "derived class not registered or exported" ) ); } // if its not a pointer to a more derived type const void *vp = static_cast(&t); if(*this_type == *true_type){ const basic_pointer_oserializer * bpos = register_type(ar, &t); ar.save_pointer(vp, bpos); return; } // convert pointer to more derived type. if this is thrown // it means that the base/derived relationship hasn't be registered vp = serialization::void_downcast( *true_type, *this_type, static_cast(&t) ); if(NULL == vp){ boost::serialization::throw_exception( archive_exception( archive_exception::unregistered_cast, true_type->get_debug_info(), this_type->get_debug_info() ) ); } // since true_type is valid, and this only gets made if the // pointer oserializer object has been created, this should never // fail const basic_pointer_oserializer * bpos = static_cast( boost::serialization::singleton< archive_serializer_map >::get_const_instance().find(*true_type) ); BOOST_ASSERT(NULL != bpos); if(NULL == bpos) boost::serialization::throw_exception( archive_exception( archive_exception::unregistered_class, "derived class not registered or exported" ) ); ar.save_pointer(vp, bpos); } }; template static void save( Archive & ar, const T & t ){ check_pointer_level< T >(); check_pointer_tracking< T >(); typedef typename mpl::eval_if< is_polymorphic< T >, mpl::identity, mpl::identity >::type type; type::save(ar, const_cast(t)); } template static void invoke(Archive &ar, const TPtr t){ register_type(ar, t); if(NULL == t){ basic_oarchive & boa = boost::serialization::smart_cast_reference(ar); boa.save_null_pointer(); save_access::end_preamble(ar); return; } save(ar, * t); } }; template struct save_enum_type { template static void invoke(Archive &ar, const T &t){ // convert enum to integers on save const int i = static_cast(t); ar << boost::serialization::make_nvp(NULL, i); } }; template struct save_array_type { template static void invoke(Archive &ar, const T &t){ typedef typename boost::remove_extent< T >::type value_type; save_access::end_preamble(ar); // consider alignment std::size_t c = sizeof(t) / ( static_cast(static_cast(&t[1])) - static_cast(static_cast(&t[0])) ); boost::serialization::collection_size_type count(c); ar << BOOST_SERIALIZATION_NVP(count); // explicit template arguments to pass intel C++ compiler ar << serialization::make_array< const value_type, boost::serialization::collection_size_type >( static_cast(&t[0]), count ); } }; } // detail template inline void save(Archive & ar, /*const*/ T &t){ typedef typename mpl::eval_if, mpl::identity >, //else typename mpl::eval_if, mpl::identity >, //else typename mpl::eval_if, mpl::identity >, //else mpl::identity > > > >::type typex; typex::invoke(ar, t); } } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_OSERIALIZER_HPP ================================================ FILE: include/boost/archive/detail/polymorphic_iarchive_route.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP #define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_iarchive_route.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 #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail{ class basic_iserializer; class basic_pointer_iserializer; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif template class polymorphic_iarchive_route : public polymorphic_iarchive, // note: gcc dynamic cross cast fails if the the derivation below is // not public. I think this is a mistake. public /*protected*/ ArchiveImplementation { private: // these are used by the serialization library. void load_object( void *t, const basic_iserializer & bis ) BOOST_OVERRIDE { ArchiveImplementation::load_object(t, bis); } const basic_pointer_iserializer * load_pointer( void * & t, const basic_pointer_iserializer * bpis_ptr, const basic_pointer_iserializer * (*finder)( const boost::serialization::extended_type_info & type ) ) BOOST_OVERRIDE { return ArchiveImplementation::load_pointer(t, bpis_ptr, finder); } void set_library_version(boost::serialization::library_version_type archive_library_version) BOOST_OVERRIDE { ArchiveImplementation::set_library_version(archive_library_version); } boost::serialization::library_version_type get_library_version() const BOOST_OVERRIDE { return ArchiveImplementation::get_library_version(); } unsigned int get_flags() const BOOST_OVERRIDE { return ArchiveImplementation::get_flags(); } void delete_created_pointers() BOOST_OVERRIDE { ArchiveImplementation::delete_created_pointers(); } void reset_object_address( const void * new_address, const void * old_address ) BOOST_OVERRIDE { ArchiveImplementation::reset_object_address(new_address, old_address); } void load_binary(void * t, std::size_t size) BOOST_OVERRIDE { ArchiveImplementation::load_binary(t, size); } // primitive types the only ones permitted by polymorphic archives void load(bool & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(char & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(signed char & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(unsigned char & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T void load(wchar_t & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #endif #endif void load(short & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(unsigned short & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(int & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(unsigned int & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(long & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(unsigned long & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #if defined(BOOST_HAS_LONG_LONG) void load(boost::long_long_type & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(boost::ulong_long_type & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #elif defined(BOOST_HAS_MS_INT64) void load(__int64 & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(unsigned __int64 & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #endif void load(float & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(double & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } void load(std::string & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #ifndef BOOST_NO_STD_WSTRING void load(std::wstring & t) BOOST_OVERRIDE { ArchiveImplementation::load(t); } #endif // used for xml and other tagged formats default does nothing void load_start(const char * name) BOOST_OVERRIDE { ArchiveImplementation::load_start(name); } void load_end(const char * name) BOOST_OVERRIDE { ArchiveImplementation::load_end(name); } void register_basic_serializer(const basic_iserializer & bis) BOOST_OVERRIDE { ArchiveImplementation::register_basic_serializer(bis); } helper_collection & get_helper_collection() BOOST_OVERRIDE { return ArchiveImplementation::get_helper_collection(); } public: // this can't be inherited because they appear in multiple // parents typedef mpl::bool_ is_loading; typedef mpl::bool_ is_saving; // the >> operator template polymorphic_iarchive & operator>>(T & t){ return polymorphic_iarchive::operator>>(t); } // the & operator template polymorphic_iarchive & operator&(T & t){ return polymorphic_iarchive::operator&(t); } // register type function template const basic_pointer_iserializer * register_type(T * t = NULL){ return ArchiveImplementation::register_type(t); } // all current archives take a stream as constructor argument template polymorphic_iarchive_route( std::basic_istream<_Elem, _Tr> & is, unsigned int flags = 0 ) : ArchiveImplementation(is, flags) {} ~polymorphic_iarchive_route() BOOST_OVERRIDE {} }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP ================================================ FILE: include/boost/archive/detail/polymorphic_oarchive_route.hpp ================================================ #ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP #define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_oarchive_route.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 #include #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail{ class basic_oserializer; class basic_pointer_oserializer; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif template class polymorphic_oarchive_route : public polymorphic_oarchive, // note: gcc dynamic cross cast fails if the the derivation below is // not public. I think this is a mistake. public /*protected*/ ArchiveImplementation { private: // these are used by the serialization library. void save_object( const void *x, const detail::basic_oserializer & bos ) BOOST_OVERRIDE { ArchiveImplementation::save_object(x, bos); } void save_pointer( const void * t, const detail::basic_pointer_oserializer * bpos_ptr ) BOOST_OVERRIDE { ArchiveImplementation::save_pointer(t, bpos_ptr); } void save_null_pointer() BOOST_OVERRIDE { ArchiveImplementation::save_null_pointer(); } // primitive types the only ones permitted by polymorphic archives void save(const bool t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const char t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const signed char t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const unsigned char t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T void save(const wchar_t t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #endif #endif void save(const short t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const unsigned short t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const int t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const unsigned int t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const long t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const unsigned long t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #if defined(BOOST_HAS_LONG_LONG) void save(const boost::long_long_type t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const boost::ulong_long_type t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #elif defined(BOOST_HAS_MS_INT64) void save(const boost::int64_t t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const boost::uint64_t t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #endif void save(const float t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const double t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } void save(const std::string & t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #ifndef BOOST_NO_STD_WSTRING void save(const std::wstring & t) BOOST_OVERRIDE { ArchiveImplementation::save(t); } #endif boost::serialization::library_version_type get_library_version() const BOOST_OVERRIDE { return ArchiveImplementation::get_library_version(); } unsigned int get_flags() const BOOST_OVERRIDE { return ArchiveImplementation::get_flags(); } void save_binary(const void * t, std::size_t size) BOOST_OVERRIDE { ArchiveImplementation::save_binary(t, size); } // used for xml and other tagged formats default does nothing void save_start(const char * name) BOOST_OVERRIDE { ArchiveImplementation::save_start(name); } void save_end(const char * name) BOOST_OVERRIDE { ArchiveImplementation::save_end(name); } void end_preamble() BOOST_OVERRIDE { ArchiveImplementation::end_preamble(); } void register_basic_serializer(const detail::basic_oserializer & bos) BOOST_OVERRIDE { ArchiveImplementation::register_basic_serializer(bos); } helper_collection & get_helper_collection() BOOST_OVERRIDE { return ArchiveImplementation::get_helper_collection(); } public: // this can't be inherited because they appear in multiple // parents typedef mpl::bool_ is_loading; typedef mpl::bool_ is_saving; // the << operator template polymorphic_oarchive & operator<<(T & t){ return polymorphic_oarchive::operator<<(t); } // the & operator template polymorphic_oarchive & operator&(T & t){ return polymorphic_oarchive::operator&(t); } // register type function template const basic_pointer_oserializer * register_type(T * t = NULL){ return ArchiveImplementation::register_type(t); } // all current archives take a stream as constructor argument template polymorphic_oarchive_route( std::basic_ostream<_Elem, _Tr> & os, unsigned int flags = 0 ) : ArchiveImplementation(os, flags) {} ~polymorphic_oarchive_route() BOOST_OVERRIDE {} }; } // namespace detail } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP ================================================ FILE: include/boost/archive/detail/register_archive.hpp ================================================ // Copyright David Abrahams 2006. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP # define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP namespace boost { namespace archive { namespace detail { // No instantiate_ptr_serialization overloads generated by // BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call // will be seen *unless* they are in an associated namespace of one of // the arguments, so we pass one of these along to make sure this // namespace is considered. See temp.dep.candidate (14.6.4.2) in the // standard. struct adl_tag {}; template struct ptr_serialization_support; // We could've just used ptr_serialization_support, above, but using // it with only a forward declaration causes vc6/7 to complain about a // missing instantiate member, even if it has one. This is just a // friendly layer of indirection. template struct _ptr_serialization_support : ptr_serialization_support { typedef int type; }; #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130) template struct counter : counter {}; template<> struct counter<0> {}; template void instantiate_ptr_serialization(Serializable* s, int, adl_tag) { instantiate_ptr_serialization(s, counter<20>()); } template struct get_counter { static const int value = sizeof(adjust_counter(counter<20>())); typedef counter type; typedef counter prior; typedef char (&next)[value+1]; }; char adjust_counter(counter<0>); template void instantiate_ptr_serialization(Serializable*, counter<0>) {} #define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ namespace boost { namespace archive { namespace detail { \ get_counter::next adjust_counter(get_counter::type);\ template \ void instantiate_ptr_serialization(Serializable* s, \ get_counter::type) { \ ptr_serialization_support x; \ instantiate_ptr_serialization(s, get_counter::prior()); \ }\ }}} #else // This function gets called, but its only purpose is to participate // in overload resolution with the functions declared by // BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. template void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {} // The function declaration generated by this macro never actually // gets called, but its return type gets instantiated, and that's // enough to cause registration of serialization functions between // Archive and any exported Serializable type. See also: // boost/serialization/export.hpp # define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ namespace boost { namespace archive { namespace detail { \ \ template \ typename _ptr_serialization_support::type \ instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \ \ }}} #endif }}} // namespace boost::archive::detail #endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP ================================================ FILE: include/boost/archive/detail/utf8_codecvt_facet.hpp ================================================ // Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) // Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). // 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) #ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP #define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP #include #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #endif // use boost's utf8 codecvt facet #include #define BOOST_UTF8_BEGIN_NAMESPACE \ namespace boost { namespace archive { namespace detail { #define BOOST_UTF8_END_NAMESPACE }}} #include #undef BOOST_UTF8_END_NAMESPACE #undef BOOST_UTF8_DECL #undef BOOST_UTF8_BEGIN_NAMESPACE #endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP ================================================ FILE: include/boost/archive/dinkumware.hpp ================================================ #ifndef BOOST_ARCHIVE_DINKUMWARE_HPP #define BOOST_ARCHIVE_DINKUMWARE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // dinkumware.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. // this file adds a couple of things that are missing from the dinkumware // implementation of the standard library. #include #include #include #include namespace std { // define i/o operators for 64 bit integers template basic_ostream & operator<<(basic_ostream & os, boost::uint64_t t){ // octal rendering of 64 bit number would be 22 octets + eos CharType d[23]; unsigned int radix; if(os.flags() & (int)std::ios_base::hex) radix = 16; else if(os.flags() & (int)std::ios_base::oct) radix = 8; else //if(s.flags() & (int)std::ios_base::dec) radix = 10; unsigned int i = 0; do{ unsigned int j = t % radix; d[i++] = j + ((j < 10) ? '0' : ('a' - 10)); t /= radix; } while(t > 0); d[i--] = '\0'; // reverse digits unsigned int j = 0; while(j < i){ CharType k = d[i]; d[i] = d[j]; d[j] = k; --i;++j; } os << d; return os; } template basic_ostream & operator<<(basic_ostream &os, boost::int64_t t){ if(0 <= t){ os << static_cast(t); } else{ os.put('-'); os << -t; } return os; } template basic_istream & operator>>(basic_istream &is, boost::int64_t & t){ CharType d; do{ d = is.get(); } while(::isspace(d)); bool negative = (d == '-'); if(negative) d = is.get(); unsigned int radix; if(is.flags() & (int)std::ios_base::hex) radix = 16; else if(is.flags() & (int)std::ios_base::oct) radix = 8; else //if(s.flags() & (int)std::ios_base::dec) radix = 10; t = 0; do{ if('0' <= d && d <= '9') t = t * radix + (d - '0'); else if('a' <= d && d <= 'f') t = t * radix + (d - 'a' + 10); else break; d = is.get(); } while(!is.fail()); // restore the delimiter is.putback(d); is.clear(); if(negative) t = -t; return is; } template basic_istream & operator>>(basic_istream &is, boost::uint64_t & t){ boost::int64_t it; is >> it; t = it; return is; } template<> class back_insert_iterator > : public iterator { public: typedef basic_string container_type; typedef container_type::reference reference; explicit back_insert_iterator(container_type & s) : container(& s) {} // construct with container back_insert_iterator & operator=( container_type::const_reference Val_ ){ // push value into container //container->push_back(Val_); *container += Val_; return (*this); } back_insert_iterator & operator*(){ return (*this); } back_insert_iterator & operator++(){ // pretend to preincrement return (*this); } back_insert_iterator operator++(int){ // pretend to postincrement return (*this); } protected: container_type *container; // pointer to container }; template inline back_insert_iterator > back_inserter( basic_string & s ){ return (std::back_insert_iterator >(s)); } template<> class back_insert_iterator > : public iterator { public: typedef basic_string container_type; typedef container_type::reference reference; explicit back_insert_iterator(container_type & s) : container(& s) {} // construct with container back_insert_iterator & operator=( container_type::const_reference Val_ ){ // push value into container //container->push_back(Val_); *container += Val_; return (*this); } back_insert_iterator & operator*(){ return (*this); } back_insert_iterator & operator++(){ // pretend to preincrement return (*this); } back_insert_iterator operator++(int){ // pretend to postincrement return (*this); } protected: container_type *container; // pointer to container }; template inline back_insert_iterator > back_inserter( basic_string & s ){ return (std::back_insert_iterator >(s)); } } // namespace std #endif //BOOST_ARCHIVE_DINKUMWARE_HPP ================================================ FILE: include/boost/archive/impl/archive_serializer_map.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // archive_serializer_map.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. ////////////////////////////////////////////////////////////////////// // implementation of basic_text_iprimitive overrides for the combination // of template parameters used to implement a text_iprimitive #include #include #include #include namespace boost { namespace archive { namespace detail { #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace extra_detail { // anon template class map : public basic_serializer_map {}; } #ifdef BOOST_MSVC # pragma warning(pop) #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL bool archive_serializer_map::insert(const basic_serializer * bs){ return boost::serialization::singleton< extra_detail::map >::get_mutable_instance().insert(bs); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void archive_serializer_map::erase(const basic_serializer * bs){ // note: previously this conditional was a runtime assertion with // BOOST_ASSERT. We've changed it because we've discovered that at // least one platform is not guaranteed to destroy singletons in // reverse order of distruction. if(boost::serialization::singleton< extra_detail::map >::is_destroyed()) return; boost::serialization::singleton< extra_detail::map >::get_mutable_instance().erase(bs); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * archive_serializer_map::find( const boost::serialization::extended_type_info & eti ) { return boost::serialization::singleton< extra_detail::map >::get_const_instance().find(eti); } } // namespace detail } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_binary_iarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_iarchive.ipp: // (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 #include #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; using ::strlen; using ::size_t; } #endif #include #include #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of binary_binary_archive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iarchive::load_override(class_name_type & t){ std::string cn; cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); load_override(cn); if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_class_name) ); std::memcpy(t, cn.data(), cn.size()); // borland tweak t.t[cn.size()] = '\0'; } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iarchive::init() { // read signature in an archive version independent manner std::string file_signature; #if 0 // commented out since it interfers with derivation BOOST_TRY { std::size_t l; this->This()->load(l); if(l == std::strlen(BOOST_ARCHIVE_SIGNATURE())) { // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != file_signature.data()) #endif file_signature.resize(l); // note breaking a rule here - could be a problem on some platform if(0 < l) this->This()->load_binary(&(*file_signature.begin()), l); } } BOOST_CATCH(archive_exception const &) { // catch stream_error archive exceptions // will cause invalid_signature archive exception to be thrown below file_signature = ""; } BOOST_CATCH_END #else // https://svn.boost.org/trac/boost/ticket/7301 * this->This() >> file_signature; #endif if(file_signature != BOOST_ARCHIVE_SIGNATURE()) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_signature) ); // make sure the version of the reading archive library can // support the format of the archive being read boost::serialization::library_version_type input_library_version; //* this->This() >> input_library_version; { int v = 0; v = this->This()->m_sb.sbumpc(); #if BOOST_ENDIAN_LITTLE_BYTE if(v < 6){ ; } else if(v < 7){ // version 6 - next byte should be zero this->This()->m_sb.sbumpc(); } else if(v < 8){ int x1; // version 7 = might be followed by zero or some other byte x1 = this->This()->m_sb.sgetc(); // it's =a zero, push it back if(0 == x1) this->This()->m_sb.sbumpc(); } else{ // version 8+ followed by a zero this->This()->m_sb.sbumpc(); } #elif BOOST_ENDIAN_BIG_BYTE if(v == 0) v = this->This()->m_sb.sbumpc(); #endif input_library_version = static_cast(v); } #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) this->set_library_version(input_library_version); #else detail::basic_iarchive::set_library_version(input_library_version); #endif if(BOOST_ARCHIVE_VERSION() < input_library_version) boost::serialization::throw_exception( archive_exception(archive_exception::unsupported_version) ); } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_binary_iprimitive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_iprimitive.ipp: // (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 #include // size_t, NULL #include // memcpy #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; using ::memcpy; } // namespace std #endif #include #include #include #include namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // implementation of basic_binary_iprimitive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::init() { // Detect attempts to pass native binary archives across // incompatible platforms. This is not fool proof but its // better than nothing. unsigned char size; this->This()->load(size); if(sizeof(int) != size) boost::serialization::throw_exception( archive_exception( archive_exception::incompatible_native_format, "size of int" ) ); this->This()->load(size); if(sizeof(long) != size) boost::serialization::throw_exception( archive_exception( archive_exception::incompatible_native_format, "size of long" ) ); this->This()->load(size); if(sizeof(float) != size) boost::serialization::throw_exception( archive_exception( archive_exception::incompatible_native_format, "size of float" ) ); this->This()->load(size); if(sizeof(double) != size) boost::serialization::throw_exception( archive_exception( archive_exception::incompatible_native_format, "size of double" ) ); // for checking endian int i; this->This()->load(i); if(1 != i) boost::serialization::throw_exception( archive_exception( archive_exception::incompatible_native_format, "endian setting" ) ); } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(wchar_t * ws) { std::size_t l; // number of wchar_t !!! this->This()->load(l); load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); ws[l] = L'\0'; } #endif #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(std::string & s) { std::size_t l; this->This()->load(l); // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(l); // note breaking a rule here - could be a problem on some platform if(0 < l) load_binary(&(*s.begin()), l); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(char * s) { std::size_t l; this->This()->load(l); load_binary(s, l); s[l] = '\0'; } #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(std::wstring & ws) { std::size_t l; this->This()->load(l); // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != ws.data()) #endif ws.resize(l); // note breaking a rule here - is could be a problem on some platform load_binary(const_cast(ws.data()), l * sizeof(wchar_t) / sizeof(char)); } #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_iprimitive::basic_binary_iprimitive( std::basic_streambuf & sb, bool no_codecvt ) : #ifndef BOOST_NO_STD_LOCALE m_sb(sb), codecvt_null_facet(1), locale_saver(m_sb), archive_locale(sb.getloc(), & codecvt_null_facet) { if(! no_codecvt){ m_sb.pubsync(); m_sb.pubimbue(archive_locale); } } #else m_sb(sb) {} #endif // scoped_ptr requires that g be a complete type at time of // destruction so define destructor here rather than in the header template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_iprimitive::~basic_binary_iprimitive(){} } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_binary_oarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_oarchive.ipp: // (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 #include #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } #endif #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of binary_binary_oarchive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oarchive::init(){ // write signature in an archive version independent manner const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); * this->This() << file_signature; // write library version const boost::serialization::library_version_type v(BOOST_ARCHIVE_VERSION()); * this->This() << v; } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_binary_oprimitive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_binary_oprimitive.ipp: // (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 #include // NULL #include #include #if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) namespace std{ using ::strlen; } // namespace std #endif #ifndef BOOST_NO_CWCHAR #include #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ using ::wcslen; } #endif #endif #include #include namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // implementation of basic_binary_oprimitive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::init() { // record native sizes of fundamental types // this is to permit detection of attempts to pass // native binary archives accross incompatible machines. // This is not foolproof but its better than nothing. this->This()->save(static_cast(sizeof(int))); this->This()->save(static_cast(sizeof(long))); this->This()->save(static_cast(sizeof(float))); this->This()->save(static_cast(sizeof(double))); // for checking endianness this->This()->save(int(1)); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::save(const char * s) { std::size_t l = std::strlen(s); this->This()->save(l); save_binary(s, l); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::save(const std::string &s) { std::size_t l = static_cast(s.size()); this->This()->save(l); save_binary(s.data(), l); } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::save(const wchar_t * ws) { std::size_t l = std::wcslen(ws); this->This()->save(l); save_binary(ws, l * sizeof(wchar_t) / sizeof(char)); } #endif #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::save(const std::wstring &ws) { std::size_t l = ws.size(); this->This()->save(l); save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); } #endif #endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_oprimitive::basic_binary_oprimitive( std::basic_streambuf & sb, bool no_codecvt ) : #ifndef BOOST_NO_STD_LOCALE m_sb(sb), codecvt_null_facet(1), locale_saver(m_sb), archive_locale(sb.getloc(), & codecvt_null_facet) { if(! no_codecvt){ m_sb.pubsync(); m_sb.pubimbue(archive_locale); } } #else m_sb(sb) {} #endif // scoped_ptr requires that g be a complete type at time of // destruction so define destructor here rather than in the header template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_binary_oprimitive::~basic_binary_oprimitive(){} } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_text_iarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_iarchive.ipp: // (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 #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } #endif #include #include #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of text_text_archive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_iarchive::load_override(class_name_type & t){ std::string cn; cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); load_override(cn); if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_class_name) ); std::memcpy(t, cn.data(), cn.size()); // borland tweak t.t[cn.size()] = '\0'; } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_iarchive::init() { // read signature in an archive version independent manner std::string file_signature; * this->This() >> file_signature; if(file_signature != BOOST_ARCHIVE_SIGNATURE()) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_signature) ); // make sure the version of the reading archive library can // support the format of the archive being read boost::serialization::library_version_type input_library_version; * this->This() >> input_library_version; #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) this->set_library_version(input_library_version); #else detail::basic_iarchive::set_library_version(input_library_version); #endif // extra little .t is to get around borland quirk if(BOOST_ARCHIVE_VERSION() < input_library_version) boost::serialization::throw_exception( archive_exception(archive_exception::unsupported_version) ); } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_text_iprimitive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_iprimitive.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // size_t, NULL #include // NULL #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include namespace boost { namespace archive { namespace detail { template static inline bool is_whitespace(CharType c); template<> inline bool is_whitespace(char t){ return 0 != std::isspace(t); } #ifndef BOOST_NO_CWCHAR template<> inline bool is_whitespace(wchar_t t){ return 0 != std::iswspace(t); } #endif } // detail // translate base64 text into binary and copy into buffer // until buffer is full. template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_iprimitive::load_binary( void *address, std::size_t count ){ typedef typename IStream::char_type CharType; if(0 == count) return; BOOST_ASSERT( static_cast((std::numeric_limits::max)()) > (count + sizeof(CharType) - 1)/sizeof(CharType) ); if(is.fail()) boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); // convert from base64 to binary typedef typename iterators::transform_width< iterators::binary_from_base64< iterators::remove_whitespace< iterators::istream_iterator > ,typename IStream::int_type > ,8 ,6 ,CharType > binary; binary i = binary(iterators::istream_iterator(is)); char * caddr = static_cast(address); // take care that we don't increment anymore than necessary while(count-- > 0){ *caddr++ = static_cast(*i++); } // skip over any excess input for(;;){ typename IStream::int_type r; r = is.get(); if(is.eof()) break; if(detail::is_whitespace(static_cast(r))) break; } } template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_iprimitive::basic_text_iprimitive( IStream &is_, bool no_codecvt ) : is(is_), flags_saver(is_), #ifndef BOOST_NO_STD_LOCALE precision_saver(is_), codecvt_null_facet(1), archive_locale(is.getloc(), & codecvt_null_facet), locale_saver(is) { if(! no_codecvt){ is_.sync(); is_.imbue(archive_locale); } is_ >> std::noboolalpha; } #else precision_saver(is_) {} #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_iprimitive::~basic_text_iprimitive(){ } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_text_oarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_oarchive.ipp: // (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 #include #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } #endif #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of basic_text_oarchive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_oarchive::newtoken() { switch(delimiter){ default: BOOST_ASSERT(false); break; case eol: this->This()->put('\n'); delimiter = space; break; case space: this->This()->put(' '); break; case none: delimiter = space; break; } } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_oarchive::init(){ // write signature in an archive version independent manner const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); * this->This() << file_signature; // write library version const boost::serialization::library_version_type v(BOOST_ARCHIVE_VERSION()); * this->This() << v; } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_text_oprimitive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_text_oprimitive.ipp: // (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 // NULL #include // std::copy #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include namespace boost { namespace archive { // translate to base64 and copy in to buffer. template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_text_oprimitive::save_binary( const void *address, std::size_t count ){ typedef typename OStream::char_type CharType; if(0 == count) return; if(os.fail()) boost::serialization::throw_exception( archive_exception(archive_exception::output_stream_error) ); os.put('\n'); typedef boost::archive::iterators::insert_linebreaks< boost::archive::iterators::base64_from_binary< boost::archive::iterators::transform_width< const char *, 6, 8 > > ,76 ,const char // cwpro8 needs this > base64_text; boost::archive::iterators::ostream_iterator oi(os); std::copy( base64_text(static_cast(address)), base64_text( static_cast(address) + count ), oi ); std::size_t tail = count % 3; if(tail > 0){ *oi++ = '='; if(tail < 2) *oi = '='; } } template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_oprimitive::basic_text_oprimitive( OStream & os_, bool no_codecvt ) : os(os_), flags_saver(os_), #ifndef BOOST_NO_STD_LOCALE precision_saver(os_), codecvt_null_facet(1), archive_locale(os.getloc(), & codecvt_null_facet), locale_saver(os) { if(! no_codecvt){ os_.flush(); os_.imbue(archive_locale); } os_ << std::noboolalpha; } #else precision_saver(os_) {} #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_text_oprimitive::~basic_text_oprimitive(){ if(boost::core::uncaught_exceptions() > 0) return; os << std::endl; } } //namespace boost } //namespace archive ================================================ FILE: include/boost/archive/impl/basic_xml_grammar.hpp ================================================ #ifndef BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP #define BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_grammar.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. // this module is derived from simplexml.cpp - an example shipped as part of // the spirit parser. This example contains the following notice: /*============================================================================= simplexml.cpp Spirit V1.3 URL: http://spirit.sourceforge.net/ Copyright (c) 2001, Daniel C. Nuffer This software is provided 'as-is', without any express or implied warranty. In no event will the copyright holder be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. =============================================================================*/ #include #include #include #include #include #include #include #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // XML grammar parsing template class BOOST_SYMBOL_VISIBLE basic_xml_grammar { public: // The following is not necessary according to DR45, but at least // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. struct return_values; friend struct return_values; private: typedef typename std::basic_istream IStream; typedef typename std::basic_string StringType; typedef typename boost::spirit::classic::chset chset_t; typedef typename boost::spirit::classic::chlit chlit_t; typedef typename boost::spirit::classic::scanner< typename std::basic_string::iterator > scanner_t; typedef typename boost::spirit::classic::rule rule_t; // Start grammar definition rule_t Reference, Eq, STag, ETag, LetterOrUnderscoreOrColon, AttValue, CharRef1, CharRef2, CharRef, AmpRef, LTRef, GTRef, AposRef, QuoteRef, CharData, CharDataChars, content, AmpName, LTName, GTName, ClassNameChar, ClassName, Name, XMLDecl, XMLDeclChars, DocTypeDecl, DocTypeDeclChars, ClassIDAttribute, ObjectIDAttribute, ClassNameAttribute, TrackingAttribute, VersionAttribute, UnusedAttribute, Attribute, SignatureAttribute, SerializationWrapper, NameHead, NameTail, AttributeList, S; // XML Character classes chset_t BaseChar, Ideographic, Char, Letter, Digit, CombiningChar, Extender, Sch, NameChar; void init_chset(); bool my_parse( IStream & is, const rule_t &rule_, const CharType delimiter = L'>' ) const ; public: struct return_values { StringType object_name; StringType contents; //class_id_type class_id; int_least16_t class_id; //object_id_type object_id; uint_least32_t object_id; //version_type version; unsigned int version; tracking_type tracking_level; StringType class_name; return_values() : version(0), tracking_level(false) {} } rv; bool parse_start_tag(IStream & is) /*const*/; bool parse_end_tag(IStream & is) const; bool parse_string(IStream & is, StringType & s) /*const*/; void init(IStream & is); bool windup(IStream & is); basic_xml_grammar(); }; } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP ================================================ FILE: include/boost/archive/impl/basic_xml_iarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_iarchive.ipp: // (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 #include // NULL #include // strlen #include #include #include #include #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of xml_text_archive template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_start(const char *name){ // if there's no name if(NULL == name) return; bool result = this->This()->gimpl->parse_start_tag(this->This()->get_is()); if(true != result){ boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); } // don't check start tag at highest level ++depth; } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_end(const char *name){ // if there's no name if(NULL == name) return; bool result = this->This()->gimpl->parse_end_tag(this->This()->get_is()); if(true != result){ boost::serialization::throw_exception( archive_exception(archive_exception::input_stream_error) ); } // don't check start tag at highest level if(0 == --depth) return; if(0 == (this->get_flags() & no_xml_tag_checking)){ // double check that the tag matches what is expected - useful for debug std::size_t parameter_name_length = std::strlen(name); std::size_t object_name_length = this->This()->gimpl->rv.object_name.size(); if(parameter_name_length != object_name_length || ! std::equal( this->This()->gimpl->rv.object_name.begin(), this->This()->gimpl->rv.object_name.end(), name ) ){ boost::serialization::throw_exception( xml_archive_exception( xml_archive_exception::xml_archive_tag_mismatch, name ) ); } } } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_override(object_id_type & t){ t = object_id_type(this->This()->gimpl->rv.object_id); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_override(version_type & t){ t = version_type(this->This()->gimpl->rv.version); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_override(class_id_type & t){ t = class_id_type(this->This()->gimpl->rv.class_id); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_iarchive::load_override(tracking_type & t){ t = this->This()->gimpl->rv.tracking_level; } template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_iarchive::basic_xml_iarchive(unsigned int flags) : detail::common_iarchive(flags), depth(0) {} template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_iarchive::~basic_xml_iarchive(){ } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/basic_xml_oarchive.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // basic_xml_oarchive.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // NULL #include #if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) namespace std{ using ::strlen; } // namespace std #endif #include #include #include #include namespace boost { namespace archive { namespace detail { template struct XML_name { void operator()(CharType t) const{ const unsigned char lookup_table[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // 0-9 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; if((unsigned)t > 127) return; if(0 == lookup_table[(unsigned)t]) boost::serialization::throw_exception( xml_archive_exception( xml_archive_exception::xml_archive_tag_name_error ) ); } }; } // namespace detail /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implemenations of functions common to both types of xml output template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::write_attribute( const char *attribute_name, int t, const char *conjunction ){ this->This()->put(' '); this->This()->put(attribute_name); this->This()->put(conjunction); this->This()->save(t); this->This()->put('"'); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::write_attribute( const char *attribute_name, const char *key ){ this->This()->put(' '); this->This()->put(attribute_name); this->This()->put("=\""); this->This()->save(key); this->This()->put('"'); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::indent(){ int i; for(i = depth; i-- > 0;) this->This()->put('\t'); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_start(const char *name) { if(NULL == name) return; // be sure name has no invalid characters std::for_each(name, name + std::strlen(name), detail::XML_name()); end_preamble(); if(depth > 0){ this->This()->put('\n'); indent(); } ++depth; this->This()->put('<'); this->This()->save(name); pending_preamble = true; indent_next = false; } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_end(const char *name) { if(NULL == name) return; // be sure name has no invalid characters std::for_each(name, name + std::strlen(name), detail::XML_name()); end_preamble(); --depth; if(indent_next){ this->This()->put('\n'); indent(); } indent_next = true; this->This()->put("This()->save(name); this->This()->put('>'); if(0 == depth) this->This()->put('\n'); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::end_preamble(){ if(pending_preamble){ this->This()->put('>'); pending_preamble = false; } } #if 0 template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const object_id_type & t) { int i = t.t; // extra .t is for borland write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override( const object_reference_type & t, int ){ int i = t.t; // extra .t is for borland write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const version_type & t) { int i = t.t; // extra .t is for borland write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); } #endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const object_id_type & t) { // borland doesn't do conversion of STRONG_TYPEDEFs very well const unsigned int i = t; write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override( const object_reference_type & t ){ const unsigned int i = t; write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const version_type & t) { const unsigned int i = t; write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const class_id_type & t) { write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override( const class_id_reference_type & t ){ write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override( const class_id_optional_type & t ){ write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const class_name_type & t) { const char * key = t; if(NULL == key) return; write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::save_override(const tracking_type & t) { write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::init(){ // xml header this->This()->put("\n"); this->This()->put("\n"); // xml document wrapper - outer root this->This()->put("This()->put(">\n"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_xml_oarchive::windup(){ // xml_trailer this->This()->put("\n"); } template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : detail::common_oarchive(flags), depth(0), pending_preamble(false), indent_next(false) { } template BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_xml_oarchive::~basic_xml_oarchive(){ } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/text_iarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_iarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. ////////////////////////////////////////////////////////////////////// // implementation of basic_text_iprimitive overrides for the combination // of template parameters used to implement a text_iprimitive #include // size_t, NULL #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include // RogueWave #include namespace boost { namespace archive { template BOOST_ARCHIVE_DECL void text_iarchive_impl::load(char *s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // Works on all tested platforms is.read(s, size); s[size] = '\0'; } template BOOST_ARCHIVE_DECL void text_iarchive_impl::load(std::string &s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(size); if(0 < size) is.read(&(*s.begin()), size); } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_DECL void text_iarchive_impl::load(wchar_t *ws) { std::size_t size; * this->This() >> size; // skip separating space is.get(); is.read((char *)ws, size * sizeof(wchar_t)/sizeof(char)); ws[size] = L'\0'; } #endif // BOOST_NO_INTRINSIC_WCHAR_T #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_DECL void text_iarchive_impl::load(std::wstring &ws) { std::size_t size; * this->This() >> size; // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != ws.data()) #endif ws.resize(size); // skip separating space is.get(); is.read((char *)ws.data(), size * sizeof(wchar_t)/sizeof(char)); } #endif // BOOST_NO_STD_WSTRING #endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_DECL void text_iarchive_impl::load_override(class_name_type & t){ basic_text_iarchive::load_override(t); } template BOOST_ARCHIVE_DECL void text_iarchive_impl::init(){ basic_text_iarchive::init(); } template BOOST_ARCHIVE_DECL text_iarchive_impl::text_iarchive_impl( std::istream & is, unsigned int flags ) : basic_text_iprimitive( is, 0 != (flags & no_codecvt) ), basic_text_iarchive(flags) {} } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/text_oarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_oarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #ifndef BOOST_NO_CWCHAR #include #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ using ::wcslen; } #endif #endif #include namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // implementation of basic_text_oprimitive overrides for the combination // of template parameters used to create a text_oprimitive template BOOST_ARCHIVE_DECL void text_oarchive_impl::save(const char * s) { const std::size_t len = std::ostream::traits_type::length(s); *this->This() << len; this->This()->newtoken(); os << s; } template BOOST_ARCHIVE_DECL void text_oarchive_impl::save(const std::string &s) { const std::size_t size = s.size(); *this->This() << size; this->This()->newtoken(); os << s; } #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_DECL void text_oarchive_impl::save(const wchar_t * ws) { const std::size_t l = std::wcslen(ws); * this->This() << l; this->This()->newtoken(); os.write((const char *)ws, l * sizeof(wchar_t)/sizeof(char)); } #endif #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_DECL void text_oarchive_impl::save(const std::wstring &ws) { const std::size_t l = ws.size(); * this->This() << l; this->This()->newtoken(); os.write((const char *)(ws.data()), l * sizeof(wchar_t)/sizeof(char)); } #endif #endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_DECL text_oarchive_impl::text_oarchive_impl( std::ostream & os, unsigned int flags ) : basic_text_oprimitive( os, 0 != (flags & no_codecvt) ), basic_text_oarchive(flags) { } template BOOST_ARCHIVE_DECL void text_oarchive_impl::save_binary(const void *address, std::size_t count){ put('\n'); this->end_preamble(); #if ! defined(__MWERKS__) this->basic_text_oprimitive::save_binary( #else this->basic_text_oprimitive::save_binary( #endif address, count ); this->delimiter = this->eol; } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/text_wiarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_text_wiarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // size_t, NULL #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include // fixup for RogueWave #ifndef BOOST_NO_STD_WSTREAMBUF #include namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // implementation of wiprimtives functions // template BOOST_WARCHIVE_DECL void text_wiarchive_impl::load(char *s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); while(size-- > 0){ *s++ = is.narrow(is.get(), '\0'); } *s = '\0'; } template BOOST_WARCHIVE_DECL void text_wiarchive_impl::load(std::string &s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(0); s.reserve(size); while(size-- > 0){ char x = is.narrow(is.get(), '\0'); s += x; } } #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_WARCHIVE_DECL void text_wiarchive_impl::load(wchar_t *s) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // Works on all tested platforms is.read(s, size); s[size] = L'\0'; } #endif #ifndef BOOST_NO_STD_WSTRING template BOOST_WARCHIVE_DECL void text_wiarchive_impl::load(std::wstring &ws) { std::size_t size; * this->This() >> size; // skip separating space is.get(); // borland complains about resize // borland de-allocator fixup #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != ws.data()) #endif ws.resize(size); // note breaking a rule here - is this a problem on some platform is.read(const_cast(ws.data()), size); } #endif template BOOST_WARCHIVE_DECL text_wiarchive_impl::text_wiarchive_impl( std::wistream & is, unsigned int flags ) : basic_text_iprimitive( is, 0 != (flags & no_codecvt) ), basic_text_iarchive(flags) { } } // archive } // boost #endif // BOOST_NO_STD_WSTREAMBUF ================================================ FILE: include/boost/archive/impl/text_woarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_woarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #ifndef BOOST_NO_STD_WSTREAMBUF #include #include // size_t #if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) namespace std{ using ::strlen; using ::size_t; } // namespace std #endif #include #include namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // implementation of woarchive functions // template BOOST_WARCHIVE_DECL void text_woarchive_impl::save(const char *s) { // note: superfluous local variable fixes borland warning const std::size_t size = std::strlen(s); * this->This() << size; this->This()->newtoken(); while(*s != '\0') os.put(os.widen(*s++)); } template BOOST_WARCHIVE_DECL void text_woarchive_impl::save(const std::string &s) { const std::size_t size = s.size(); * this->This() << size; this->This()->newtoken(); const char * cptr = s.data(); for(std::size_t i = size; i-- > 0;) os.put(os.widen(*cptr++)); } #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_WARCHIVE_DECL void text_woarchive_impl::save(const wchar_t *ws) { const std::size_t size = std::wostream::traits_type::length(ws); * this->This() << size; this->This()->newtoken(); os.write(ws, size); } #endif #ifndef BOOST_NO_STD_WSTRING template BOOST_WARCHIVE_DECL void text_woarchive_impl::save(const std::wstring &ws) { const std::size_t size = ws.length(); * this->This() << size; this->This()->newtoken(); os.write(ws.data(), size); } #endif } // namespace archive } // namespace boost #endif ================================================ FILE: include/boost/archive/impl/xml_iarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_iarchive_impl.cpp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // memcpy #include // NULL #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } // namespace std #endif #ifndef BOOST_NO_CWCHAR #include // mbstate_t and mbrtowc #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::mbstate_t; using ::mbrtowc; } // namespace std #endif #endif // BOOST_NO_CWCHAR #include // RogueWave and Dinkumware #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #include #include #include #include #include #include #include "basic_xml_grammar.hpp" namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implemenations of functions specific to char archives // wide char stuff used by char archives #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_DECL void xml_iarchive_impl::load(std::wstring &ws){ std::string s; bool result = gimpl->parse_string(is, s); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != ws.data()) #endif ws.resize(0); std::mbstate_t mbs = std::mbstate_t(); const char * start = s.data(); const char * end = start + s.size(); while(start < end){ wchar_t wc; std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs); if(count == static_cast(-1)) boost::serialization::throw_exception( iterators::dataflow_exception( iterators::dataflow_exception::invalid_conversion ) ); if(count == static_cast(-2)) continue; start += count; ws += wc; } } #endif // BOOST_NO_STD_WSTRING #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_DECL void xml_iarchive_impl::load(wchar_t * ws){ std::string s; bool result = gimpl->parse_string(is, s); if(! result) boost::serialization::throw_exception( xml_archive_exception( xml_archive_exception::xml_archive_parsing_error ) ); std::mbstate_t mbs = std::mbstate_t(); const char * start = s.data(); const char * end = start + s.size(); while(start < end){ wchar_t wc; std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs); if(static_cast(-1) == length) boost::serialization::throw_exception( iterators::dataflow_exception( iterators::dataflow_exception::invalid_conversion ) ); if(static_cast(-2) == length) continue; start += length; *ws++ = wc; } *ws = L'\0'; } #endif // BOOST_NO_INTRINSIC_WCHAR_T #endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_DECL void xml_iarchive_impl::load(std::string &s){ bool result = gimpl->parse_string(is, s); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); } template BOOST_ARCHIVE_DECL void xml_iarchive_impl::load(char * s){ std::string tstring; bool result = gimpl->parse_string(is, tstring); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); std::memcpy(s, tstring.data(), tstring.size()); s[tstring.size()] = 0; } template BOOST_ARCHIVE_DECL void xml_iarchive_impl::load_override(class_name_type & t){ const std::string & s = gimpl->rv.class_name; if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_class_name) ); char * tptr = t; std::memcpy(tptr, s.data(), s.size()); tptr[s.size()] = '\0'; } template BOOST_ARCHIVE_DECL void xml_iarchive_impl::init(){ gimpl->init(is); this->set_library_version( boost::serialization::library_version_type(gimpl->rv.version) ); } template BOOST_ARCHIVE_DECL xml_iarchive_impl::xml_iarchive_impl( std::istream &is_, unsigned int flags ) : basic_text_iprimitive( is_, 0 != (flags & no_codecvt) ), basic_xml_iarchive(flags), gimpl(new xml_grammar()) {} template BOOST_ARCHIVE_DECL xml_iarchive_impl::~xml_iarchive_impl(){ if(boost::core::uncaught_exceptions() > 0) return; if(0 == (this->get_flags() & no_header)){ gimpl->windup(is); } } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/xml_oarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_oarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include // std::copy #include #include // strlen #include // msvc 6.0 needs this to suppress warnings #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::strlen; } // namespace std #endif #include #include #include #ifndef BOOST_NO_CWCHAR #include #include #endif namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implemenations of functions specific to char archives // wide char stuff used by char archives #ifndef BOOST_NO_CWCHAR // copy chars to output escaping to xml and translating wide chars to mb chars template void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){ typedef boost::archive::iterators::mb_from_wchar< boost::archive::iterators::xml_escape > translator; std::copy( translator(begin), translator(end), boost::archive::iterators::ostream_iterator(os) ); } #ifndef BOOST_NO_STD_WSTRING template BOOST_ARCHIVE_DECL void xml_oarchive_impl::save(const std::wstring & ws){ // at least one library doesn't typedef value_type for strings // so rather than using string directly make a pointer iterator out of it // save_iterator(os, ws.data(), ws.data() + std::wcslen(ws.data())); save_iterator(os, ws.data(), ws.data() + ws.size()); } #endif #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_DECL void xml_oarchive_impl::save(const wchar_t * ws){ save_iterator(os, ws, ws + std::wcslen(ws)); } #endif #endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_DECL void xml_oarchive_impl::save(const std::string & s){ // at least one library doesn't typedef value_type for strings // so rather than using string directly make a pointer iterator out of it typedef boost::archive::iterators::xml_escape< const char * > xml_escape_translator; std::copy( xml_escape_translator(s.data()), xml_escape_translator(s.data()+ s.size()), boost::archive::iterators::ostream_iterator(os) ); } template BOOST_ARCHIVE_DECL void xml_oarchive_impl::save(const char * s){ typedef boost::archive::iterators::xml_escape< const char * > xml_escape_translator; std::copy( xml_escape_translator(s), xml_escape_translator(s + std::strlen(s)), boost::archive::iterators::ostream_iterator(os) ); } template BOOST_ARCHIVE_DECL xml_oarchive_impl::xml_oarchive_impl( std::ostream & os_, unsigned int flags ) : basic_text_oprimitive( os_, 0 != (flags & no_codecvt) ), basic_xml_oarchive(flags) {} template BOOST_ARCHIVE_DECL void xml_oarchive_impl::save_binary(const void *address, std::size_t count){ this->end_preamble(); #if ! defined(__MWERKS__) this->basic_text_oprimitive::save_binary( #else this->basic_text_oprimitive::save_binary( #endif address, count ); this->indent_next = true; } template BOOST_ARCHIVE_DECL xml_oarchive_impl::~xml_oarchive_impl(){ if(boost::core::uncaught_exceptions() > 0) return; if(0 == (this->get_flags() & no_header)){ this->put("\n"); } } } // namespace archive } // namespace boost ================================================ FILE: include/boost/archive/impl/xml_wiarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_wiarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } //std #endif #include // msvc 6.0 needs this to suppress warnings #ifndef BOOST_NO_STD_WSTREAMBUF #include #include // std::copy #include // Dinkumware and RogueWave #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) #include #endif #include #include #include #include #include #include #include #include #include #include "basic_xml_grammar.hpp" namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implemenations of functions specific to wide char archives namespace { // anonymous void copy_to_ptr(char * s, const std::wstring & ws){ std::copy( iterators::mb_from_wchar( ws.begin() ), iterators::mb_from_wchar( ws.end() ), s ); s[ws.size()] = 0; } } // anonymous template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::load(std::string & s){ std::wstring ws; bool result = gimpl->parse_string(is, ws); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) if(NULL != s.data()) #endif s.resize(0); s.reserve(ws.size()); std::copy( iterators::mb_from_wchar( ws.begin() ), iterators::mb_from_wchar( ws.end() ), std::back_inserter(s) ); } #ifndef BOOST_NO_STD_WSTRING template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::load(std::wstring & ws){ bool result = gimpl->parse_string(is, ws); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); } #endif template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::load(char * s){ std::wstring ws; bool result = gimpl->parse_string(is, ws); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); copy_to_ptr(s, ws); } #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::load(wchar_t * ws){ std::wstring twstring; bool result = gimpl->parse_string(is, twstring); if(! result) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) ); std::memcpy(ws, twstring.c_str(), twstring.size()); ws[twstring.size()] = L'\0'; } #endif template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::load_override(class_name_type & t){ const std::wstring & ws = gimpl->rv.class_name; if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) boost::serialization::throw_exception( archive_exception(archive_exception::invalid_class_name) ); copy_to_ptr(t, ws); } template BOOST_WARCHIVE_DECL void xml_wiarchive_impl::init(){ gimpl->init(is); this->set_library_version( boost::serialization::library_version_type(gimpl->rv.version) ); } template BOOST_WARCHIVE_DECL xml_wiarchive_impl::xml_wiarchive_impl( std::wistream &is_, unsigned int flags ) : basic_text_iprimitive( is_, true // don't change the codecvt - use the one below ), basic_xml_iarchive(flags), gimpl(new xml_wgrammar()) { if(0 == (flags & no_codecvt)){ archive_locale = std::locale( is_.getloc(), new boost::archive::detail::utf8_codecvt_facet ); // libstdc++ crashes without this is_.sync(); is_.imbue(archive_locale); } } template BOOST_WARCHIVE_DECL xml_wiarchive_impl::~xml_wiarchive_impl(){ if(boost::core::uncaught_exceptions() > 0) return; if(0 == (this->get_flags() & no_header)){ gimpl->windup(is); } } } // namespace archive } // namespace boost #endif // BOOST_NO_STD_WSTREAMBUF ================================================ FILE: include/boost/archive/impl/xml_woarchive_impl.ipp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_woarchive_impl.ipp: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #ifndef BOOST_NO_STD_WSTREAMBUF #include #include #include // std::copy #include #include // strlen #include // mbtowc #ifndef BOOST_NO_CWCHAR #include // wcslen #endif #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::strlen; #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) using ::mbtowc; using ::wcslen; #endif } // namespace std #endif #include #include #include #include #include #include #include #include namespace boost { namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implemenations of functions specific to wide char archives // copy chars to output escaping to xml and widening characters as we go template void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ typedef iterators::wchar_from_mb< iterators::xml_escape > xmbtows; std::copy( xmbtows(begin), xmbtows(end), boost::archive::iterators::ostream_iterator(os) ); } template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save(const std::string & s){ // note: we don't use s.begin() and s.end() because dinkumware // doesn't have string::value_type defined. So use a wrapper // around these values to implement the definitions. const char * begin = s.data(); const char * end = begin + s.size(); save_iterator(os, begin, end); } #ifndef BOOST_NO_STD_WSTRING template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save(const std::wstring & ws){ #if 0 typedef iterators::xml_escape xmbtows; std::copy( xmbtows(ws.begin()), xmbtows(ws.end()), boost::archive::iterators::ostream_iterator(os) ); #endif typedef iterators::xml_escape xmbtows; std::copy( xmbtows(ws.data()), xmbtows(ws.data() + ws.size()), boost::archive::iterators::ostream_iterator(os) ); } #endif //BOOST_NO_STD_WSTRING template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save(const char * s){ save_iterator(os, s, s + std::strlen(s)); } #ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save(const wchar_t * ws){ typedef iterators::xml_escape xmbtows; std::copy( xmbtows(ws), xmbtows(ws + std::wcslen(ws)), boost::archive::iterators::ostream_iterator(os) ); } #endif template BOOST_WARCHIVE_DECL xml_woarchive_impl::xml_woarchive_impl( std::wostream & os_, unsigned int flags ) : basic_text_oprimitive( os_, true // don't change the codecvt - use the one below ), basic_xml_oarchive(flags) { if(0 == (flags & no_codecvt)){ archive_locale = std::locale( os_.getloc(), new boost::archive::detail::utf8_codecvt_facet ); os_.flush(); os_.imbue(archive_locale); } } template BOOST_WARCHIVE_DECL xml_woarchive_impl::~xml_woarchive_impl(){ if(boost::core::uncaught_exceptions() > 0) return; if(0 == (this->get_flags() & no_header)){ os << L""; } } template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save_binary( const void *address, std::size_t count ){ this->end_preamble(); #if ! defined(__MWERKS__) this->basic_text_oprimitive::save_binary( #else this->basic_text_oprimitive::save_binary( #endif address, count ); this->indent_next = true; } } // namespace archive } // namespace boost #endif //BOOST_NO_STD_WSTREAMBUF ================================================ FILE: include/boost/archive/iterators/base64_exception.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP #define BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // base64_exception.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 #ifndef BOOST_NO_EXCEPTIONS #include #include namespace boost { namespace archive { namespace iterators { ////////////////////////////////////////////////////////////////////// // exceptions thrown by base64s // class base64_exception : public std::exception { public: typedef enum { invalid_code, // attempt to encode a value > 6 bits invalid_character, // decode a value not in base64 char set other_exception } exception_code; exception_code code; base64_exception(exception_code c = other_exception) : code(c) {} virtual const char *what( ) const BOOST_NOEXCEPT_OR_NOTHROW { const char *msg = "unknown exception code"; switch(code){ case invalid_code: msg = "attempt to encode a value > 6 bits"; break; case invalid_character: msg = "attempt to decode a value not in base64 char set"; break; default: BOOST_ASSERT(false); break; } return msg; } }; } // namespace iterators } // namespace archive } // namespace boost #endif //BOOST_NO_EXCEPTIONS #endif //BOOST_ARCHIVE_ITERATORS_ARCHIVE_EXCEPTION_HPP ================================================ FILE: include/boost/archive/iterators/base64_from_binary.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP #define BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // base64_from_binary.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 #include // size_t #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // convert binary integers to base64 characters namespace detail { template struct from_6_bit { typedef CharType result_type; CharType operator()(CharType t) const{ static const char * lookup_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/"; BOOST_ASSERT(t < 64); return lookup_table[static_cast(t)]; } }; } // namespace detail // note: what we would like to do is // template // typedef transform_iterator< // from_6_bit, // transform_width // > base64_from_binary; // but C++ won't accept this. Rather than using a "type generator" and // using a different syntax, make a derivation which should be equivalent. // // Another issue addressed here is that the transform_iterator doesn't have // a templated constructor. This makes it incompatible with the dataflow // ideal. This is also addressed here. //template template< class Base, class CharType = typename boost::iterator_value::type > class base64_from_binary : public transform_iterator< detail::from_6_bit, Base > { friend class boost::iterator_core_access; typedef transform_iterator< typename detail::from_6_bit, Base > super_t; public: // make composable by using templated constructor template base64_from_binary(T start) : super_t( Base(static_cast< T >(start)), detail::from_6_bit() ) {} // intel 7.1 doesn't like default copy constructor base64_from_binary(const base64_from_binary & rhs) : super_t( Base(rhs.base_reference()), detail::from_6_bit() ) {} // base64_from_binary(){}; }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP ================================================ FILE: include/boost/archive/iterators/binary_from_base64.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP #define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // binary_from_base64.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 #include #include #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // convert base64 characters to binary data namespace detail { template struct to_6_bit { typedef CharType result_type; CharType operator()(CharType t) const{ static const signed char lookup_table[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // render '=' as 0 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 }; // metrowerks trips this assertion - how come? #if ! defined(__MWERKS__) BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); #endif signed char value = -1; if((unsigned)t <= 127) value = lookup_table[(unsigned)t]; if(-1 == value) boost::serialization::throw_exception( dataflow_exception(dataflow_exception::invalid_base64_character) ); return value; } }; } // namespace detail // note: what we would like to do is // template // typedef transform_iterator< // from_6_bit, // transform_width // > base64_from_binary; // but C++ won't accept this. Rather than using a "type generator" and // using a different syntax, make a derivation which should be equivalent. // // Another issue addressed here is that the transform_iterator doesn't have // a templated constructor. This makes it incompatible with the dataflow // ideal. This is also addressed here. template< class Base, class CharType = typename boost::iterator_value::type > class binary_from_base64 : public transform_iterator< detail::to_6_bit, Base > { friend class boost::iterator_core_access; typedef transform_iterator< detail::to_6_bit, Base > super_t; public: // make composable by using templated constructor template binary_from_base64(T start) : super_t( Base(static_cast< T >(start)), detail::to_6_bit() ) {} // intel 7.1 doesn't like default copy constructor binary_from_base64(const binary_from_base64 & rhs) : super_t( Base(rhs.base_reference()), detail::to_6_bit() ) {} // binary_from_base64(){}; }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP ================================================ FILE: include/boost/archive/iterators/dataflow.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP #define BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // dataflow.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 #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace archive { namespace iterators { // poor man's tri-state struct tri_state { enum state_enum { is_false = false, is_true = true, is_indeterminant } m_state; // convert to bool operator bool (){ BOOST_ASSERT(is_indeterminant != m_state); return is_true == m_state ? true : false; } // assign from bool tri_state & operator=(bool rhs) { m_state = rhs ? is_true : is_false; return *this; } tri_state(bool rhs) : m_state(rhs ? is_true : is_false) {} tri_state(state_enum state) : m_state(state) {} bool operator==(const tri_state & rhs) const { return m_state == rhs.m_state; } bool operator!=(const tri_state & rhs) const { return m_state != rhs.m_state; } }; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implement functions common to dataflow iterators template class dataflow { bool m_eoi; protected: // test for iterator equality tri_state equal(const Derived & rhs) const { if(m_eoi && rhs.m_eoi) return true; if(m_eoi || rhs.m_eoi) return false; return tri_state(tri_state::is_indeterminant); } void eoi(bool tf){ m_eoi = tf; } bool eoi() const { return m_eoi; } public: dataflow(bool tf) : m_eoi(tf) {} dataflow() : // used for iterator end m_eoi(true) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP ================================================ FILE: include/boost/archive/iterators/dataflow_exception.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP #define BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // dataflow_exception.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 #ifndef BOOST_NO_EXCEPTIONS #include #endif //BOOST_NO_EXCEPTIONS #include namespace boost { namespace archive { namespace iterators { ////////////////////////////////////////////////////////////////////// // exceptions thrown by dataflows // class dataflow_exception : public std::exception { public: typedef enum { invalid_6_bitcode, invalid_base64_character, invalid_xml_escape_sequence, comparison_not_permitted, invalid_conversion, other_exception } exception_code; exception_code code; dataflow_exception(exception_code c = other_exception) : code(c) {} const char *what( ) const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { const char *msg = "unknown exception code"; switch(code){ case invalid_6_bitcode: msg = "attempt to encode a value > 6 bits"; break; case invalid_base64_character: msg = "attempt to decode a value not in base64 char set"; break; case invalid_xml_escape_sequence: msg = "invalid xml escape_sequence"; break; case comparison_not_permitted: msg = "cannot invoke iterator comparison now"; break; case invalid_conversion: msg = "invalid multbyte/wide char conversion"; break; default: BOOST_ASSERT(false); break; } return msg; } }; } // namespace iterators } // namespace archive } // namespace boost #endif //BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP ================================================ FILE: include/boost/archive/iterators/escape.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP #define BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // escape.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 #include // NULL #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // insert escapes into text template class escape : public boost::iterator_adaptor< Derived, Base, typename boost::iterator_value::type, single_pass_traversal_tag, typename boost::iterator_value::type > { typedef typename boost::iterator_value::type base_value_type; typedef typename boost::iterator_reference::type reference_type; friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< Derived, Base, base_value_type, single_pass_traversal_tag, base_value_type > super_t; typedef escape this_t; void dereference_impl() { m_current_value = static_cast(this)->fill(m_bnext, m_bend); m_full = true; } //Access the value referred to reference_type dereference() const { if(!m_full) const_cast(this)->dereference_impl(); return m_current_value; } bool equal(const this_t & rhs) const { if(m_full){ if(! rhs.m_full) const_cast(& rhs)->dereference_impl(); } else{ if(rhs.m_full) const_cast(this)->dereference_impl(); } if(m_bnext != rhs.m_bnext) return false; if(this->base_reference() != rhs.base_reference()) return false; return true; } void increment(){ if(m_bnext != m_bend && ++m_bnext < m_bend){ m_current_value = *m_bnext; return; } ++(this->base_reference()); m_bnext = NULL; m_bend = NULL; m_full = false; } // buffer to handle pending characters const base_value_type *m_bnext; const base_value_type *m_bend; bool m_full; base_value_type m_current_value; public: escape(Base base) : super_t(base), m_bnext(NULL), m_bend(NULL), m_full(false), m_current_value(0) { } }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP ================================================ FILE: include/boost/archive/iterators/insert_linebreaks.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP #define BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // insert_linebreaks.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 #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::memcpy; } #endif #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // insert line break every N characters template< class Base, int N, class CharType = typename boost::iterator_value::type > class insert_linebreaks : public iterator_adaptor< insert_linebreaks, Base, CharType, single_pass_traversal_tag, CharType > { private: friend class boost::iterator_core_access; typedef iterator_adaptor< insert_linebreaks, Base, CharType, single_pass_traversal_tag, CharType > super_t; bool equal(const insert_linebreaks & rhs) const { return // m_count == rhs.m_count // && base_reference() == rhs.base_reference() this->base_reference() == rhs.base_reference() ; } void increment() { if(m_count == N){ m_count = 0; return; } ++m_count; ++(this->base_reference()); } CharType dereference() const { if(m_count == N) return '\n'; return * (this->base_reference()); } unsigned int m_count; public: // make composable by using templated constructor template insert_linebreaks(T start) : super_t(Base(static_cast< T >(start))), m_count(0) {} // intel 7.1 doesn't like default copy constructor insert_linebreaks(const insert_linebreaks & rhs) : super_t(rhs.base_reference()), m_count(rhs.m_count) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP ================================================ FILE: include/boost/archive/iterators/istream_iterator.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP #define BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // istream_iterator.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. // note: this is a custom version of the standard istream_iterator. // This is necessary as the standard version doesn't work as expected // for wchar_t based streams on systems for which wchar_t not a true // type but rather a synonym for some integer type. #include // NULL #include #include namespace boost { namespace archive { namespace iterators { // given a type, make an input iterator based on a pointer to that type template class istream_iterator : public boost::iterator_facade< istream_iterator, Elem, std::input_iterator_tag, Elem > { friend class boost::iterator_core_access; typedef istream_iterator this_t ; typedef typename boost::iterator_facade< istream_iterator, Elem, std::input_iterator_tag, Elem > super_t; typedef typename std::basic_istream istream_type; bool equal(const this_t & rhs) const { // note: only works for comparison against end of stream return m_istream == rhs.m_istream; } //Access the value referred to Elem dereference() const { return static_cast(m_istream->peek()); } void increment(){ if(NULL != m_istream){ m_istream->ignore(1); } } istream_type *m_istream; Elem m_current_value; public: istream_iterator(istream_type & is) : m_istream(& is) { //increment(); } istream_iterator() : m_istream(NULL), m_current_value(NULL) {} istream_iterator(const istream_iterator & rhs) : m_istream(rhs.m_istream), m_current_value(rhs.m_current_value) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP ================================================ FILE: include/boost/archive/iterators/mb_from_wchar.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP #define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // mb_from_wchar.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 #include // size_t #include // memcpy #ifndef BOOST_NO_CWCHAR #include // mbstate_t #endif #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::mbstate_t; using ::memcpy; } // namespace std #endif #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // class used by text archives to translate wide strings and to char // strings of the currently selected locale template // the input iterator class mb_from_wchar : public boost::iterator_adaptor< mb_from_wchar, Base, wchar_t, single_pass_traversal_tag, char > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< mb_from_wchar, Base, wchar_t, single_pass_traversal_tag, char > super_t; typedef mb_from_wchar this_t; char dereference_impl() { if(! m_full){ fill(); m_full = true; } return m_buffer[m_bnext]; } char dereference() const { return (const_cast(this))->dereference_impl(); } // test for iterator equality bool equal(const mb_from_wchar & rhs) const { // once the value is filled, the base_reference has been incremented // so don't permit comparison anymore. return 0 == m_bend && 0 == m_bnext && this->base_reference() == rhs.base_reference() ; } void fill(){ wchar_t value = * this->base_reference(); const wchar_t *wend; char *bend; BOOST_VERIFY( m_codecvt_facet.out( m_mbs, & value, & value + 1, wend, m_buffer, m_buffer + sizeof(m_buffer), bend ) == std::codecvt_base::ok ); m_bnext = 0; m_bend = bend - m_buffer; } void increment(){ if(++m_bnext < m_bend) return; m_bend = m_bnext = 0; ++(this->base_reference()); m_full = false; } boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; std::mbstate_t m_mbs; // buffer to handle pending characters char m_buffer[9 /* MB_CUR_MAX */]; std::size_t m_bend; std::size_t m_bnext; bool m_full; public: // make composable by using templated constructor template mb_from_wchar(T start) : super_t(Base(static_cast< T >(start))), m_mbs(std::mbstate_t()), m_bend(0), m_bnext(0), m_full(false) {} // intel 7.1 doesn't like default copy constructor mb_from_wchar(const mb_from_wchar & rhs) : super_t(rhs.base_reference()), m_mbs(rhs.m_mbs), m_bend(rhs.m_bend), m_bnext(rhs.m_bnext), m_full(rhs.m_full) { std::memcpy(m_buffer, rhs.m_buffer, sizeof(m_buffer)); } }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP ================================================ FILE: include/boost/archive/iterators/ostream_iterator.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP #define BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // ostream_iterator.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. // note: this is a custom version of the standard ostream_iterator. // This is necessary as the standard version doesn't work as expected // for wchar_t based streams on systems for which wchar_t not a true // type but rather a synonym for some integer type. #include #include namespace boost { namespace archive { namespace iterators { // given a type, make an input iterator based on a pointer to that type template class ostream_iterator : public boost::iterator_facade< ostream_iterator, Elem, std::output_iterator_tag, ostream_iterator & > { friend class boost::iterator_core_access; typedef ostream_iterator this_t ; typedef Elem char_type; typedef std::basic_ostream ostream_type; //emulate the behavior of std::ostream ostream_iterator & dereference() const { return const_cast(*this); } bool equal(const this_t & rhs) const { return m_ostream == rhs.m_ostream; } void increment(){} protected: ostream_type *m_ostream; void put_val(char_type e){ if(NULL != m_ostream){ m_ostream->put(e); if(! m_ostream->good()) m_ostream = NULL; } } public: this_t & operator=(char_type c){ put_val(c); return *this; } ostream_iterator(ostream_type & os) : m_ostream (& os) {} ostream_iterator() : m_ostream (NULL) {} ostream_iterator(const ostream_iterator & rhs) : m_ostream (rhs.m_ostream) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP ================================================ FILE: include/boost/archive/iterators/remove_whitespace.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP #define BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // remove_whitespace.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 #include #include #include // here is the default standard implementation of the functor used // by the filter iterator to remove spaces. Unfortunately usage // of this implementation in combination with spirit trips a bug // VC 6.5. The only way I can find to work around it is to // implement a special non-standard version for this platform #ifndef BOOST_NO_CWCTYPE #include // iswspace #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::iswspace; } #endif #endif #include // isspace #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::isspace; } #endif #if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) // this is required for the RW STL on Linux and Tru64. #undef isspace #undef iswspace #endif namespace { // anonymous template struct remove_whitespace_predicate; template<> struct remove_whitespace_predicate { bool operator()(unsigned char t){ return ! std::isspace(t); } }; #ifndef BOOST_NO_CWCHAR template<> struct remove_whitespace_predicate { bool operator()(wchar_t t){ return ! std::iswspace(t); } }; #endif } // namespace anonymous /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // convert base64 file data (including whitespace and padding) to binary namespace boost { namespace archive { namespace iterators { // custom version of filter iterator which doesn't look ahead further than // necessary template class filter_iterator : public boost::iterator_adaptor< filter_iterator, Base, use_default, single_pass_traversal_tag > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< filter_iterator, Base, use_default, single_pass_traversal_tag > super_t; typedef filter_iterator this_t; typedef typename super_t::reference reference_type; reference_type dereference_impl(){ if(! m_full){ while(! m_predicate(* this->base_reference())) ++(this->base_reference()); m_full = true; } return * this->base_reference(); } reference_type dereference() const { return const_cast(this)->dereference_impl(); } Predicate m_predicate; bool m_full; public: // note: this function is public only because comeau compiler complained // I don't know if this is because the compiler is wrong or what void increment(){ m_full = false; ++(this->base_reference()); } filter_iterator(Base start) : super_t(start), m_full(false) {} filter_iterator(){} }; template class remove_whitespace : public filter_iterator< remove_whitespace_predicate< typename boost::iterator_value::type //typename Base::value_type >, Base > { friend class boost::iterator_core_access; typedef filter_iterator< remove_whitespace_predicate< typename boost::iterator_value::type //typename Base::value_type >, Base > super_t; public: // remove_whitespace(){} // why is this needed? // make composable by using templated constructor template remove_whitespace(T start) : super_t(Base(static_cast< T >(start))) {} // intel 7.1 doesn't like default copy constructor remove_whitespace(const remove_whitespace & rhs) : super_t(rhs.base_reference()) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP ================================================ FILE: include/boost/archive/iterators/transform_width.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP #define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // transform_width.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. // iterator which takes elements of x bits and returns elements of y bits. // used to change streams of 8 bit characters into streams of 6 bit characters. // and vice-versa for implementing base64 encodeing/decoding. Be very careful // when using and end iterator. end is only reliable detected when the input // stream length is some common multiple of x and y. E.G. Base64 6 bit // character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters // or 3 8 bit characters #include #include #include // std::min namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // class used by text archives to translate char strings to wchar_t // strings of the currently selected locale template< class Base, int BitsOut, int BitsIn, class CharType = typename boost::iterator_value::type // output character > class transform_width : public boost::iterator_adaptor< transform_width, Base, CharType, single_pass_traversal_tag, CharType > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< transform_width, Base, CharType, single_pass_traversal_tag, CharType > super_t; typedef transform_width this_t; typedef typename iterator_value::type base_value_type; void fill(); CharType dereference() const { if(!m_buffer_out_full) const_cast(this)->fill(); return m_buffer_out; } bool equal_impl(const this_t & rhs){ if(BitsIn < BitsOut) // discard any left over bits return this->base_reference() == rhs.base_reference(); else{ // BitsIn > BitsOut // zero fill if(this->base_reference() == rhs.base_reference()){ m_end_of_sequence = true; return 0 == m_remaining_bits; } return false; } } // standard iterator interface bool equal(const this_t & rhs) const { return const_cast(this)->equal_impl(rhs); } void increment(){ m_buffer_out_full = false; } bool m_buffer_out_full; CharType m_buffer_out; // last read element from input base_value_type m_buffer_in; // number of bits to left in the input buffer. unsigned int m_remaining_bits; // flag to indicate we've reached end of data. bool m_end_of_sequence; public: // make composable by using templated constructor template transform_width(T start) : super_t(Base(static_cast< T >(start))), m_buffer_out_full(false), m_buffer_out(0), // To disable GCC warning, but not truly necessary //(m_buffer_in will be initialized later before being //used because m_remaining_bits == 0) m_buffer_in(0), m_remaining_bits(0), m_end_of_sequence(false) {} // intel 7.1 doesn't like default copy constructor transform_width(const transform_width & rhs) : super_t(rhs.base_reference()), m_buffer_out_full(rhs.m_buffer_out_full), m_buffer_out(rhs.m_buffer_out), m_buffer_in(rhs.m_buffer_in), m_remaining_bits(rhs.m_remaining_bits), m_end_of_sequence(false) {} }; template< class Base, int BitsOut, int BitsIn, class CharType > void transform_width::fill() { unsigned int missing_bits = BitsOut; m_buffer_out = 0; do{ if(0 == m_remaining_bits){ if(m_end_of_sequence){ m_buffer_in = 0; m_remaining_bits = missing_bits; } else{ m_buffer_in = * this->base_reference()++; m_remaining_bits = BitsIn; } } // append these bits to the next output // up to the size of the output unsigned int i = (std::min)(missing_bits, m_remaining_bits); // shift interesting bits to least significant position base_value_type j = m_buffer_in >> (m_remaining_bits - i); // and mask off the un interesting higher bits // note presumption of twos complement notation j &= (1 << i) - 1; // append then interesting bits to the output value m_buffer_out <<= i; m_buffer_out |= j; // and update counters missing_bits -= i; m_remaining_bits -= i; }while(0 < missing_bits); m_buffer_out_full = true; } } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP ================================================ FILE: include/boost/archive/iterators/unescape.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP #define BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // unescape.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 #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // class used by text archives to translate char strings to wchar_t // strings of the currently selected locale template class unescape : public boost::iterator_adaptor< unescape, Base, typename pointee::type, single_pass_traversal_tag, typename pointee::type > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< unescape, Base, typename pointee::type, single_pass_traversal_tag, typename pointee::type > super_t; typedef unescape this_t; public: typedef typename this_t::value_type value_type; typedef typename this_t::reference reference; private: value_type dereference_impl() { if(! m_full){ m_current_value = static_cast(this)->drain(); m_full = true; } return m_current_value; } reference dereference() const { return const_cast(this)->dereference_impl(); } value_type m_current_value; bool m_full; void increment(){ ++(this->base_reference()); dereference_impl(); m_full = false; } public: unescape(Base base) : super_t(base), m_full(false) {} }; } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP ================================================ FILE: include/boost/archive/iterators/wchar_from_mb.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP #define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // wchar_from_mb.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 #include // size_t #ifndef BOOST_NO_CWCHAR #include // mbstate_t #endif #include // copy #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::mbstate_t; } // namespace std #endif #include #include #include #include #include #include #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // class used by text archives to translate char strings to wchar_t // strings of the currently selected locale template class wchar_from_mb : public boost::iterator_adaptor< wchar_from_mb, Base, wchar_t, single_pass_traversal_tag, wchar_t > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< wchar_from_mb, Base, wchar_t, single_pass_traversal_tag, wchar_t > super_t; typedef wchar_from_mb this_t; void drain(); wchar_t dereference() const { if(m_output.m_next == m_output.m_next_available) return static_cast(0); return * m_output.m_next; } void increment(){ if(m_output.m_next == m_output.m_next_available) return; if(++m_output.m_next == m_output.m_next_available){ if(m_input.m_done) return; drain(); } } bool equal(this_t const & rhs) const { return dereference() == rhs.dereference(); } boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; std::mbstate_t m_mbs; template struct sliding_buffer { boost::array m_buffer; typename boost::array::const_iterator m_next_available; typename boost::array::iterator m_next; bool m_done; // default ctor sliding_buffer() : m_next_available(m_buffer.begin()), m_next(m_buffer.begin()), m_done(false) {} // copy ctor sliding_buffer(const sliding_buffer & rhs) : m_next_available( std::copy( rhs.m_buffer.begin(), rhs.m_next_available, m_buffer.begin() ) ), m_next( m_buffer.begin() + (rhs.m_next - rhs.m_buffer.begin()) ), m_done(rhs.m_done) {} }; sliding_buffer::type> m_input; sliding_buffer::type> m_output; public: // make composable by using templated constructor template wchar_from_mb(T start) : super_t(Base(static_cast< T >(start))), m_mbs(std::mbstate_t()) { BOOST_ASSERT(std::mbsinit(&m_mbs)); drain(); } // default constructor used as an end iterator wchar_from_mb(){} // copy ctor wchar_from_mb(const wchar_from_mb & rhs) : super_t(rhs.base_reference()), m_mbs(rhs.m_mbs), m_input(rhs.m_input), m_output(rhs.m_output) {} }; template void wchar_from_mb::drain(){ BOOST_ASSERT(! m_input.m_done); for(;;){ typename boost::iterators::iterator_reference::type c = *(this->base_reference()); // a null character in a multibyte stream is takes as end of string if(0 == c){ m_input.m_done = true; break; } ++(this->base_reference()); * const_cast::type *>( (m_input.m_next_available++) ) = c; // if input buffer is full - we're done for now if(m_input.m_buffer.end() == m_input.m_next_available) break; } const typename boost::iterators::iterator_value::type * input_new_start; typename iterator_value::type * next_available; BOOST_ATTRIBUTE_UNUSED // redundant with ignore_unused below but clarifies intention std::codecvt_base::result r = m_codecvt_facet.in( m_mbs, m_input.m_buffer.begin(), m_input.m_next_available, input_new_start, m_output.m_buffer.begin(), m_output.m_buffer.end(), next_available ); BOOST_ASSERT(std::codecvt_base::ok == r); m_output.m_next_available = next_available; m_output.m_next = m_output.m_buffer.begin(); // we're done with some of the input so shift left. m_input.m_next_available = std::copy( input_new_start, m_input.m_next_available, m_input.m_buffer.begin() ); m_input.m_next = m_input.m_buffer.begin(); } } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP ================================================ FILE: include/boost/archive/iterators/xml_escape.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP #define BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_escape.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 #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // insert escapes into xml text template class xml_escape : public escape, Base> { friend class boost::iterator_core_access; typedef escape, Base> super_t; public: char fill(const char * & bstart, const char * & bend); wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend); template xml_escape(T start) : super_t(Base(static_cast< T >(start))) {} // intel 7.1 doesn't like default copy constructor xml_escape(const xml_escape & rhs) : super_t(rhs.base_reference()) {} }; template char xml_escape::fill( const char * & bstart, const char * & bend ){ char current_value = * this->base_reference(); switch(current_value){ case '<': bstart = "<"; bend = bstart + 4; break; case '>': bstart = ">"; bend = bstart + 4; break; case '&': bstart = "&"; bend = bstart + 5; break; case '"': bstart = """; bend = bstart + 6; break; case '\'': bstart = "'"; bend = bstart + 6; break; default: bstart=""; bend=bstart; return current_value; } return *bstart; } template wchar_t xml_escape::fill( const wchar_t * & bstart, const wchar_t * & bend ){ wchar_t current_value = * this->base_reference(); switch(current_value){ case '<': bstart = L"<"; bend = bstart + 4; break; case '>': bstart = L">"; bend = bstart + 4; break; case '&': bstart = L"&"; bend = bstart + 5; break; case '"': bstart = L"""; bend = bstart + 6; break; case '\'': bstart = L"'"; bend = bstart + 6; break; default: return current_value; } return *bstart; } } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP ================================================ FILE: include/boost/archive/iterators/xml_unescape.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP #define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_unescape.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 #include #include #include #include #include namespace boost { namespace archive { namespace iterators { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // replace &??? xml escape sequences with the corresponding characters template class xml_unescape : public unescape, Base> { friend class boost::iterator_core_access; typedef xml_unescape this_t; typedef unescape super_t; typedef typename boost::iterator_reference reference_type; reference_type dereference() const { return unescape, Base>::dereference(); } public: // msvc versions prior to 14.0 crash with and ICE #if BOOST_WORKAROUND(BOOST_MSVC, < 1900) typedef int value_type; #else typedef typename super_t::value_type value_type; #endif void drain_residue(const char *literal); value_type drain(); template xml_unescape(T start) : super_t(Base(static_cast< T >(start))) {} // intel 7.1 doesn't like default copy constructor xml_unescape(const xml_unescape & rhs) : super_t(rhs.base_reference()) {} }; template void xml_unescape::drain_residue(const char * literal){ do{ if(* literal != * ++(this->base_reference())) boost::serialization::throw_exception( dataflow_exception( dataflow_exception::invalid_xml_escape_sequence ) ); } while('\0' != * ++literal); } // note key constraint on this function is that can't "look ahead" any // more than necessary into base iterator. Doing so would alter the base // iterator reference which would make subsequent iterator comparisons // incorrect and thereby break the composiblity of iterators. template typename xml_unescape::value_type //int xml_unescape::drain(){ value_type retval = * this->base_reference(); if('&' != retval){ return retval; } retval = * ++(this->base_reference()); switch(retval){ case 'l': // < drain_residue("t;"); retval = '<'; break; case 'g': // > drain_residue("t;"); retval = '>'; break; case 'a': retval = * ++(this->base_reference()); switch(retval){ case 'p': // ' drain_residue("os;"); retval = '\''; break; case 'm': // & drain_residue("p;"); retval = '&'; break; } break; case 'q': drain_residue("uot;"); retval = '"'; break; } return retval; } } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP ================================================ FILE: include/boost/archive/iterators/xml_unescape_exception.hpp ================================================ #ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP #define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_unescape_exception.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 #ifndef BOOST_NO_EXCEPTIONS #include #include namespace boost { namespace archive { namespace iterators { ////////////////////////////////////////////////////////////////////// // exceptions thrown by xml_unescapes // class xml_unescape_exception : public std::exception { public: xml_unescape_exception() {} virtual const char *what( ) const BOOST_NOEXCEPT_OR_NOTHROW { return "xml contained un-recognized escape code"; } }; } // namespace iterators } // namespace archive } // namespace boost #endif //BOOST_NO_EXCEPTIONS #endif //BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP ================================================ FILE: include/boost/archive/polymorphic_binary_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_binary_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_binary_iarchive : public detail::polymorphic_iarchive_route { public: polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) : detail::polymorphic_iarchive_route(is, flags) {} ~polymorphic_binary_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_binary_iarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_binary_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_binary_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_binary_oarchive : public detail::polymorphic_oarchive_route { public: polymorphic_binary_oarchive(std::ostream & os, unsigned int flags = 0) : detail::polymorphic_oarchive_route(os, flags) {} ~polymorphic_binary_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_binary_oarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // std::size_t #include // ULONG_MAX #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_iarchive; class basic_iserializer; } class polymorphic_iarchive; class BOOST_SYMBOL_VISIBLE polymorphic_iarchive_impl : public detail::interface_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else friend class detail::interface_iarchive; friend class load_access; #endif // primitive types the only ones permitted by polymorphic archives virtual void load(bool & t) = 0; virtual void load(char & t) = 0; virtual void load(signed char & t) = 0; virtual void load(unsigned char & t) = 0; #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T virtual void load(wchar_t & t) = 0; #endif #endif virtual void load(short & t) = 0; virtual void load(unsigned short & t) = 0; virtual void load(int & t) = 0; virtual void load(unsigned int & t) = 0; virtual void load(long & t) = 0; virtual void load(unsigned long & t) = 0; #if defined(BOOST_HAS_LONG_LONG) virtual void load(boost::long_long_type & t) = 0; virtual void load(boost::ulong_long_type & t) = 0; #elif defined(BOOST_HAS_MS_INT64) virtual void load(__int64 & t) = 0; virtual void load(unsigned __int64 & t) = 0; #endif virtual void load(float & t) = 0; virtual void load(double & t) = 0; // string types are treated as primitives virtual void load(std::string & t) = 0; #ifndef BOOST_NO_STD_WSTRING virtual void load(std::wstring & t) = 0; #endif // used for xml and other tagged formats virtual void load_start(const char * name) = 0; virtual void load_end(const char * name) = 0; virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0; virtual detail::helper_collection & get_helper_collection() = 0; // msvc and borland won't automatically pass these to the base class so // make it explicit here template void load_override(T & t) { archive::load(* this->This(), t); } // special treatment for name-value pairs. template void load_override( const boost::serialization::nvp< T > & t ){ load_start(t.name()); archive::load(* this->This(), t.value()); load_end(t.name()); } protected: virtual ~polymorphic_iarchive_impl() {} public: // utility function implemented by all legal archives virtual void set_library_version( boost::serialization::library_version_type archive_library_version ) = 0; virtual boost::serialization::library_version_type get_library_version() const = 0; virtual unsigned int get_flags() const = 0; virtual void delete_created_pointers() = 0; virtual void reset_object_address( const void * new_address, const void * old_address ) = 0; virtual void load_binary(void * t, std::size_t size) = 0; // these are used by the serialization library implementation. virtual void load_object( void *t, const detail::basic_iserializer & bis ) = 0; virtual const detail::basic_pointer_iserializer * load_pointer( void * & t, const detail::basic_pointer_iserializer * bpis_ptr, const detail::basic_pointer_iserializer * (*finder)( const boost::serialization::extended_type_info & type ) ) = 0; }; } // namespace archive } // namespace boost #include // pops abi_suffix.hpp pragmas namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_iarchive : public polymorphic_iarchive_impl { public: ~polymorphic_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_iarchive) #endif // BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include // size_t #include // ULONG_MAX #include #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include // must be the last header namespace boost { namespace serialization { class extended_type_info; } // namespace serialization namespace archive { namespace detail { class basic_oarchive; class basic_oserializer; } class polymorphic_oarchive; class BOOST_SYMBOL_VISIBLE polymorphic_oarchive_impl : public detail::interface_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else friend class detail::interface_oarchive; friend class save_access; #endif // primitive types the only ones permitted by polymorphic archives virtual void save(const bool t) = 0; virtual void save(const char t) = 0; virtual void save(const signed char t) = 0; virtual void save(const unsigned char t) = 0; #ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_INTRINSIC_WCHAR_T virtual void save(const wchar_t t) = 0; #endif #endif virtual void save(const short t) = 0; virtual void save(const unsigned short t) = 0; virtual void save(const int t) = 0; virtual void save(const unsigned int t) = 0; virtual void save(const long t) = 0; virtual void save(const unsigned long t) = 0; #if defined(BOOST_HAS_LONG_LONG) virtual void save(const boost::long_long_type t) = 0; virtual void save(const boost::ulong_long_type t) = 0; #elif defined(BOOST_HAS_MS_INT64) virtual void save(const __int64 t) = 0; virtual void save(const unsigned __int64 t) = 0; #endif virtual void save(const float t) = 0; virtual void save(const double t) = 0; // string types are treated as primitives virtual void save(const std::string & t) = 0; #ifndef BOOST_NO_STD_WSTRING virtual void save(const std::wstring & t) = 0; #endif virtual void save_null_pointer() = 0; // used for xml and other tagged formats virtual void save_start(const char * name) = 0; virtual void save_end(const char * name) = 0; virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0; virtual detail::helper_collection & get_helper_collection() = 0; virtual void end_preamble() = 0; // msvc and borland won't automatically pass these to the base class so // make it explicit here template void save_override(T & t) { archive::save(* this->This(), t); } // special treatment for name-value pairs. template void save_override( const ::boost::serialization::nvp< T > & t ){ save_start(t.name()); archive::save(* this->This(), t.const_value()); save_end(t.name()); } protected: virtual ~polymorphic_oarchive_impl() {} public: // utility functions implemented by all legal archives virtual unsigned int get_flags() const = 0; virtual boost::serialization::library_version_type get_library_version() const = 0; virtual void save_binary(const void * t, std::size_t size) = 0; virtual void save_object( const void *x, const detail::basic_oserializer & bos ) = 0; virtual void save_pointer( const void * t, const detail::basic_pointer_oserializer * bpos_ptr ) = 0; }; // note: preserve naming symmetry class BOOST_SYMBOL_VISIBLE polymorphic_oarchive : public polymorphic_oarchive_impl { public: ~polymorphic_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_oarchive) #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_text_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_text_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_text_iarchive : public detail::polymorphic_iarchive_route { public: polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) : detail::polymorphic_iarchive_route(is, flags) {} ~polymorphic_text_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_text_iarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_text_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_text_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_text_oarchive : public detail::polymorphic_oarchive_route { public: polymorphic_text_oarchive(std::ostream & os, unsigned int flags = 0) : detail::polymorphic_oarchive_route(os, flags) {} ~polymorphic_text_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_text_oarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_text_wiarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_text_wiarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_text_wiarchive : public detail::polymorphic_iarchive_route { public: polymorphic_text_wiarchive(std::wistream & is, unsigned int flags = 0) : detail::polymorphic_iarchive_route(is, flags) {} ~polymorphic_text_wiarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_text_wiarchive ) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_text_woarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_text_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_text_woarchive : public detail::polymorphic_oarchive_route { public: polymorphic_text_woarchive(std::wostream & os, unsigned int flags = 0) : detail::polymorphic_oarchive_route(os, flags) {} ~polymorphic_text_woarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_text_woarchive ) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_xml_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_xml_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_xml_iarchive : public detail::polymorphic_iarchive_route { public: polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) : detail::polymorphic_iarchive_route(is, flags) {} ~polymorphic_xml_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_xml_iarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_xml_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_xml_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_xml_oarchive : public detail::polymorphic_oarchive_route { public: polymorphic_xml_oarchive(std::ostream & os, unsigned int flags = 0) : detail::polymorphic_oarchive_route(os, flags) {} ~polymorphic_xml_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_xml_oarchive ) #endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_xml_wiarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_xml_wiarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_xml_wiarchive : public detail::polymorphic_iarchive_route { public: polymorphic_xml_wiarchive(std::wistream & is, unsigned int flags = 0) : detail::polymorphic_iarchive_route(is, flags) {} ~polymorphic_xml_wiarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_xml_wiarchive ) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP ================================================ FILE: include/boost/archive/polymorphic_xml_woarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP #define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // polymorphic_xml_woarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE polymorphic_xml_woarchive : public detail::polymorphic_oarchive_route { public: polymorphic_xml_woarchive(std::wostream & os, unsigned int flags = 0) : detail::polymorphic_oarchive_route(os, flags) {} ~polymorphic_xml_woarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( boost::archive::polymorphic_xml_woarchive ) #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP ================================================ FILE: include/boost/archive/text_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_TEXT_IARCHIVE_HPP #define BOOST_ARCHIVE_TEXT_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE text_iarchive_impl : public basic_text_iprimitive, public basic_text_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_iarchive; friend class load_access; #endif template void load(T & t){ basic_text_iprimitive::load(t); } void load(version_type & t){ unsigned int v; load(v); t = version_type(v); } void load(boost::serialization::item_version_type & t){ unsigned int v; load(v); t = boost::serialization::item_version_type(v); } BOOST_ARCHIVE_DECL void load(char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_ARCHIVE_DECL void load(wchar_t * t); #endif BOOST_ARCHIVE_DECL void load(std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_DECL void load(std::wstring &ws); #endif template void load_override(T & t){ basic_text_iarchive::load_override(t); } BOOST_ARCHIVE_DECL void load_override(class_name_type & t); BOOST_ARCHIVE_DECL void init(); BOOST_ARCHIVE_DECL text_iarchive_impl(std::istream & is, unsigned int flags); // don't import inline definitions! leave this as a reminder. //BOOST_ARCHIVE_DECL ~text_iarchive_impl() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE text_iarchive : public text_iarchive_impl{ public: text_iarchive(std::istream & is_, unsigned int flags = 0) : // note: added _ to suppress useless gcc warning text_iarchive_impl(is_, flags) { if(0 == (flags & no_header)) init(); } ~text_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_iarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_TEXT_IARCHIVE_HPP ================================================ FILE: include/boost/archive/text_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_TEXT_OARCHIVE_HPP #define BOOST_ARCHIVE_TEXT_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // std::size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE text_oarchive_impl : /* protected ? */ public basic_text_oprimitive, public basic_text_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_oarchive; friend class basic_text_oarchive; friend class save_access; #endif template void save(const T & t){ this->newtoken(); basic_text_oprimitive::save(t); } void save(const version_type & t){ save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ save(static_cast(t)); } BOOST_ARCHIVE_DECL void save(const char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_ARCHIVE_DECL void save(const wchar_t * t); #endif BOOST_ARCHIVE_DECL void save(const std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_DECL void save(const std::wstring &ws); #endif BOOST_ARCHIVE_DECL text_oarchive_impl(std::ostream & os, unsigned int flags); // don't import inline definitions! leave this as a reminder. //BOOST_ARCHIVE_DECL ~text_oarchive_impl() BOOST_OVERRIDE {} public: BOOST_ARCHIVE_DECL void save_binary(const void *address, std::size_t count); }; // do not derive from this class. If you want to extend this functionality // via inheritance, derived from text_oarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE text_oarchive : public text_oarchive_impl { public: text_oarchive(std::ostream & os_, unsigned int flags = 0) : // note: added _ to suppress useless gcc warning text_oarchive_impl(os_, flags) { if(0 == (flags & no_header)) init(); } ~text_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_ARCHIVE_TEXT_OARCHIVE_HPP ================================================ FILE: include/boost/archive/text_wiarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP #define BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_wiarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE text_wiarchive_impl : public basic_text_iprimitive, public basic_text_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_iarchive; friend load_access; #else friend class detail::interface_iarchive; friend class load_access; #endif #endif template void load(T & t){ basic_text_iprimitive::load(t); } void load(version_type & t){ unsigned int v; load(v); t = version_type(v); } void load(boost::serialization::item_version_type & t){ unsigned int v; load(v); t = boost::serialization::item_version_type(v); } BOOST_WARCHIVE_DECL void load(char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_WARCHIVE_DECL void load(wchar_t * t); #endif BOOST_WARCHIVE_DECL void load(std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_WARCHIVE_DECL void load(std::wstring &ws); #endif template void load_override(T & t){ basic_text_iarchive::load_override(t); } BOOST_WARCHIVE_DECL text_wiarchive_impl(std::wistream & is, unsigned int flags); ~text_wiarchive_impl() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE text_wiarchive : public text_wiarchive_impl{ public: text_wiarchive(std::wistream & is, unsigned int flags = 0) : text_wiarchive_impl(is, flags) { if(0 == (flags & no_header)) init(); } ~text_wiarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_wiarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP ================================================ FILE: include/boost/archive/text_woarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP #define BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // text_woarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include // size_t #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE text_woarchive_impl : public basic_text_oprimitive, public basic_text_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) // for some inexplicable reason insertion of "class" generates compile erro // on msvc 7.1 friend detail::interface_oarchive; friend basic_text_oarchive; friend save_access; #else friend class detail::interface_oarchive; friend class basic_text_oarchive; friend class save_access; #endif #endif template void save(const T & t){ this->newtoken(); basic_text_oprimitive::save(t); } void save(const version_type & t){ save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ save(static_cast(t)); } BOOST_WARCHIVE_DECL void save(const char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_WARCHIVE_DECL void save(const wchar_t * t); #endif BOOST_WARCHIVE_DECL void save(const std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_WARCHIVE_DECL void save(const std::wstring &ws); #endif text_woarchive_impl(std::wostream & os, unsigned int flags) : basic_text_oprimitive( os, 0 != (flags & no_codecvt) ), basic_text_oarchive(flags) {} public: void save_binary(const void *address, std::size_t count){ put(static_cast('\n')); this->end_preamble(); #if ! defined(__MWERKS__) this->basic_text_oprimitive::save_binary( #else this->basic_text_oprimitive::save_binary( #endif address, count ); put(static_cast('\n')); this->delimiter = this->none; } }; // we use the following because we can't use // typedef text_oarchive_impl > text_oarchive; // do not derive from this class. If you want to extend this functionality // via inheritance, derived from text_oarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE text_woarchive : public text_woarchive_impl { public: text_woarchive(std::wostream & os, unsigned int flags = 0) : text_woarchive_impl(os, flags) { if(0 == (flags & no_header)) init(); } ~text_woarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_woarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP ================================================ FILE: include/boost/archive/tmpdir.hpp ================================================ #ifndef BOOST_ARCHIVE_TMPDIR_HPP #define BOOST_ARCHIVE_TMPDIR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // tmpdir.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 // getenv #include // NULL #include #ifdef BOOST_NO_STDC_NAMESPACE namespace std { using ::getenv; } #endif namespace boost { namespace archive { inline const char * tmpdir(){ const char *dirname; dirname = std::getenv("TMP"); if(NULL == dirname) dirname = std::getenv("TMPDIR"); if(NULL == dirname) dirname = std::getenv("TEMP"); if(NULL == dirname){ //BOOST_ASSERT(false); // no temp directory found dirname = "."; } return dirname; } } // archive } // boost #endif // BOOST_ARCHIVE_TMPDIR_HPP ================================================ FILE: include/boost/archive/wcslen.hpp ================================================ #ifndef BOOST_ARCHIVE_WCSLEN_HPP #define BOOST_ARCHIVE_WCSLEN_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // wcslen.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 // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #ifndef BOOST_NO_CWCHAR // a couple of libraries which include wchar_t don't include // wcslen #if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB < 306 \ || defined(__LIBCOMO__) namespace std { inline std::size_t wcslen(const wchar_t * ws) { const wchar_t * eows = ws; while(* eows != 0) ++eows; return eows - ws; } } // namespace std #else #ifndef BOOST_NO_CWCHAR #include #endif #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ using ::wcslen; } #endif #endif // wcslen #endif //BOOST_NO_CWCHAR #endif //BOOST_ARCHIVE_WCSLEN_HPP ================================================ FILE: include/boost/archive/xml_archive_exception.hpp ================================================ #ifndef BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP #define BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_archive_exception.hpp: // (C) Copyright 2007 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 #include #include #include #include #include // must be the last header namespace boost { namespace archive { ////////////////////////////////////////////////////////////////////// // exceptions thrown by xml archives // class BOOST_SYMBOL_VISIBLE xml_archive_exception : public virtual boost::archive::archive_exception { public: typedef enum { xml_archive_parsing_error, // see save_register xml_archive_tag_mismatch, xml_archive_tag_name_error } exception_code; BOOST_ARCHIVE_DECL xml_archive_exception( exception_code c, const char * e1 = NULL, const char * e2 = NULL ); BOOST_ARCHIVE_DECL xml_archive_exception(xml_archive_exception const &); BOOST_ARCHIVE_DECL ~xml_archive_exception() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE; }; }// namespace archive }// namespace boost #include // pops abi_suffix.hpp pragmas #endif //BOOST_XML_ARCHIVE_ARCHIVE_EXCEPTION_HPP ================================================ FILE: include/boost/archive/xml_iarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_XML_IARCHIVE_HPP #define BOOST_ARCHIVE_XML_IARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_iarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail template class basic_xml_grammar; typedef basic_xml_grammar xml_grammar; template class BOOST_SYMBOL_VISIBLE xml_iarchive_impl : public basic_text_iprimitive, public basic_xml_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_iarchive; friend class basic_xml_iarchive; friend class load_access; #endif // use boost:scoped_ptr to implement automatic deletion; boost::scoped_ptr gimpl; std::istream & get_is(){ return is; } template void load(T & t){ basic_text_iprimitive::load(t); } void load(version_type & t){ unsigned int v; load(v); t = version_type(v); } void load(boost::serialization::item_version_type & t){ unsigned int v; load(v); t = boost::serialization::item_version_type(v); } BOOST_ARCHIVE_DECL void load(char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_ARCHIVE_DECL void load(wchar_t * t); #endif BOOST_ARCHIVE_DECL void load(std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_DECL void load(std::wstring &ws); #endif template void load_override(T & t){ basic_xml_iarchive::load_override(t); } BOOST_ARCHIVE_DECL void load_override(class_name_type & t); BOOST_ARCHIVE_DECL void init(); BOOST_ARCHIVE_DECL xml_iarchive_impl(std::istream & is, unsigned int flags); BOOST_ARCHIVE_DECL ~xml_iarchive_impl() BOOST_OVERRIDE; }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE xml_iarchive : public xml_iarchive_impl{ public: xml_iarchive(std::istream & is, unsigned int flags = 0) : xml_iarchive_impl(is, flags) { if(0 == (flags & no_header)) init(); } ~xml_iarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_iarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_XML_IARCHIVE_HPP ================================================ FILE: include/boost/archive/xml_oarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_XML_OARCHIVE_HPP #define BOOST_ARCHIVE_XML_OARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_oarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE xml_oarchive_impl : public basic_text_oprimitive, public basic_xml_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_oarchive; friend class basic_xml_oarchive; friend class save_access; #endif template void save(const T & t){ basic_text_oprimitive::save(t); } void save(const version_type & t){ save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ save(static_cast(t)); } BOOST_ARCHIVE_DECL void save(const char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_ARCHIVE_DECL void save(const wchar_t * t); #endif BOOST_ARCHIVE_DECL void save(const std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_ARCHIVE_DECL void save(const std::wstring &ws); #endif BOOST_ARCHIVE_DECL xml_oarchive_impl(std::ostream & os, unsigned int flags); BOOST_ARCHIVE_DECL ~xml_oarchive_impl() BOOST_OVERRIDE; public: BOOST_ARCHIVE_DECL void save_binary(const void *address, std::size_t count); }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { // we use the following because we can't use // typedef xml_oarchive_impl > xml_oarchive; // do not derive from this class. If you want to extend this functionality // via inheritance, derived from xml_oarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE xml_oarchive : public xml_oarchive_impl { public: xml_oarchive(std::ostream & os, unsigned int flags = 0) : xml_oarchive_impl(os, flags) { if(0 == (flags & no_header)) init(); } ~xml_oarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_oarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP ================================================ FILE: include/boost/archive/xml_wiarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_XML_WIARCHIVE_HPP #define BOOST_ARCHIVE_XML_WIARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_wiarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_iarchive; } // namespace detail template class basic_xml_grammar; typedef basic_xml_grammar xml_wgrammar; template class BOOST_SYMBOL_VISIBLE xml_wiarchive_impl : public basic_text_iprimitive, public basic_xml_iarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_iarchive; friend class basic_xml_iarchive; friend class load_access; #endif std::locale archive_locale; boost::scoped_ptr gimpl; std::wistream & get_is(){ return is; } template void load(T & t){ basic_text_iprimitive::load(t); } void load(version_type & t){ unsigned int v; load(v); t = version_type(v); } void load(boost::serialization::item_version_type & t){ unsigned int v; load(v); t = boost::serialization::item_version_type(v); } BOOST_WARCHIVE_DECL void load(char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_WARCHIVE_DECL void load(wchar_t * t); #endif BOOST_WARCHIVE_DECL void load(std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_WARCHIVE_DECL void load(std::wstring &ws); #endif template void load_override(T & t){ basic_xml_iarchive::load_override(t); } BOOST_WARCHIVE_DECL void load_override(class_name_type & t); BOOST_WARCHIVE_DECL void init(); BOOST_WARCHIVE_DECL xml_wiarchive_impl(std::wistream & is, unsigned int flags); BOOST_WARCHIVE_DECL ~xml_wiarchive_impl() BOOST_OVERRIDE; }; } // namespace archive } // namespace boost #ifdef BOOST_MSVC # pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { class BOOST_SYMBOL_VISIBLE xml_wiarchive : public xml_wiarchive_impl{ public: xml_wiarchive(std::wistream & is, unsigned int flags = 0) : xml_wiarchive_impl(is, flags) { if(0 == (flags & no_header)) init(); } ~xml_wiarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_wiarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_XML_WIARCHIVE_HPP ================================================ FILE: include/boost/archive/xml_woarchive.hpp ================================================ #ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP #define BOOST_ARCHIVE_XML_WOARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // xml_woarchive.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 #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else #include // size_t #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace archive { namespace detail { template class interface_oarchive; } // namespace detail template class BOOST_SYMBOL_VISIBLE xml_woarchive_impl : public basic_text_oprimitive, public basic_xml_oarchive { #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else protected: friend class detail::interface_oarchive; friend class basic_xml_oarchive; friend class save_access; #endif //void end_preamble(){ // basic_xml_oarchive::end_preamble(); //} template void save(const T & t){ basic_text_oprimitive::save(t); } void save(const version_type & t){ save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ save(static_cast(t)); } BOOST_WARCHIVE_DECL void save(const char * t); #ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_WARCHIVE_DECL void save(const wchar_t * t); #endif BOOST_WARCHIVE_DECL void save(const std::string &s); #ifndef BOOST_NO_STD_WSTRING BOOST_WARCHIVE_DECL void save(const std::wstring &ws); #endif BOOST_WARCHIVE_DECL xml_woarchive_impl(std::wostream & os, unsigned int flags); BOOST_WARCHIVE_DECL ~xml_woarchive_impl() BOOST_OVERRIDE; public: BOOST_WARCHIVE_DECL void save_binary(const void *address, std::size_t count); }; // we use the following because we can't use // typedef xml_woarchive_impl > xml_woarchive; // do not derive from this class. If you want to extend this functionality // via inheritance, derived from xml_woarchive_impl instead. This will // preserve correct static polymorphism. class BOOST_SYMBOL_VISIBLE xml_woarchive : public xml_woarchive_impl { public: xml_woarchive(std::wostream & os, unsigned int flags = 0) : xml_woarchive_impl(os, flags) { if(0 == (flags & no_header)) init(); } ~xml_woarchive() BOOST_OVERRIDE {} }; } // namespace archive } // namespace boost // required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive) #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_NO_STD_WSTREAMBUF #endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP ================================================ FILE: include/boost/serialization/access.hpp ================================================ #ifndef BOOST_SERIALIZATION_ACCESS_HPP #define BOOST_SERIALIZATION_ACCESS_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // access.hpp: interface for serialization system. // (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 namespace boost { namespace archive { namespace detail { template class iserializer; template class oserializer; } // namespace detail } // namespace archive namespace serialization { // forward declarations template inline void serialize_adl(Archive &, T &, const unsigned int); namespace detail { template struct member_saver; template struct member_loader; } // namespace detail // use an "accessor class so that we can use: // "friend class boost::serialization::access;" // in any serialized class to permit clean, safe access to private class members // by the serialization system class access { public: // grant access to "real" serialization defaults #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS public: #else template friend struct detail::member_saver; template friend struct detail::member_loader; template friend class archive::detail::iserializer; template friend class archive::detail::oserializer; template friend inline void serialize( Archive & ar, T & t, const unsigned int file_version ); template friend inline void save_construct_data( Archive & ar, const T * t, const unsigned int file_version ); template friend inline void load_construct_data( Archive & ar, T * t, const unsigned int file_version ); #endif // pass calls to users's class implementation template static void member_save( Archive & ar, //const T & t, T & t, const unsigned int file_version ){ t.save(ar, file_version); } template static void member_load( Archive & ar, T & t, const unsigned int file_version ){ t.load(ar, file_version); } template static void serialize( Archive & ar, T & t, const unsigned int file_version ){ // note: if you get a compile time error here with a // message something like: // cannot convert parameter 1 from to // a likely possible cause is that the class T contains a // serialize function - but that serialize function isn't // a template and corresponds to a file type different than // the class Archive. To resolve this, don't include an // archive type other than that for which the serialization // function is defined!!! t.serialize(ar, file_version); } template static void destroy( const T * t) // const appropriate here? { // the const business is an MSVC 6.0 hack that should be // benign on everything else delete const_cast(t); } template static void construct(T * t){ // default is inplace invocation of default constructor // Note the :: before the placement new. Required if the // class doesn't have a class-specific placement new defined. ::new(t)T; } template static T & cast_reference(U & u){ return static_cast(u); } template static T * cast_pointer(U * u){ return static_cast(u); } }; } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_ACCESS_HPP ================================================ FILE: include/boost/serialization/archive_input_unordered_map.hpp ================================================ #ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP #define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization/unordered_map.hpp: // serialization for stl unordered_map templates // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // (C) Copyright 2014 Jim Bell // 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 #include #include #include #include namespace boost { namespace serialization { namespace stl { // map input template struct archive_input_unordered_map { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); ar >> boost::serialization::make_nvp("item", t.reference()); std::pair result = s.insert(boost::move(t.reference())); // note: the following presumes that the map::value_type was NOT tracked // in the archive. This is the usual case, but here there is no way // to determine that. if(result.second){ ar.reset_object_address( & (result.first->second), & t.reference().second ); } } }; // multimap input template struct archive_input_unordered_multimap { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::const_iterator result = s.insert(t.reference()); // note: the following presumes that the map::value_type was NOT tracked // in the archive. This is the usual case, but here there is no way // to determine that. ar.reset_object_address( & result->second, & t.reference() ); } }; } // stl } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP ================================================ FILE: include/boost/serialization/archive_input_unordered_set.hpp ================================================ #ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP #define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // archive_input_unordered_set.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // (C) Copyright 2014 Jim Bell // 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 #include #include #include namespace boost { namespace serialization { namespace stl { // unordered_set input template struct archive_input_unordered_set { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); std::pair result = s.insert(boost::move(t.reference())); if(result.second) ar.reset_object_address(& (* result.first), & t.reference()); } }; // unordered_multiset input template struct archive_input_unordered_multiset { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::const_iterator result = s.insert(boost::move(t.reference())); ar.reset_object_address(& (* result), & t.reference()); } }; } // stl } // serialization } // boost #endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP ================================================ FILE: include/boost/serialization/array.hpp ================================================ #ifndef BOOST_SERIALIZATION_ARRAY_HPP #define BOOST_SERIALIZATION_ARRAY_HPP // (C) Copyright 2005 Matthias Troyer and Dave Abrahams // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // for serialization of . If not supported by the standard // library - this file becomes empty. This is to avoid breaking backward // compatibility for applications which used this header to support // serialization of native arrays. Code to serialize native arrays is // now always include by default. RR #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) #include #include // std::size_t namespace std{ using ::size_t; } // namespace std #endif #include #ifndef BOOST_NO_CXX11_HDR_ARRAY #include #include namespace boost { namespace serialization { template void serialize(Archive& ar, std::array& a, const unsigned int /* version */) { ar & boost::serialization::make_nvp( "elems", *static_cast(static_cast(a.data())) ); } } } // end namespace boost::serialization #endif // BOOST_NO_CXX11_HDR_ARRAY #endif //BOOST_SERIALIZATION_ARRAY_HPP ================================================ FILE: include/boost/serialization/array_optimization.hpp ================================================ #ifndef BOOST_SERIALIZATION_ARRAY_OPTIMIZATION_HPP #define BOOST_SERIALIZATION_ARRAY_OPTIMIZATION_HPP // (C) Copyright 2005 Matthias Troyer and Dave Abrahams // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include namespace boost { namespace serialization { template struct use_array_optimization : boost::mpl::always {}; } } // end namespace boost::serialization #define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \ namespace boost { namespace serialization { \ template <> struct use_array_optimization { \ template \ struct apply : boost::mpl::apply1::type \ >::type {}; \ }; }} #endif //BOOST_SERIALIZATION_ARRAY_OPTIMIZATION_HPP ================================================ FILE: include/boost/serialization/array_wrapper.hpp ================================================ #ifndef BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP #define BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP // (C) Copyright 2005 Matthias Troyer and Dave Abrahams // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { template class array_wrapper : public wrapper_traits > { private: array_wrapper & operator=(const array_wrapper & rhs); // note: I would like to make the copy constructor private but this breaks // make_array. So I make make_array a friend template friend const boost::serialization::array_wrapper make_array(Tx * t, S s); public: array_wrapper(const array_wrapper & rhs) : m_t(rhs.m_t), m_element_count(rhs.m_element_count) {} public: array_wrapper(T * t, std::size_t s) : m_t(t), m_element_count(s) {} // default implementation template void serialize_optimized(Archive &ar, const unsigned int, mpl::false_ ) const { // default implementation does the loop std::size_t c = count(); T * t = address(); while(0 < c--) ar & boost::serialization::make_nvp("item", *t++); } // optimized implementation template void serialize_optimized(Archive &ar, const unsigned int version, mpl::true_ ) { boost::serialization::split_member(ar, *this, version); } // default implementation template void save(Archive &ar, const unsigned int version) const { ar.save_array(*this,version); } // default implementation template void load(Archive &ar, const unsigned int version) { ar.load_array(*this,version); } // default implementation template void serialize(Archive &ar, const unsigned int version) { typedef typename boost::serialization::use_array_optimization::template apply< typename remove_const< T >::type >::type use_optimized; serialize_optimized(ar,version,use_optimized()); } T * address() const { return m_t; } std::size_t count() const { return m_element_count; } private: T * const m_t; const std::size_t m_element_count; }; template inline const array_wrapper< T > make_array(T* t, S s){ const array_wrapper< T > a(t, s); return a; } } } // end namespace boost::serialization #endif //BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP ================================================ FILE: include/boost/serialization/assume_abstract.hpp ================================================ #ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP #define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // assume_abstract_class.hpp: // (C) Copyright 2008 Robert Ramey // 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. // this is useful for compilers which don't support the boost::is_abstract #include #include #ifndef BOOST_NO_IS_ABSTRACT // if there is an intrinsic is_abstract defined, we don't have to do anything #define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) // but forward to the "official" is_abstract namespace boost { namespace serialization { template struct is_abstract : boost::is_abstract< T > {} ; } // namespace serialization } // namespace boost #else // we have to "make" one namespace boost { namespace serialization { template struct is_abstract : boost::false_type {}; } // namespace serialization } // namespace boost // define a macro to make explicit designation of this more transparent #define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \ namespace boost { \ namespace serialization { \ template<> \ struct is_abstract< T > : boost::true_type {}; \ template<> \ struct is_abstract< const T > : boost::true_type {}; \ }} \ /**/ #endif // BOOST_NO_IS_ABSTRACT #endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP ================================================ FILE: include/boost/serialization/base_object.hpp ================================================ #ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP #define BOOST_SERIALIZATION_BASE_OBJECT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // base_object.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. // if no archive headers have been included this is a no op // this is to permit BOOST_EXPORT etc to be included in a // file declaration header #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { namespace detail { // get the base type for a given derived type // preserving the const-ness template struct base_cast { typedef typename mpl::if_< is_const, const B, B >::type type; BOOST_STATIC_ASSERT(is_const::value == is_const::value); }; // only register void casts if the types are polymorphic template struct base_register { struct polymorphic { static void const * invoke(){ Base const * const b = 0; Derived const * const d = 0; return & void_cast_register(d, b); } }; struct non_polymorphic { static void const * invoke(){ return 0; } }; static void const * invoke(){ typedef typename mpl::eval_if< is_polymorphic, mpl::identity, mpl::identity >::type type; return type::invoke(); } }; } // namespace detail template typename detail::base_cast::type & base_object(Derived &d) { BOOST_STATIC_ASSERT(( is_base_and_derived::value)); BOOST_STATIC_ASSERT(! is_pointer::value); typedef typename detail::base_cast::type type; detail::base_register::invoke(); return access::cast_reference(d); } } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP ================================================ FILE: include/boost/serialization/binary_object.hpp ================================================ #ifndef BOOST_SERIALIZATION_BINARY_OBJECT_HPP #define BOOST_SERIALIZATION_BINARY_OBJECT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // nvp.hpp: interface for serialization system. // (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 #include // std::size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include namespace boost { namespace serialization { struct binary_object : public wrapper_traits > { void const * m_t; std::size_t m_size; template void save(Archive & ar, const unsigned int /* file_version */) const { ar.save_binary(m_t, m_size); } template void load(Archive & ar, const unsigned int /* file_version */) const { ar.load_binary(const_cast(m_t), m_size); } BOOST_SERIALIZATION_SPLIT_MEMBER() binary_object & operator=(const binary_object & rhs) { m_t = rhs.m_t; m_size = rhs.m_size; return *this; } binary_object(const void * const t, std::size_t size) : m_t(t), m_size(size) {} binary_object(const binary_object & rhs) : m_t(rhs.m_t), m_size(rhs.m_size) {} }; // just a little helper to support the convention that all serialization // wrappers follow the naming convention make_xxxxx inline const binary_object make_binary_object(const void * t, std::size_t size){ return binary_object(t, size); } } // namespace serialization } // boost #endif // BOOST_SERIALIZATION_BINARY_OBJECT_HPP ================================================ FILE: include/boost/serialization/bitset.hpp ================================================ /*! * \file bitset.hpp * \brief Provides Boost.Serialization support for std::bitset * \author Brian Ravnsgaard Riis * \author Kenneth Riddile * \date 16.09.2004, updated 04.03.2009 * \copyright 2004 Brian Ravnsgaard Riis * \license Boost Software License 1.0 */ #ifndef BOOST_SERIALIZATION_BITSET_HPP #define BOOST_SERIALIZATION_BITSET_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include // size_t #include #include #include #include namespace boost{ namespace serialization{ template inline void save( Archive & ar, std::bitset const & t, const unsigned int /* version */ ){ const std::string bits = t.template to_string< std::string::value_type, std::string::traits_type, std::string::allocator_type >(); ar << BOOST_SERIALIZATION_NVP( bits ); } template inline void load( Archive & ar, std::bitset & t, const unsigned int /* version */ ){ std::string bits; ar >> BOOST_SERIALIZATION_NVP( bits ); t = std::bitset(bits); } template inline void serialize( Archive & ar, std::bitset & t, const unsigned int version ){ boost::serialization::split_free( ar, t, version ); } // don't track bitsets since that would trigger tracking // all over the program - which probably would be a surprise. // also, tracking would be hard to implement since, we're // serialization a representation of the data rather than // the data itself. template struct tracking_level > : mpl::int_ {} ; } //serialization } //boost #endif // BOOST_SERIALIZATION_BITSET_HPP ================================================ FILE: include/boost/serialization/boost_array.hpp ================================================ #ifndef BOOST_SERIALIZATION_BOOST_ARRAY_HPP #define BOOST_SERIALIZATION_BOOST_ARRAY_HPP // (C) Copyright 2005 Matthias Troyer and Dave Abrahams // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include namespace boost { namespace serialization { // implement serialization for boost::array template void serialize(Archive& ar, boost::array& a, const unsigned int /* version */) { ar & boost::serialization::make_nvp("elems", a.elems); } } } // end namespace boost::serialization #endif //BOOST_SERIALIZATION_BOOST_ARRAY_HPP ================================================ FILE: include/boost/serialization/boost_unordered_map.hpp ================================================ #ifndef BOOST_SERIALIZATION_BOOST_SERIALIZATION_UNORDERED_MAP_HPP #define BOOST_SERIALIZATION_BOOST_SERIALIZATION_UNORDERED_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization/unordered_map.hpp: // serialization for stl unordered_map templates // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // (C) Copyright 2014 Jim Bell // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include BOOST_STATIC_ASSERT_MSG( false, "Boost.Unordered now provides its own Serialization support. " "This header is no longer necessary and is now deprecated." ) #endif // BOOST_SERIALIZATION_BOOST_SERIALIZATION_UNORDERED_MAP_HPP ================================================ FILE: include/boost/serialization/boost_unordered_set.hpp ================================================ #ifndef BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP #define BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // unordered_set.hpp: serialization for boost unordered_set templates // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // (C) Copyright 2014 Jim Bell // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include BOOST_STATIC_ASSERT_MSG( false, "Boost.Unordered now provides its own Serialization support. " "This header is no longer necessary and is now deprecated." ) #endif // BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP ================================================ FILE: include/boost/serialization/collection_size_type.hpp ================================================ #ifndef BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP #define BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP // (C) Copyright 2005 Matthias Troyer // 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 // size_t #include #include #include #include namespace boost { namespace serialization { //BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type) class collection_size_type { private: typedef std::size_t base_type; base_type t; public: collection_size_type(): t(0) {} explicit collection_size_type(const std::size_t & t_) : t(t_) {} collection_size_type(const collection_size_type & t_) : t(t_.t) {} collection_size_type & operator=(const collection_size_type & rhs){ t = rhs.t; return *this; } collection_size_type & operator=(const unsigned int & rhs){ t = rhs; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type & () { return t; } bool operator==(const collection_size_type & rhs) const { return t == rhs.t; } bool operator<(const collection_size_type & rhs) const { return t < rhs.t; } }; } } // end namespace boost::serialization BOOST_CLASS_IMPLEMENTATION(collection_size_type, primitive_type) BOOST_IS_BITWISE_SERIALIZABLE(collection_size_type) #endif //BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP ================================================ FILE: include/boost/serialization/collection_traits.hpp ================================================ #ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // collection_traits.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. // This header assigns a level implementation trait to a collection type // for all primitives. It is needed so that archives which are meant to be // portable don't write class information in the archive. Since, not all // compiles recognize the same set of primitive types, the possibility // exists for archives to be non-portable if class information for primitive // types is included. This is addressed by the following macros. #include #include #include #include #include // ULONG_MAX #include #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \ template<> \ struct implementation_level< C < T > > { \ typedef mpl::integral_c_tag tag; \ typedef mpl::int_ type; \ BOOST_STATIC_CONSTANT(int, value = object_serializable); \ }; \ /**/ #if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T) #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) #else #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \ /**/ #endif #if defined(BOOST_HAS_LONG_LONG) #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \ /**/ #else #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) #endif #define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \ namespace boost { namespace serialization { \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ } } \ /**/ #endif // BOOST_SERIALIZATION_COLLECTION_TRAITS ================================================ FILE: include/boost/serialization/collections_load_imp.hpp ================================================ #ifndef BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP #define BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #if defined(_MSC_VER) && (_MSC_VER <= 1020) # pragma warning (disable : 4786) // too long name, harmless warning #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // collections_load_imp.hpp: serialization for loading stl collections // (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. // helper function templates for serialization of collections #include #include // size_t #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include namespace boost{ namespace serialization { namespace stl { ////////////////////////////////////////////////////////////////////// // implementation of serialization for STL containers // template< class Archive, class T > typename boost::enable_if< typename detail::is_default_constructible< typename T::value_type >, void >::type collection_load_impl( Archive & ar, T & t, collection_size_type count, item_version_type /*item_version*/ ){ t.resize(count); typename T::iterator hint; hint = t.begin(); while(count-- > 0){ ar >> boost::serialization::make_nvp("item", *hint++); } } template< class Archive, class T > typename boost::disable_if< typename detail::is_default_constructible< typename T::value_type >, void >::type collection_load_impl( Archive & ar, T & t, collection_size_type count, item_version_type item_version ){ t.clear(); while(count-- > 0){ detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); t.push_back(boost::move(u.reference())); ar.reset_object_address(& t.back() , u.address()); } } } // namespace stl } // namespace serialization } // namespace boost #endif //BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP ================================================ FILE: include/boost/serialization/collections_save_imp.hpp ================================================ #ifndef BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP #define BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // collections_save_imp.hpp: serialization for stl collections // (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. // helper function templates for serialization of collections #include #include #include #include #include #include #include namespace boost{ namespace serialization { namespace stl { ////////////////////////////////////////////////////////////////////// // implementation of serialization for STL containers // template inline void save_collection( Archive & ar, const Container &s, collection_size_type count) { ar << BOOST_SERIALIZATION_NVP(count); // record number of elements const item_version_type item_version( version::value ); ar << BOOST_SERIALIZATION_NVP(item_version); typename Container::const_iterator it = s.begin(); while(count-- > 0){ // note borland emits a no-op without the explicit namespace boost::serialization::save_construct_data_adl( ar, boost::addressof(*it), item_version ); ar << boost::serialization::make_nvp("item", *it++); } } template inline void save_collection(Archive & ar, const Container &s) { // record number of elements collection_size_type count(s.size()); save_collection(ar, s, count); } } // namespace stl } // namespace serialization } // namespace boost #endif //BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP ================================================ FILE: include/boost/serialization/complex.hpp ================================================ #ifndef BOOST_SERIALIZATION_COMPLEX_HPP #define BOOST_SERIALIZATION_COMPLEX_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization/utility.hpp: // serialization for stl utility templates // (C) Copyright 2007 Matthias Troyer . // 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 #include #include #include #include namespace boost { namespace serialization { template inline void serialize( Archive & ar, std::complex< T > & t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } template inline void save( Archive & ar, std::complex< T > const & t, const unsigned int /* file_version */ ){ const T re = t.real(); const T im = t.imag(); ar << boost::serialization::make_nvp("real", re); ar << boost::serialization::make_nvp("imag", im); } template inline void load( Archive & ar, std::complex< T >& t, const unsigned int /* file_version */ ){ T re; T im; ar >> boost::serialization::make_nvp("real", re); ar >> boost::serialization::make_nvp("imag", im); t = std::complex< T >(re,im); } // specialization of serialization traits for complex template struct is_bitwise_serializable > : public is_bitwise_serializable< T > {}; template struct implementation_level > : mpl::int_ {} ; // treat complex just like builtin arithmetic types for tracking template struct tracking_level > : mpl::int_ {} ; } // serialization } // namespace boost #endif // BOOST_SERIALIZATION_COMPLEX_HPP ================================================ FILE: include/boost/serialization/config.hpp ================================================ #ifndef BOOST_SERIALIZATION_CONFIG_HPP #define BOOST_SERIALIZATION_CONFIG_HPP // config.hpp ---------------------------------------------// // (c) Copyright Robert Ramey 2004 // 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 library home page at http://www.boost.org/libs/serialization //----------------------------------------------------------------------------// // This header implements separate compilation features as described in // http://www.boost.org/more/separate_compilation.html #include #include // note: this version incorporates the related code into the the // the same library as BOOST_ARCHIVE. This could change some day in the // future // if BOOST_SERIALIZATION_DECL is defined undefine it now: #ifdef BOOST_SERIALIZATION_DECL #undef BOOST_SERIALIZATION_DECL #endif // we need to import/export our code only if the user has specifically // asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost // libraries to be dynamically linked, or BOOST_SERIALIZATION_DYN_LINK // if they want just this one to be dynamically liked: #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) #if !defined(BOOST_DYN_LINK) #define BOOST_DYN_LINK #endif // export if this is our own source, otherwise import: #if defined(BOOST_SERIALIZATION_SOURCE) #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT #else #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT #endif // defined(BOOST_SERIALIZATION_SOURCE) #endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) // if BOOST_SERIALIZATION_DECL isn't defined yet define it now: #ifndef BOOST_SERIALIZATION_DECL #define BOOST_SERIALIZATION_DECL #endif // enable automatic library variant selection ------------------------------// #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ && !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ && !defined(BOOST_SERIALIZATION_SOURCE) // // Set the name of our library, this will get undef'ed by auto_link.hpp // once it's done with it: // #define BOOST_LIB_NAME boost_serialization // // If we're importing code from a dll, then tell auto_link.hpp about it: // #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) # define BOOST_DYN_LINK #endif // // And include the header that does the work: // #include #endif #endif // BOOST_SERIALIZATION_CONFIG_HPP ================================================ FILE: include/boost/serialization/deque.hpp ================================================ #ifndef BOOST_SERIALIZATION_DEQUE_HPP #define BOOST_SERIALIZATION_DEQUE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // deque.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 #include #include #include #include #include namespace boost { namespace serialization { template inline void save( Archive & ar, const std::deque &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::deque >(ar, t); } template inline void load( Archive & ar, std::deque &t, const unsigned int /* file_version */ ){ const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } stl::collection_load_impl(ar, t, count, item_version); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::deque &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(std::deque) #endif // BOOST_SERIALIZATION_DEQUE_HPP ================================================ FILE: include/boost/serialization/detail/is_default_constructible.hpp ================================================ #ifndef BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP #define BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // is_default_constructible.hpp: serialization for loading stl collections // // (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 #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) #include namespace boost{ namespace serialization { namespace detail { template struct is_default_constructible : public std::is_default_constructible {}; } // detail } // serialization } // boost #else // we don't have standard library support for is_default_constructible // so we fake it by using boost::has_trivial_construtor. But this is not // actually correct because it's possible that a default constructor // to be non trivial. So when using this, make sure you're not using your // own definition of of T() but are using the actual default one! #include namespace boost{ namespace serialization { namespace detail { template struct is_default_constructible : public boost::has_trivial_constructor {}; } // detail } // serialization } // boost #endif #endif // BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP ================================================ FILE: include/boost/serialization/detail/shared_count_132.hpp ================================================ #ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED #define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif // // detail/shared_count.hpp // // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // #include #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. #endif #include #include #include #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) #include #endif #include // std::auto_ptr, std::allocator #include // std::less #include // std::exception #include // std::bad_alloc #include // std::type_info in get_deleter #include // std::size_t #include // msvc 6.0 needs this for warning suppression #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif namespace boost_132 { // Debug hooks #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); void sp_array_constructor_hook(void * px); void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); void sp_array_destructor_hook(void * px); #endif // The standard library that comes with Borland C++ 5.5.1 // defines std::exception and its members as having C calling // convention (-pc). When the definition of bad_weak_ptr // is compiled with -ps, the compiler issues an error. // Hence, the temporary #pragma option -pc below. The version // check is deliberately conservative. class bad_weak_ptr: public std::exception { public: virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW { return "boost::bad_weak_ptr"; } }; namespace detail{ class sp_counted_base { //private: typedef boost::detail::lightweight_mutex mutex_type; public: sp_counted_base(): use_count_(1), weak_count_(1) { } virtual ~sp_counted_base() // nothrow { } // dispose() is called when use_count_ drops to zero, to release // the resources managed by *this. virtual void dispose() = 0; // nothrow // destruct() is called when weak_count_ drops to zero. virtual void destruct() // nothrow { delete this; } virtual void * get_deleter(std::type_info const & ti) = 0; void add_ref_copy() { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif ++use_count_; } void add_ref_lock() { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr()); ++use_count_; } void release() // nothrow { { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif long new_use_count = --use_count_; if(new_use_count != 0) return; } dispose(); weak_release(); } void weak_add_ref() // nothrow { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif ++weak_count_; } void weak_release() // nothrow { long new_weak_count; { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif new_weak_count = --weak_count_; } if(new_weak_count == 0) { destruct(); } } long use_count() const // nothrow { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif return use_count_; } //private: public: sp_counted_base(sp_counted_base const &); sp_counted_base & operator= (sp_counted_base const &); long use_count_; // #shared long weak_count_; // #weak + (#shared != 0) #if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) mutable mutex_type mtx_; #endif }; #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) { boost::sp_scalar_constructor_hook(px, sizeof(T), pn); } template void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) { boost::sp_array_constructor_hook(px); } template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) { } template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) { boost::sp_scalar_destructor_hook(px, sizeof(T), pn); } template void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) { boost::sp_array_destructor_hook(px); } template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) { } #endif // // Borland's Codeguard trips up over the -Vx- option here: // #ifdef __CODEGUARD__ # pragma option push -Vx- #endif template class sp_counted_base_impl: public sp_counted_base { //private: public: P ptr; // copy constructor must not throw D del; // copy constructor must not throw sp_counted_base_impl(sp_counted_base_impl const &); sp_counted_base_impl & operator= (sp_counted_base_impl const &); typedef sp_counted_base_impl this_type; public: // pre: initial_use_count <= initial_weak_count, d(p) must not throw sp_counted_base_impl(P p, D d): ptr(p), del(d) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) detail::cbi_call_constructor_hook(this, p, d, 0); #endif } virtual void dispose() // nothrow { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) detail::cbi_call_destructor_hook(this, ptr, del, 0); #endif del(ptr); } virtual void * get_deleter(std::type_info const & ti) { return ti == typeid(D)? &del: 0; } #if defined(BOOST_SP_USE_STD_ALLOCATOR) void * operator new(std::size_t) { return std::allocator().allocate(1, static_cast(0)); } void operator delete(void * p) { std::allocator().deallocate(static_cast(p), 1); } #endif #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) void * operator new(std::size_t) { return boost::detail::quick_allocator::alloc(); } void operator delete(void * p) { boost::detail::quick_allocator::dealloc(p); } #endif }; #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) int const shared_count_id = 0x2C35F101; int const weak_count_id = 0x298C38A4; #endif class weak_count; class shared_count { //private: public: sp_counted_base * pi_; #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) int id_; #endif friend class weak_count; public: shared_count(): pi_(0) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { } template shared_count(P p, D d): pi_(0) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { #ifndef BOOST_NO_EXCEPTIONS try { pi_ = new sp_counted_base_impl(p, d); } catch(...) { d(p); // delete p throw; } #else pi_ = new sp_counted_base_impl(p, d); if(pi_ == 0) { d(p); // delete p boost::serialization::throw_exception(std::bad_alloc()); } #endif } #ifndef BOOST_NO_AUTO_PTR // auto_ptr is special cased to provide the strong guarantee template explicit shared_count(std::auto_ptr & r): pi_( new sp_counted_base_impl< Y *, boost::checked_deleter >(r.get(), boost::checked_deleter())) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { r.release(); } #endif ~shared_count() // nothrow { if(pi_ != 0) pi_->release(); #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) id_ = 0; #endif } shared_count(shared_count const & r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { if(pi_ != 0) pi_->add_ref_copy(); } explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 shared_count & operator= (shared_count const & r) // nothrow { sp_counted_base * tmp = r.pi_; if(tmp != pi_) { if(tmp != 0) tmp->add_ref_copy(); if(pi_ != 0) pi_->release(); pi_ = tmp; } return *this; } void swap(shared_count & r) // nothrow { sp_counted_base * tmp = r.pi_; r.pi_ = pi_; pi_ = tmp; } long use_count() const // nothrow { return pi_ != 0? pi_->use_count(): 0; } bool unique() const // nothrow { return use_count() == 1; } friend inline bool operator==(shared_count const & a, shared_count const & b) { return a.pi_ == b.pi_; } friend inline bool operator<(shared_count const & a, shared_count const & b) { return std::less()(a.pi_, b.pi_); } void * get_deleter(std::type_info const & ti) const { return pi_? pi_->get_deleter(ti): 0; } }; #ifdef __CODEGUARD__ # pragma option pop #endif class weak_count { private: sp_counted_base * pi_; #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) int id_; #endif friend class shared_count; public: weak_count(): pi_(0) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(weak_count_id) #endif { } weak_count(shared_count const & r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { if(pi_ != 0) pi_->weak_add_ref(); } weak_count(weak_count const & r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { if(pi_ != 0) pi_->weak_add_ref(); } ~weak_count() // nothrow { if(pi_ != 0) pi_->weak_release(); #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) id_ = 0; #endif } weak_count & operator= (shared_count const & r) // nothrow { sp_counted_base * tmp = r.pi_; if(tmp != 0) tmp->weak_add_ref(); if(pi_ != 0) pi_->weak_release(); pi_ = tmp; return *this; } weak_count & operator= (weak_count const & r) // nothrow { sp_counted_base * tmp = r.pi_; if(tmp != 0) tmp->weak_add_ref(); if(pi_ != 0) pi_->weak_release(); pi_ = tmp; return *this; } void swap(weak_count & r) // nothrow { sp_counted_base * tmp = r.pi_; r.pi_ = pi_; pi_ = tmp; } long use_count() const // nothrow { return pi_ != 0? pi_->use_count(): 0; } friend inline bool operator==(weak_count const & a, weak_count const & b) { return a.pi_ == b.pi_; } friend inline bool operator<(weak_count const & a, weak_count const & b) { return std::less()(a.pi_, b.pi_); } }; inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { if(pi_ != 0) { pi_->add_ref_lock(); } else { boost::serialization::throw_exception(bad_weak_ptr()); } } } // namespace detail } // namespace boost BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base) #endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED ================================================ FILE: include/boost/serialization/detail/shared_ptr_132.hpp ================================================ #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED #define BOOST_SHARED_PTR_132_HPP_INCLUDED // // shared_ptr.hpp // // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. // Copyright (c) 2001, 2002, 2003 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. // #include // for broken compiler workarounds #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) #include #else #include #include #include #include #include #include #include // for std::auto_ptr #include // for std::swap #include // for std::less #include // for std::bad_cast #include // for std::basic_ostream #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash # pragma warning(push) # pragma warning(disable:4284) // odd return type for operator-> #endif namespace boost_132 { template class weak_ptr; template class enable_shared_from_this; namespace detail { struct static_cast_tag {}; struct const_cast_tag {}; struct dynamic_cast_tag {}; struct polymorphic_cast_tag {}; template struct shared_ptr_traits { typedef T & reference; }; template<> struct shared_ptr_traits { typedef void reference; }; #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) template<> struct shared_ptr_traits { typedef void reference; }; template<> struct shared_ptr_traits { typedef void reference; }; template<> struct shared_ptr_traits { typedef void reference; }; #endif // enable_shared_from_this support template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px ) { if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); } inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) { } } // namespace detail // // shared_ptr // // An enhanced relative of scoped_ptr with reference counted copy semantics. // The object pointed to is deleted when the last shared_ptr pointing to it // is destroyed or reset. // template class shared_ptr { private: // Borland 5.5.1 specific workaround typedef shared_ptr< T > this_type; public: typedef T element_type; typedef T value_type; typedef T * pointer; typedef typename detail::shared_ptr_traits< T >::reference reference; shared_ptr(): px(0), pn() // never throws in 1.30+ { } template explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter()) // Y must be complete { detail::sp_enable_shared_from_this( pn, p, p ); } // // Requirements: D's copy constructor must not throw // // shared_ptr will release p by calling d(p) // template shared_ptr(Y * p, D d): px(p), pn(p, d) { detail::sp_enable_shared_from_this( pn, p, p ); } // generated copy constructor, assignment, destructor are fine... // except that Borland C++ has a bug, and g++ with -Wsynth warns #if defined(__GNUC__) shared_ptr & operator=(shared_ptr const & r) // never throws { px = r.px; pn = r.pn; // shared_count::op= doesn't throw return *this; } #endif template explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw { // it is now safe to copy r.px, as pn(r.pn) did not throw px = r.px; } template shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws { } template shared_ptr(shared_ptr const & r, detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) { } template shared_ptr(shared_ptr const & r, detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) { } template shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) { if(px == 0) // need to allocate new counter -- the cast failed { pn = detail::shared_count(); } } template shared_ptr(shared_ptr const & r, detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) { if(px == 0) { boost::serialization::throw_exception(std::bad_cast()); } } #ifndef BOOST_NO_AUTO_PTR template explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() { Y * tmp = r.get(); pn = detail::shared_count(r); detail::sp_enable_shared_from_this( pn, tmp, tmp ); } #endif #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) template shared_ptr & operator=(shared_ptr const & r) // never throws { px = r.px; pn = r.pn; // shared_count::op= doesn't throw return *this; } #endif #ifndef BOOST_NO_AUTO_PTR template shared_ptr & operator=(std::auto_ptr & r) { this_type(r).swap(*this); return *this; } #endif void reset() // never throws in 1.30+ { this_type().swap(*this); } template void reset(Y * p) // Y must be complete { BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors this_type(p).swap(*this); } template void reset(Y * p, D d) { this_type(p, d).swap(*this); } reference operator* () const // never throws { BOOST_ASSERT(px != 0); return *px; } T * operator-> () const // never throws { BOOST_ASSERT(px != 0); return px; } T * get() const // never throws { return px; } // implicit conversion to "bool" #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) operator bool () const { return px != 0; } #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) typedef T * (this_type::*unspecified_bool_type)() const; operator unspecified_bool_type() const // never throws { return px == 0? 0: &this_type::get; } #else typedef T * this_type::*unspecified_bool_type; operator unspecified_bool_type() const // never throws { return px == 0? 0: &this_type::px; } #endif // operator! is redundant, but some compilers need it bool operator! () const // never throws { return px == 0; } bool unique() const // never throws { return pn.unique(); } long use_count() const // never throws { return pn.use_count(); } void swap(shared_ptr< T > & other) // never throws { std::swap(px, other.px); pn.swap(other.pn); } template bool _internal_less(shared_ptr const & rhs) const { return pn < rhs.pn; } void * _internal_get_deleter(std::type_info const & ti) const { return pn.get_deleter(ti); } // Tasteless as this may seem, making all members public allows member templates // to work in the absence of member template friends. (Matthew Langston) #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS private: template friend class shared_ptr; template friend class weak_ptr; #endif public: // for serialization T * px; // contained pointer detail::shared_count pn; // reference counter }; // shared_ptr template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) { return a.get() == b.get(); } template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) { return a.get() != b.get(); } template inline bool operator<(shared_ptr< T > const & a, shared_ptr const & b) { return a._internal_less(b); } template inline void swap(shared_ptr< T > & a, shared_ptr< T > & b) { a.swap(b); } template shared_ptr< T > static_pointer_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::static_cast_tag()); } template shared_ptr< T > const_pointer_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::const_cast_tag()); } template shared_ptr< T > dynamic_pointer_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::dynamic_cast_tag()); } // shared_*_cast names are deprecated. Use *_pointer_cast instead. template shared_ptr< T > shared_static_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::static_cast_tag()); } template shared_ptr< T > shared_dynamic_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::dynamic_cast_tag()); } template shared_ptr< T > shared_polymorphic_cast(shared_ptr const & r) { return shared_ptr< T >(r, detail::polymorphic_cast_tag()); } template shared_ptr< T > shared_polymorphic_downcast(shared_ptr const & r) { BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); return shared_static_cast< T >(r); } // get_pointer() enables boost::mem_fn to recognize shared_ptr template inline T * get_pointer(shared_ptr< T > const & p) { return p.get(); } // operator<< template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) { os << p.get(); return os; } // get_deleter (experimental) #if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) // g++ 2.9x doesn't allow static_cast(void *) // apparently EDG 2.38 also doesn't accept it template D * get_deleter(shared_ptr< T > const & p) { void const * q = p._internal_get_deleter(typeid(D)); return const_cast(static_cast(q)); } #else template D * get_deleter(shared_ptr< T > const & p) { return static_cast(p._internal_get_deleter(typeid(D))); } #endif } // namespace boost #ifdef BOOST_MSVC # pragma warning(pop) #endif #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) #endif // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED ================================================ FILE: include/boost/serialization/detail/shared_ptr_nmt_132.hpp ================================================ #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED #define BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED // // detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates // // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. // Copyright (c) 2001, 2002 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. // #include #include #include #include #ifndef BOOST_NO_AUTO_PTR # include // for std::auto_ptr #endif #include // for std::swap #include // for std::less #include // for std::bad_alloc namespace boost { template class shared_ptr { private: typedef detail::atomic_count count_type; public: typedef T element_type; typedef T value_type; explicit shared_ptr(T * p = 0): px(p) { #ifndef BOOST_NO_EXCEPTIONS try // prevent leak if new throws { pn = new count_type(1); } catch(...) { boost::checked_delete(p); throw; } #else pn = new count_type(1); if(pn == 0) { boost::checked_delete(p); boost::serialization::throw_exception(std::bad_alloc()); } #endif } ~shared_ptr() { if(--*pn == 0) { boost::checked_delete(px); delete pn; } } shared_ptr(shared_ptr const & r): px(r.px) // never throws { pn = r.pn; ++*pn; } shared_ptr & operator=(shared_ptr const & r) { shared_ptr(r).swap(*this); return *this; } #ifndef BOOST_NO_AUTO_PTR explicit shared_ptr(std::auto_ptr< T > & r) { pn = new count_type(1); // may throw px = r.release(); // fix: moved here to stop leak if new throws } shared_ptr & operator=(std::auto_ptr< T > & r) { shared_ptr(r).swap(*this); return *this; } #endif void reset(T * p = 0) { BOOST_ASSERT(p == 0 || p != px); shared_ptr(p).swap(*this); } T & operator*() const // never throws { BOOST_ASSERT(px != 0); return *px; } T * operator->() const // never throws { BOOST_ASSERT(px != 0); return px; } T * get() const // never throws { return px; } long use_count() const // never throws { return *pn; } bool unique() const // never throws { return *pn == 1; } void swap(shared_ptr< T > & other) // never throws { std::swap(px, other.px); std::swap(pn, other.pn); } private: T * px; // contained pointer count_type * pn; // ptr to reference counter }; template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) { return a.get() == b.get(); } template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) { return a.get() != b.get(); } template inline bool operator<(shared_ptr< T > const & a, shared_ptr< T > const & b) { return std::less()(a.get(), b.get()); } template void swap(shared_ptr< T > & a, shared_ptr< T > & b) { a.swap(b); } // get_pointer() enables boost::mem_fn to recognize shared_ptr template inline T * get_pointer(shared_ptr< T > const & p) { return p.get(); } } // namespace boost #endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED ================================================ FILE: include/boost/serialization/detail/stack_constructor.hpp ================================================ #ifndef BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP #define BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // stack_constructor.hpp: serialization for loading stl collections // (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 #include namespace boost{ namespace serialization { namespace detail { // reserve space on stack for an object of type T without actually // construction such an object template struct stack_allocate { T * address() { return static_cast(storage_.address()); } T & reference() { return * address(); } private: typedef typename boost::aligned_storage< sizeof(T), boost::alignment_of::value > type; type storage_; }; // construct element on the stack template struct stack_construct : public stack_allocate { stack_construct(Archive & ar, const unsigned int version){ // note borland emits a no-op without the explicit namespace boost::serialization::load_construct_data_adl( ar, this->address(), version ); } ~stack_construct(){ this->address()->~T(); // undo load_construct_data above } }; } // detail } // serialization } // boost #endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP ================================================ FILE: include/boost/serialization/export.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXPORT_HPP #define BOOST_SERIALIZATION_EXPORT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // export.hpp: set traits of classes to be serialized // (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. // (C) Copyright 2006 David Abrahams - http://www.boost.org. // implementation of class export functionality. This is an alternative to // "forward declaration" method to provoke instantiation of derived classes // that are to be serialized through pointers. #include #include // NULL #include #include #include #include #include #include #include #include #include // for guid_defined only #include #include #include #include #include namespace boost { namespace archive { namespace detail { class basic_pointer_iserializer; class basic_pointer_oserializer; template class pointer_iserializer; template class pointer_oserializer; template struct export_impl { static const basic_pointer_iserializer & enable_load(mpl::true_){ return boost::serialization::singleton< pointer_iserializer >::get_const_instance(); } static const basic_pointer_oserializer & enable_save(mpl::true_){ return boost::serialization::singleton< pointer_oserializer >::get_const_instance(); } inline static void enable_load(mpl::false_) {} inline static void enable_save(mpl::false_) {} }; // On many platforms, naming a specialization of this template is // enough to cause its argument to be instantiated. template struct instantiate_function {}; template struct ptr_serialization_support { # if defined(BOOST_MSVC) || defined(__SUNPRO_CC) virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; # else static BOOST_DLLEXPORT void instantiate() BOOST_USED; typedef instantiate_function< &ptr_serialization_support::instantiate > x; # endif }; template BOOST_DLLEXPORT void ptr_serialization_support::instantiate() { export_impl::enable_save( typename Archive::is_saving() ); export_impl::enable_load( typename Archive::is_loading() ); } // Note INTENTIONAL usage of anonymous namespace in header. // This was made this way so that export.hpp could be included // in other headers. This is still under study. namespace extra_detail { template struct guid_initializer { void export_guid(mpl::false_) const { // generates the statically-initialized objects whose constructors // register the information allowing serialization of T objects // through pointers to their base classes. instantiate_ptr_serialization((T*)0, 0, adl_tag()); } void export_guid(mpl::true_) const { } guid_initializer const & export_guid() const { BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); // note: exporting an abstract base class will have no effect // and cannot be used to instantiate serialization code // (one might be using this in a DLL to instantiate code) //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); export_guid(boost::serialization::is_abstract< T >()); return *this; } }; template struct init_guid; } // anonymous } // namespace detail } // namespace archive } // namespace boost #define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ namespace boost { \ namespace archive { \ namespace detail { \ namespace extra_detail { \ template<> \ struct init_guid< T > { \ static guid_initializer< T > const & g; \ }; \ guid_initializer< T > const & init_guid< T >::g = \ ::boost::serialization::singleton< \ guid_initializer< T > \ >::get_mutable_instance().export_guid(); \ }}}} \ /**/ #define BOOST_CLASS_EXPORT_KEY2(T, K) \ namespace boost { \ namespace serialization { \ template<> \ struct guid_defined< T > : boost::mpl::true_ {}; \ template<> \ inline const char * guid< T >(){ \ return K; \ } \ } /* serialization */ \ } /* boost */ \ /**/ #define BOOST_CLASS_EXPORT_KEY(T) \ BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ /**/ #define BOOST_CLASS_EXPORT_GUID(T, K) \ BOOST_CLASS_EXPORT_KEY2(T, K) \ BOOST_CLASS_EXPORT_IMPLEMENT(T) \ /**/ #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) // CodeWarrior fails to construct static members of class templates // when they are instantiated from within templates, so on that // compiler we ask users to specifically register base/derived class // relationships for exported classes. On all other compilers, use of // this macro is entirely optional. # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ namespace { \ static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ , 3); \ } #else # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) #endif // check for unnecessary export. T isn't polymorphic so there is no // need to export it. #define BOOST_CLASS_EXPORT_CHECK(T) \ BOOST_STATIC_WARNING( \ boost::is_polymorphic::value \ ); \ /**/ // the default exportable class identifier is the class name // the default list of archives types for which code id generated // are the originally included with this serialization system #define BOOST_CLASS_EXPORT(T) \ BOOST_CLASS_EXPORT_GUID( \ T, \ BOOST_PP_STRINGIZE(T) \ ) \ /**/ #endif // BOOST_SERIALIZATION_EXPORT_HPP ================================================ FILE: include/boost/serialization/extended_type_info.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP #define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // extended_type_info.hpp: interface for portable version of type_info // (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. // for now, extended type info is part of the serialization libraries // this could change in the future. #include #include #include // NULL #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275) #endif #define BOOST_SERIALIZATION_MAX_KEY_SIZE 128 namespace boost { namespace serialization { namespace void_cast_detail{ class void_caster; } class BOOST_SYMBOL_VISIBLE extended_type_info : private boost::noncopyable { private: friend class boost::serialization::void_cast_detail::void_caster; // used to uniquely identify the type of class derived from this one // so that different derivations of this class can be simultaneously // included in implementation of sets and maps. const unsigned int m_type_info_key; virtual bool is_less_than(const extended_type_info & /*rhs*/) const = 0; virtual bool is_equal(const extended_type_info & /*rhs*/) const = 0; const char * m_key; protected: BOOST_SERIALIZATION_DECL void key_unregister() const; BOOST_SERIALIZATION_DECL void key_register() const; // this class can't be used as is. It's just the // common functionality for all type_info replacement // systems. Hence, make these protected BOOST_SERIALIZATION_DECL extended_type_info( const unsigned int type_info_key, const char * key ); virtual BOOST_SERIALIZATION_DECL ~extended_type_info(); public: const char * get_key() const { return m_key; } virtual const char * get_debug_info() const = 0; BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const; BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const; bool operator!=(const extended_type_info &rhs) const { return !(operator==(rhs)); } // note explicit "export" of static function to work around // gcc 4.5 mingw error static BOOST_SERIALIZATION_DECL const extended_type_info * find(const char *key); // for plugins virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0; virtual void destroy(void const * const /*p*/) const = 0; }; template struct guid_defined : boost::mpl::false_ {}; namespace ext { template struct guid_impl { static inline const char * call() { return NULL; } }; } template inline const char * guid(){ return ext::guid_impl::call(); } } // namespace serialization } // namespace boost #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP ================================================ FILE: include/boost/serialization/extended_type_info_no_rtti.hpp ================================================ #ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP #define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif // extended_type_info_no_rtti.hpp: implementation for version that depends // on runtime typing (rtti - typeid) but uses a user specified string // as the portable class identifier. // (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 #include #include #include #include #include #include #include #include #include #include #include #include // hijack serialization access #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275 4511 4512) #endif namespace boost { namespace serialization { /////////////////////////////////////////////////////////////////////// // define a special type_info that doesn't depend on rtti which is not // available in all situations. namespace no_rtti_system { // common base class to share type_info_key. This is used to // identify the method used to keep track of the extended type class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 : public extended_type_info { protected: BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key); BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0() BOOST_OVERRIDE; public: BOOST_SERIALIZATION_DECL bool is_less_than(const boost::serialization::extended_type_info &rhs) const BOOST_OVERRIDE; BOOST_SERIALIZATION_DECL bool is_equal(const boost::serialization::extended_type_info &rhs) const BOOST_OVERRIDE; }; } // no_rtti_system template class extended_type_info_no_rtti : public no_rtti_system::extended_type_info_no_rtti_0, public singleton > { template struct action { struct defined { static const char * invoke(){ return guid< T >(); } }; struct undefined { // if your program traps here - you failed to // export a guid for this type. the no_rtti // system requires export for types serialized // as pointers. BOOST_STATIC_ASSERT(0 == sizeof(T)); static const char * invoke(); }; static const char * invoke(){ typedef typename boost::mpl::if_c< tf, defined, undefined >::type type; return type::invoke(); } }; public: extended_type_info_no_rtti() : no_rtti_system::extended_type_info_no_rtti_0( action::value >::invoke()) { key_register(); } ~extended_type_info_no_rtti() BOOST_OVERRIDE { key_unregister(); } const extended_type_info * get_derived_extended_type_info(const T & t) const { // find the type that corresponds to the most derived type. // this implementation doesn't depend on typeid() but assumes // that the specified type has a function of the following signature. // A common implementation of such a function is to define as a virtual // function. So if the type is not a polymorphic type it's likely an error BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); const char * derived_key = t.get_key(); BOOST_ASSERT(NULL != derived_key); return boost::serialization::extended_type_info::find(derived_key); } const char * get_key() const{ return action::value >::invoke(); } const char * get_debug_info() const BOOST_OVERRIDE { return action::value >::invoke(); } void * construct(unsigned int count, ...) const BOOST_OVERRIDE { // count up the arguments void * r = NULL; std::va_list ap; va_start(ap, count); switch(count){ case 0: r = factory::type, 0>(ap); break; case 1: r = factory::type, 1>(ap); break; case 2: r = factory::type, 2>(ap); break; case 3: r = factory::type, 3>(ap); break; case 4: r = factory::type, 4>(ap); break; default: BOOST_ASSERT(false); // too many arguments // throw exception here? } va_end(ap); return r; } void destroy(void const * const p) const BOOST_OVERRIDE { boost::serialization::access::destroy( static_cast(p) ); //delete static_cast(p) ; } }; } // namespace serialization } // namespace boost /////////////////////////////////////////////////////////////////////////////// // If no other implementation has been designated as default, // use this one. To use this implementation as the default, specify it // before any of the other headers. #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO namespace boost { namespace serialization { template struct extended_type_info_impl { typedef typename boost::serialization::extended_type_info_no_rtti< T > type; }; } // namespace serialization } // namespace boost #endif #ifdef BOOST_MSVC # pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP ================================================ FILE: include/boost/serialization/extended_type_info_typeid.hpp ================================================ #ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP #define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif // extended_type_info_typeid.hpp: implementation for version that depends // on runtime typing (rtti - typeid) but uses a user specified string // as the portable class identifier. // (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 #include #include #include #include #include #include #include #include #include #include #include // hijack serialization access #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4251 4231 4660 4275 4511 4512) #endif namespace boost { namespace serialization { namespace typeid_system { class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 : public extended_type_info { const char * get_debug_info() const BOOST_OVERRIDE { if(static_cast(0) == m_ti) return static_cast(0); return m_ti->name(); } protected: const std::type_info * m_ti; BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key); BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0() BOOST_OVERRIDE; BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti); BOOST_SERIALIZATION_DECL void type_unregister(); BOOST_SERIALIZATION_DECL const extended_type_info * get_extended_type_info(const std::type_info & ti) const; public: BOOST_SERIALIZATION_DECL bool is_less_than(const extended_type_info &rhs) const BOOST_OVERRIDE; BOOST_SERIALIZATION_DECL bool is_equal(const extended_type_info &rhs) const BOOST_OVERRIDE; const std::type_info & get_typeid() const { return *m_ti; } }; } // typeid_system template class extended_type_info_typeid : public typeid_system::extended_type_info_typeid_0, public singleton > { public: extended_type_info_typeid() : typeid_system::extended_type_info_typeid_0( boost::serialization::guid< T >() ) { type_register(typeid(T)); key_register(); } ~extended_type_info_typeid() BOOST_OVERRIDE { key_unregister(); type_unregister(); } // get the eti record for the true type of this record // relying upon standard type info implementation (rtti) const extended_type_info * get_derived_extended_type_info(const T & t) const { // note: this implementation - based on usage of typeid (rtti) // only does something if the class has at least one virtual function. BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); return typeid_system::extended_type_info_typeid_0::get_extended_type_info( typeid(t) ); } const char * get_key() const { return boost::serialization::guid< T >(); } void * construct(unsigned int count, ...) const BOOST_OVERRIDE { // count up the arguments void * r = NULL; std::va_list ap; va_start(ap, count); switch(count){ case 0: r = factory::type, 0>(ap); break; case 1: r = factory::type, 1>(ap); break; case 2: r = factory::type, 2>(ap); break; case 3: r = factory::type, 3>(ap); break; case 4: r = factory::type, 4>(ap); break; default: BOOST_ASSERT(false); // too many arguments // throw exception here? } va_end(ap); return r; } void destroy(void const * const p) const BOOST_OVERRIDE { boost::serialization::access::destroy( static_cast(p) ); //delete static_cast(p); } }; } // namespace serialization } // namespace boost /////////////////////////////////////////////////////////////////////////////// // If no other implementation has been designated as default, // use this one. To use this implementation as the default, specify it // before any of the other headers. #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO namespace boost { namespace serialization { template struct extended_type_info_impl { typedef typename boost::serialization::extended_type_info_typeid< T > type; }; } // namespace serialization } // namespace boost #endif #ifdef BOOST_MSVC #pragma warning(pop) #endif #include // pops abi_suffix.hpp pragmas #endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP ================================================ FILE: include/boost/serialization/factory.hpp ================================================ #ifndef BOOST_SERIALIZATION_FACTORY_HPP #define BOOST_SERIALIZATION_FACTORY_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif // factory.hpp: create an instance from an extended_type_info instance. // (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 // valist #include // NULL #include #include #include namespace std{ #if defined(__LIBCOMO__) using ::va_list; #endif } // namespace std namespace boost { namespace serialization { // default implementation does nothing. template T * factory(std::va_list){ BOOST_ASSERT(false); // throw exception here? return NULL; } } // namespace serialization } // namespace boost #define BOOST_SERIALIZATION_FACTORY(N, T, A0, A1, A2, A3) \ namespace boost { \ namespace serialization { \ template<> \ T * factory(std::va_list ap){ \ BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ , A0 a0 = va_arg(ap, A0);, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ , A1 a1 = va_arg(ap, A1);, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ , A2 a2 = va_arg(ap, A2);, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ , A3 a3 = va_arg(ap, A3);, BOOST_PP_EMPTY()) \ return new T( \ BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ , a0, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 1)) \ , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ , a1, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 2)) \ , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ , a2, BOOST_PP_EMPTY()) \ BOOST_PP_IF(BOOST_PP_GREATER(N, 3)) \ , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ , a3, BOOST_PP_EMPTY()) \ ); \ } \ } \ } /**/ #define BOOST_SERIALIZATION_FACTORY_4(T, A0, A1, A2, A3) \ BOOST_SERIALIZATION_FACTORY(4, T, A0, A1, A2, A3) #define BOOST_SERIALIZATION_FACTORY_3(T, A0, A1, A2) \ BOOST_SERIALIZATION_FACTORY(3, T, A0, A1, A2, 0) #define BOOST_SERIALIZATION_FACTORY_2(T, A0, A1) \ BOOST_SERIALIZATION_FACTORY(2, T, A0, A1, 0, 0) #define BOOST_SERIALIZATION_FACTORY_1(T, A0) \ BOOST_SERIALIZATION_FACTORY(1, T, A0, 0, 0, 0) #define BOOST_SERIALIZATION_FACTORY_0(T) \ namespace boost { \ namespace serialization { \ template<> \ T * factory(std::va_list){ \ return new T(); \ } \ } \ } \ /**/ #endif // BOOST_SERIALIZATION_FACTORY_HPP ================================================ FILE: include/boost/serialization/force_include.hpp ================================================ #ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP #define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // force_include.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 // the following help macro is to guarantee that certain coded // is not removed by over-eager linker optimiser. In certain cases // we create static objects must be created but are actually never // referenced - creation has a side-effect such as global registration // which is important to us. We make an effort to refer these objects // so that a smart linker won't remove them as being unreferenced. // In microsoft compilers, inlining the code that does the referring // means the code gets lost and the static object is not included // in the library and hence never registered. This manifests itself // in an ungraceful crash at runtime when (and only when) built in // release mode. #if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__) # define BOOST_DLLEXPORT __declspec(dllexport) #elif ! defined(_WIN32) && ! defined(_WIN64) # if defined(__MWERKS__) # define BOOST_DLLEXPORT __declspec(dllexport) # elif defined(__GNUC__) && (__GNUC__ >= 3) # define BOOST_USED __attribute__ ((__used__)) # elif defined(__IBMCPP__) && (__IBMCPP__ >= 1110) # define BOOST_USED __attribute__ ((__used__)) # elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800) # define BOOST_USED __attribute__ ((__used__)) # endif #endif #ifndef BOOST_USED # define BOOST_USED #endif #ifndef BOOST_DLLEXPORT # define BOOST_DLLEXPORT #endif #endif // BOOST_SERIALIZATION_FORCE_INCLUDE_HPP ================================================ FILE: include/boost/serialization/forward_list.hpp ================================================ #ifndef BOOST_SERIALIZATION_FORWARD_LIST_HPP #define BOOST_SERIALIZATION_FORWARD_LIST_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // forward_list.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 #include #include // distance #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { template inline void save( Archive & ar, const std::forward_list &t, const unsigned int /*file_version*/ ){ const collection_size_type count(std::distance(t.cbegin(), t.cend())); boost::serialization::stl::save_collection< Archive, std::forward_list >(ar, t, count); } namespace stl { template< class Archive, class T, class Allocator > typename boost::disable_if< typename detail::is_default_constructible< typename std::forward_list::value_type >, void >::type collection_load_impl( Archive & ar, std::forward_list &t, collection_size_type count, item_version_type item_version ){ t.clear(); boost::serialization::detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); t.push_front(boost::move(u.reference())); typename std::forward_list::iterator last; last = t.begin(); ar.reset_object_address(&(*t.begin()) , & u.reference()); while(--count > 0){ detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); last = t.insert_after(last, boost::move(u.reference())); ar.reset_object_address(&(*last) , & u.reference()); } } } // stl template inline void load( Archive & ar, std::forward_list &t, const unsigned int /*file_version*/ ){ const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } stl::collection_load_impl(ar, t, count, item_version); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::forward_list &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(std::forward_list) #endif // BOOST_SERIALIZATION_FORWARD_LIST_HPP ================================================ FILE: include/boost/serialization/hash_collections_load_imp.hpp ================================================ #ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP #define BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once # pragma warning (disable : 4786) // too long name, harmless warning #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // hash_collections_load_imp.hpp: serialization for loading stl collections // (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. // helper function templates for serialization of hashed collections #include #include #include namespace boost{ namespace serialization { namespace stl { ////////////////////////////////////////////////////////////////////// // implementation of serialization for STL containers // template inline void load_hash_collection(Archive & ar, Container &s) { collection_size_type count; collection_size_type bucket_count; boost::serialization::item_version_type item_version(0); boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements if(boost::serialization::library_version_type(6) != library_version){ ar >> BOOST_SERIALIZATION_NVP(count); ar >> BOOST_SERIALIZATION_NVP(bucket_count); } else{ // note: fixup for error in version 6. collection size was // changed to size_t BUT for hashed collections it was implemented // as an unsigned int. This should be a problem only on win64 machines // but I'll leave it for everyone just in case. unsigned int c; unsigned int bc; ar >> BOOST_SERIALIZATION_NVP(c); count = c; ar >> BOOST_SERIALIZATION_NVP(bc); bucket_count = bc; } if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } s.clear(); #if ! defined(__MWERKS__) s.resize(bucket_count); #endif InputFunction ifunc; while(count-- > 0){ ifunc(ar, s, item_version); } } } // namespace stl } // namespace serialization } // namespace boost #endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP ================================================ FILE: include/boost/serialization/hash_collections_save_imp.hpp ================================================ #ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP #define BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // hash_collections_save_imp.hpp: serialization for stl collections // (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. // helper function templates for serialization of collections #include #include #include #include #include #include namespace boost{ namespace serialization { namespace stl { ////////////////////////////////////////////////////////////////////// // implementation of serialization for STL containers // template inline void save_hash_collection(Archive & ar, const Container &s) { collection_size_type count(s.size()); const collection_size_type bucket_count(s.bucket_count()); const item_version_type item_version( version::value ); #if 0 /* should only be necessary to create archives of previous versions * which is not currently supported. So for now comment this out */ boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements if(boost::serialization::library_version_type(6) != library_version){ ar << BOOST_SERIALIZATION_NVP(count); ar << BOOST_SERIALIZATION_NVP(bucket_count); } else{ // note: fixup for error in version 6. collection size was // changed to size_t BUT for hashed collections it was implemented // as an unsigned int. This should be a problem only on win64 machines // but I'll leave it for everyone just in case. const unsigned int c = count; const unsigned int bc = bucket_count; ar << BOOST_SERIALIZATION_NVP(c); ar << BOOST_SERIALIZATION_NVP(bc); } if(boost::serialization::library_version_type(3) < library_version){ // record number of elements // make sure the target type is registered so we can retrieve // the version when we load ar << BOOST_SERIALIZATION_NVP(item_version); } #else ar << BOOST_SERIALIZATION_NVP(count); ar << BOOST_SERIALIZATION_NVP(bucket_count); ar << BOOST_SERIALIZATION_NVP(item_version); #endif typename Container::const_iterator it = s.begin(); while(count-- > 0){ // note borland emits a no-op without the explicit namespace boost::serialization::save_construct_data_adl( ar, &(*it), boost::serialization::version< typename Container::value_type >::value ); ar << boost::serialization::make_nvp("item", *it++); } } } // namespace stl } // namespace serialization } // namespace boost #endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP ================================================ FILE: include/boost/serialization/hash_map.hpp ================================================ #ifndef BOOST_SERIALIZATION_HASH_MAP_HPP #define BOOST_SERIALIZATION_HASH_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // hash_map.hpp: serialization for stl hash_map templates // (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 #ifdef BOOST_HAS_HASH #include BOOST_HASH_MAP_HEADER #include // pair #include #include #include #include #include namespace boost { namespace serialization { namespace stl { // hash_map input template struct archive_input_hash_map { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); std::pair result = s.insert(boost::move(t.reference())); // note: the following presumes that the map::value_type was NOT tracked // in the archive. This is the usual case, but here there is no way // to determine that. if(result.second){ ar.reset_object_address( & (result.first->second), & t.reference().second ); } } }; // hash_multimap input template struct archive_input_hash_multimap { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::const_iterator result = s.insert(boost::move(t.reference())); // note: the following presumes that the map::value_type was NOT tracked // in the archive. This is the usual case, but here there is no way // to determine that. ar.reset_object_address( & result->second, & t.reference() ); } }; } // stl template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void save( Archive & ar, const BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::save_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator > >(ar, t); } template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void load( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::load_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator >, boost::serialization::stl::archive_input_hash_map< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator > > >(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void serialize( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_map< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } // hash_multimap template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void save( Archive & ar, const BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::save_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator > >(ar, t); } template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void load( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::load_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator >, boost::serialization::stl::archive_input_hash_multimap< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator > > >(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template< class Archive, class Key, class T, class HashFcn, class EqualKey, class Allocator > inline void serialize( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< Key, T, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #endif // BOOST_HAS_HASH #endif // BOOST_SERIALIZATION_HASH_MAP_HPP ================================================ FILE: include/boost/serialization/hash_set.hpp ================================================ #ifndef BOOST_SERIALIZATION_HASH_SET_HPP #define BOOST_SERIALIZATION_HASH_SET_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // hash_set.hpp: serialization for stl hash_set templates // (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 #ifdef BOOST_HAS_HASH #include BOOST_HASH_SET_HEADER #include #include #include #include #include namespace boost { namespace serialization { namespace stl { // hash_set input template struct archive_input_hash_set { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); std::pair result = s.insert(boost::move(t.reference())); if(result.second) ar.reset_object_address(& (* result.first), & t.reference()); } }; // hash_multiset input template struct archive_input_hash_multiset { inline void operator()( Archive &ar, Container &s, const unsigned int v ){ typedef typename Container::value_type type; detail::stack_construct t(ar, v); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::const_iterator result = s.insert(boost::move(t.reference())); ar.reset_object_address(& (* result), & t.reference()); } }; } // stl template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void save( Archive & ar, const BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::save_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator > >(ar, t); } template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void load( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::load_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator >, boost::serialization::stl::archive_input_hash_set< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator > > >(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void serialize( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_set< Key, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } // hash_multiset template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void save( Archive & ar, const BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::save_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator > >(ar, t); } template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void load( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator > &t, const unsigned int file_version ){ boost::serialization::stl::load_hash_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator >, boost::serialization::stl::archive_input_hash_multiset< Archive, BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator > > >(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template< class Archive, class Key, class HashFcn, class EqualKey, class Allocator > inline void serialize( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< Key, HashFcn, EqualKey, Allocator > & t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_set) BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_multiset) #endif // BOOST_HAS_HASH #endif // BOOST_SERIALIZATION_HASH_SET_HPP ================================================ FILE: include/boost/serialization/is_bitwise_serializable.hpp ================================================ // (C) Copyright 2007 Matthias Troyer // 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) // Authors: Matthias Troyer /** @file is_bitwise_serializable.hpp * * This header provides a traits class for determining whether a class * can be serialized (in a non-portable way) just by copying the bits. */ #ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP #define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include namespace boost { namespace serialization { template struct is_bitwise_serializable : public is_arithmetic< T > {}; } // namespace serialization } // namespace boost // define a macro to make explicit designation of this more transparent #define BOOST_IS_BITWISE_SERIALIZABLE(T) \ namespace boost { \ namespace serialization { \ template<> \ struct is_bitwise_serializable< T > : mpl::true_ {}; \ }} \ /**/ #endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP ================================================ FILE: include/boost/serialization/item_version_type.hpp ================================================ #ifndef BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP #define BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP // (C) Copyright 2010 Robert Ramey // 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 // uint_least8_t #include #include #include // fixes broken example build on x86_64-linux-gnu-gcc-4.6.0 #include namespace boost { namespace serialization { #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 4267 ) #endif class item_version_type { private: typedef unsigned int base_type; base_type t; public: // should be private - but MPI fails if it's not!!! item_version_type(): t(0) {} explicit item_version_type(const unsigned int t_) : t(t_){ BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } item_version_type(const item_version_type & t_) : t(t_.t) {} item_version_type & operator=(item_version_type rhs){ t = rhs.t; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type & () { return t; } bool operator==(const item_version_type & rhs) const { return t == rhs.t; } bool operator<(const item_version_type & rhs) const { return t < rhs.t; } }; #if defined(_MSC_VER) #pragma warning( pop ) #endif } } // end namespace boost::serialization BOOST_IS_BITWISE_SERIALIZABLE(item_version_type) BOOST_CLASS_IMPLEMENTATION(item_version_type, primitive_type) #endif //BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP ================================================ FILE: include/boost/serialization/level.hpp ================================================ #ifndef BOOST_SERIALIZATION_LEVEL_HPP #define BOOST_SERIALIZATION_LEVEL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // level.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 #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { struct basic_traits; // default serialization implementation level template struct implementation_level_impl { template struct traits_class_level { typedef typename U::level type; }; typedef mpl::integral_c_tag tag; // note: at least one compiler complained w/o the full qualification // on basic traits below typedef typename mpl::eval_if< is_base_and_derived, traits_class_level< T >, //else typename mpl::eval_if< is_fundamental< T >, mpl::int_, //else typename mpl::eval_if< is_class< T >, mpl::int_, //else typename mpl::eval_if< is_array< T >, mpl::int_, //else typename mpl::eval_if< is_enum< T >, mpl::int_, //else mpl::int_ > > > > >::type type; // vc 7.1 doesn't like enums here BOOST_STATIC_CONSTANT(int, value = type::value); }; template struct implementation_level : public implementation_level_impl { }; template inline bool operator>=(implementation_level< T > t, enum level_type l) { return t.value >= (int)l; } } // namespace serialization } // namespace boost // specify the level of serialization implementation for the class // require that class info saved when versioning is used #define BOOST_CLASS_IMPLEMENTATION(T, E) \ namespace boost { \ namespace serialization { \ template <> \ struct implementation_level_impl< const T > \ { \ typedef mpl::integral_c_tag tag; \ typedef mpl::int_< E > type; \ BOOST_STATIC_CONSTANT( \ int, \ value = implementation_level_impl::type::value \ ); \ }; \ } \ } /**/ #endif // BOOST_SERIALIZATION_LEVEL_HPP ================================================ FILE: include/boost/serialization/level_enum.hpp ================================================ #ifndef BOOST_SERIALIZATION_LEVEL_ENUM_HPP #define BOOST_SERIALIZATION_LEVEL_ENUM_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // level_enum.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. namespace boost { namespace serialization { // for each class used in the program, specify which level // of serialization should be implemented // names for each level enum level_type { // Don't serialize this type. An attempt to do so should // invoke a compile time assertion. not_serializable = 0, // write/read this type directly to the archive. In this case // serialization code won't be called. This is the default // case for fundamental types. It presumes a member function or // template in the archive class that can handle this type. // there is no runtime overhead associated reading/writing // instances of this level primitive_type = 1, // Serialize the objects of this type using the objects "serialize" // function or template. This permits values to be written/read // to/from archives but includes no class or version information. object_serializable = 2, /////////////////////////////////////////////////////////////////// // once an object is serialized at one of the above levels, the // corresponding archives cannot be read if the implementation level // for the archive object is changed. /////////////////////////////////////////////////////////////////// // Add class information to the archive. Class information includes // implementation level, class version and class name if available object_class_info = 3 }; } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_LEVEL_ENUM_HPP ================================================ FILE: include/boost/serialization/library_version_type.hpp ================================================ #ifndef BOOST_SERIALIZATION_LIBRARY_VERSION_TYPE_HPP #define BOOST_SERIALIZATION_LIBRARY_VERSION_TYPE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // library_version_type.hpp: // (C) Copyright 2002-2020 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 // count #include // uint_least16_t #include #include #include namespace boost { namespace serialization { #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4244 4267 ) #endif /* NOTE : Warning : Warning : Warning : Warning : Warning * Don't ever changes this. If you do, they previously created * binary archives won't be readable !!! */ class library_version_type { private: typedef uint_least16_t base_type; base_type t; public: library_version_type(): t(0) {} explicit library_version_type(const unsigned int & t_) : t(t_){ BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } library_version_type(const library_version_type & t_) : t(t_.t) {} library_version_type & operator=(const library_version_type & rhs){ t = rhs.t; return *this; } // used for text output operator base_type () const { return t; } // used for text input operator base_type & (){ return t; } bool operator==(const library_version_type & rhs) const { return t == rhs.t; } bool operator<(const library_version_type & rhs) const { return t < rhs.t; } }; #if defined(_MSC_VER) #pragma warning( pop ) #endif } // serialization } // boost #endif // BOOST_SERIALIZATION_LIBRARY_VERSION_TYPE_HPP ================================================ FILE: include/boost/serialization/list.hpp ================================================ #ifndef BOOST_SERIALIZATION_LIST_HPP #define BOOST_SERIALIZATION_LIST_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // list.hpp: serialization for stl list templates // (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 #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { template inline void save( Archive & ar, const std::list &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::list >(ar, t); } template inline void load( Archive & ar, std::list &t, const unsigned int /* file_version */ ){ const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } stl::collection_load_impl(ar, t, count, item_version); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::list & t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(std::list) #endif // BOOST_SERIALIZATION_LIST_HPP ================================================ FILE: include/boost/serialization/map.hpp ================================================ #ifndef BOOST_SERIALIZATION_MAP_HPP #define BOOST_SERIALIZATION_MAP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization/map.hpp: // serialization for stl map templates // (C) Copyright 2002-2014 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 #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { ////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // implementation of serialization for map and mult-map STL containers template inline void load_map_collection(Archive & ar, Container &s) { s.clear(); const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } typename Container::iterator hint; hint = s.begin(); while(count-- > 0){ typedef typename Container::value_type type; detail::stack_construct t(ar, item_version); ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::iterator result = s.insert(hint, boost::move(t.reference())); ar.reset_object_address(& (result->second), & t.reference().second); hint = result; ++hint; } } // map template inline void save( Archive & ar, const std::map &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::map >(ar, t); } template inline void load( Archive & ar, std::map &t, const unsigned int /* file_version */ ){ load_map_collection(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::map &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } // multimap template inline void save( Archive & ar, const std::multimap &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::multimap >(ar, t); } template inline void load( Archive & ar, std::multimap &t, const unsigned int /* file_version */ ){ load_map_collection(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::multimap &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost #endif // BOOST_SERIALIZATION_MAP_HPP ================================================ FILE: include/boost/serialization/nvp.hpp ================================================ #ifndef BOOST_SERIALIZATION_NVP_HPP #define BOOST_SERIALIZATION_NVP_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // nvp.hpp: interface for serialization system. // (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 #include #define BOOST_SERIALIZATION_NVP(name) \ boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name) /**/ #define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \ boost::serialization::make_nvp( \ BOOST_PP_STRINGIZE(name), \ boost::serialization::base_object(*this) \ ) /**/ #include #include #include #include #include namespace boost { namespace serialization { template void save( Archive & ar, const nvp & t, const unsigned int /* file_version */ ){ ar << t.const_value(); } template void load( Archive & ar, nvp & t , const unsigned int /* file_version */ ){ ar >> t.value(); } template inline void serialize( Archive & ar, nvp & t, const unsigned int file_version ){ split_free(ar, t, file_version); } template struct implementation_level > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); }; template struct implementation_level > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); }; // nvp objects are generally created on the stack and are never tracked template struct tracking_level > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); }; template struct tracking_level > { typedef mpl::integral_c_tag tag; typedef mpl::int_ type; BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); }; // these traits aren't used by nvp so they don't need to be defined #if 0 template struct version > { typedef mpl::integral_c_tag tag; typedef mpl::int_<0> type; BOOST_STATIC_CONSTANT(int, value = 0); }; struct version > { typedef mpl::integral_c_tag tag; typedef mpl::int_<0> type; BOOST_STATIC_CONSTANT(int, value = 0); }; template struct extended_type_info_impl > { typedef extended_type_info_impl< T > type; }; #endif template struct is_wrapper > { typedef boost::mpl::true_ type; }; template struct is_wrapper > { typedef boost::mpl::true_ type; }; } // serialization } // boost #endif // BOOST_SERIALIZATION_NVP_HPP ================================================ FILE: include/boost/serialization/optional.hpp ================================================ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // (C) Copyright 2002-4 Pavel Vozenilek . // 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) // Provides non-intrusive serialization for boost::optional. #ifndef BOOST_SERIALIZATION_OPTIONAL_HPP #define BOOST_SERIALIZATION_OPTIONAL_HPP #if defined(_MSC_VER) # pragma once #endif #include #include #ifndef BOOST_NO_CXX17_HDR_OPTIONAL #include #endif #include #include #include #include #include #include #include // function specializations must be defined in the appropriate // namespace - boost::serialization namespace boost { namespace serialization { namespace detail { // OT is of the form optional template void save_impl( Archive & ar, const OT & ot ){ // It is an inherent limitation to the serialization of optional.hpp // that the underlying type must be either a pointer or must have a // default constructor. It's possible that this could change sometime // in the future, but for now, one will have to work around it. This can // be done by serialization the optional as optional #ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS BOOST_STATIC_ASSERT( boost::serialization::detail::is_default_constructible::value || boost::is_pointer::value ); #endif const bool tflag(ot); ar << boost::serialization::make_nvp("initialized", tflag); if (tflag){ ar << boost::serialization::make_nvp("value", *ot); } } // OT is of the form optional template void load_impl( Archive & ar, OT & ot, const unsigned int version ){ bool tflag; ar >> boost::serialization::make_nvp("initialized", tflag); if(! tflag){ ot.reset(); return; } if(0 == version){ boost::serialization::item_version_type item_version(0); boost::serialization::library_version_type library_version( ar.get_library_version() ); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } } typename OT::value_type t; ar >> boost::serialization::make_nvp("value",t); ot = t; } } // detail template void save( Archive & ar, const boost::optional< T > & ot, const unsigned int /*version*/ ){ detail::save_impl(ar, ot); } #ifndef BOOST_NO_CXX17_HDR_OPTIONAL template void save( Archive & ar, const std::optional< T > & ot, const unsigned int /*version*/ ){ detail::save_impl(ar, ot); } #endif template void load( Archive & ar, boost::optional< T > & ot, const unsigned int version ){ detail::load_impl(ar, ot, version); } #ifndef BOOST_NO_CXX17_HDR_OPTIONAL template void load( Archive & ar, std::optional< T > & ot, const unsigned int version ){ detail::load_impl(ar, ot, version); } #endif template void serialize( Archive & ar, boost::optional< T > & ot, const unsigned int version ){ boost::serialization::split_free(ar, ot, version); } #ifndef BOOST_NO_CXX17_HDR_OPTIONAL template void serialize( Archive & ar, std::optional< T > & ot, const unsigned int version ){ boost::serialization::split_free(ar, ot, version); } #endif template struct version >{ BOOST_STATIC_CONSTANT(int, value = 1); }; #ifndef BOOST_NO_CXX17_HDR_OPTIONAL template struct version >{ BOOST_STATIC_CONSTANT(int, value = 1); }; #endif } // serialization } // boost #endif // BOOST_SERIALIZATION_OPTIONAL_HPP ================================================ FILE: include/boost/serialization/priority_queue.hpp ================================================ #ifndef BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP #define BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // priority_queue.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 #include #include #include // function specializations must be defined in the appropriate // namespace - boost::serialization #if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) #define STD _STLP_STD #else #define STD std #endif namespace boost { namespace serialization { namespace detail{ template struct priority_queue_save : public STD::priority_queue { template void operator()(Archive & ar, const unsigned int file_version) const { save(ar, STD::priority_queue::c, file_version); } }; template struct priority_queue_load : public STD::priority_queue { template void operator()(Archive & ar, const unsigned int file_version) { load(ar, STD::priority_queue::c, file_version); } }; } // detail template inline void serialize( Archive & ar, std::priority_queue< T, Container, Compare> & t, const unsigned int file_version ){ typedef typename mpl::eval_if< typename Archive::is_saving, mpl::identity >, mpl::identity > >::type typex; static_cast(t)(ar, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::priority_queue) #undef STD #endif // BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP ================================================ FILE: include/boost/serialization/queue.hpp ================================================ #ifndef BOOST_SERIALIZATION_QUEUE_HPP #define BOOST_SERIALIZATION_QUEUE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // queue.hpp // (C) Copyright 2014 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 #include #include #include // function specializations must be defined in the appropriate // namespace - boost::serialization #if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) #define STD _STLP_STD #else #define STD std #endif namespace boost { namespace serialization { namespace detail { template struct queue_save : public STD::queue { template void operator()(Archive & ar, const unsigned int file_version) const { save(ar, STD::queue::c, file_version); } }; template struct queue_load : public STD::queue { template void operator()(Archive & ar, const unsigned int file_version) { load(ar, STD::queue::c, file_version); } }; } // detail template inline void serialize( Archive & ar, std::queue< T, C> & t, const unsigned int file_version ){ typedef typename mpl::eval_if< typename Archive::is_saving, mpl::identity >, mpl::identity > >::type typex; static_cast(t)(ar, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::queue) #undef STD #endif // BOOST_SERIALIZATION_QUEUE_HPP ================================================ FILE: include/boost/serialization/scoped_ptr.hpp ================================================ #ifndef BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 #define BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 #if defined(_MSC_VER) # pragma once #endif // Copyright (c) 2003 Vladimir Prus. // 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) // Provides non-intrusive serialization for boost::scoped_ptr // Does not allow to serialize scoped_ptr's to builtin types. #include #include #include #include namespace boost { namespace serialization { template void save( Archive & ar, const boost::scoped_ptr< T > & t, const unsigned int /* version */ ){ T* r = t.get(); ar << boost::serialization::make_nvp("scoped_ptr", r); } template void load( Archive & ar, boost::scoped_ptr< T > & t, const unsigned int /* version */ ){ T* r; ar >> boost::serialization::make_nvp("scoped_ptr", r); t.reset(r); } template void serialize( Archive& ar, boost::scoped_ptr< T >& t, const unsigned int version ){ boost::serialization::split_free(ar, t, version); } } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 ================================================ FILE: include/boost/serialization/serialization.hpp ================================================ #ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP #define BOOST_SERIALIZATION_SERIALIZATION_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #if defined(_MSC_VER) # pragma warning (disable : 4675) // suppress ADL warning #endif #include #include /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization.hpp: interface for serialization system. // (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. ////////////////////////////////////////////////////////////////////// // public interface to serialization. ///////////////////////////////////////////////////////////////////////////// // layer 0 - intrusive version // declared and implemented for each user defined class to be serialized // // template // serialize(Archive &ar, const unsigned int file_version){ // ar & base_object(*this) & member1 & member2 ... ; // } ///////////////////////////////////////////////////////////////////////////// // layer 1 - layer that routes member access through the access class. // this is what permits us to grant access to private class member functions // by specifying friend class boost::serialization::access #include ///////////////////////////////////////////////////////////////////////////// // layer 2 - default implementation of non-intrusive serialization. // namespace boost { namespace serialization { BOOST_STRONG_TYPEDEF(unsigned int, version_type) // default implementation - call the member function "serialize" template inline void serialize( Archive & ar, T & t, const unsigned int file_version ){ access::serialize(ar, t, static_cast(file_version)); } // save data required for construction template inline void save_construct_data( Archive & /*ar*/, const T * /*t*/, const unsigned int /*file_version */ ){ // default is to save no data because default constructor // requires no arguments. } // load data required for construction and invoke constructor in place template inline void load_construct_data( Archive & /*ar*/, T * t, const unsigned int /*file_version*/ ){ // default just uses the default constructor. going // through access permits usage of otherwise private default // constructor access::construct(t); } ///////////////////////////////////////////////////////////////////////////// // layer 3 - move call into serialization namespace so that ADL will function // in the manner we desire. // // on compilers which don't implement ADL. only the current namespace // i.e. boost::serialization will be searched. // // on compilers which DO implement ADL // serialize overrides can be in any of the following // // 1) same namepace as Archive // 2) same namespace as T // 3) boost::serialization // // Due to Martin Ecker template inline void serialize_adl( Archive & ar, T & t, const unsigned int file_version ){ const version_type v(file_version); serialize(ar, t, v); } template inline void save_construct_data_adl( Archive & ar, const T * t, const unsigned int file_version ){ const version_type v(file_version); save_construct_data(ar, t, v); } template inline void load_construct_data_adl( Archive & ar, T * t, const unsigned int file_version ){ // see above comment const version_type v(file_version); load_construct_data(ar, t, v); } } // namespace serialization } // namespace boost #endif //BOOST_SERIALIZATION_SERIALIZATION_HPP ================================================ FILE: include/boost/serialization/set.hpp ================================================ #ifndef BOOST_SERIALIZATION_SET_HPP #define BOOST_SERIALIZATION_SET_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // set.hpp: serialization for stl set templates // (C) Copyright 2002-2014 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 #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { template inline void load_set_collection(Archive & ar, Container &s) { s.clear(); const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } typename Container::iterator hint; hint = s.begin(); while(count-- > 0){ typedef typename Container::value_type type; detail::stack_construct t(ar, item_version); // borland fails silently w/o full namespace ar >> boost::serialization::make_nvp("item", t.reference()); typename Container::iterator result = s.insert(hint, boost::move(t.reference())); const type * new_address = & (* result); ar.reset_object_address(new_address, & t.reference()); hint = result; } } template inline void save( Archive & ar, const std::set &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::set >(ar, t); } template inline void load( Archive & ar, std::set &t, const unsigned int /* file_version */ ){ load_set_collection(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::set & t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } // multiset template inline void save( Archive & ar, const std::multiset &t, const unsigned int /* file_version */ ){ boost::serialization::stl::save_collection< Archive, std::multiset >(ar, t); } template inline void load( Archive & ar, std::multiset &t, const unsigned int /* file_version */ ){ load_set_collection(ar, t); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, std::multiset & t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(std::set) BOOST_SERIALIZATION_COLLECTION_TRAITS(std::multiset) #endif // BOOST_SERIALIZATION_SET_HPP ================================================ FILE: include/boost/serialization/shared_ptr.hpp ================================================ #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP #define BOOST_SERIALIZATION_SHARED_PTR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // shared_ptr.hpp: serialization for boost shared pointer // (C) Copyright 2004 Robert Ramey and Martin Ecker // 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 // NULL #include #include #include #include #include #include #include #include #include #include #include /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // boost:: shared_ptr serialization traits // version 1 to distinguish from boost 1.32 version. Note: we can only do this // for a template when the compiler supports partial template specialization #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace boost { namespace serialization{ template struct version< ::boost::shared_ptr< T > > { typedef mpl::integral_c_tag tag; #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) typedef typename mpl::int_<1> type; #else typedef mpl::int_<1> type; #endif BOOST_STATIC_CONSTANT(int, value = type::value); }; // don't track shared pointers template struct tracking_level< ::boost::shared_ptr< T > > { typedef mpl::integral_c_tag tag; #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) typedef typename mpl::int_< ::boost::serialization::track_never> type; #else typedef mpl::int_< ::boost::serialization::track_never> type; #endif BOOST_STATIC_CONSTANT(int, value = type::value); }; }} #define BOOST_SERIALIZATION_SHARED_PTR(T) #else // define macro to let users of these compilers do this #define BOOST_SERIALIZATION_SHARED_PTR(T) \ BOOST_CLASS_VERSION( \ ::boost::shared_ptr< T >, \ 1 \ ) \ BOOST_CLASS_TRACKING( \ ::boost::shared_ptr< T >, \ ::boost::serialization::track_never \ ) \ /**/ #endif namespace boost { namespace serialization{ struct null_deleter { void operator()(void const *) const {} }; /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization for boost::shared_ptr // 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. void * const shared_ptr_helper_id = 0; template inline void save( Archive & ar, const boost::shared_ptr< T > &t, const unsigned int /* file_version */ ){ // The most common cause of trapping here would be serializing // something like shared_ptr. This occurs because int // is never tracked by default. Wrap int in a trackable type BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); const T * t_ptr = t.get(); ar << boost::serialization::make_nvp("px", t_ptr); } #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP template inline void load( Archive & ar, boost::shared_ptr< T > &t, const unsigned int file_version ){ // something like shared_ptr. This occurs because int // is never tracked by default. Wrap int in a trackable type BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); T* r; if(file_version < 1){ ar.register_type(static_cast< boost_132::detail::sp_counted_base_impl * >(NULL)); boost_132::shared_ptr< T > sp; ar >> boost::serialization::make_nvp("px", sp.px); ar >> boost::serialization::make_nvp("pn", sp.pn); // got to keep the sps around so the sp.pns don't disappear boost::serialization::shared_ptr_helper & h = ar.template get_helper< shared_ptr_helper >( shared_ptr_helper_id ); h.append(sp); r = sp.get(); } else{ ar >> boost::serialization::make_nvp("px", r); } shared_ptr_helper & h = ar.template get_helper >( shared_ptr_helper_id ); h.reset(t,r); } #else template inline void load( Archive & ar, boost::shared_ptr< T > &t, const unsigned int /*file_version*/ ){ // The most common cause of trapping here would be serializing // something like shared_ptr. This occurs because int // is never tracked by default. Wrap int in a trackable type BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); T* r; ar >> boost::serialization::make_nvp("px", r); boost::serialization::shared_ptr_helper & h = ar.template get_helper >( shared_ptr_helper_id ); h.reset(t,r); } #endif template inline void serialize( Archive & ar, boost::shared_ptr< T > &t, const unsigned int file_version ){ // correct shared_ptr serialization depends upon object tracking // being used. BOOST_STATIC_ASSERT( boost::serialization::tracking_level< T >::value != boost::serialization::track_never ); boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // std::shared_ptr serialization traits // version 1 to distinguish from boost 1.32 version. Note: we can only do this // for a template when the compiler supports partial template specialization #ifndef BOOST_NO_CXX11_SMART_PTR #include // note: we presume that any compiler/library which supports C++11 // std::pointers also supports template partial specialization // trap here if such presumption were to turn out to wrong!!! #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_STATIC_ASSERT(false); #endif namespace boost { namespace serialization{ template struct version< ::std::shared_ptr< T > > { typedef mpl::integral_c_tag tag; typedef mpl::int_<1> type; BOOST_STATIC_CONSTANT(int, value = type::value); }; // don't track shared pointers template struct tracking_level< ::std::shared_ptr< T > > { typedef mpl::integral_c_tag tag; typedef mpl::int_< ::boost::serialization::track_never> type; BOOST_STATIC_CONSTANT(int, value = type::value); }; }} // the following just keeps older programs from breaking #define BOOST_SERIALIZATION_SHARED_PTR(T) namespace boost { namespace serialization{ /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // serialization for std::shared_ptr template inline void save( Archive & ar, const std::shared_ptr< T > &t, const unsigned int /* file_version */ ){ // The most common cause of trapping here would be serializing // something like shared_ptr. This occurs because int // is never tracked by default. Wrap int in a trackable type BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); const T * t_ptr = t.get(); ar << boost::serialization::make_nvp("px", t_ptr); } template inline void load( Archive & ar, std::shared_ptr< T > &t, const unsigned int /*file_version*/ ){ // The most common cause of trapping here would be serializing // something like shared_ptr. This occurs because int // is never tracked by default. Wrap int in a trackable type BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); T* r; ar >> boost::serialization::make_nvp("px", r); //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load; boost::serialization::shared_ptr_helper & h = ar.template get_helper< shared_ptr_helper >( shared_ptr_helper_id ); h.reset(t,r); } template inline void serialize( Archive & ar, std::shared_ptr< T > &t, const unsigned int file_version ){ // correct shared_ptr serialization depends upon object tracking // being used. BOOST_STATIC_ASSERT( boost::serialization::tracking_level< T >::value != boost::serialization::track_never ); boost::serialization::split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #endif // BOOST_NO_CXX11_SMART_PTR #endif // BOOST_SERIALIZATION_SHARED_PTR_HPP ================================================ FILE: include/boost/serialization/shared_ptr_132.hpp ================================================ #ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP #define BOOST_SERIALIZATION_SHARED_PTR_132_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // shared_ptr.hpp: serialization for boost shared pointer // (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. // note: totally unadvised hack to gain access to private variables // in shared_ptr and shared_count. Unfortunately its the only way to // do this without changing shared_ptr and shared_count // the best we can do is to detect a conflict here #include #include #include // NULL #include #include #include #include #include // mark base class as an (uncreatable) base class #include ///////////////////////////////////////////////////////////// // Maintain a couple of lists of loaded shared pointers of the old previous // version (1.32) namespace boost_132 { namespace serialization { namespace detail { struct null_deleter { void operator()(void const *) const {} }; } // namespace detail } // namespace serialization } // namespace boost_132 ///////////////////////////////////////////////////////////// // sp_counted_base_impl serialization namespace boost { namespace serialization { template inline void serialize( Archive & /* ar */, boost_132::detail::sp_counted_base_impl & /* t */, const unsigned int /*file_version*/ ){ // register the relationship between each derived class // its polymorphic base boost::serialization::void_cast_register< boost_132::detail::sp_counted_base_impl, boost_132::detail::sp_counted_base >( static_cast *>(NULL), static_cast(NULL) ); } template inline void save_construct_data( Archive & ar, const boost_132::detail::sp_counted_base_impl *t, const unsigned int /* file_version */ ){ // variables used for construction ar << boost::serialization::make_nvp("ptr", t->ptr); } template inline void load_construct_data( Archive & ar, boost_132::detail::sp_counted_base_impl * t, const unsigned int /* file_version */ ){ P ptr_; ar >> boost::serialization::make_nvp("ptr", ptr_); // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); // placement // note: the original ::new... above is replaced by the one here. This one // creates all new objects with a null_deleter so that after the archive // is finished loading and the shared_ptrs are destroyed - the underlying // raw pointers are NOT deleted. This is necessary as they are used by the // new system as well. ::new(t)boost_132::detail::sp_counted_base_impl< P, boost_132::serialization::detail::null_deleter >( ptr_, boost_132::serialization::detail::null_deleter() ); // placement new // compensate for that fact that a new shared count always is // initialized with one. the add_ref_copy below will increment it // every time its serialized so without this adjustment // the use and weak counts will be off by one. t->use_count_ = 0; } } // serialization } // namespace boost ///////////////////////////////////////////////////////////// // shared_count serialization namespace boost { namespace serialization { template inline void save( Archive & ar, const boost_132::detail::shared_count &t, const unsigned int /* file_version */ ){ ar << boost::serialization::make_nvp("pi", t.pi_); } template inline void load( Archive & ar, boost_132::detail::shared_count &t, const unsigned int /* file_version */ ){ ar >> boost::serialization::make_nvp("pi", t.pi_); if(NULL != t.pi_) t.pi_->add_ref_copy(); } } // serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) ///////////////////////////////////////////////////////////// // implement serialization for shared_ptr< T > namespace boost { namespace serialization { template inline void save( Archive & ar, const boost_132::shared_ptr< T > &t, const unsigned int /* file_version */ ){ // only the raw pointer has to be saved // the ref count is maintained automatically as shared pointers are loaded ar.register_type(static_cast< boost_132::detail::sp_counted_base_impl > * >(NULL)); ar << boost::serialization::make_nvp("px", t.px); ar << boost::serialization::make_nvp("pn", t.pn); } template inline void load( Archive & ar, boost_132::shared_ptr< T > &t, const unsigned int /* file_version */ ){ // only the raw pointer has to be saved // the ref count is maintained automatically as shared pointers are loaded ar.register_type(static_cast< boost_132::detail::sp_counted_base_impl > * >(NULL)); ar >> boost::serialization::make_nvp("px", t.px); ar >> boost::serialization::make_nvp("pn", t.pn); } template inline void serialize( Archive & ar, boost_132::shared_ptr< T > &t, const unsigned int file_version ){ // correct shared_ptr serialization depends upon object tracking // being used. BOOST_STATIC_ASSERT( boost::serialization::tracking_level< T >::value != boost::serialization::track_never ); boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost // note: change below uses null_deleter // This macro is used to export GUIDS for shared pointers to allow // the serialization system to export them properly. David Tonge #define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ typedef boost_132::detail::sp_counted_base_impl< \ T *, \ boost::checked_deleter< T > \ > __shared_ptr_ ## T; \ BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ BOOST_CLASS_EXPORT_GUID(T, K) \ /**/ #define BOOST_SHARED_POINTER_EXPORT(T) \ BOOST_SHARED_POINTER_EXPORT_GUID( \ T, \ BOOST_PP_STRINGIZE(T) \ ) \ /**/ #endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP ================================================ FILE: include/boost/serialization/shared_ptr_helper.hpp ================================================ #ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP #define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // shared_ptr_helper.hpp: serialization for boost shared pointer // (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo // 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 #include #include #include // NULL #include #include #include #include #include #include #include #include #include namespace boost_132 { template class shared_ptr; } namespace boost { namespace serialization { #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS template class SPT > void load( Archive & ar, SPT< class U > &t, const unsigned int file_version ); #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // a common class for holding various types of shared pointers template class SPT> class shared_ptr_helper { typedef std::map< const void *, // address of object SPT // address shared ptr to single instance > object_shared_pointer_map; // list of shared_pointers create accessible by raw pointer. This // is used to "match up" shared pointers loaded at different // points in the archive. Note, we delay construction until // it is actually used since this is by default included as // a "mix-in" even if shared_ptr isn't used. object_shared_pointer_map * m_o_sp; struct null_deleter { void operator()(void const *) const {} }; #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ || defined(BOOST_MSVC) \ || defined(__SUNPRO_CC) public: #else template friend void boost::serialization::load( Archive & ar, SPT< U > &t, const unsigned int file_version ); #endif #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP // list of loaded pointers. This is used to be sure that the pointers // stay around long enough to be "matched" with other pointers loaded // by the same archive. These are created with a "null_deleter" so that // when this list is destroyed - the underlying raw pointers are not // destroyed. This has to be done because the pointers are also held by // new system which is disjoint from this set. This is implemented // by a change in load_construct_data below. It makes this file suitable // only for loading pointers into a 1.33 or later boost system. std::list > * m_pointers_132; void append(const boost_132::shared_ptr & t){ if(NULL == m_pointers_132) m_pointers_132 = new std::list >; m_pointers_132->push_back(t); } #endif struct non_polymorphic { template static const boost::serialization::extended_type_info * get_object_type(U & ){ return & boost::serialization::singleton< typename boost::serialization::type_info_implementation< U >::type >::get_const_instance(); } }; struct polymorphic { template static const boost::serialization::extended_type_info * get_object_type(U & u){ return boost::serialization::singleton< typename boost::serialization::type_info_implementation< U >::type >::get_const_instance().get_derived_extended_type_info(u); } }; public: template void reset(SPT< T > & s, T * t){ if(NULL == t){ s.reset(); return; } const boost::serialization::extended_type_info * this_type = & boost::serialization::type_info_implementation< T >::type ::get_const_instance(); // get pointer to the most derived object's eti. This is effectively // the object type identifier typedef typename mpl::if_< is_polymorphic< T >, polymorphic, non_polymorphic >::type type; const boost::serialization::extended_type_info * true_type = type::get_object_type(*t); // note:if this exception is thrown, be sure that derived pointer // is either registered or exported. if(NULL == true_type) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::unregistered_class, this_type->get_debug_info() ) ); // get void pointer to the most derived type // this uniquely identifies the object referred to // oid = "object identifier" const void * oid = void_downcast( *true_type, *this_type, t ); if(NULL == oid) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::unregistered_cast, true_type->get_debug_info(), this_type->get_debug_info() ) ); // make tracking array if necessary if(NULL == m_o_sp) m_o_sp = new object_shared_pointer_map; typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); // if it's a new object if(i == m_o_sp->end()){ s.reset(t); std::pair result; result = m_o_sp->insert(std::make_pair(oid, s)); BOOST_ASSERT(result.second); } // if the object has already been seen else{ s = SPT(i->second, t); } } shared_ptr_helper() : m_o_sp(NULL) #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP , m_pointers_132(NULL) #endif {} virtual ~shared_ptr_helper(){ if(NULL != m_o_sp) delete m_o_sp; #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP if(NULL != m_pointers_132) delete m_pointers_132; #endif } }; } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP ================================================ FILE: include/boost/serialization/singleton.hpp ================================================ #ifndef BOOST_SERIALIZATION_SINGLETON_HPP #define BOOST_SERIALIZATION_SINGLETON_HPP /////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 // singleton.hpp // // Copyright David Abrahams 2006. Original version // // Copyright Robert Ramey 2007. Changes made to permit // application throughout the serialization library. // // Copyright Alexander Grund 2018. Corrections to singleton lifetime // // 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) // // The intention here is to define a template which will convert // any class into a singleton with the following features: // // a) initialized before first use. // b) thread-safe for const access to the class // c) non-locking // // In order to do this, // a) Initialize dynamically when used. // b) Require that all singletons be initialized before main // is called or any entry point into the shared library is invoked. // This guarantees no race condition for initialization. // In debug mode, we assert that no non-const functions are called // after main is invoked. // // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #include #include #include // must be the last header #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif namespace boost { namespace serialization { ////////////////////////////////////////////////////////////////////// // Provides a dynamically-initialized (singleton) instance of T in a // way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or // http://lists.boost.org/Archives/boost/2006/05/105286.php for // details. // // Singletons created by this code are guaranteed to be unique // within the executable or shared library which creates them. // This is sufficient and in fact ideal for the serialization library. // The singleton is created when the module is loaded and destroyed // when the module is unloaded. // This base class has two functions. // First it provides a module handle for each singleton indicating // the executable or shared library in which it was created. This // turns out to be necessary and sufficient to implement the tables // used by serialization library. // Second, it provides a mechanism to detect when a non-const function // is called after initialization. // Make a singleton to lock/unlock all singletons for alteration. // The intent is that all singletons created/used by this code // are to be initialized before main is called. A test program // can lock all the singletons when main is entered. Thus any // attempt to retrieve a mutable instance while locked will // generate an assertion if compiled for debug. // The singleton template can be used in 2 ways: // 1 (Recommended): Publicly inherit your type T from singleton, // make its ctor protected and access it via T::get_const_instance() // 2: Simply access singleton without changing T. Note that this only // provides a global instance accessible by singleton::get_const_instance() // or singleton::get_mutable_instance() to prevent using multiple instances // of T make its ctor protected // Note on usage of BOOST_DLLEXPORT: These functions are in danger of // being eliminated by the optimizer when building an application in // release mode. Usage of the macro is meant to signal the compiler/linker // to avoid dropping these functions which seem to be unreferenced. // This usage is not related to autolinking. class BOOST_SYMBOL_VISIBLE singleton_module : public boost::noncopyable { private: BOOST_DLLEXPORT bool & get_lock() BOOST_USED { static bool lock = false; return lock; } public: BOOST_DLLEXPORT void lock(){ get_lock() = true; } BOOST_DLLEXPORT void unlock(){ get_lock() = false; } BOOST_DLLEXPORT bool is_locked(){ return get_lock(); } }; static inline singleton_module & get_singleton_module(){ static singleton_module m; return m; } namespace detail { // This is the class actually instantiated and hence the real singleton. // So there will only be one instance of this class. This does not hold // for singleton as a class derived from singleton could be // instantiated multiple times. // It also provides a flag `is_destroyed` which returns true, when the // class was destructed. It is static and hence accessible even after // destruction. This can be used to check, if the singleton is still // accessible e.g. in destructors of other singletons. template class singleton_wrapper : public T { static bool & get_is_destroyed(){ // Prefer a static function member to avoid LNK1179. // Note: As this is for a singleton (1 instance only) it must be set // never be reset (to false)! static bool is_destroyed_flag = false; return is_destroyed_flag; } public: singleton_wrapper(){ BOOST_ASSERT(! is_destroyed()); } ~singleton_wrapper(){ get_is_destroyed() = true; } static bool is_destroyed(){ return get_is_destroyed(); } }; } // detail template class singleton { private: static T * m_instance; // include this to provoke instantiation at pre-execution time static void use(T const &) {} static T & get_instance() { BOOST_ASSERT(! is_destroyed()); // use a wrapper so that types T with protected constructors can be used // Using a static function member avoids LNK1179 static detail::singleton_wrapper< T > t; // note that the following is absolutely essential. // commenting out this statement will cause compilers to fail to // construct the instance at pre-execution time. This would prevent // our usage/implementation of "locking" and introduce uncertainty into // the sequence of object initialization. // Unfortunately, this triggers detectors of undefined behavior // and reports an error. But I've been unable to find a different way // of guaranteeing that the the singleton is created at pre-main time. if (m_instance) use(* m_instance); return static_cast(t); } protected: // Do not allow instantiation of a singleton. But we want to allow // `class T: public singleton` so we can't delete this ctor BOOST_DLLEXPORT singleton(){} public: BOOST_DLLEXPORT static T & get_mutable_instance(){ BOOST_ASSERT(! get_singleton_module().is_locked()); return get_instance(); } BOOST_DLLEXPORT static const T & get_const_instance(){ return get_instance(); } BOOST_DLLEXPORT static bool is_destroyed(){ return detail::singleton_wrapper< T >::is_destroyed(); } }; // Assigning the instance reference to a static member forces initialization // at startup time as described in // https://groups.google.com/forum/#!topic/microsoft.public.vc.language/kDVNLnIsfZk template T * singleton< T >::m_instance = & singleton< T >::get_instance(); } // namespace serialization } // namespace boost #include // pops abi_suffix.hpp pragmas #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif // BOOST_SERIALIZATION_SINGLETON_HPP ================================================ FILE: include/boost/serialization/slist.hpp ================================================ #ifndef BOOST_SERIALIZATION_SLIST_HPP #define BOOST_SERIALIZATION_SLIST_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // slist.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 #ifdef BOOST_HAS_SLIST #include BOOST_SLIST_HEADER #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { template inline void save( Archive & ar, const BOOST_STD_EXTENSION_NAMESPACE::slist &t, const unsigned int file_version ){ boost::serialization::stl::save_collection< Archive, BOOST_STD_EXTENSION_NAMESPACE::slist >(ar, t); } namespace stl { template< class Archive, class T, class Allocator > typename boost::disable_if< typename detail::is_default_constructible< typename BOOST_STD_EXTENSION_NAMESPACE::slist::value_type >, void >::type collection_load_impl( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::slist &t, collection_size_type count, item_version_type item_version ){ t.clear(); boost::serialization::detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); t.push_front(boost::move(u.reference())); typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; last = t.begin(); ar.reset_object_address(&(*t.begin()) , & u.reference()); while(--count > 0){ detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); last = t.insert_after(last, boost::move(u.reference())); ar.reset_object_address(&(*last) , & u.reference()); } } } // stl template inline void load( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::slist &t, const unsigned int file_version ){ const boost::serialization::library_version_type library_version( ar.get_library_version() ); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); if(boost::serialization::library_version_type(3) < library_version){ ar >> BOOST_SERIALIZATION_NVP(item_version); } if(detail::is_default_constructible()){ t.resize(count); typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator hint; hint = t.begin(); while(count-- > 0){ ar >> boost::serialization::make_nvp("item", *hint++); } } else{ t.clear(); boost::serialization::detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); t.push_front(boost::move(u.reference())); typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; last = t.begin(); ar.reset_object_address(&(*t.begin()) , & u.reference()); while(--count > 0){ detail::stack_construct u(ar, item_version); ar >> boost::serialization::make_nvp("item", u.reference()); last = t.insert_after(last, boost::move(u.reference())); ar.reset_object_address(&(*last) , & u.reference()); } } } // split non-intrusive serialization function member into separate // non intrusive save/load member functions template inline void serialize( Archive & ar, BOOST_STD_EXTENSION_NAMESPACE::slist &t, const unsigned int file_version ){ boost::serialization::split_free(ar, t, file_version); } } // serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::slist) #endif // BOOST_HAS_SLIST #endif // BOOST_SERIALIZATION_SLIST_HPP ================================================ FILE: include/boost/serialization/smart_cast.hpp ================================================ #ifndef BOOST_SERIALIZATION_SMART_CAST_HPP #define BOOST_SERIALIZATION_SMART_CAST_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // smart_cast.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/libs/serialization for updates, documentation, and revision history. // casting of pointers and references. // In casting between different C++ classes, there are a number of // rules that have to be kept in mind in deciding whether to use // static_cast or dynamic_cast. // a) dynamic casting can only be applied when one of the types is polymorphic // Otherwise static_cast must be used. // b) only dynamic casting can do runtime error checking // use of static_cast is generally un checked even when compiled for debug // c) static_cast would be considered faster than dynamic_cast. // If casting is applied to a template parameter, there is no apriori way // to know which of the two casting methods will be permitted or convenient. // smart_cast uses C++ type_traits, and program debug mode to select the // most convenient cast to use. #include #include #include // NULL #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { namespace smart_cast_impl { template struct reference { struct polymorphic { struct linear { template static T cast(U & u){ return static_cast< T >(u); } }; struct cross { template static T cast(U & u){ return dynamic_cast< T >(u); } }; template static T cast(U & u){ // if we're in debug mode #if ! defined(NDEBUG) \ || defined(__MWERKS__) // do a checked dynamic cast return cross::cast(u); #else // borland 5.51 chokes here so we can't use it // note: if remove_reference isn't function for these types // cross casting will be selected this will work but will // not be the most efficient method. This will conflict with // the original smart_cast motivation. typedef typename mpl::eval_if< typename mpl::and_< mpl::not_::type, U > >, mpl::not_::type > > >, // borland chokes w/o full qualification here mpl::identity, mpl::identity >::type typex; // typex works around gcc 2.95 issue return typex::cast(u); #endif } }; struct non_polymorphic { template static T cast(U & u){ return static_cast< T >(u); } }; template static T cast(U & u){ typedef typename mpl::eval_if< boost::is_polymorphic, mpl::identity, mpl::identity >::type typex; return typex::cast(u); } }; template struct pointer { struct polymorphic { // unfortunately, this below fails to work for virtual base // classes. need has_virtual_base to do this. // Subject for further study #if 0 struct linear { template static T cast(U * u){ return static_cast< T >(u); } }; struct cross { template static T cast(U * u){ T tmp = dynamic_cast< T >(u); #ifndef NDEBUG if ( tmp == 0 ) throw_exception(std::bad_cast()); #endif return tmp; } }; template static T cast(U * u){ typedef typename mpl::eval_if< typename mpl::and_< mpl::not_::type, U > >, mpl::not_::type > > >, // borland chokes w/o full qualification here mpl::identity, mpl::identity >::type typex; return typex::cast(u); } #else template static T cast(U * u){ T tmp = dynamic_cast< T >(u); #ifndef NDEBUG if ( tmp == 0 ) throw_exception(std::bad_cast()); #endif return tmp; } #endif }; struct non_polymorphic { template static T cast(U * u){ return static_cast< T >(u); } }; template static T cast(U * u){ typedef typename mpl::eval_if< boost::is_polymorphic, mpl::identity, mpl::identity >::type typex; return typex::cast(u); } }; template struct void_pointer { template static TPtr cast(UPtr uptr){ return static_cast(uptr); } }; template struct error { // if we get here, its because we are using one argument in the // cast on a system which doesn't support partial template // specialization template static T cast(U){ BOOST_STATIC_ASSERT(sizeof(T)==0); return * static_cast(NULL); } }; } // smart_cast_impl // this implements: // smart_cast(Source * s) // smart_cast(s) // note that it will fail with // smart_cast(s) template T smart_cast(U u) { typedef typename mpl::eval_if< typename mpl::or_< boost::is_same, boost::is_same, boost::is_same, boost::is_same >, mpl::identity >, // else typename mpl::eval_if, mpl::identity >, // else typename mpl::eval_if, mpl::identity >, // else mpl::identity > > > >::type typex; return typex::cast(u); } // this implements: // smart_cast_reference(Source & s) template T smart_cast_reference(U & u) { return smart_cast_impl::reference< T >::cast(u); } } // namespace serialization } // namespace boost #endif // BOOST_SERIALIZATION_SMART_CAST_HPP ================================================ FILE: include/boost/serialization/split_free.hpp ================================================ #ifndef BOOST_SERIALIZATION_SPLIT_FREE_HPP #define BOOST_SERIALIZATION_SPLIT_FREE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // split_free.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 #include #include #include namespace boost { namespace archive { namespace detail { template class interface_oarchive; template class interface_iarchive; } // namespace detail } // namespace archive namespace serialization { template struct free_saver { static void invoke( Archive & ar, const T & t, const unsigned int file_version ){ // use function overload (version_type) to workaround // two-phase lookup issue const version_type v(file_version); save(ar, t, v); } }; template struct free_loader { static void invoke( Archive & ar, T & t, const unsigned int file_version ){ // use function overload (version_type) to workaround // two-phase lookup issue const version_type v(file_version); load(ar, t, v); } }; template inline void split_free( Archive & ar, T & t, const unsigned int file_version ){ typedef typename mpl::eval_if< typename Archive::is_saving, mpl::identity >, mpl::identity > >::type typex; typex::invoke(ar, t, file_version); } } // namespace serialization } // namespace boost #define BOOST_SERIALIZATION_SPLIT_FREE(T) \ namespace boost { namespace serialization { \ template \ inline void serialize( \ Archive & ar, \ T & t, \ const unsigned int file_version \ ){ \ split_free(ar, t, file_version); \ } \ }} /**/ #endif // BOOST_SERIALIZATION_SPLIT_FREE_HPP ================================================ FILE: include/boost/serialization/split_member.hpp ================================================ #ifndef BOOST_SERIALIZATION_SPLIT_MEMBER_HPP #define BOOST_SERIALIZATION_SPLIT_MEMBER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // split_member.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 #include #include #include namespace boost { namespace archive { namespace detail { template class interface_oarchive; template class interface_iarchive; } // namespace detail } // namespace archive namespace serialization { namespace detail { template struct member_saver { static void invoke( Archive & ar, const T & t, const unsigned int file_version ){ access::member_save(ar, t, file_version); } }; template struct member_loader { static void invoke( Archive & ar, T & t, const unsigned int file_version ){ access::member_load(ar, t, file_version); } }; } // detail template inline void split_member( Archive & ar, T & t, const unsigned int file_version ){ typedef typename mpl::eval_if< typename Archive::is_saving, mpl::identity >, mpl::identity > >::type typex; typex::invoke(ar, t, file_version); } } // namespace serialization } // namespace boost // split member function serialize function into save/load #define BOOST_SERIALIZATION_SPLIT_MEMBER() \ template \ void serialize( \ Archive &ar, \ const unsigned int file_version \ ){ \ boost::serialization::split_member(ar, *this, file_version); \ } \ /**/ #endif // BOOST_SERIALIZATION_SPLIT_MEMBER_HPP ================================================ FILE: include/boost/serialization/stack.hpp ================================================ #ifndef BOOST_SERIALIZATION_STACK_HPP #define BOOST_SERIALIZATION_STACK_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // stack.hpp // (C) Copyright 2014 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 #include #include #include // function specializations must be defined in the appropriate // namespace - boost::serialization #if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) #define STD _STLP_STD #else #define STD std #endif namespace boost { namespace serialization { namespace detail{ template struct stack_save : public STD::stack { template void operator()(Archive & ar, const unsigned int file_version) const { save(ar, STD::stack::c, file_version); } }; template struct stack_load : public STD::stack { template void operator()(Archive & ar, const unsigned int file_version) { load(ar, STD::stack::c, file_version); } }; } // detail template inline void serialize( Archive & ar, std::stack< T, C> & t, const unsigned int file_version ){ typedef typename mpl::eval_if< typename Archive::is_saving, mpl::identity >, mpl::identity > >::type typex; static_cast(t)(ar, file_version); } } // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::stack) #undef STD #endif // BOOST_SERIALIZATION_DEQUE_HPP ================================================ FILE: include/boost/serialization/state_saver.hpp ================================================ #ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP #define BOOST_SERIALIZATION_STATE_SAVER_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // state_saver.hpp: // (C) Copyright 2003-4 Pavel Vozenilek and 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/libs/serialization for updates, documentation, and revision history. // Inspired by Daryle Walker's iostate_saver concept. This saves the original // value of a variable when a state_saver is constructed and restores // upon destruction. Useful for being sure that state is restored to // variables upon exit from scope. #include #ifndef BOOST_NO_EXCEPTIONS #include #endif #include #include #include #include #include #include namespace boost { namespace serialization { template // T requirements: // - POD or object semantic (cannot be reference, function, ...) // - copy constructor // - operator = (no-throw one preferred) class state_saver : private boost::noncopyable { private: const T previous_value; T & previous_ref; struct restore { static void invoke(T & previous_ref, const T & previous_value){ previous_ref = previous_value; // won't throw } }; struct restore_with_exception { static void invoke(T & previous_ref, const T & previous_value){ BOOST_TRY{ previous_ref = previous_value; } BOOST_CATCH(::std::exception &) { // we must ignore it - we are in destructor } BOOST_CATCH_END } }; public: state_saver( T & object ) : previous_value(object), previous_ref(object) {} ~state_saver() { #ifndef BOOST_NO_EXCEPTIONS typedef typename mpl::eval_if< has_nothrow_copy< T >, mpl::identity, mpl::identity >::type typex; typex::invoke(previous_ref, previous_value); #else previous_ref = previous_value; #endif } }; // state_saver<> } // serialization } // boost #endif //BOOST_SERIALIZATION_STATE_SAVER_HPP ================================================ FILE: include/boost/serialization/static_warning.hpp ================================================ #ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP #define BOOST_SERIALIZATION_STATIC_WARNING_HPP // (C) Copyright Robert Ramey 2003. Jonathan Turkanis 2004. // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/static_assert for documentation. /* Revision history: 15 June 2003 - Initial version. 31 March 2004 - improved diagnostic messages and portability (Jonathan Turkanis) 03 April 2004 - works on VC6 at class and namespace scope - ported to DigitalMars - static warnings disabled by default; when enabled, uses pragmas to enable required compiler warnings on MSVC, Intel, Metrowerks and Borland 5.x. (Jonathan Turkanis) 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3 - static warnings ENabled by default; when enabled, (Robert Ramey) */ #include // // Implementation // Makes use of the following warnings: // 1. GCC prior to 3.3: division by zero. // 2. BCC 6.0 preview: unreferenced local variable. // 3. DigitalMars: returning address of local automatic variable. // 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp') // 5. All others: deletion of pointer to incomplete type. // // The trick is to find code which produces warnings containing the name of // a structure or variable. Details, with same numbering as above: // 1. static_warning_impl::value is zero iff B is false, so diving an int // by this value generates a warning iff B is false. // 2. static_warning_impl::type has a constructor iff B is true, so an // unreferenced variable of this type generates a warning iff B is false. // 3. static_warning_impl::type overloads operator& to return a dynamically // allocated int pointer only is B is true, so returning the address of an // automatic variable of this type generates a warning iff B is false. // 4. static_warning_impl::STATIC_WARNING is declared as a struct iff B is // false. // 5. static_warning_impl::type is incomplete iff B is false, so deleting a // pointer to this type generates a warning iff B is false. // //------------------Enable selected warnings----------------------------------// // Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. // 6. replaced implementation with one which depends solely on // mpl::print<>. The previous one was found to fail for functions // under recent versions of gcc and intel compilers - Robert Ramey #include #include #include #include #include namespace boost { namespace serialization { template struct BOOST_SERIALIZATION_STATIC_WARNING_LINE{}; template struct static_warning_test{ typename boost::mpl::eval_if_c< B, boost::mpl::true_, typename boost::mpl::identity< boost::mpl::print< BOOST_SERIALIZATION_STATIC_WARNING_LINE > > >::type type; }; template struct BOOST_SERIALIZATION_SS {}; } // serialization } // boost #define BOOST_SERIALIZATION_BSW(B, L) \ typedef boost::serialization::BOOST_SERIALIZATION_SS< \ sizeof( boost::serialization::static_warning_test< B, L > ) \ > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_ATTRIBUTE_UNUSED; #define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__) #endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP ================================================ FILE: include/boost/serialization/std_variant.hpp ================================================ #ifndef BOOST_SERIALIZATION_STD_VARIANT_HPP #define BOOST_SERIALIZATION_STD_VARIANT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // variant.hpp - non-intrusive serialization of variant types // // copyright (c) 2019 Samuel Debionne, ESRF // // 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. // // Widely inspired form boost::variant serialization // #include #include #include #include #include #include namespace boost { namespace serialization { template struct std_variant_save_visitor { std_variant_save_visitor(Archive& ar) : m_ar(ar) {} template void operator()(T const & value) const { m_ar << BOOST_SERIALIZATION_NVP(value); } private: Archive & m_ar; }; template struct std_variant_load_visitor { std_variant_load_visitor(Archive& ar) : m_ar(ar) {} template void operator()(T & value) const { m_ar >> BOOST_SERIALIZATION_NVP(value); } private: Archive & m_ar; }; template void save( Archive & ar, std::variant const & v, unsigned int /*version*/ ){ const std::size_t which = v.index(); ar << BOOST_SERIALIZATION_NVP(which); std_variant_save_visitor visitor(ar); std::visit(visitor, v); } // Minimalist metaprogramming for handling parameter pack namespace mp { namespace detail { template struct front_impl; template