From 632df7aab5e1fb3458ea53be2704c83462b2caa9 Mon Sep 17 00:00:00 2001 From: Robert Ramey Date: Mon, 8 May 2017 09:18:36 -0700 Subject: [PATCH] correct implementation of serialization for boost::optional --- include/boost/serialization/optional.hpp | 44 ++++++++++-------------- test/A.hpp | 1 - test/test_optional.cpp | 32 +++++++++++++++-- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/include/boost/serialization/optional.hpp b/include/boost/serialization/optional.hpp index ecd1756d..32ae1fa9 100644 --- a/include/boost/serialization/optional.hpp +++ b/include/boost/serialization/optional.hpp @@ -29,6 +29,7 @@ #include #include #include +#include // function specializations must be defined in the appropriate // namespace - boost::serialization @@ -53,17 +54,6 @@ void save( const bool tflag = t.is_initialized(); ar << boost::serialization::make_nvp("initialized", tflag); if (tflag){ - const boost::serialization::item_version_type item_version(version< T >::value); - #if 0 - const boost::archive::library_version_type library_version( - ar.get_library_version() - }; - if(boost::archive::library_version_type(3) < library_version){ - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif ar << boost::serialization::make_nvp("value", *t); } } @@ -72,7 +62,7 @@ template void load( Archive & ar, boost::optional< T > & t, - const unsigned int /*version*/ + const unsigned int version ){ bool tflag; ar >> boost::serialization::make_nvp("initialized", tflag); @@ -81,20 +71,17 @@ void load( return; } - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); + if(0 == version){ + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } } - detail::stack_allocate tp; - ar >> boost::serialization::make_nvp("value", tp.reference()); - t.reset(boost::move(tp.reference())); - ar.reset_object_address( - t.get_ptr(), - & tp.reference() - ); + t = T(); + ar >> boost::serialization::make_nvp("value", *t); } template @@ -106,7 +93,12 @@ void serialize( boost::serialization::split_free(ar, t, version); } +template +struct version > { + BOOST_STATIC_CONSTANT(int, value = 1); +}; + } // serialization -} // namespace boost +} // boost #endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ diff --git a/test/A.hpp b/test/A.hpp index 69322785..29cc15ff 100644 --- a/test/A.hpp +++ b/test/A.hpp @@ -18,7 +18,6 @@ #include // for friend output operators #include // size_t -#include #include #if defined(BOOST_NO_STDC_NAMESPACE) diff --git a/test/test_optional.cpp b/test/test_optional.cpp index bee2c6b4..7eb7ee50 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -24,9 +24,16 @@ namespace std{ #include "test_tools.hpp" #include +#include -#include "A.hpp" -#include "A.ipp" +struct A { + int m_x; + template + void serialize(Archive & ar, const unsigned int version){}; + bool operator==(const A & rhs) const { + return m_x == rhs.m_x; + } +}; int test_main( int /* argc */, char* /* argv */[] ) { @@ -35,22 +42,43 @@ int test_main( int /* argc */, char* /* argv */[] ) const boost::optional aoptional1; const boost::optional aoptional2(123); + const boost::optional aoptional3; + A a; + const boost::optional aoptional4(a); + const boost::optional aoptional5; + const boost::optional aoptional6(& a); { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS); oa << boost::serialization::make_nvp("aoptional1",aoptional1); oa << boost::serialization::make_nvp("aoptional2",aoptional2); + oa << boost::serialization::make_nvp("aoptional3",aoptional3); + oa << boost::serialization::make_nvp("aoptional4",aoptional4); + oa << boost::serialization::make_nvp("aoptional5",aoptional5); + oa << boost::serialization::make_nvp("aoptional6",aoptional6); } boost::optional aoptional1a(999); boost::optional aoptional2a; + boost::optional aoptional3a; + boost::optional aoptional4a; + boost::optional aoptional5a; + boost::optional aoptional6a; { test_istream is(testfile, TEST_STREAM_FLAGS); test_iarchive ia(is, TEST_ARCHIVE_FLAGS); ia >> boost::serialization::make_nvp("aoptional1",aoptional1a); ia >> boost::serialization::make_nvp("aoptional2",aoptional2a); + ia >> boost::serialization::make_nvp("aoptional3",aoptional3a); + ia >> boost::serialization::make_nvp("aoptional4",aoptional4a); + ia >> boost::serialization::make_nvp("aoptional5",aoptional5a); + ia >> boost::serialization::make_nvp("aoptional6",aoptional6a); } BOOST_CHECK(aoptional1 == aoptional1a); BOOST_CHECK(aoptional2 == aoptional2a); + BOOST_CHECK(aoptional3 == aoptional3a); + BOOST_CHECK(aoptional4.get() == aoptional4a.get()); + BOOST_CHECK(aoptional5 == aoptional5a); + BOOST_CHECK(*aoptional6.get() == *aoptional6a.get()); std::remove(testfile); return EXIT_SUCCESS;