- Numerics
@@ -155,6 +156,65 @@ redundant save/load operations.
BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
+
+Some types, specially those with complicated lifetime behavior or limited
+access to their internal state, might need or benefit from elaborate serialization
+algorithms. In these cases, it can be advantageous to have a helper object
+associated to the current archive that can be used to store contextual
+information relevant to the particular type serialization algorithm.
+
+
+class complex_type
+{
+ ...
+};
+
+BOOST_SERIALIZATION_SPLIT_FREE(complex_type)
+
+class complex_type_serialization_helper
+{
+ // maintain contextual information for complex_type
+ // serialization algorithm
+};
+
+namespace boost {
+namespace serialization {
+
+template<class Archive>
+void save(Archive & ar, const complex_type & x, unsigned int /* version */)
+{
+ complex_type_serialization_helper & hlp =
+ ar.template get_helper<complex_type_serialization_helper>();
+
+ // implement complex_type save algorithm with the aid of hlp
+}
+
+template<class Archive>
+void load(Archive & ar, complex_type & x, unsigned int /* version */)
+{
+ complex_type_serialization_helper & hlp =
+ ar.template get_helper<complex_type_serialization_helper>();
+
+ // implement complex_type load algorithm with the aid of hlp
+}
+
+} // namespace serialization
+} // namespace boost
+
+get_helper<complex_type_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.
+Although the example code does not show it, the helper types used for saving and loading
+can be different. A notable example of a type whose serialization routines use helper support
+is boost::shared_ptr. The test
+program test_helper_support.cpp
+shows how to use helper support to implement a serialization algorithm
+for a string type that avoids emitting duplicate contents.
+
By default, for each class serialized, class information is written to the archive.
This information includes version number, implementation level and tracking
diff --git a/include/boost/archive/basic_streambuf_locale_saver.hpp b/include/boost/archive/basic_streambuf_locale_saver.hpp
index afb13f98..6bf8f715 100644
--- a/include/boost/archive/basic_streambuf_locale_saver.hpp
+++ b/include/boost/archive/basic_streambuf_locale_saver.hpp
@@ -50,7 +50,7 @@ public:
explicit basic_streambuf_locale_saver( state_type &s )
: s_save_( s ), a_save_( s.getloc() )
{}
- basic_streambuf_locale_saver( state_type &s, aspect_type const &a )
+ explicit basic_streambuf_locale_saver( state_type &s, aspect_type const &a )
: s_save_( s ), a_save_( s.pubimbue(a) )
{}
~basic_streambuf_locale_saver()
diff --git a/include/boost/archive/binary_iarchive.hpp b/include/boost/archive/binary_iarchive.hpp
index a0b21cc5..d07bbbe4 100644
--- a/include/boost/archive/binary_iarchive.hpp
+++ b/include/boost/archive/binary_iarchive.hpp
@@ -56,13 +56,7 @@ public:
} // namespace archive
} // namespace boost
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
-namespace boost {
+namespace boost {
namespace archive {
// do not derive from this class. If you want to extend this functionality
@@ -73,9 +67,7 @@ class binary_iarchive :
boost::archive::binary_iarchive,
std::istream::char_type,
std::istream::traits_type
- >,
- public detail::shared_ptr_helper
-{
+ >{
public:
binary_iarchive(std::istream & is, unsigned int flags = 0) :
binary_iarchive_impl<
diff --git a/include/boost/archive/binary_wiarchive.hpp b/include/boost/archive/binary_wiarchive.hpp
index fb183417..ce6576ee 100644
--- a/include/boost/archive/binary_wiarchive.hpp
+++ b/include/boost/archive/binary_wiarchive.hpp
@@ -56,12 +56,6 @@ public:
} // namespace archive
} // namespace boost
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
namespace boost {
namespace archive {
diff --git a/include/boost/archive/detail/basic_iarchive.hpp b/include/boost/archive/detail/basic_iarchive.hpp
index 865f0448..fdafbbf8 100644
--- a/include/boost/archive/detail/basic_iarchive.hpp
+++ b/include/boost/archive/detail/basic_iarchive.hpp
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include // must be the last header
namespace boost {
@@ -41,7 +42,8 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
//////////////////////////////////////////////////////////////////////
// class basic_iarchive - read serialized objects from a input stream
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive :
- private boost::noncopyable
+ private boost::noncopyable,
+ public boost::archive::detail::helper_collection
{
friend class basic_iarchive_impl;
// hide implementation of this class to minimize header conclusion
diff --git a/include/boost/archive/detail/basic_oarchive.hpp b/include/boost/archive/detail/basic_oarchive.hpp
index 73cd7980..f65d1103 100644
--- a/include/boost/archive/detail/basic_oarchive.hpp
+++ b/include/boost/archive/detail/basic_oarchive.hpp
@@ -25,7 +25,7 @@
#include
#include
-
+#include
#include // must be the last header
namespace boost {
@@ -39,10 +39,12 @@ namespace detail {
class basic_oarchive_impl;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
+
//////////////////////////////////////////////////////////////////////
// class basic_oarchive - write serialized objects to an output stream
class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive :
- private boost::noncopyable
+ private boost::noncopyable,
+ public boost::archive::detail::helper_collection
{
friend class basic_oarchive_impl;
// hide implementation of this class to minimize header conclusion
diff --git a/include/boost/archive/impl/xml_woarchive_impl.ipp b/include/boost/archive/impl/xml_woarchive_impl.ipp
index 11b9a8dd..ff97daa5 100644
--- a/include/boost/archive/impl/xml_woarchive_impl.ipp
+++ b/include/boost/archive/impl/xml_woarchive_impl.ipp
@@ -135,20 +135,21 @@ xml_woarchive_impl::xml_woarchive_impl(
// a) before output is invoked or
// b) after flush has been called. This prevents one-to-many
// transforms (such as one to many transforms from getting
- // mixed up. Unfortunately, STLPort doesn't respect b) above
- // so the restoration of the original archive locale done by
- // the locale_saver doesn't get processed,
- // before the current one is destroyed.
- // so the codecvt doesn't get replaced with the orginal
- // so closing the stream invokes codecvt::do_unshift
- // so it crashes because the corresponding locale that contained
- // the codecvt isn't around any more.
- // we can hack around this by using a static codecvt that never
- // gets destroyed.
+ // mixed up.
if(0 == (flags & no_codecvt)){
boost::archive::detail::utf8_codecvt_facet *pfacet;
#if defined(__SGI_STL_PORT)
- static boost::archive::detail::utf8_codecvt_facet
+ // Unfortunately, STLPort doesn't respect b) above
+ // so the restoration of the original archive locale done by
+ // the locale_saver doesn't get processed,
+ // before the current one is destroyed.
+ // so the codecvt doesn't get replaced with the orginal
+ // so closing the stream invokes codecvt::do_unshift
+ // so it crashes because the corresponding locale that contained
+ // the codecvt isn't around any more.
+ // we can hack around this by using a static codecvt that never
+ // gets destroyed.
+ static boost::archive::detail::utf8_codecvt_facet
facet(static_cast(1));
pfacet = & facet;
#else
diff --git a/include/boost/archive/polymorphic_iarchive.hpp b/include/boost/archive/polymorphic_iarchive.hpp
index b32a2f03..4714dd31 100644
--- a/include/boost/archive/polymorphic_iarchive.hpp
+++ b/include/boost/archive/polymorphic_iarchive.hpp
@@ -155,18 +155,11 @@ public:
#include // pops abi_suffix.hpp pragmas
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
-namespace boost {
+namespace boost {
namespace archive {
class polymorphic_iarchive :
- public polymorphic_iarchive_impl,
- public detail::shared_ptr_helper
+ public polymorphic_iarchive_impl
{
public:
virtual ~polymorphic_iarchive(){};
diff --git a/include/boost/archive/shared_ptr_helper.hpp b/include/boost/archive/shared_ptr_helper.hpp
deleted file mode 100644
index 3df46055..00000000
--- a/include/boost/archive/shared_ptr_helper.hpp
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
-#define BOOST_ARCHIVE_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 pointern
-
-// (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 // must be the last headern
-
-namespace boost_132 {
- template class shared_ptr;
-}
-namespace boost {
- template class shared_ptr;
- namespace serialization {
- class extended_type_info;
- template
- inline void load(
- Archive & ar,
- boost::shared_ptr< T > &t,
- const unsigned int file_version
- );
- }
-namespace archive{
-namespace detail {
-
-/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
-// a common class for holding various types of shared pointers
-
-class shared_ptr_helper {
- struct collection_type_compare {
- bool operator()(
- const shared_ptr &lhs,
- const shared_ptr &rhs
- )const{
- return lhs.get() < rhs.get();
- }
- };
- typedef std::set<
- boost::shared_ptr,
- collection_type_compare
- > collection_type;
- typedef collection_type::const_iterator iterator_type;
- // list of shared_pointers create accessable 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.
- collection_type * m_pointers;
-
- struct null_deleter {
- void operator()(void const *) const {}
- };
-
- struct void_deleter {
- const boost::serialization::extended_type_info * m_eti;
- void_deleter(const boost::serialization::extended_type_info *eti) :
- m_eti(eti)
- {}
- void operator()(void *vp) const {
- m_eti->destroy(vp);
- }
- };
-
-#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
-public:
-#else
- template
- friend inline void boost::serialization::load(
- Archive & ar,
- boost::shared_ptr< T > &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 underlaying 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;
-// #endif
-
- // returns pointer to object and an indicator whether this is a
- // new entry (true) or a previous one (false)
- BOOST_ARCHIVE_DECL(shared_ptr)
- get_od(
- const void * od,
- const boost::serialization::extended_type_info * true_type,
- const boost::serialization::extended_type_info * this_type
- );
-
- BOOST_ARCHIVE_DECL(void)
- append(const boost::shared_ptr &);
-
- template
- struct non_polymorphic {
- static const boost::serialization::extended_type_info *
- get_object_identifier(T &){
- return & boost::serialization::singleton<
- BOOST_DEDUCED_TYPENAME
- boost::serialization::type_info_implementation< T >::type
- >::get_const_instance();
- }
- };
- template
- struct polymorphic {
- static const boost::serialization::extended_type_info *
- get_object_identifier(T & t){
- return boost::serialization::singleton<
- BOOST_DEDUCED_TYPENAME
- boost::serialization::type_info_implementation< T >::type
- >::get_const_instance().get_derived_extended_type_info(t);
- }
- };
-public:
- template
- void reset(shared_ptr< 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. This is effectively
- // the object identifern
- typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
- is_polymorphic< T >,
- mpl::identity >,
- mpl::identity >
- >::type type;
-
- const boost::serialization::extended_type_info * true_type
- = type::get_object_identifier(*t);
-
- // note:if this exception is thrown, be sure that derived pointern
- // is either registered or exported.
- if(NULL == true_type)
- boost::serialization::throw_exception(
- archive_exception(
- archive_exception::unregistered_class,
- this_type->get_debug_info()
- )
- );
- shared_ptr r =
- get_od(
- static_cast(t),
- true_type,
- this_type
- );
- if(!r){
- s.reset(t);
- const void * od = void_downcast(
- *true_type,
- *this_type,
- static_cast(t)
- );
- shared_ptr sp(s, od);
- append(sp);
- }
- else{
- s = shared_ptr< T >(
- r,
- static_cast(r.get())
- );
- }
- }
-
-// #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
- BOOST_ARCHIVE_DECL(void)
- append(const boost_132::shared_ptr & t);
-// #endif
-public:
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
- shared_ptr_helper();
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
- ~shared_ptr_helper();
-};
-
-} // namespace detail
-} // namespace archive
-} // namespace boost
-
-#include // pops abi_suffix.hpp pragmas
-
-#endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP
diff --git a/include/boost/archive/text_iarchive.hpp b/include/boost/archive/text_iarchive.hpp
index fa0c88c8..13cb9930 100644
--- a/include/boost/archive/text_iarchive.hpp
+++ b/include/boost/archive/text_iarchive.hpp
@@ -121,12 +121,6 @@ public:
#include // pops abi_suffix.hpp pragmas
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
@@ -136,9 +130,7 @@ namespace boost {
namespace archive {
class text_iarchive :
- public text_iarchive_impl,
- public detail::shared_ptr_helper
-{
+ public text_iarchive_impl{
public:
text_iarchive(std::istream & is_, unsigned int flags = 0) :
// note: added _ to suppress useless gcc warning
diff --git a/include/boost/archive/text_wiarchive.hpp b/include/boost/archive/text_wiarchive.hpp
index e386e490..b927a7e3 100644
--- a/include/boost/archive/text_wiarchive.hpp
+++ b/include/boost/archive/text_wiarchive.hpp
@@ -117,12 +117,6 @@ public:
#include // pops abi_suffix.hpp pragmas
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
@@ -132,9 +126,7 @@ namespace boost {
namespace archive {
class text_wiarchive :
- public text_wiarchive_impl,
- public detail::shared_ptr_helper
-{
+ public text_wiarchive_impl{
public:
text_wiarchive(std::wistream & is, unsigned int flags = 0) :
text_wiarchive_impl(is, flags)
diff --git a/include/boost/archive/xml_iarchive.hpp b/include/boost/archive/xml_iarchive.hpp
index c82fe436..cdb8cdc3 100644
--- a/include/boost/archive/xml_iarchive.hpp
+++ b/include/boost/archive/xml_iarchive.hpp
@@ -129,13 +129,6 @@ public:
#endif
#include // pops abi_suffix.hpp pragmas
-
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
@@ -145,9 +138,7 @@ namespace boost {
namespace archive {
class xml_iarchive :
- public xml_iarchive_impl,
- public detail::shared_ptr_helper
-{
+ public xml_iarchive_impl{
public:
xml_iarchive(std::istream & is, unsigned int flags = 0) :
xml_iarchive_impl(is, flags)
diff --git a/include/boost/archive/xml_wiarchive.hpp b/include/boost/archive/xml_wiarchive.hpp
index 253081fc..4d4e1a33 100644
--- a/include/boost/archive/xml_wiarchive.hpp
+++ b/include/boost/archive/xml_wiarchive.hpp
@@ -135,12 +135,6 @@ public:
#include // pops abi_suffix.hpp pragmas
-// note special treatment of shared_ptr. This type needs a special
-// structure associated with every archive. We created a "mix-in"
-// class to provide this functionality. Since shared_ptr holds a
-// special esteem in the boost library - we included it here by default.
-#include
-
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
@@ -150,9 +144,7 @@ namespace boost {
namespace archive {
class xml_wiarchive :
- public xml_wiarchive_impl,
- public detail::shared_ptr_helper
-{
+ public xml_wiarchive_impl{
public:
xml_wiarchive(std::wistream & is, unsigned int flags = 0) :
xml_wiarchive_impl(is, flags)
diff --git a/include/boost/serialization/shared_ptr.hpp b/include/boost/serialization/shared_ptr.hpp
index d6d73c95..f348b12b 100644
--- a/include/boost/serialization/shared_ptr.hpp
+++ b/include/boost/serialization/shared_ptr.hpp
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include
#include
@@ -130,13 +131,13 @@ inline void load(
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
- ar.append(sp);
+ ar.template get_helper().append(sp);
r = sp.get();
}
else{
ar >> boost::serialization::make_nvp("px", r);
}
- ar.reset(t,r);
+ ar.template get_helper().reset(t,r);
}
#else
@@ -152,7 +153,7 @@ inline void load(
BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
T* r;
ar >> boost::serialization::make_nvp("px", r);
- ar.reset(t,r);
+ ar.template get_helper().reset(t,r);
}
#endif
diff --git a/src/basic_iarchive.cpp b/src/basic_iarchive.cpp
index 87a44112..3a246900 100644
--- a/src/basic_iarchive.cpp
+++ b/src/basic_iarchive.cpp
@@ -418,7 +418,6 @@ basic_iarchive_impl::load_pointer(
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type_
)
-
){
m_moveable_objects.is_pointer = true;
serialization::state_saver w(m_moveable_objects.is_pointer);
@@ -452,7 +451,7 @@ basic_iarchive_impl::load_pointer(
bpis_ptr = (*finder)(*eti);
}
BOOST_ASSERT(NULL != bpis_ptr);
- class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer());
+ // class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer());
BOOST_VERIFY(register_type(bpis_ptr->get_basic_serializer()) == cid);
int i = cid;
cobject_id_vector[i].bpis_ptr = bpis_ptr;
diff --git a/src/shared_ptr_helper.cpp b/src/shared_ptr_helper.cpp
deleted file mode 100644
index 0cb5f40e..00000000
--- a/src/shared_ptr_helper.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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 pointern
-
-// (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