1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-04-11 14:40:46 +01:00

Serialise std::vector of numeric types as multidimensional object if size is regular ... or individually if ragged

This commit is contained in:
Michael Marshall 2021-05-21 20:08:56 +01:00
parent 8cfc7342cd
commit 244b4aa07f
2 changed files with 71 additions and 25 deletions

View File

@ -34,11 +34,13 @@ namespace Grid
template <typename U> template <typename U>
void writeDefault(const std::string &s, const U &x); void writeDefault(const std::string &s, const U &x);
template <typename U> template <typename U>
void writeRagged(const std::string &s, const std::vector<U> &x);
template <typename U>
typename std::enable_if<element<std::vector<U>>::is_number, void>::type typename std::enable_if<element<std::vector<U>>::is_number, void>::type
writeDefault(const std::string &s, const std::vector<U> &x); writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
writeDefault(const std::string &s, const std::vector<U> &x); writeDefault(const std::string &s, const std::vector<U> &x) { writeRagged(s, x); }
template <typename U> template <typename U>
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements); void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
H5NS::Group & getGroup(void); H5NS::Group & getGroup(void);
@ -64,11 +66,13 @@ namespace Grid
template <typename U> template <typename U>
void readDefault(const std::string &s, U &output); void readDefault(const std::string &s, U &output);
template <typename U> template <typename U>
void readRagged(const std::string &s, std::vector<U> &x);
template <typename U>
typename std::enable_if<element<std::vector<U>>::is_number, void>::type typename std::enable_if<element<std::vector<U>>::is_number, void>::type
readDefault(const std::string &s, std::vector<U> &x); readDefault(const std::string &s, std::vector<U> &x);
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
readDefault(const std::string &s, std::vector<U> &x); readDefault(const std::string &s, std::vector<U> &x) { readRagged(s, x); }
template <typename U> template <typename U>
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim); void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
H5NS::Group & getGroup(void); H5NS::Group & getGroup(void);
@ -179,21 +183,27 @@ namespace Grid
typename std::enable_if<element<std::vector<U>>::is_number, void>::type typename std::enable_if<element<std::vector<U>>::is_number, void>::type
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x) Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
{ {
// alias to element type if (isFlat(x))
typedef typename element<std::vector<U>>::type Element; {
// alias to element type
// flatten the vector and getting dimensions typedef typename element<std::vector<U>>::type Element;
Flatten<std::vector<U>> flat(x);
std::vector<size_t> dim; // flatten the vector and getting dimensions
const auto &flatx = flat.getFlatVector(); Flatten<std::vector<U>> flat(x);
for (auto &d: flat.getDim()) std::vector<size_t> dim;
dim.push_back(d); const auto &flatx = flat.getFlatVector();
writeMultiDim<Element>(s, dim, &flatx[0], flatx.size()); for (auto &d: flat.getDim())
dim.push_back(d);
writeMultiDim<Element>(s, dim, &flatx[0], flatx.size());
}
else
{
writeRagged(s, x);
}
} }
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type void Hdf5Writer::writeRagged(const std::string &s, const std::vector<U> &x)
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
{ {
push(s); push(s);
writeSingleAttribute(x.size(), HDF5_GRID_GUARD "vector_size", writeSingleAttribute(x.size(), HDF5_GRID_GUARD "vector_size",
@ -275,22 +285,39 @@ namespace Grid
typename std::enable_if<element<std::vector<U>>::is_number, void>::type typename std::enable_if<element<std::vector<U>>::is_number, void>::type
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x) Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
{ {
// alias to element type bool bRagged{ false };
typedef typename element<std::vector<U>>::type Element; H5E_auto2_t h5at;
void * f5at_p;
::H5::Exception::getAutoPrint(h5at, &f5at_p);
::H5::Exception::dontPrint();
try {
push(s);
bRagged = group_.attrExists(HDF5_GRID_GUARD "vector_size");
pop();
} catch(...) {}
::H5::Exception::setAutoPrint(h5at, f5at_p);
if (bRagged)
{
readRagged(s, x);
}
else
{
// alias to element type
typedef typename element<std::vector<U>>::type Element;
std::vector<size_t> dim; std::vector<size_t> dim;
std::vector<Element> buf; std::vector<Element> buf;
readMultiDim( s, buf, dim ); readMultiDim( s, buf, dim );
// reconstruct the multidimensional vector // reconstruct the multidimensional vector
Reconstruct<std::vector<U>> r(buf, dim); Reconstruct<std::vector<U>> r(buf, dim);
x = r.getVector(); x = r.getVector();
}
} }
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type void Hdf5Reader::readRagged(const std::string &s, std::vector<U> &x)
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
{ {
uint64_t size; uint64_t size;

View File

@ -459,6 +459,25 @@ namespace Grid {
return os; return os;
} }
// In general, scalar types are considered "flat" (regularly shaped)
template <typename T>
bool isFlat(const T &t) { return true; }
// Return non-zero if all dimensions of this std::vector<std::vector<T>> are regularly shaped
template <typename T>
bool isFlat(const std::vector<std::vector<T>> &v)
{
// Make sure all of my rows are the same size
for (std::size_t i = 1; i < v.size(); ++i)
{
if (v[i].size() != v[0].size() || !isFlat(v[i]))
{
return false;
}
}
return true;
}
} }
// helper function to read space-separated values // helper function to read space-separated values