Skip to content

Commit

Permalink
#161 extract reconstructor traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Strzebonski authored and jstrzebonski committed Oct 8, 2021
1 parent ac826b7 commit a807d5a
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 65 deletions.
15 changes: 8 additions & 7 deletions src/checkpoint/container/vector_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define INCLUDED_CHECKPOINT_CONTAINER_VECTOR_SERIALIZE_H

#include "checkpoint/common.h"
#include "checkpoint/dispatch/dispatch.h"
#include "checkpoint/dispatch/reconstructor.h"
#include "checkpoint/serializers/serializers_headers.h"

Expand Down Expand Up @@ -78,15 +79,15 @@ serializeVectorMeta(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
template <typename T, typename VectorAllocator>
void constructVectorDataWithResize(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isDefaultConsType<T>* = nullptr
typename ReconstructorTraits<T>::template isDefaultConsType<T>* = nullptr
) {
vec.resize(vec_size);
}

template <typename T, typename VectorAllocator>
void constructVectorDataWithResize(
SerialSizeType const, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isNotDefaultConsType<T>* = nullptr
typename ReconstructorTraits<T>::template isNotDefaultConsType<T>* = nullptr
) {
static_assert(
SerializableTraits<T, void>::is_tagged_constructible or
Expand All @@ -108,7 +109,7 @@ struct Allocated {
template <typename T, typename VectorAllocator>
void constructVectorDataReconstruct(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isReconstructibleType<T>* = nullptr
typename ReconstructorTraits<T>::template isReconstructibleType<T>* = nullptr
) {
Allocated<T> const allocated;
for (SerialSizeType i = 0; i < vec_size; ++i) {
Expand All @@ -120,7 +121,7 @@ void constructVectorDataReconstruct(
template <typename T, typename VectorAllocator>
void constructVectorDataReconstruct(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isNonIntReconstructibleType<T>* = nullptr
typename ReconstructorTraits<T>::template isNonIntReconstructibleType<T>* = nullptr
) {
Allocated<T> const allocated;
for (SerialSizeType i = 0; i < vec_size; ++i) {
Expand All @@ -133,23 +134,23 @@ void constructVectorDataReconstruct(
template <typename T, typename VectorAllocator>
void constructVectorDataReconstruct(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isNotReconstructibleType<T>* = nullptr
typename ReconstructorTraits<T>::template isNotReconstructibleType<T>* = nullptr
) {
constructVectorDataWithResize(vec_size, vec);
}

template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isTaggedConstructibleType<T>* = nullptr
typename ReconstructorTraits<T>::template isTaggedConstructibleType<T>* = nullptr
) {
vec.resize(vec_size, T{SERIALIZE_CONSTRUCT_TAG{}});
}

template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
typename dispatch::Reconstructor<T>::template isNotTaggedConstructibleType<T>* = nullptr
typename ReconstructorTraits<T>::template isNotTaggedConstructibleType<T>* = nullptr
) {
constructVectorDataReconstruct(vec_size, vec);
}
Expand Down
105 changes: 47 additions & 58 deletions src/checkpoint/dispatch/reconstructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,72 +45,39 @@
#define INCLUDED_CHECKPOINT_DISPATCH_RECONSTRUCTOR_H

#include "checkpoint/common.h"
#include "checkpoint/traits/serializable_traits.h"
#include "checkpoint/traits/reconstructor_traits.h"
#include "checkpoint/dispatch/reconstructor_tag.h"

#include <type_traits>
#include <tuple>
#include <cstdlib>

namespace checkpoint { namespace dispatch {

template <typename T>
struct Reconstructor {
template <typename U>
using isDefaultConsType =
typename std::enable_if<std::is_default_constructible<U>::value, T>::type;

template <typename U>
using isNotDefaultConsType =
typename std::enable_if<not std::is_default_constructible<U>::value, T>::type;

template <typename U>
using isReconstructibleType =
typename std::enable_if<
SerializableTraits<U,void>::is_intrusive_reconstructible, T
>::type;

template <typename U>
using isNonIntReconstructibleType =
typename std::enable_if<
SerializableTraits<U,void>::is_nonintrusive_reconstructible, T
>::type;

template <typename U>
using isNotReconstructibleType =
typename std::enable_if<not SerializableTraits<U,void>::is_reconstructible, T>::type;

template <typename U>
using isTaggedConstructibleType =
typename std::enable_if<SerializableTraits<U,void>::is_tagged_constructible, T>::type;

template <typename U>
using isNotTaggedConstructibleType =
typename std::enable_if<not SerializableTraits<U,void>::is_tagged_constructible, T>::type;

template <typename U>
using isConstructible =
typename std::enable_if<SerializableTraits<U,void>::is_constructible, T>::type;

template <typename U>
using isNotConstructible =
typename std::enable_if<not SerializableTraits<U,void>::is_constructible, T>::type;

// Default-construct as lowest priority in reconstruction preference
template <typename U = T>
static T* constructDefault(void* buf, isDefaultConsType<U>* = nullptr) {
debug_checkpoint("DeserializerDispatch: default constructor: buf=%p\n", buf);
static T* constructDefault(
void* buf,
typename ReconstructorTraits<T>::template isDefaultConsType<U>* = nullptr
) {
debug_checkpoint(
"DeserializerDispatch: default constructor: buf=%p\n", buf
);
T* t_ptr = new (buf) T{};
return t_ptr;
}

// Fail, no valid option to constructing T
template <typename U = T>
static T* constructDefault(void* buf, isNotDefaultConsType<U>* = nullptr) {
static T* constructDefault(
void* buf,
typename ReconstructorTraits<T>::template isNotDefaultConsType<U>* = nullptr
) {
static_assert(
SerializableTraits<U,void>::is_tagged_constructible or
SerializableTraits<U,void>::is_reconstructible or
std::is_default_constructible<U>::value,
SerializableTraits<U, void>::is_tagged_constructible or
SerializableTraits<U, void>::is_reconstructible or
std::is_default_constructible<U>::value,
"Either a default constructor, reconstruct() function, or tagged "
"constructor are required for de-serialization"
);
Expand All @@ -129,39 +96,56 @@ struct Reconstructor {

// Intrusive reconstruct
template <typename U = T>
static T* constructReconstruct(void* buf, isReconstructibleType<U>* = nullptr) {
static T* constructReconstruct(
void* buf,
typename ReconstructorTraits<T>::template isReconstructibleType<U>* = nullptr
) {
debug_checkpoint("DeserializerDispatch: T::reconstruct(): buf=%p\n", buf);
auto& t = T::reconstruct(buf);
return &t;
}

// Non-intrusive reconstruct
template <typename U = T>
static T* constructReconstruct(void* buf, isNonIntReconstructibleType<U>* = nullptr) {
debug_checkpoint("DeserializerDispatch: non-int reconstruct(): buf=%p\n", buf);
static T* constructReconstruct(
void* buf,
typename ReconstructorTraits<T>::template isNonIntReconstructibleType<U>* = nullptr
) {
debug_checkpoint(
"DeserializerDispatch: non-int reconstruct(): buf=%p\n", buf
);
T* t = nullptr;
// Explicitly call bare to invoke ADL
reconstruct(t,buf);
reconstruct(t, buf);
return t;
}

/// Non-reconstruct pass-through
template <typename U = T>
static T* constructReconstruct(void* buf, isNotReconstructibleType<U>* = nullptr) {
static T* constructReconstruct(
void* buf,
typename ReconstructorTraits<T>::template isNotReconstructibleType<U>* = nullptr
) {
return constructDefault<U>(buf);
}

/// Tagged constructor
template <typename U = T>
static T* constructTag(void* buf, isTaggedConstructibleType<U>* = nullptr) {
static T* constructTag(
void* buf,
typename ReconstructorTraits<T>::template isTaggedConstructibleType<U>* = nullptr
) {
debug_checkpoint("DeserializerDispatch: tagged constructor: buf=%p\n", buf);
T* t_ptr = new (buf) T{SERIALIZE_CONSTRUCT_TAG{}};
return t_ptr;
}

/// Non-tagged constructor pass-through
template <typename U = T>
static T* constructTag(void* buf, isNotTaggedConstructibleType<U>* = nullptr) {
static T* constructTag(
void* buf,
typename ReconstructorTraits<T>::template isNotTaggedConstructibleType<U>* = nullptr
) {
return constructReconstruct<U>(buf);
}

Expand All @@ -173,12 +157,18 @@ struct Reconstructor {
/// Overloads that allow failure to reconstruct so SFINAE overloads don't
/// static assert out
template <typename U = T>
static T* constructAllowFailImpl(void* buf, isConstructible<U>* = nullptr) {
static T* constructAllowFailImpl(
void* buf,
typename ReconstructorTraits<T>::template isConstructible<U>* = nullptr
) {
return construct<U>(buf);
}

template <typename U = T>
static T* constructAllowFailImpl(void* buf, isNotConstructible<U>* = nullptr) {
static T* constructAllowFailImpl(
void* buf,
typename ReconstructorTraits<T>::template isNotConstructible<U>* = nullptr
) {
std::unique_ptr<char[]> msg = std::make_unique<char[]>(32768);
sprintf(
&msg[0],
Expand All @@ -197,7 +187,6 @@ struct Reconstructor {
static T* constructAllowFail(void* buf) {
return constructAllowFailImpl<U>(buf);
}

};

}} /* end namespace checkpoint::dispatch */
Expand Down
95 changes: 95 additions & 0 deletions src/checkpoint/traits/reconstructor_traits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
//@HEADER
// *****************************************************************************
//
// reconstructor_traits.h
// DARMA Toolkit v. 1.0.0
// DARMA/checkpoint => Serialization Library
//
// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC
// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
// Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact [email protected]
//
// *****************************************************************************
//@HEADER
*/

#if !defined INCLUDED_CHECKPOINT_TRAITS_RECONSTRUCTOR_TRAITS_H
#define INCLUDED_CHECKPOINT_TRAITS_RECONSTRUCTOR_TRAITS_H

#include "checkpoint/traits/serializable_traits.h"

#include <type_traits>

namespace checkpoint {

template <typename T>
struct ReconstructorTraits {
template <typename U>
using isDefaultConsType =
typename std::enable_if<std::is_default_constructible<U>::value, T>::type;

template <typename U>
using isNotDefaultConsType = typename std::enable_if<
not std::is_default_constructible<U>::value, T>::type;

template <typename U>
using isReconstructibleType = typename std::enable_if<
SerializableTraits<U, void>::is_intrusive_reconstructible, T>::type;

template <typename U>
using isNonIntReconstructibleType = typename std::enable_if<
SerializableTraits<U, void>::is_nonintrusive_reconstructible, T>::type;

template <typename U>
using isNotReconstructibleType = typename std::enable_if<
not SerializableTraits<U, void>::is_reconstructible, T>::type;

template <typename U>
using isTaggedConstructibleType = typename std::enable_if<
SerializableTraits<U, void>::is_tagged_constructible, T>::type;

template <typename U>
using isNotTaggedConstructibleType = typename std::enable_if<
not SerializableTraits<U, void>::is_tagged_constructible, T>::type;

template <typename U>
using isConstructible = typename std::enable_if<
SerializableTraits<U, void>::is_constructible, T>::type;

template <typename U>
using isNotConstructible = typename std::enable_if<
not SerializableTraits<U, void>::is_constructible, T>::type;
};

} // namespace checkpoint

#endif /*INCLUDED_CHECKPOINT_TRAITS_RECONSTRUCTOR_TRAITS_H*/

0 comments on commit a807d5a

Please sign in to comment.