diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp index 2ed2fdbc..cb27c957 100644 --- a/include/cereal/types/memory.hpp +++ b/include/cereal/types/memory.hpp @@ -54,6 +54,23 @@ namespace cereal { return {std::forward(t)}; } + + //! A struct that acts as a wrapper around calling load_andor_allocate + /*! The purpose of this is to allow a load_and_allocate call to properly enter into the + 'data' NVP of the ptr_wrapper + @internal */ + template + struct LoadAndAllocateLoadWrapper + { + LoadAndAllocateLoadWrapper() = default; + + inline void serialize( Archive & ar ) + { + ptr = ::cereal::detail::Load::load_andor_allocate( ar ); + } + + T * ptr; + }; } //! Saving std::shared_ptr for non polymorphic types @@ -140,8 +157,10 @@ namespace cereal if( id & detail::msb_32bit ) { - ptr.reset( detail::Load::load_andor_allocate( ar ) ); - ar.registerSharedPointer(id, ptr); + // Use wrapper to enter into "data" nvp + memory_detail::LoadAndAllocateLoadWrapper loadWrapper; + ar( loadWrapper ); + ptr.reset( loadWrapper.ptr ); } else { @@ -205,7 +224,12 @@ namespace cereal auto & ptr = wrapper.ptr; if( isValid ) - ptr.reset( detail::Load::load_andor_allocate( ar ) ); + { + // Use wrapper to enter into "data" nvp + memory_detail::LoadAndAllocateLoadWrapper loadWrapper; + ar( loadWrapper ); + ptr.reset( loadWrapper.ptr ); + } else ptr.reset( nullptr ); } diff --git a/unittests.cpp b/unittests.cpp index a6bbe854..3fdaf310 100644 --- a/unittests.cpp +++ b/unittests.cpp @@ -2570,11 +2570,15 @@ void test_chrono() for(int ii=0; ii<100; ++ii) { auto o_timePoint1 = std::chrono::system_clock::now(); + #ifndef CEREAL_OLDER_GCC auto o_timePoint2 = std::chrono::steady_clock::now(); + #endif // CEREAL_OLDER_GCC auto o_timePoint3 = std::chrono::high_resolution_clock::now(); auto o_duration1 = std::chrono::system_clock::now() - o_timePoint1; + #ifndef CEREAL_OLDER_GCC auto o_duration2 = std::chrono::steady_clock::now() - o_timePoint2; + #endif // CEREAL_OLDER_GCC auto o_duration3 = std::chrono::high_resolution_clock::now() - o_timePoint3; std::ostringstream os; @@ -2582,18 +2586,26 @@ void test_chrono() OArchive oar(os); oar(o_timePoint1); + #ifndef CEREAL_OLDER_GCC oar(o_timePoint2); + #endif // CEREAL_OLDER_GCC oar(o_timePoint3); oar(o_duration1); + #ifndef CEREAL_OLDER_GCC oar(o_duration2); + #endif // CEREAL_OLDER_GCC oar(o_duration3); } decltype(o_timePoint1) i_timePoint1; + #ifndef CEREAL_OLDER_GCC decltype(o_timePoint2) i_timePoint2; + #endif // CEREAL_OLDER_GCC decltype(o_timePoint3) i_timePoint3; decltype(o_duration1) i_duration1; + #ifndef CEREAL_OLDER_GCC decltype(o_duration2) i_duration2; + #endif // CEREAL_OLDER_GCC decltype(o_duration3) i_duration3; std::istringstream is(os.str()); @@ -2601,18 +2613,26 @@ void test_chrono() IArchive iar(is); iar(i_timePoint1); + #ifndef CEREAL_OLDER_GCC iar(i_timePoint2); + #endif // CEREAL_OLDER_GCC iar(i_timePoint3); iar(i_duration1); + #ifndef CEREAL_OLDER_GCC iar(i_duration2); + #endif // CEREAL_OLDER_GCC iar(i_duration3); } BOOST_CHECK( o_timePoint1 == i_timePoint1 ); + #ifndef CEREAL_OLDER_GCC BOOST_CHECK( o_timePoint2 == i_timePoint2 ); + #endif // CEREAL_OLDER_GCC BOOST_CHECK( o_timePoint3 == i_timePoint3 ); BOOST_CHECK( o_duration1 == i_duration1 ); + #ifndef CEREAL_OLDER_GCC BOOST_CHECK( o_duration2 == i_duration2 ); + #endif // CEREAL_OLDER_GCC BOOST_CHECK( o_duration3 == i_duration3 ); } }