30 #ifndef CEREAL_TYPES_SHARED_PTR_HPP_
31 #define CEREAL_TYPES_SHARED_PTR_HPP_
39 namespace memory_detail
47 PtrWrapper(T && p) : ptr(std::forward<T>(p)) {}
55 template<
class T>
inline
58 return {std::forward<T>(t)};
65 template <
class Archive,
class T>
72 inline void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar )
120 using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type;
121 using ParentType = std::enable_shared_from_this<BaseType>;
122 using StorageType =
typename std::aligned_storage<sizeof(ParentType)>::type;
128 itsPtr( static_cast<ParentType *>( ptr ) ),
131 std::memcpy( &itsState, itsPtr,
sizeof(ParentType) );
137 std::memcpy( itsPtr, &itsState,
sizeof(ParentType) );
142 StorageType itsState;
150 template <
class Archive,
class T>
inline
151 void loadAndConstructSharedPtr( Archive & ar, T * ptr, std::true_type )
168 template <
class Archive,
class T>
inline
169 void loadAndConstructSharedPtr( Archive & ar, T * ptr, std::false_type )
171 memory_detail::LoadAndConstructLoadWrapper<Archive, T> loadWrapper( ptr );
177 template <
class Archive,
class T>
inline
178 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
181 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
185 template <
class Archive,
class T>
inline
186 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
189 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
193 template <
class Archive,
class T>
inline
194 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
197 auto const sptr = ptr.lock();
198 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( sptr )) );
202 template <
class Archive,
class T>
inline
203 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
206 std::shared_ptr<T> sptr;
207 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( sptr )) );
212 template <
class Archive,
class T,
class D>
inline
213 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
216 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
220 template <
class Archive,
class T,
class D>
inline
221 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
224 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
232 template <
class Archive,
class T>
inline
235 auto & ptr = wrapper.ptr;
237 uint32_t
id = ar.registerSharedPointer( ptr.get() );
240 if(
id & detail::msb_32bit )
248 template <
class Archive,
class T>
inline
249 typename std::enable_if<traits::has_load_and_construct<T, Archive>::value,
void>::type
252 auto & ptr = wrapper.ptr;
258 if(
id & detail::msb_32bit )
262 using ST =
typename std::aligned_storage<sizeof(T)>::type;
267 auto valid = std::make_shared<bool>( false );
271 ptr.reset( reinterpret_cast<T *>(
new ST() ),
277 delete reinterpret_cast<ST *
>( t );
281 ar.registerSharedPointer(
id, ptr );
284 memory_detail::loadAndConstructSharedPtr( ar, ptr.get(), typename ::cereal::traits::has_shared_from_this<T>::type() );
290 ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
295 template <
class Archive,
class T>
inline
296 typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value,
void>::type
299 auto & ptr = wrapper.ptr;
305 if(
id & detail::msb_32bit )
307 ptr.reset( detail::Construct<T, Archive>::load_andor_construct() );
308 ar.registerSharedPointer(
id, ptr );
312 ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
317 template <
class Archive,
class T,
class D>
inline
320 auto & ptr = wrapper.ptr;
337 template <
class Archive,
class T,
class D>
inline
338 typename std::enable_if<traits::has_load_and_construct<T, Archive>::value,
void>::type
344 auto & ptr = wrapper.ptr;
350 using ST =
typename std::aligned_storage<sizeof(T)>::type;
354 std::unique_ptr<ST> stPtr(
new ST() );
357 memory_detail::LoadAndConstructLoadWrapper<Archive, T> loadWrapper( reinterpret_cast<T *>( stPtr.get() ) );
363 ptr.reset( reinterpret_cast<T *>( stPtr.release() ) );
366 ptr.reset(
nullptr );
371 template <
class Archive,
class T,
class D>
inline
372 typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value,
void>::type
378 auto & ptr = wrapper.ptr;
382 ptr.reset( detail::Construct<T, Archive>::load_andor_construct() );
387 ptr.reset(
nullptr );
392 #endif // CEREAL_TYPES_SHARED_PTR_HPP_
#define CEREAL_NVP_(name, value)
Convenience for creating a templated NVP.
Definition: helpers.hpp:197
Used to construct types with no default constructor.
Definition: access.hpp:151
A struct that acts as a wrapper around calling load_andor_construct.
Definition: memory.hpp:66
Definition: memory.hpp:117
EnableSharedStateHelper(T *ptr)
Saves the state of some type inheriting from enable_shared_from_this.
Definition: memory.hpp:127
Definition: access.hpp:39
A wrapper class to notify cereal that it is ok to serialize the contained pointer.
Definition: memory.hpp:45
Main cereal functionality.
~EnableSharedStateHelper()
Restores the state of the held pointer.
Definition: memory.hpp:135
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:58
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition: macros.hpp:65
Definition: traits.hpp:1279