diff options
Diffstat (limited to 'boost/serialization/optional.hpp')
-rw-r--r-- | boost/serialization/optional.hpp | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/boost/serialization/optional.hpp b/boost/serialization/optional.hpp index 4024cf5e61..ecd1756d50 100644 --- a/boost/serialization/optional.hpp +++ b/boost/serialization/optional.hpp @@ -19,12 +19,16 @@ #include <boost/archive/detail/basic_iarchive.hpp> #include <boost/optional.hpp> +#include <boost/move/utility_core.hpp> + #include <boost/serialization/item_version_type.hpp> #include <boost/serialization/split_free.hpp> #include <boost/serialization/level.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/version.hpp> +#include <boost/type_traits/is_pointer.hpp> #include <boost/serialization/detail/stack_constructor.hpp> +#include <boost/serialization/detail/is_default_constructible.hpp> // function specializations must be defined in the appropriate // namespace - boost::serialization @@ -37,6 +41,15 @@ void save( const boost::optional< T > & t, const unsigned int /*version*/ ){ + // 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<T> as optional<T *> + BOOST_STATIC_ASSERT( + boost::serialization::detail::is_default_constructible<T>::value + || boost::is_pointer<T>::value + ); const bool tflag = t.is_initialized(); ar << boost::serialization::make_nvp("initialized", tflag); if (tflag){ @@ -63,22 +76,25 @@ void load( ){ bool tflag; ar >> boost::serialization::make_nvp("initialized", tflag); - if (tflag){ - 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){ - // item_version is handled as an attribute so it doesnt need an NVP - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - detail::stack_construct<Archive, T> aux(ar, item_version); - ar >> boost::serialization::make_nvp("value", aux.reference()); - t.reset(aux.reference()); - } - else { + if(! tflag){ t.reset(); + 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); } + 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() + ); } template<class Archive, class T> |