Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce '{Shallow,Deep}CopyBuffer'. #795

Merged
merged 2 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/highfive/bits/H5Attribute_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ inline void Attribute::read(T& array) const {
auto r = details::data_converter::get_reader<T>(dims, array);
read(r.get_pointer(), buffer_info.data_type);
// re-arrange results
r.unserialize();
r.unserialize(array);
auto t = create_datatype<typename details::inspector<T>::base_type>();
auto c = t.getClass();
if (c == DataTypeClass::VarLen || t.isVariableStr()) {
Expand Down
157 changes: 99 additions & 58 deletions include/highfive/bits/H5Converter_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,91 +8,132 @@
*/
#pragma once

#include <type_traits>

#include "H5Inspector_misc.hpp"
#include "../H5DataType.hpp"

namespace HighFive {
namespace details {

template <typename T>
struct Writer {
using hdf5_type = typename inspector<T>::hdf5_type;
const hdf5_type* get_pointer() {
if (vec.empty()) {
return ptr;
} else {
return vec.data();
}
template <class T, class V = void>
struct enable_shallow_copy: public std::enable_if<inspector<T>::is_trivially_copyable, V> {};

template <class T, class V = void>
struct enable_deep_copy: public std::enable_if<!inspector<T>::is_trivially_copyable, V> {};

template <typename T, bool IsReadOnly>
struct ShallowCopyBuffer {
using type = unqualified_t<T>;
using hdf5_type =
typename std::conditional<IsReadOnly,
typename std::add_const<typename inspector<T>::hdf5_type>::type,
typename inspector<T>::hdf5_type>::type;

ShallowCopyBuffer() = delete;

explicit ShallowCopyBuffer(typename std::conditional<IsReadOnly, const T&, T&>::type val)
: ptr(inspector<T>::data(val)){};

hdf5_type* get_pointer() const {
return ptr;
}

void unserialize(T& val) const {
/* nothing to do. */
}
std::vector<hdf5_type> vec{};
const hdf5_type* ptr{nullptr};

private:
hdf5_type* ptr;
};

template <typename T>
struct Reader {
template <class T>
struct DeepCopyBuffer {
using type = unqualified_t<T>;
using hdf5_type = typename inspector<type>::hdf5_type;

Reader(const std::vector<size_t>& _dims, type& _val)
: dims(_dims)
, val(_val) {}
explicit DeepCopyBuffer(const std::vector<size_t>& _dims)
: buffer(inspector<T>::getSize(_dims))
, dims(_dims) {}

hdf5_type* get_pointer() {
if (vec.empty()) {
return inspector<type>::data(val);
} else {
return vec.data();
}
return buffer.data();
}

void unserialize() {
if (!vec.empty()) {
inspector<type>::unserialize(vec.data(), dims, val);
}
hdf5_type const* get_pointer() const {
return buffer.data();
}

std::vector<size_t> dims{};
std::vector<hdf5_type> vec{};
type& val{};
void unserialize(T& val) const {
inspector<type>::unserialize(buffer.data(), dims, val);
}

private:
std::vector<hdf5_type> buffer;
std::vector<size_t> dims;
};

struct data_converter {
template <typename T>
static typename std::enable_if<inspector<T>::is_trivially_copyable, Writer<T>>::type serialize(
const typename inspector<T>::type& val) {
Writer<T> w;
w.ptr = inspector<T>::data(val);
return w;
}

template <typename T>
static typename std::enable_if<!inspector<T>::is_trivially_copyable, Writer<T>>::type serialize(
const typename inspector<T>::type& val) {
Writer<T> w;
w.vec.resize(inspector<T>::getSizeVal(val));
inspector<T>::serialize(val, w.vec.data());
return w;
template <typename T, typename Enable = void>
struct Writer;

template <typename T>
struct Writer<T, typename enable_shallow_copy<T>::type>: public ShallowCopyBuffer<T, true> {
private:
using super = ShallowCopyBuffer<T, true>;

public:
explicit Writer(const T& val)
: super(val){};
};

template <typename T>
struct Writer<T, typename enable_deep_copy<T>::type>: public DeepCopyBuffer<T> {
explicit Writer(const T& val)
: DeepCopyBuffer<T>(inspector<T>::getDimensions(val)) {
inspector<T>::serialize(val, this->get_pointer());
}
};


template <typename T, typename Enable = void>
struct Reader;

template <typename T>
struct Reader<T, typename enable_shallow_copy<T>::type>: public ShallowCopyBuffer<T, false> {
private:
using super = ShallowCopyBuffer<T, false>;
using type = typename super::type;

public:
Reader(const std::vector<size_t>&, type& val)
: super(val) {}
};

template <typename T>
struct Reader<T, typename enable_deep_copy<T>::type>: public DeepCopyBuffer<T> {
private:
using super = DeepCopyBuffer<T>;
using type = typename super::type;

public:
Reader(const std::vector<size_t>& _dims, type&)
: super(_dims) {}
};


struct data_converter {
template <typename T>
static
typename std::enable_if<inspector<unqualified_t<T>>::is_trivially_copyable, Reader<T>>::type
get_reader(const std::vector<size_t>& dims, T& val) {
auto effective_dims = details::squeezeDimensions(dims, inspector<T>::recursive_ndim);
Reader<T> r(effective_dims, val);
inspector<T>::prepare(r.val, effective_dims);
return r;
static Writer<T> serialize(const typename inspector<T>::type& val) {
return Writer<T>(val);
}

template <typename T>
static typename std::enable_if<!inspector<unqualified_t<T>>::is_trivially_copyable,
Reader<T>>::type
get_reader(const std::vector<size_t>& dims, T& val) {
static Reader<T> get_reader(const std::vector<size_t>& dims, T& val) {
// TODO Use bufferinfo for recursive_ndim
auto effective_dims = details::squeezeDimensions(dims, inspector<T>::recursive_ndim);

Reader<T> r(effective_dims, val);
inspector<T>::prepare(r.val, effective_dims);
r.vec.resize(inspector<T>::getSize(effective_dims));
return r;
inspector<T>::prepare(val, effective_dims);
return Reader<T>(effective_dims, val);
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/highfive/bits/H5Slice_traits_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ inline void SliceTraits<Derivate>::read(T& array, const DataTransferProps& xfer_
auto r = details::data_converter::get_reader<T>(dims, array);
read(r.get_pointer(), buffer_info.data_type, xfer_props);
// re-arrange results
r.unserialize();
r.unserialize(array);
auto t = create_datatype<typename details::inspector<T>::base_type>();
auto c = t.getClass();
if (c == DataTypeClass::VarLen || t.isVariableStr()) {
Expand Down