Skip to content

Commit

Permalink
#161 add vector and list reconstruction for non copyable types
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Strzebonski committed Jul 16, 2021
1 parent de1d276 commit da6c6d7
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 5 deletions.
27 changes: 23 additions & 4 deletions src/checkpoint/container/list_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ namespace checkpoint {

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
not std::is_same<Serializer, checkpoint::Footprinter>::value,
void
> deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size
not std::is_same<Serializer, checkpoint::Footprinter>::value, void>
deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size,
typename ReconstructorTraits<ElmT>::template isCopyConstructible<ElmT>* = nullptr
) {
using Alloc = dispatch::Allocator<ElmT>;
using Reconstructor =
Expand All @@ -73,6 +73,25 @@ inline typename std::enable_if_t<
}
}

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
not std::is_same<Serializer, checkpoint::Footprinter>::value, void>
deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size,
typename ReconstructorTraits<ElmT>::template isNotCopyConstructible<ElmT>* = nullptr
) {
using Alloc = dispatch::Allocator<ElmT>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<ElmT>::CleanT>;

Alloc allocated;
for (typename ContainerT::size_type i = 0; i < size; ++i) {
auto* reconstructed = Reconstructor::construct(allocated.buf);
s | *reconstructed;
cont.emplace_back(std::move(*reconstructed));
}
}

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
std::is_same<Serializer, checkpoint::Footprinter>::value,
Expand Down
20 changes: 19 additions & 1 deletion src/checkpoint/container/vector_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ void constructVectorData(
template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename ReconstructorTraits<T>::template isNotDefaultConsType<T>* = nullptr
typename ReconstructorTraits<T>::template isNotDefaultConsType<T>* = nullptr,
typename ReconstructorTraits<T>::template isCopyConstructible<T>* = nullptr
) {
using Alloc = dispatch::Allocator<T>;
using Reconstructor =
Expand All @@ -99,6 +100,23 @@ void constructVectorData(
vec.resize(vec_size, *reconstructed);
}

template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename ReconstructorTraits<T>::template isNotDefaultConsType<T>* = nullptr,
typename ReconstructorTraits<T>::template isNotCopyConstructible<T>* = nullptr
) {
using Alloc = dispatch::Allocator<T>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<T>::CleanT>;

Alloc allocated;
for (SerialSizeType i = 0; i < vec_size; ++i) {
auto* reconstructed = Reconstructor::construct(allocated.buf);
vec.emplace_back(std::move(*reconstructed));
}
}

template <typename Serializer, typename T, typename VectorAllocator>
void serialize(Serializer& s, std::vector<T, VectorAllocator>& vec) {
auto const vec_size = serializeVectorMeta(s, vec);
Expand Down
8 changes: 8 additions & 0 deletions src/checkpoint/traits/reconstructor_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ struct ReconstructorTraits {
template <typename U>
using isNotConstructible = typename std::enable_if<
not SerializableTraits<U, void>::is_constructible, T>::type;

template <typename U>
using isCopyConstructible =
typename std::enable_if<std::is_copy_constructible<U>::value, T>::type;

template <typename U>
using isNotCopyConstructible =
typename std::enable_if<not std::is_copy_constructible<U>::value, T>::type;
};

} // namespace checkpoint
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/test_vector_serializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,47 @@ TEST_F(VectorTest, test_vector_tagged_ctor) {
}
}

struct NonCopyableReconstruct {
static constexpr int val_ctor = 5;
static constexpr int val_reconstruct = 105;

int i;

NonCopyableReconstruct() = delete;
NonCopyableReconstruct(const NonCopyableReconstruct&) = delete;
NonCopyableReconstruct& operator=(const NonCopyableReconstruct& other);
NonCopyableReconstruct(NonCopyableReconstruct&&) = default;
NonCopyableReconstruct& operator=(NonCopyableReconstruct&& other) = default;

explicit NonCopyableReconstruct(int ii) : i{ii} { }

static NonCopyableReconstruct& reconstruct(void* buf) {
auto b = new (buf) NonCopyableReconstruct{val_reconstruct};
return *b;
}

template <typename Serializer>
void serialize(Serializer& s) {
s | i;
}
};

constexpr int NonCopyableReconstruct::val_ctor;
constexpr int NonCopyableReconstruct::val_reconstruct;

TEST_F(VectorTest, test_vector_non_copyable_reconstruct) {
std::vector<NonCopyableReconstruct> ncrs;
ncrs.reserve(3);
ncrs.emplace_back(NonCopyableReconstruct::val_ctor);
ncrs.emplace_back(NonCopyableReconstruct::val_ctor);
ncrs.emplace_back(NonCopyableReconstruct::val_ctor);
auto ret = serialize<std::vector<NonCopyableReconstruct>>(ncrs);
auto deser =
deserialize<std::vector<NonCopyableReconstruct>>(ret->getBuffer());

for (auto const& tc : *deser) {
EXPECT_EQ(tc.i, NonCopyableReconstruct::val_ctor);
}
}

}}}

0 comments on commit da6c6d7

Please sign in to comment.