summaryrefslogtreecommitdiff
path: root/boost/serialization/optional.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/serialization/optional.hpp')
-rw-r--r--boost/serialization/optional.hpp44
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>