mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
Implemented PtrWrapper in memory
This commit is contained in:
@@ -32,12 +32,33 @@
|
|||||||
|
|
||||||
namespace cereal
|
namespace cereal
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
//! A wrapper class to notify cereal that it is ok to serialize the contained pointer
|
||||||
|
/*! This mechanism allows us to intercept and properly handle polymorphic pointers
|
||||||
|
\note Users should _not_ use this class directly */
|
||||||
|
template<class T>
|
||||||
|
struct PtrWrapper
|
||||||
|
{
|
||||||
|
PtrWrapper(T && p) : ptr(std::forward<T>(p)) {}
|
||||||
|
T & ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Make a PtrWrapper
|
||||||
|
/*! \note Users should _not_ use this method directly */
|
||||||
|
template<class T>
|
||||||
|
PtrWrapper<T> make_ptr_wrapper(T && t)
|
||||||
|
{
|
||||||
|
return {std::forward<T>(t)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Saving std::shared_ptr for non polymorphic types
|
//! Saving std::shared_ptr for non polymorphic types
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::shared_ptr<T> const & ptr )
|
save( Archive & ar, std::shared_ptr<T> const & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::shared_ptr, case when no user load and allocate for non polymorphic types
|
//! Loading std::shared_ptr, case when no user load and allocate for non polymorphic types
|
||||||
@@ -45,7 +66,7 @@ namespace cereal
|
|||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
load( Archive & ar, std::shared_ptr<T> & ptr )
|
load( Archive & ar, std::shared_ptr<T> & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::weak_ptr for non polymorphic types
|
//! Saving std::weak_ptr for non polymorphic types
|
||||||
@@ -53,7 +74,7 @@ namespace cereal
|
|||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::weak_ptr for non polymorphic types
|
//! Loading std::weak_ptr for non polymorphic types
|
||||||
@@ -61,7 +82,7 @@ namespace cereal
|
|||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
load( Archive & ar, std::weak_ptr<T> & ptr )
|
load( Archive & ar, std::weak_ptr<T> & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::unique_ptr for non polymorphic types
|
//! Saving std::unique_ptr for non polymorphic types
|
||||||
@@ -69,7 +90,7 @@ namespace cereal
|
|||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::unique_ptr<T, D> const & ptr )
|
save( Archive & ar, std::unique_ptr<T, D> const & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::unique_ptr, case when user provides load_and_allocate for non polymorphic types
|
//! Loading std::unique_ptr, case when user provides load_and_allocate for non polymorphic types
|
||||||
@@ -77,15 +98,15 @@ namespace cereal
|
|||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
||||||
{
|
{
|
||||||
ar( detail::ptr_wrapper( ptr ) );
|
ar( detail::make_ptr_wrapper( ptr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ######################################################################
|
||||||
|
// Pointer wrapper implementations follow below
|
||||||
|
|
||||||
|
//! Saving std::shared_ptr (wrapper implementation)
|
||||||
|
|
||||||
//! Saving std::shared_ptr for non polymorphic types
|
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
void save( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> const & wraper )
|
void save( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> const &> const & wrapper )
|
||||||
{
|
{
|
||||||
auto & ptr = wrapper.ptr;
|
auto & ptr = wrapper.ptr;
|
||||||
|
|
||||||
@@ -98,12 +119,14 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::shared_ptr, case when user load and allocate for non polymorphic types
|
//! Loading std::shared_ptr, case when user load and allocate (wrapper implementation)
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value
|
typename std::enable_if<!std::is_polymorphic<T>::value
|
||||||
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||||
load( Archive & ar, std::shared_ptr<T> & ptr )
|
load( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
ar( id );
|
ar( id );
|
||||||
@@ -119,12 +142,14 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::shared_ptr, case when no user load and allocate for non polymorphic types
|
//! Loading std::shared_ptr, case when no user load and allocate (wrapper implementation)
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value
|
typename std::enable_if<!std::is_polymorphic<T>::value
|
||||||
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||||
load( Archive & ar, std::shared_ptr<T> & ptr )
|
load( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
ar( id );
|
ar( id );
|
||||||
@@ -141,53 +166,59 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::weak_ptr for non polymorphic types
|
//! Saving std::weak_ptr (wrapper implementation)
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
save( Archive & ar, detail::PtrWrapper<std::weak_ptr<T> const &> const & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
|
|
||||||
auto sptr = ptr.lock();
|
auto sptr = ptr.lock();
|
||||||
ar( sptr );
|
ar( sptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::weak_ptr for non polymorphic types
|
//! Loading std::weak_ptr (wrapper implementation)
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
load( Archive & ar, std::weak_ptr<T> & ptr )
|
load( Archive & ar, detail::PtrWrapper<std::weak_ptr<T> &> & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
|
|
||||||
std::shared_ptr<T> sptr;
|
std::shared_ptr<T> sptr;
|
||||||
ar( sptr );
|
ar( sptr );
|
||||||
ptr = sptr;
|
ptr = sptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::unique_ptr for non polymorphic types
|
//! Saving std::unique_ptr (wrapper implementation)
|
||||||
template <class Archive, class T, class D> inline
|
template <class Archive, class T, class D> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::unique_ptr<T, D> const & ptr )
|
save( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> const &> const & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
ar( *ptr );
|
ar( *ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::unique_ptr, case when user provides load_and_allocate for non polymorphic types
|
//! Loading std::unique_ptr, case when user provides load_and_allocate (wrapper implementation)
|
||||||
template <class Archive, class T, class D> inline
|
template <class Archive, class T, class D> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value
|
typename std::enable_if<!std::is_polymorphic<T>::value
|
||||||
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||||
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
load( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::unique_ptr, case when no load_and_allocate for non polymorphic types
|
//! Loading std::unique_ptr, case when no load_and_allocate (wrapper implementation)
|
||||||
template <class Archive, class T, class D> inline
|
template <class Archive, class T, class D> inline
|
||||||
typename std::enable_if<!std::is_polymorphic<T>::value
|
typename std::enable_if<!std::is_polymorphic<T>::value
|
||||||
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||||
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
load( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
|
||||||
{
|
{
|
||||||
|
auto & ptr = wrapper.ptr;
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
||||||
ar( *ptr );
|
ar( *ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace cereal
|
} // namespace cereal
|
||||||
|
|
||||||
#endif // CEREAL_TYPES_SHARED_PTR_HPP_
|
#endif // CEREAL_TYPES_SHARED_PTR_HPP_
|
||||||
|
|||||||
@@ -56,56 +56,13 @@ namespace cereal
|
|||||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::shared_ptr<T> const & ptr )
|
save( Archive & ar, std::shared_ptr<T> const & ptr )
|
||||||
{
|
{
|
||||||
uint32_t id = ar.registerSharedPointer( ptr.get() );
|
|
||||||
ar( id );
|
|
||||||
|
|
||||||
if( id & detail::msb_32bit )
|
|
||||||
{
|
|
||||||
ar( *ptr );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::shared_ptr, case when user load and allocate for polymorphic types
|
//! Loading std::shared_ptr, case when user load and allocate for polymorphic types
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T> inline
|
||||||
typename std::enable_if<std::is_polymorphic<T>::value
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
|
||||||
load( Archive & ar, std::shared_ptr<T> & ptr )
|
load( Archive & ar, std::shared_ptr<T> & ptr )
|
||||||
{
|
{
|
||||||
uint32_t id;
|
|
||||||
|
|
||||||
ar( id );
|
|
||||||
|
|
||||||
if( id & detail::msb_32bit )
|
|
||||||
{
|
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
|
||||||
ar.registerSharedPointer(id, ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = std::static_pointer_cast<T>(ar.getSharedPointer(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Loading std::shared_ptr, case when no user load and allocate for polymorphic types
|
|
||||||
template <class Archive, class T> inline
|
|
||||||
typename std::enable_if<std::is_polymorphic<T>::value
|
|
||||||
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
|
||||||
load( Archive & ar, std::shared_ptr<T> & ptr )
|
|
||||||
{
|
|
||||||
uint32_t id;
|
|
||||||
|
|
||||||
ar( id );
|
|
||||||
|
|
||||||
if( id & detail::msb_32bit )
|
|
||||||
{
|
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
|
||||||
ar( *ptr );
|
|
||||||
ar.registerSharedPointer(id, ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = std::static_pointer_cast<T>(ar.getSharedPointer(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::weak_ptr for polymorphic types
|
//! Saving std::weak_ptr for polymorphic types
|
||||||
@@ -113,8 +70,6 @@ namespace cereal
|
|||||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
||||||
{
|
{
|
||||||
auto sptr = ptr.lock();
|
|
||||||
ar( sptr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::weak_ptr for polymorphic types
|
//! Loading std::weak_ptr for polymorphic types
|
||||||
@@ -122,9 +77,6 @@ namespace cereal
|
|||||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
load( Archive & ar, std::weak_ptr<T> & ptr )
|
load( Archive & ar, std::weak_ptr<T> & ptr )
|
||||||
{
|
{
|
||||||
std::shared_ptr<T> sptr;
|
|
||||||
ar( sptr );
|
|
||||||
ptr = sptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving std::unique_ptr for polymorphic types
|
//! Saving std::unique_ptr for polymorphic types
|
||||||
@@ -132,26 +84,13 @@ namespace cereal
|
|||||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
save( Archive & ar, std::unique_ptr<T, D> const & ptr )
|
save( Archive & ar, std::unique_ptr<T, D> const & ptr )
|
||||||
{
|
{
|
||||||
ar( *ptr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading std::unique_ptr, case when user provides load_and_allocate for polymorphic types
|
//! Loading std::unique_ptr, case when user provides load_and_allocate for polymorphic types
|
||||||
template <class Archive, class T, class D> inline
|
template <class Archive, class T, class D> inline
|
||||||
typename std::enable_if<std::is_polymorphic<T>::value
|
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||||
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
|
||||||
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
||||||
{
|
{
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Loading std::unique_ptr, case when no load_and_allocate for polymorphic types
|
|
||||||
template <class Archive, class T, class D> inline
|
|
||||||
typename std::enable_if<std::is_polymorphic<T>::value
|
|
||||||
&& !traits::has_load_and_allocate<T, Archive>(), void>::type
|
|
||||||
load( Archive & ar, std::unique_ptr<T, D> & ptr )
|
|
||||||
{
|
|
||||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
|
||||||
ar( *ptr );
|
|
||||||
}
|
}
|
||||||
} // namespace cereal
|
} // namespace cereal
|
||||||
#endif // CEREAL_TYPES_POLYMORPHIC_HPP_
|
#endif // CEREAL_TYPES_POLYMORPHIC_HPP_
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ template <class T>
|
|||||||
void nop(T&&t) {}
|
void nop(T&&t) {}
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
cereal::detail::StaticObject<cereal::detail::BindingMap<cereal::BinaryOutputArchive>>::getInstance().map[std::type_index(typeid(MyType))](0, 0);
|
|
||||||
//cereal::Singleton<boost::archive::detail::extra_detail::guid_initializer<MyType>>::getInstance();
|
cereal::detail::StaticObject<
|
||||||
|
cereal::detail::BindingMap<cereal::BinaryOutputArchive>
|
||||||
|
>::getInstance().map[std::type_index(typeid(MyType))](0, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user