Skip to content

Commit

Permalink
correct implementation of serialization for boost::optional
Browse files Browse the repository at this point in the history
  • Loading branch information
robertramey committed May 8, 2017
1 parent 49f8f59 commit 632df7a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 29 deletions.
44 changes: 18 additions & 26 deletions include/boost/serialization/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <boost/type_traits/is_pointer.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
#include <boost/serialization/detail/is_default_constructible.hpp>
#include <boost/serialization/force_include.hpp>

// function specializations must be defined in the appropriate
// namespace - boost::serialization
Expand All @@ -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);
}
}
Expand All @@ -72,7 +62,7 @@ template<class Archive, class T>
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);
Expand All @@ -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<T> 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<class Archive, class T>
Expand All @@ -106,7 +93,12 @@ void serialize(
boost::serialization::split_free(ar, t, version);
}

template<class T>
struct version<boost::optional<T> > {
BOOST_STATIC_CONSTANT(int, value = 1);
};

} // serialization
} // namespace boost
} // boost

#endif // BOOST_SERIALIZATION_OPTIONAL_HPP_
1 change: 0 additions & 1 deletion test/A.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

#include <ostream> // for friend output operators
#include <cstddef> // size_t
#include <string>
#include <boost/config.hpp>

#if defined(BOOST_NO_STDC_NAMESPACE)
Expand Down
32 changes: 30 additions & 2 deletions test/test_optional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ namespace std{
#include "test_tools.hpp"

#include <boost/serialization/optional.hpp>
#include <boost/serialization/string.hpp>

#include "A.hpp"
#include "A.ipp"
struct A {
int m_x;
template<class Archive>
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 */[] )
{
Expand All @@ -35,22 +42,43 @@ int test_main( int /* argc */, char* /* argv */[] )

const boost::optional<int> aoptional1;
const boost::optional<int> aoptional2(123);
const boost::optional<A> aoptional3;
A a;
const boost::optional<A> aoptional4(a);
const boost::optional<A *> aoptional5;
const boost::optional<A *> 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<int> aoptional1a(999);
boost::optional<int> aoptional2a;
boost::optional<A> aoptional3a;
boost::optional<A> aoptional4a;
boost::optional<A *> aoptional5a;
boost::optional<A *> 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;
Expand Down

0 comments on commit 632df7a

Please sign in to comment.