Implemented PtrWrapper in memory

This commit is contained in:
Randolph Voorhies
2013-06-28 14:02:13 -07:00
parent 3815c06798
commit 35f538ecae
3 changed files with 64 additions and 90 deletions

View File

@@ -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_

View File

@@ -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_

View File

@@ -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);
}