diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp index 55447ee8..77f8a18a 100644 --- a/include/cereal/types/memory.hpp +++ b/include/cereal/types/memory.hpp @@ -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 + struct PtrWrapper + { + PtrWrapper(T && p) : ptr(std::forward(p)) {} + T & ptr; + }; + + //! Make a PtrWrapper + /*! \note Users should _not_ use this method directly */ + template + PtrWrapper make_ptr_wrapper(T && t) + { + return {std::forward(t)}; + } + } + //! Saving std::shared_ptr for non polymorphic types template inline typename std::enable_if::value, void>::type save( Archive & ar, std::shared_ptr 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::value, void>::type load( Archive & ar, std::shared_ptr & 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::value, void>::type save( Archive & ar, std::weak_ptr 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::value, void>::type load( Archive & ar, std::weak_ptr & 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::value, void>::type save( Archive & ar, std::unique_ptr 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::value, void>::type load( Archive & ar, std::unique_ptr & 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 inline - void save( Archive & ar, detail::PtrWrapper const & wraper ) + void save( Archive & ar, detail::PtrWrapper 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 inline typename std::enable_if::value && traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::shared_ptr & ptr ) + load( Archive & ar, detail::PtrWrapper &> & 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 inline typename std::enable_if::value && !traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::shared_ptr & ptr ) + load( Archive & ar, detail::PtrWrapper &> & 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 inline typename std::enable_if::value, void>::type - save( Archive & ar, std::weak_ptr const & ptr ) + save( Archive & ar, detail::PtrWrapper 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 inline typename std::enable_if::value, void>::type - load( Archive & ar, std::weak_ptr & ptr ) + load( Archive & ar, detail::PtrWrapper &> & wrapper ) { + auto & ptr = wrapper.ptr; + std::shared_ptr sptr; ar( sptr ); ptr = sptr; } - //! Saving std::unique_ptr for non polymorphic types + //! Saving std::unique_ptr (wrapper implementation) template inline typename std::enable_if::value, void>::type - save( Archive & ar, std::unique_ptr const & ptr ) + save( Archive & ar, detail::PtrWrapper 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 inline typename std::enable_if::value && traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::unique_ptr & ptr ) + load( Archive & ar, detail::PtrWrapper &> & wrapper ) { + auto & ptr = wrapper.ptr; ptr.reset( detail::Load::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 inline typename std::enable_if::value && !traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::unique_ptr & ptr ) + load( Archive & ar, detail::PtrWrapper &> & wrapper ) { + auto & ptr = wrapper.ptr; ptr.reset( detail::Load::load_andor_allocate( ar ) ); ar( *ptr ); } - } // namespace cereal #endif // CEREAL_TYPES_SHARED_PTR_HPP_ diff --git a/include/cereal/types/polymorphic.hpp b/include/cereal/types/polymorphic.hpp index ad05506d..d66f4e55 100644 --- a/include/cereal/types/polymorphic.hpp +++ b/include/cereal/types/polymorphic.hpp @@ -56,56 +56,13 @@ namespace cereal typename std::enable_if::value, void>::type save( Archive & ar, std::shared_ptr 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 inline - typename std::enable_if::value - && traits::has_load_and_allocate(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, std::shared_ptr & ptr ) { - uint32_t id; - - ar( id ); - - if( id & detail::msb_32bit ) - { - ptr.reset( detail::Load::load_andor_allocate( ar ) ); - ar.registerSharedPointer(id, ptr); - } - else - { - ptr = std::static_pointer_cast(ar.getSharedPointer(id)); - } - } - - //! Loading std::shared_ptr, case when no user load and allocate for polymorphic types - template inline - typename std::enable_if::value - && !traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::shared_ptr & ptr ) - { - uint32_t id; - - ar( id ); - - if( id & detail::msb_32bit ) - { - ptr.reset( detail::Load::load_andor_allocate( ar ) ); - ar( *ptr ); - ar.registerSharedPointer(id, ptr); - } - else - { - ptr = std::static_pointer_cast(ar.getSharedPointer(id)); - } } //! Saving std::weak_ptr for polymorphic types @@ -113,8 +70,6 @@ namespace cereal typename std::enable_if::value, void>::type save( Archive & ar, std::weak_ptr 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::value, void>::type load( Archive & ar, std::weak_ptr & ptr ) { - std::shared_ptr sptr; - ar( sptr ); - ptr = sptr; } //! Saving std::unique_ptr for polymorphic types @@ -132,26 +84,13 @@ namespace cereal typename std::enable_if::value, void>::type save( Archive & ar, std::unique_ptr const & ptr ) { - ar( *ptr ); } //! Loading std::unique_ptr, case when user provides load_and_allocate for polymorphic types template inline - typename std::enable_if::value - && traits::has_load_and_allocate(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, std::unique_ptr & ptr ) { - ptr.reset( detail::Load::load_andor_allocate( ar ) ); - } - - //! Loading std::unique_ptr, case when no load_and_allocate for polymorphic types - template inline - typename std::enable_if::value - && !traits::has_load_and_allocate(), void>::type - load( Archive & ar, std::unique_ptr & ptr ) - { - ptr.reset( detail::Load::load_andor_allocate( ar ) ); - ar( *ptr ); } } // namespace cereal #endif // CEREAL_TYPES_POLYMORPHIC_HPP_ diff --git a/sandbox_rtti.cpp b/sandbox_rtti.cpp index 290bd407..5525d8bd 100644 --- a/sandbox_rtti.cpp +++ b/sandbox_rtti.cpp @@ -37,6 +37,10 @@ template void nop(T&&t) {} int main() { - cereal::detail::StaticObject>::getInstance().map[std::type_index(typeid(MyType))](0, 0); - //cereal::Singleton>::getInstance(); + + cereal::detail::StaticObject< + cereal::detail::BindingMap + >::getInstance().map[std::type_index(typeid(MyType))](0, 0); + + }