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 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
|
||||
template <class Archive, class T> inline
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
@@ -45,7 +66,7 @@ namespace cereal
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
@@ -53,7 +74,7 @@ namespace cereal
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
@@ -61,7 +82,7 @@ namespace cereal
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
@@ -69,7 +90,7 @@ namespace cereal
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
@@ -77,15 +98,15 @@ namespace cereal
|
||||
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
|
||||
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 for non polymorphic types
|
||||
//! Saving std::shared_ptr (wrapper implementation)
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
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 )
|
||||
load( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
|
||||
{
|
||||
auto & ptr = wrapper.ptr;
|
||||
|
||||
uint32_t 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
|
||||
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 )
|
||||
load( Archive & ar, detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
|
||||
{
|
||||
auto & ptr = wrapper.ptr;
|
||||
|
||||
uint32_t 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
|
||||
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();
|
||||
ar( sptr );
|
||||
}
|
||||
|
||||
//! Loading std::weak_ptr for non polymorphic types
|
||||
//! Loading std::weak_ptr (wrapper implementation)
|
||||
template <class Archive, class T> inline
|
||||
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;
|
||||
ar( 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
|
||||
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 );
|
||||
}
|
||||
|
||||
//! 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
|
||||
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 )
|
||||
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 ) );
|
||||
}
|
||||
|
||||
//! 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
|
||||
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 )
|
||||
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 ) );
|
||||
ar( *ptr );
|
||||
}
|
||||
|
||||
|
||||
} // namespace cereal
|
||||
|
||||
#endif // CEREAL_TYPES_SHARED_PTR_HPP_
|
||||
|
||||
@@ -56,56 +56,13 @@ namespace cereal
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
template <class Archive, class T> inline
|
||||
typename std::enable_if<std::is_polymorphic<T>::value
|
||||
&& traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, 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.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
|
||||
@@ -113,8 +70,6 @@ namespace cereal
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
save( Archive & ar, std::weak_ptr<T> const & ptr )
|
||||
{
|
||||
auto sptr = ptr.lock();
|
||||
ar( sptr );
|
||||
}
|
||||
|
||||
//! Loading std::weak_ptr for polymorphic types
|
||||
@@ -122,9 +77,6 @@ namespace cereal
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
load( Archive & ar, std::weak_ptr<T> & ptr )
|
||||
{
|
||||
std::shared_ptr<T> sptr;
|
||||
ar( sptr );
|
||||
ptr = sptr;
|
||||
}
|
||||
|
||||
//! Saving std::unique_ptr for polymorphic types
|
||||
@@ -132,26 +84,13 @@ namespace cereal
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
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
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
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
|
||||
#endif // CEREAL_TYPES_POLYMORPHIC_HPP_
|
||||
|
||||
@@ -37,6 +37,10 @@ template <class T>
|
||||
void nop(T&&t) {}
|
||||
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