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)) {}
56 template<
class T>
inline
59 return {std::forward<T>(t)};
66 template <
class Archive,
class T>
79 inline void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar )
135 using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type;
136 using ParentType = std::enable_shared_from_this<BaseType>;
137 using StorageType =
typename std::aligned_storage<
sizeof(ParentType),
CEREAL_ALIGNOF(ParentType)>::type;
143 itsPtr( static_cast<ParentType *>( ptr ) ),
147 std::memcpy( &itsState, itsPtr,
sizeof(ParentType) );
156 std::memcpy(
static_cast<void *
>(itsPtr), &itsState,
sizeof(ParentType) );
169 StorageType itsState;
178 template <
class Archive,
class T>
inline
197 template <
class Archive,
class T>
inline
206 template <
class Archive,
class T>
inline
207 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
210 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
214 template <
class Archive,
class T>
inline
215 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
218 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
222 template <
class Archive,
class T>
inline
223 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
226 auto const sptr = ptr.lock();
227 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( sptr )) );
231 template <
class Archive,
class T>
inline
232 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
235 std::shared_ptr<T> sptr;
236 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( sptr )) );
241 template <
class Archive,
class T,
class D>
inline
242 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
245 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
249 template <
class Archive,
class T,
class D>
inline
250 typename std::enable_if<!std::is_polymorphic<T>::value,
void>::type
253 ar(
CEREAL_NVP_(
"ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
261 template <
class Archive,
class T>
inline
264 auto & ptr = wrapper.ptr;
266 uint32_t
id = ar.registerSharedPointer( ptr );
269 if(
id & detail::msb_32bit )
277 template <
class Archive,
class T>
inline
278 typename std::enable_if<traits::has_load_and_construct<T, Archive>::value,
void>::type
285 if(
id & detail::msb_32bit )
289 using ST =
typename std::aligned_storage<
sizeof(T),
CEREAL_ALIGNOF(T)>::type;
294 auto valid = std::make_shared<bool>(
false );
298 using NonConstT =
typename std::remove_const<T>::type;
299 std::shared_ptr<NonConstT> ptr(
reinterpret_cast<NonConstT *
>(
new ST()),
305 delete reinterpret_cast<ST *
>( t );
309 ar.registerSharedPointer(
id, ptr );
312 memory_detail::loadAndConstructSharedPtr( ar, ptr.get(), typename ::cereal::traits::has_shared_from_this<NonConstT>::type() );
316 wrapper.ptr = std::move(ptr);
319 wrapper.ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
324 template <
class Archive,
class T>
inline
325 typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value,
void>::type
332 if(
id & detail::msb_32bit )
334 using NonConstT =
typename std::remove_const<T>::type;
336 ar.registerSharedPointer(
id, ptr );
338 wrapper.ptr = std::move(ptr);
341 wrapper.ptr = std::static_pointer_cast<T>(ar.getSharedPointer(
id));
346 template <
class Archive,
class T,
class D>
inline
349 auto & ptr = wrapper.ptr;
366 template <
class Archive,
class T,
class D>
inline
367 typename std::enable_if<traits::has_load_and_construct<T, Archive>::value,
void>::type
373 auto & ptr = wrapper.ptr;
377 using NonConstT =
typename std::remove_const<T>::type;
380 using ST =
typename std::aligned_storage<
sizeof(NonConstT),
CEREAL_ALIGNOF(NonConstT)>::type;
384 std::unique_ptr<ST> stPtr(
new ST() );
393 ptr.reset(
reinterpret_cast<T *
>( stPtr.release() ) );
396 ptr.reset(
nullptr );
401 template <
class Archive,
class T,
class D>
inline
402 typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value,
void>::type
410 using NonConstT =
typename std::remove_const<T>::type;
413 wrapper.ptr = std::move(ptr);
417 wrapper.ptr.reset(
nullptr );
425 #endif // CEREAL_TYPES_SHARED_PTR_HPP_