27 #ifndef CEREAL_TYPES_SHARED_PTR_HPP_
28 #define CEREAL_TYPES_SHARED_PTR_HPP_
30 #include <cereal/cereal.hpp>
35 namespace memory_detail
43 PtrWrapper(T && p) : ptr(std::forward<T>(p)) {}
49 template<
class T>
inline
52 return {std::forward<T>(t)};
57 template <
class Archive,
class T>
inline
58 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
59 save( Archive & ar, std::shared_ptr<T>
const & ptr )
61 ar( _CEREAL_NVP(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
65 template <
class Archive,
class T>
inline
66 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
67 load( Archive & ar, std::shared_ptr<T> & ptr )
69 ar( memory_detail::make_ptr_wrapper( ptr ) );
73 template <
class Archive,
class T>
inline
74 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
75 save( Archive & ar, std::weak_ptr<T>
const & ptr )
77 auto sptr = ptr.lock();
78 ar( _CEREAL_NVP(
"ptr_wrapper", memory_detail::make_ptr_wrapper( sptr )) );
82 template <
class Archive,
class T>
inline
83 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
84 load( Archive & ar, std::weak_ptr<T> & ptr )
86 std::shared_ptr<T> sptr;
87 ar( memory_detail::make_ptr_wrapper( sptr ) );
92 template <
class Archive,
class T,
class D>
inline
93 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
94 save( Archive & ar, std::unique_ptr<T, D>
const & ptr )
96 ar( _CEREAL_NVP(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
100 template <
class Archive,
class T,
class D>
inline
101 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
102 load( Archive & ar, std::unique_ptr<T, D> & ptr )
104 ar( memory_detail::make_ptr_wrapper( ptr ) );
111 template <
class Archive,
class T>
inline
112 void save( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T>
const &>
const & wrapper )
114 auto & ptr = wrapper.ptr;
116 uint32_t
id = ar.registerSharedPointer( ptr.get() );
117 ar( _CEREAL_NVP(
"id",
id) );
119 if(
id & detail::msb_32bit )
121 ar( _CEREAL_NVP(
"data", *ptr) );
126 template <
class Archive,
class T>
inline
127 typename std::enable_if<traits::has_load_and_allocate<T, Archive>(),
void>::type
128 load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
130 auto & ptr = wrapper.ptr;
136 if(
id & detail::msb_32bit )
138 ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
139 ar.registerSharedPointer(
id, ptr);
143 ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
148 template <
class Archive,
class T>
inline
149 typename std::enable_if<!traits::has_load_and_allocate<T, Archive>(),
void>::type
150 load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
152 auto & ptr = wrapper.ptr;
158 if(
id & detail::msb_32bit )
160 ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
162 ar.registerSharedPointer(
id, ptr);
166 ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
171 template <
class Archive,
class T,
class D>
inline
172 void save( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D>
const &>
const & wrapper )
174 auto & ptr = wrapper.ptr;
181 ar( _CEREAL_NVP(
"valid", uint8_t(0)) );
184 ar( _CEREAL_NVP(
"valid", uint8_t(1)) );
185 ar( _CEREAL_NVP(
"data", *ptr) );
190 template <
class Archive,
class T,
class D>
inline
191 typename std::enable_if<traits::has_load_and_allocate<T, Archive>(),
void>::type
192 load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
197 auto & ptr = wrapper.ptr;
200 ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
202 ptr.reset(
nullptr );
206 template <
class Archive,
class T,
class D>
inline
207 typename std::enable_if<!traits::has_load_and_allocate<T, Archive>(),
void>::type
208 load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
213 auto & ptr = wrapper.ptr;
217 ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
222 ptr.reset(
nullptr );
227 #endif // CEREAL_TYPES_SHARED_PTR_HPP_