diff --git a/examples/checkpoint_example_to_file_nonintrusive.cc b/examples/checkpoint_example_to_file_nonintrusive.cc index e369b5be..b3a99869 100644 --- a/examples/checkpoint_example_to_file_nonintrusive.cc +++ b/examples/checkpoint_example_to_file_nonintrusive.cc @@ -140,18 +140,19 @@ int main(int, char**) { // Call the serialization routine for the variable `my_test_inst` // The output is a unique pointer: `std::unique_ptr` // (defined in `src/checkpoint_api.h`) - magistrate::serializeToFile(my_test_inst, "hello.txt"); + std::string my_filename = "CheckpointExampleToFileNoninstrusive.txt"; + magistrate::serializeToFile(my_test_inst, my_filename); // // De-serializes from the file an object of type 'MyTestType' // out will be an object of type 'std::unique_ptr' // - auto out = magistrate::deserializeFromFile("hello.txt"); + auto out = magistrate::deserializeFromFile(my_filename); if (my_test_inst == *out) { std::cout << " Serialization / Deserialization from file worked. \n"; } else { - std::cout << " Serialization / Deserialization from file failed. \n"; + std::cout << " Serialization / Deserialization from file failed. \n" << std::flush; assert(false); } @@ -164,7 +165,7 @@ int main(int, char**) { // Here 'out_2' will contain an empty vector and an integer 'len_' set to 0. // - magistrate::deserializeInPlaceFromFile("hello.txt", &out_2); + magistrate::deserializeInPlaceFromFile(my_filename, &out_2); // // Now 'out_2' will contain: @@ -175,7 +176,7 @@ int main(int, char**) { if (my_test_inst == out_2) { std::cout << " Deserialization in-place from file worked. \n"; } else { - std::cout << " Deserialization in-place from file failed. \n"; + std::cout << " Deserialization in-place from file failed. \n" << std::flush; assert(false); } diff --git a/examples/checkpoint_example_user_traits.cc b/examples/checkpoint_example_user_traits.cc index bf2ef9b2..bf1d7053 100644 --- a/examples/checkpoint_example_user_traits.cc +++ b/examples/checkpoint_example_user_traits.cc @@ -49,12 +49,12 @@ int main(int, char**){ //Each invocation will be handled based on the traits attached auto s_info_a = checkpoint::serialize(obj); - auto s_info_b = checkpoint::serialize(obj); - auto s_info_c = checkpoint::serialize(obj); - auto s_info_d = checkpoint::serialize(obj); - auto s_info_e = checkpoint::serialize(obj); - auto s_info_f = checkpoint::serialize(obj); - auto s_info_g = checkpoint::serialize(obj); - auto s_info_h = checkpoint::serialize(obj); - auto s_info_i = checkpoint::serialize(obj); + auto s_info_b = checkpoint::serialize(obj); + auto s_info_c = checkpoint::serialize(obj); + auto s_info_d = checkpoint::serialize(obj); + auto s_info_e = checkpoint::serialize(obj); + auto s_info_f = checkpoint::serialize(obj); + auto s_info_g = checkpoint::serialize(obj); + auto s_info_h = checkpoint::serialize(obj); + auto s_info_i = checkpoint::serialize(obj); } diff --git a/src/checkpoint/checkpoint_api.h b/src/checkpoint/checkpoint_api.h index 83162753..2dbb50cf 100644 --- a/src/checkpoint/checkpoint_api.h +++ b/src/checkpoint/checkpoint_api.h @@ -78,7 +78,7 @@ using SerializedReturnType = std::unique_ptr; * \return a \c std::unique_ptr to a \c SerializedInfo containing the buffer * with serialized data and the size of the buffer */ -template +template SerializedReturnType serialize(T& target, BufferCallbackType fn = nullptr); /** @@ -132,7 +132,7 @@ std::unique_ptr deserialize(char* buf); * \param[in] t a valid pointer to a \c T that has been user-allocated and * constructed */ -template +template void deserializeInPlace(char* buf, T* t); /** @@ -153,7 +153,7 @@ std::unique_ptr deserialize(SerializedReturnType&& in); * * \return number of bytes for the \c target */ -template +template std::size_t getSize(T& target); /** @@ -170,7 +170,7 @@ std::size_t getSize(T& target); * * \return memory footprint of the \c target */ -template +template std::size_t getMemoryFootprint(T& target, std::size_t size_offset = 0); /** @@ -184,7 +184,7 @@ std::size_t getMemoryFootprint(T& target, std::size_t size_offset = 0); * \param[in] target the \c T to serialize * \param[in] file name of the file to create */ -template +template void serializeToFile(T& target, std::string const& file); /** @@ -214,7 +214,7 @@ std::unique_ptr deserializeFromFile(std::string const& file); * \param[in] file the filename to read with bytes for \c T * \param[in] t a valid, constructed \c T to deserialize into */ -template +template void deserializeInPlaceFromFile(std::string const& file, T* buf); /** @@ -227,7 +227,7 @@ void deserializeInPlaceFromFile(std::string const& file, T* buf); * \param[in] target the \c T to serialize * \param[in] stream to serialize into, with tellp and write functions. */ -template +template void serializeToStream(T& target, StreamT& stream); /** @@ -243,7 +243,7 @@ void serializeToStream(T& target, StreamT& stream); * * \return unique pointer to the new object \c T */ -template +template std::unique_ptr deserializeFromStream(StreamT& stream); /** @@ -257,7 +257,7 @@ std::unique_ptr deserializeFromStream(StreamT& stream); * \param[in] stream the stream to read with bytes for \c T, with tellg and read functions * \param[in] t a valid, constructed \c T to deserialize into */ -template +template void deserializeInPlaceFromStream(StreamT& stream, T* buf); diff --git a/src/checkpoint/checkpoint_api.impl.h b/src/checkpoint/checkpoint_api.impl.h index e78c92a6..f04f4bff 100644 --- a/src/checkpoint/checkpoint_api.impl.h +++ b/src/checkpoint/checkpoint_api.impl.h @@ -53,9 +53,9 @@ namespace checkpoint { -template +template SerializedReturnType serialize(T& target, BufferCallbackType fn) { - auto ret = dispatch::serializeType(target, fn); + auto ret = dispatch::serializeType>(target, fn); auto& buf = std::get<0>(ret); std::unique_ptr base_ptr( static_cast(buf.release()) @@ -65,43 +65,43 @@ SerializedReturnType serialize(T& target, BufferCallbackType fn) { template T* deserialize(char* buf, char* object_buf) { - return dispatch::deserializeType(buf, object_buf); + return dispatch::deserializeType>(buf, object_buf); } template std::unique_ptr deserialize(char* buf) { - auto t = dispatch::deserializeType(buf); + auto t = dispatch::deserializeType>(buf); return std::unique_ptr(t); } template std::unique_ptr deserialize(SerializedReturnType&& in) { - auto t = dispatch::deserializeType(in->getBuffer()); + auto t = dispatch::deserializeType>(in->getBuffer()); return std::unique_ptr(t); } -template +template void deserializeInPlace(char* buf, T* t) { - return dispatch::deserializeType(dispatch::InPlaceTag{}, buf, t); + return dispatch::deserializeType>(dispatch::InPlaceTag{}, buf, t); } -template +template std::size_t getSize(T& target) { - return dispatch::Standard::size>(target); + return dispatch::Standard::size>(target); } -template +template std::size_t getMemoryFootprint(T& target, std::size_t size_offset) { return size_offset + std::max( - dispatch::Standard::footprint>(target), + dispatch::Standard::footprint>(target), sizeof(target) ); } -template +template void serializeToFile(T& target, std::string const& file) { auto len = getSize(target); - dispatch::Standard::pack, Traits...>>( + dispatch::Standard::pack, UserTraitHolder>( target, len, buffer::IOBuffer::WriteToFileTag{}, len, file ); } @@ -110,23 +110,23 @@ template std::unique_ptr deserializeFromFile(std::string const& file) { auto mem = dispatch::Standard::allocate(); T* t_buf = dispatch::Standard::construct(mem); - auto t = dispatch::Standard::unpack, Traits...>>( + auto t = dispatch::Standard::unpack, UserTraitHolder>( t_buf, buffer::IOBuffer::ReadFromFileTag{}, file ); return std::unique_ptr(t); } -template +template void deserializeInPlaceFromFile(std::string const& file, T* t) { - dispatch::Standard::unpack, Traits...>>( + dispatch::Standard::unpack, UserTraitHolder>( t, buffer::IOBuffer::ReadFromFileTag{}, file ); } -template +template void serializeToStream(T& target, StreamT& stream) { auto len = getSize(target); - dispatch::Standard::pack, Traits...>>( + dispatch::Standard::pack, UserTraitHolder>( target, len, stream ); } @@ -135,15 +135,15 @@ template std::unique_ptr deserializeFromStream(StreamT& stream) { auto mem = dispatch::Standard::allocate(); T* t_buf = dispatch::Standard::construct(mem); - auto t = dispatch::Standard::unpack, Traits...>>( + auto t = dispatch::Standard::unpack, UserTraitHolder>( t_buf, stream ); return std::unique_ptr(t); } -template +template void deserializeInPlaceFromStream(StreamT& stream, T* t) { - dispatch::Standard::unpack, Traits...>>( + dispatch::Standard::unpack, UserTraitHolder>( t, stream ); } diff --git a/src/checkpoint/container/atomic_serialize.h b/src/checkpoint/container/atomic_serialize.h index f0783453..e1bc80e3 100644 --- a/src/checkpoint/container/atomic_serialize.h +++ b/src/checkpoint/container/atomic_serialize.h @@ -54,7 +54,7 @@ template < typename SerializerT, typename T, typename = std::enable_if_t< - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > void serialize(SerializerT& s, const std::atomic& atomic) { diff --git a/src/checkpoint/container/function_serialize.h b/src/checkpoint/container/function_serialize.h index 4ab98f3e..6a192fee 100644 --- a/src/checkpoint/container/function_serialize.h +++ b/src/checkpoint/container/function_serialize.h @@ -68,9 +68,7 @@ template < typename Res, typename... ArgTypes, typename = std::enable_if_t< - checkpoint::is_footprinter< - SerializerT - >::value + checkpoint::is_footprinter_v > > void serializeFunction(SerializerT& s, std::function& fn) { diff --git a/src/checkpoint/container/kokkos_unordered_map_serialize.h b/src/checkpoint/container/kokkos_unordered_map_serialize.h index d07b0e6f..81183452 100644 --- a/src/checkpoint/container/kokkos_unordered_map_serialize.h +++ b/src/checkpoint/container/kokkos_unordered_map_serialize.h @@ -117,7 +117,7 @@ template < typename Hasher, typename EqualTo > typename std::enable_if_t< - not checkpoint::is_footprinter::value, void + not checkpoint::is_footprinter_v, void > serialize( SerializerT& s, Kokkos::UnorderedMap& map @@ -140,7 +140,7 @@ template < typename Hasher, typename EqualTo > typename std::enable_if_t< - checkpoint::is_footprinter::value, void + checkpoint::is_footprinter_v, void > serialize( SerializerT& s, Kokkos::UnorderedMap& map diff --git a/src/checkpoint/container/list_serialize.h b/src/checkpoint/container/list_serialize.h index 72f6d1b8..262a08d5 100644 --- a/src/checkpoint/container/list_serialize.h +++ b/src/checkpoint/container/list_serialize.h @@ -56,7 +56,7 @@ namespace checkpoint { template inline typename std::enable_if_t< - not checkpoint::is_footprinter::value, void + not checkpoint::is_footprinter_v, void > deserializeOrderedElems( Serializer& s, ContainerT& cont, typename ContainerT::size_type size, @@ -76,7 +76,7 @@ deserializeOrderedElems( template inline typename std::enable_if_t< - not checkpoint::is_footprinter::value, void + not checkpoint::is_footprinter_v, void > deserializeOrderedElems( Serializer& s, ContainerT& cont, typename ContainerT::size_type size, @@ -96,7 +96,7 @@ deserializeOrderedElems( template inline typename std::enable_if_t< - checkpoint::is_footprinter::value, void + checkpoint::is_footprinter_v, void > deserializeOrderedElems( Serializer&, ContainerT&, typename ContainerT::size_type diff --git a/src/checkpoint/container/map_serialize.h b/src/checkpoint/container/map_serialize.h index 39e1b6b8..a1a2a880 100644 --- a/src/checkpoint/container/map_serialize.h +++ b/src/checkpoint/container/map_serialize.h @@ -58,7 +58,7 @@ namespace checkpoint { template inline typename std::enable_if_t< - not checkpoint::is_footprinter::value, + not checkpoint::is_footprinter_v, void > deserializeEmplaceElems( Serializer& s, ContainerT& cont, typename ContainerT::size_type size @@ -77,7 +77,7 @@ inline typename std::enable_if_t< template inline typename std::enable_if_t< - checkpoint::is_footprinter::value, + checkpoint::is_footprinter_v, void > deserializeEmplaceElems( Serializer&, ContainerT&, typename ContainerT::size_type diff --git a/src/checkpoint/container/queue_serialize.h b/src/checkpoint/container/queue_serialize.h index 8da15f1c..485fbccc 100644 --- a/src/checkpoint/container/queue_serialize.h +++ b/src/checkpoint/container/queue_serialize.h @@ -108,7 +108,7 @@ template < typename SerializerT, typename Q, typename = std::enable_if_t< - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > void serializeQueueLikeContainer(SerializerT& s, const Q& q) { diff --git a/src/checkpoint/container/raw_ptr_serialize.h b/src/checkpoint/container/raw_ptr_serialize.h index cb1df132..30814ad9 100644 --- a/src/checkpoint/container/raw_ptr_serialize.h +++ b/src/checkpoint/container/raw_ptr_serialize.h @@ -61,7 +61,7 @@ template < typename SerializerT, typename T, typename = std::enable_if_t< - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > void serialize(SerializerT& s, T* ptr) { @@ -92,7 +92,7 @@ void serializeRawPtr(SerializerT& s, void* ptr) { #define CHECKPOINT_FOOTPRINT_PIMPL_WITH_SIZEOF_PTR(PIMPL_TYPE) \ template < \ typename SerializerT, \ - typename = std::enable_if_t< checkpoint::is_footprinter::value > \ + typename = std::enable_if_t< checkpoint::is_footprinter_v > \ > \ void serialize(SerializerT &s, PIMPL_TYPE *t) { \ s.countBytes(t); \ diff --git a/src/checkpoint/container/shared_ptr_serialize.h b/src/checkpoint/container/shared_ptr_serialize.h index f880aef0..db854b52 100644 --- a/src/checkpoint/container/shared_ptr_serialize.h +++ b/src/checkpoint/container/shared_ptr_serialize.h @@ -52,7 +52,7 @@ template < typename SerializerT, typename T, typename = std::enable_if_t< - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > void serialize(SerializerT& s, std::shared_ptr& ptr) { diff --git a/src/checkpoint/container/thread_serialize.h b/src/checkpoint/container/thread_serialize.h index d755ce39..d2596a18 100644 --- a/src/checkpoint/container/thread_serialize.h +++ b/src/checkpoint/container/thread_serialize.h @@ -53,7 +53,7 @@ namespace checkpoint { template < typename SerializerT, typename = std::enable_if_t< - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > void serialize(SerializerT& s, const std::thread& t) { diff --git a/src/checkpoint/container/vector_serialize.h b/src/checkpoint/container/vector_serialize.h index ede47ad0..ed4478c6 100644 --- a/src/checkpoint/container/vector_serialize.h +++ b/src/checkpoint/container/vector_serialize.h @@ -56,7 +56,7 @@ namespace checkpoint { template typename std::enable_if_t< - not checkpoint::is_footprinter::value, SerialSizeType + not checkpoint::is_footprinter_v, SerialSizeType > serializeVectorMeta(SerializerT& s, std::vector& vec) { SerialSizeType vec_capacity = vec.capacity(); @@ -108,7 +108,7 @@ void constructVectorData( template typename std::enable_if_t< - not checkpoint::is_footprinter::value, void + not checkpoint::is_footprinter_v, void > serialize(SerializerT& s, std::vector& vec) { auto const vec_size = serializeVectorMeta(s, vec); @@ -122,7 +122,7 @@ serialize(SerializerT& s, std::vector& vec) { template typename std::enable_if_t< - not checkpoint::is_footprinter::value, void + not checkpoint::is_footprinter_v, void > serialize(SerializerT& s, std::vector& vec) { auto const vec_size = serializeVectorMeta(s, vec); @@ -146,7 +146,7 @@ serialize(SerializerT& s, std::vector& vec) { template typename std::enable_if_t< - checkpoint::is_footprinter::value, void + checkpoint::is_footprinter_v, void > serialize(SerializerT& s, std::vector& vec) { s.countBytes(vec); @@ -156,7 +156,7 @@ serialize(SerializerT& s, std::vector& vec) { template typename std::enable_if_t< - checkpoint::is_footprinter::value, void + checkpoint::is_footprinter_v, void > serialize(SerializerT& s, std::vector& vec) { s.countBytes(vec); diff --git a/src/checkpoint/dispatch/dispatch.h b/src/checkpoint/dispatch/dispatch.h index 08e613b8..b5cefcaf 100644 --- a/src/checkpoint/dispatch/dispatch.h +++ b/src/checkpoint/dispatch/dispatch.h @@ -98,7 +98,7 @@ struct Traverse { * * \return the constructed traverser after traversal is complete */ - template + template , typename... Args> static TraverserT with(T& target, Args&&... args); /** @@ -131,7 +131,7 @@ struct Standard { * * \return the number of bytes */ - template + template static SerialSizeType size(T& target, Args&&... args); /** @@ -142,20 +142,19 @@ struct Standard { * * \return memory footprint of \c T */ - template + template static SerialSizeType footprint(T& target, Args&&... args); /** * \brief Pack \c target that requires \c size number of bytes. * * \param[in] target the target to pack - * \param[in] size the number of bytes for \c target * \param[in] args arguments to the packer's constructor * * \return the packer after packing */ - template - static PackerT pack(T& target, SerialSizeType const& size, Args&&... args); + template + static PackerT pack(T& target, Args&&... args); /** * \brief Unpack \c T from packed byte-buffer \c mem @@ -166,7 +165,7 @@ struct Standard { * * \return a pointer to an unpacked \c T */ - template + template static T* unpack(T* mem, Args&&... args); /** @@ -188,7 +187,7 @@ struct Standard { static SerialByteType* allocate(); }; -template +template buffer::ImplReturnType packBuffer( T& target, SerialSizeType size, BufferObtainFnType fn ); @@ -196,13 +195,13 @@ buffer::ImplReturnType packBuffer( template inline void serializeArray(Serializer& s, T* array, SerialSizeType const len); -template +template buffer::ImplReturnType serializeType(T& target, BufferObtainFnType fn = nullptr); -template +template T* deserializeType(SerialByteType* data, SerialByteType* allocBuf = nullptr); -template +template void deserializeType(InPlaceTag, SerialByteType* data, T* t); template diff --git a/src/checkpoint/dispatch/dispatch.impl.h b/src/checkpoint/dispatch/dispatch.impl.h index 451938c2..568848cb 100644 --- a/src/checkpoint/dispatch/dispatch.impl.h +++ b/src/checkpoint/dispatch/dispatch.impl.h @@ -50,6 +50,7 @@ #include #include +#include namespace checkpoint { @@ -166,13 +167,22 @@ TraverserT& Traverse::with(T& target, TraverserT& t, SerialSizeType len) { return t; } -template +template TraverserT Traverse::with(T& target, Args&&... args) { #if !defined(SERIALIZATION_ERROR_CHECKING) using CleanT = typename CleanType::CleanT; #endif - - TraverserT t(std::forward(args)...); + + TraverserT t_base(std::forward(args)...); + auto t = SerializerRef(&t_base, Traits{}); + + //std::optional t_opt; + //if constexpr(is_serializer_ref) { + // t_opt.emplace(std::in_place, std::forward(args)...); + //} else { + // t_opt.emplace(std::forward(args)...); + //} + //TraverserT& t = t_opt.value(); #if !defined(SERIALIZATION_ERROR_CHECKING) withTypeIdx(t); @@ -184,7 +194,7 @@ TraverserT Traverse::with(T& target, Args&&... args) { withMemUsed(t, 1); #endif - return t; + return t_base; } template @@ -192,22 +202,22 @@ T* Traverse::reconstruct(SerialByteType* mem) { return Reconstructor::CleanT>::construct(mem); } -template +template SerialSizeType Standard::size(T& target, Args&&... args) { - auto sizer = Traverse::with(target, std::forward(args)...); - return sizer->getSize(); + auto sizer = Traverse::with(target, std::forward(args)...); + return sizer.getSize(); } -template +template SerialSizeType Standard::footprint(T& target, Args&&... args) { auto footprinter = - Traverse::with(target, std::forward(args)...); - return footprinter->getMemoryFootprint(); + Traverse::with(target, std::forward(args)...); + return footprinter.getMemoryFootprint(); } -template -PackerT Standard::pack(T& target, SerialSizeType const& size, Args&&... args) { - return Traverse::with(target, size, std::forward(args)...); +template +PackerT Standard::pack(T& target, Args&&... args) { + return Traverse::with(target, std::forward(args)...); } template @@ -215,9 +225,9 @@ SerialByteType* Standard::allocate() { return reinterpret_cast(std::allocator{}.allocate(1)); } -template +template T* Standard::unpack(T* t_buf, Args&&... args) { - Traverse::with(*t_buf, std::forward(args)...); + Traverse::with(*t_buf, std::forward(args)...); return t_buf; } @@ -247,44 +257,44 @@ validatePackerBufferSize(PackerT const& p, SerialSizeType bufferSize) { } } -template +template buffer::ImplReturnType packBuffer(T& target, SerialSizeType size, BufferObtainFnType fn) { SerialByteType* user_buf = fn ? fn(size) : nullptr; if (user_buf == nullptr) { auto p = - Standard::pack, UserTraits...>>(target, size); + Standard::pack, UserTraits>(target, size); validatePackerBufferSize(p, size); - return std::make_tuple(std::move(p->extractPackedBuffer()), size); + return std::make_tuple(std::move(p.extractPackedBuffer()), size); } else { - auto p = Standard::pack, UserTraits...>>( + auto p = Standard::pack, UserTraits>( target, size, std::make_unique(user_buf, size) ); validatePackerBufferSize(p, size); - return std::make_tuple(std::move(p->extractPackedBuffer()), size); + return std::make_tuple(std::move(p.extractPackedBuffer()), size); } } -template +template buffer::ImplReturnType serializeType(T& target, BufferObtainFnType fn) { - auto len = Standard::size>(target); + auto len = Standard::size(target); debug_checkpoint("serializeType: len=%ld\n", len); - return packBuffer(target, len, fn); + return packBuffer(target, len, fn); } -template +template T* deserializeType(SerialByteType* data, SerialByteType* allocBuf) { auto mem = allocBuf ? allocBuf : Standard::allocate(); auto t_buf = std::unique_ptr(Standard::construct(mem)); T* traverser = - Standard::unpack, UserTraits...>>(t_buf.get(), data); + Standard::unpack, UserTraits>(t_buf.get(), data); t_buf.release(); return traverser; } -template +template void deserializeType(InPlaceTag, SerialByteType* data, T* t) { - Standard::unpack, UserTraits...>>(t, data); + Standard::unpack, UserTraits>(t, data); } }} /* end namespace checkpoint::dispatch */ diff --git a/src/checkpoint/dispatch/dispatch_serializer_nonbyte.h b/src/checkpoint/dispatch/dispatch_serializer_nonbyte.h index 9bc2fd9a..cae6b4f1 100644 --- a/src/checkpoint/dispatch/dispatch_serializer_nonbyte.h +++ b/src/checkpoint/dispatch/dispatch_serializer_nonbyte.h @@ -112,7 +112,7 @@ struct SerializerDispatchNonByte { template using justFootprint = typename std::enable_if< - checkpoint::is_footprinter::value and + checkpoint::is_footprinter_v and not SerializableTraits::is_traversable and not std::is_enum::value, T diff --git a/src/checkpoint/dispatch/vrt/virtual_serialize.h b/src/checkpoint/dispatch/vrt/virtual_serialize.h index 5196d4c5..99f8c81f 100644 --- a/src/checkpoint/dispatch/vrt/virtual_serialize.h +++ b/src/checkpoint/dispatch/vrt/virtual_serialize.h @@ -59,18 +59,13 @@ namespace checkpoint { namespace dispatch { namespace vrt { */ template void virtualSerialize(T*& base, SerializerT& s) { + //We can't support traited serializing with virtual types. + static_assert(std::is_same_v, "User Traits are incompatible with virtual serialization"); + // Get the real base in case this is called on a derived type using BaseT = ::checkpoint::dispatch::vrt::checkpoint_base_type_t; auto serializer_idx = serializer_registry::makeObjIdx(); - if constexpr (not std::is_same_v){ - static bool warned_once = false; - if(!warned_once){ - fprintf(stderr, "Warning: Magistrate cannot support UserTraits being visible to virtually serialized objects.\n"); - warned_once = true; - } - } - base->_checkpointDynamicSerialize(&s, serializer_idx, no_type_idx); } @@ -155,7 +150,7 @@ struct ReconstructAsVirtualIfNeeded< SerializerT, typename std::enable_if_t< dispatch::vrt::VirtualSerializeTraits::has_not_virtual_serialize and - not checkpoint::is_footprinter::value + not checkpoint::is_footprinter_v > > { static T* apply(SerializerT&, dispatch::vrt::TypeIdx) { @@ -171,7 +166,7 @@ struct ReconstructAsVirtualIfNeeded< SerializerT, typename std::enable_if_t< dispatch::vrt::VirtualSerializeTraits::has_not_virtual_serialize and - checkpoint::is_footprinter::value + checkpoint::is_footprinter_v > > { static T* apply(SerializerT&, dispatch::vrt::TypeIdx) { return nullptr; } diff --git a/src/checkpoint/serializers/footprinter.h b/src/checkpoint/serializers/footprinter.h index dbd027b7..7d38d44b 100644 --- a/src/checkpoint/serializers/footprinter.h +++ b/src/checkpoint/serializers/footprinter.h @@ -76,8 +76,8 @@ namespace { template struct is_footprinter_impl : public std::false_type {}; - template - struct is_footprinter_impl> : std::true_type {}; + template + struct is_footprinter_impl> : std::true_type {}; template <> struct is_footprinter_impl : std::true_type {}; @@ -86,6 +86,9 @@ namespace { template using is_footprinter = is_footprinter_impl>; +template +static constexpr const bool is_footprinter_v = is_footprinter::value; + } /* end namespace checkpoint */ #endif /*INCLUDED_SRC_CHECKPOINT_SERIALIZERS_FOOTPRINTER_H*/ diff --git a/src/checkpoint/serializers/reference.h b/src/checkpoint/serializers/serializer_ref.h similarity index 81% rename from src/checkpoint/serializers/reference.h rename to src/checkpoint/serializers/serializer_ref.h index 7e402c62..9afbb6c2 100644 --- a/src/checkpoint/serializers/reference.h +++ b/src/checkpoint/serializers/serializer_ref.h @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// reference.h +// serializer_ref.h // DARMA/checkpoint => Serialization Library // // Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC @@ -41,8 +41,8 @@ //@HEADER */ -#if !defined INCLUDED_CHECKPOINT_SERIALIZERS_REFERENCE_H -#define INCLUDED_CHECKPOINT_SERIALIZERS_REFERENCE_H +#if !defined INCLUDED_CHECKPOINT_SERIALIZERS_SERIALIZER_REF_H +#define INCLUDED_CHECKPOINT_SERIALIZERS_SERIALIZER_REF_H #include "checkpoint/common.h" #include "checkpoint/serializers/base_serializer.h" @@ -54,29 +54,22 @@ namespace checkpoint { -namespace { - template - struct first_type_matches : public std::false_type {}; - template - struct first_type_matches : public std::true_type {}; -} - -template +template> struct SerializerRef { - using TraitHolder = typename UserTraitHolder::BaseTraits; + using TraitHolder = typename UserTraits::BaseTraits; //Passing initialization to the serializer implementation - template - explicit SerializerRef(Args&&... args) - { - if constexpr(first_type_matches, std::decay_t...>::value and sizeof...(Args) == 1) { - //If only 1 arg which is a shared pointer to the base serializer, use that instead of initializing a new serializer. - impl = {std::forward(args)...}; - } else { - impl = std::make_shared(std::forward(args)...); - } - } + explicit SerializerRef(SerT* m_impl, const UserTraits& = {}) : + impl(m_impl) + { } + + //Copy constructor, possibly changing the traits + template + explicit SerializerRef( + const SerializerRef& other + ) : impl(other.impl) + { } //Now forward along Serializer function calls and types using ModeType = eSerializationMode; @@ -109,11 +102,11 @@ struct SerializerRef - SerT* operator->(){ return impl.get(); } + SerT* operator->(){ return impl; } - template - operator SerializerRef() const { - return SerializerRef(impl); + template + operator SerializerRef() const { + return SerializerRef(*this); } @@ -154,25 +147,31 @@ struct SerializerRef template auto withTraits(UserTraitHolder = {}){ using NewTraitHolder = typename TraitHolder::template with; - return setTraits(NewTraitHolder()); + //return setTraits(NewTraitHolder {}); + return SerializerRef(*this); } //Returns a new reference with traits removed (if present) from this reference's traits. template auto withoutTraits(UserTraitHolder = {}){ using NewTraitHolder = typename TraitHolder::template without; - return setTraits(NewTraitHolder()); + return SerializerRef(*this); } //Returns a new reference with traits set to the inputs, regardless of this reference's traits. template - SerializerRef setTraits(UserTraitHolder = {}){ - return *this; + SerializerRef> setTraits( + const UserTraitHolder& = {} + ){ + return SerializerRef>(*this); } -private: - std::shared_ptr impl; +protected: + SerT *const impl; + + template + friend struct SerializerRef; }; } -#endif /*INCLUDED_CHECKPOINT_SERIALIZERS_REFERENCE_H*/ +#endif /*INCLUDED_CHECKPOINT_SERIALIZERS_SERIALIZER_REF_H*/ diff --git a/src/checkpoint/serializers/serializers_headers.h b/src/checkpoint/serializers/serializers_headers.h index d7b5c44a..e9b4c674 100644 --- a/src/checkpoint/serializers/serializers_headers.h +++ b/src/checkpoint/serializers/serializers_headers.h @@ -46,7 +46,7 @@ #include "checkpoint/common.h" #include "checkpoint/serializers/base_serializer.h" -#include "checkpoint/serializers/reference.h" +#include "checkpoint/serializers/serializer_ref.h" #include "checkpoint/serializers/footprinter.h" #include "checkpoint/serializers/sizer.h" #include "checkpoint/serializers/packer.h"