File indexing completed on 2026-06-06 08:33:52
0001 #pragma once
0002
0003 #include "bits/H5Inspector_decl.hpp"
0004 #include "H5Exception.hpp"
0005
0006 #include <Eigen/Core>
0007 #include <Eigen/Dense>
0008
0009 namespace HighFive {
0010 namespace details {
0011
0012 template <class EigenType>
0013 struct eigen_inspector {
0014 using type = EigenType;
0015 using value_type = typename EigenType::Scalar;
0016 using base_type = typename inspector<value_type>::base_type;
0017 using hdf5_type = base_type;
0018
0019
0020 static_assert(int(EigenType::ColsAtCompileTime) == int(EigenType::MaxColsAtCompileTime),
0021 "Padding isn't supported.");
0022 static_assert(int(EigenType::RowsAtCompileTime) == int(EigenType::MaxRowsAtCompileTime),
0023 "Padding isn't supported.");
0024
0025 static constexpr bool is_row_major() {
0026 return EigenType::ColsAtCompileTime == 1 || EigenType::RowsAtCompileTime == 1 ||
0027 EigenType::IsRowMajor;
0028 }
0029
0030
0031 static constexpr size_t ndim = 2;
0032 static constexpr size_t min_ndim = ndim + inspector<value_type>::min_ndim;
0033 static constexpr size_t max_ndim = ndim + inspector<value_type>::max_ndim;
0034 static constexpr bool is_trivially_copyable = is_row_major() &&
0035 std::is_trivially_copyable<value_type>::value &&
0036 inspector<value_type>::is_trivially_nestable;
0037 static constexpr bool is_trivially_nestable = false;
0038
0039 static size_t getRank(const type& val) {
0040 return ndim + inspector<value_type>::getRank(val.data()[0]);
0041 }
0042
0043 static std::vector<size_t> getDimensions(const type& val) {
0044 std::vector<size_t> sizes{static_cast<size_t>(val.rows()), static_cast<size_t>(val.cols())};
0045 auto s = inspector<value_type>::getDimensions(val.data()[0]);
0046 sizes.insert(sizes.end(), s.begin(), s.end());
0047 return sizes;
0048 }
0049
0050 static void prepare(type& val, const std::vector<size_t>& dims) {
0051 if (dims[0] != static_cast<size_t>(val.rows()) ||
0052 dims[1] != static_cast<size_t>(val.cols())) {
0053 val.resize(static_cast<typename type::Index>(dims[0]),
0054 static_cast<typename type::Index>(dims[1]));
0055 }
0056 }
0057
0058 static hdf5_type* data(type& val) {
0059 if (!is_trivially_copyable) {
0060 throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
0061 }
0062
0063 return inspector<value_type>::data(*val.data());
0064 }
0065
0066 static const hdf5_type* data(const type& val) {
0067 if (!is_trivially_copyable) {
0068 throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
0069 }
0070
0071 return inspector<value_type>::data(*val.data());
0072 }
0073
0074 static void serialize(const type& val, const std::vector<size_t>& dims, hdf5_type* m) {
0075 Eigen::Index n_rows = val.rows();
0076 Eigen::Index n_cols = val.cols();
0077
0078 auto subdims = std::vector<size_t>(dims.begin() + ndim, dims.end());
0079 auto subsize = compute_total_size(subdims);
0080 for (Eigen::Index i = 0; i < n_rows; ++i) {
0081 for (Eigen::Index j = 0; j < n_cols; ++j) {
0082 inspector<value_type>::serialize(val(i, j), dims, m);
0083 m += subsize;
0084 }
0085 }
0086 }
0087
0088 static void unserialize(const hdf5_type* vec_align,
0089 const std::vector<size_t>& dims,
0090 type& val) {
0091 if (dims.size() < 2) {
0092 std::ostringstream os;
0093 os << "Impossible to pair DataSet with " << dims.size()
0094 << " dimensions into an eigen-matrix.";
0095 throw DataSpaceException(os.str());
0096 }
0097
0098 auto n_rows = static_cast<Eigen::Index>(dims[0]);
0099 auto n_cols = static_cast<Eigen::Index>(dims[1]);
0100
0101 auto subdims = std::vector<size_t>(dims.begin() + ndim, dims.end());
0102 auto subsize = compute_total_size(subdims);
0103 for (Eigen::Index i = 0; i < n_rows; ++i) {
0104 for (Eigen::Index j = 0; j < n_cols; ++j) {
0105 inspector<value_type>::unserialize(vec_align, subdims, val(i, j));
0106 vec_align += subsize;
0107 }
0108 }
0109 }
0110 };
0111
0112 template <typename T, int M, int N, int Options>
0113 struct inspector<Eigen::Matrix<T, M, N, Options>>
0114 : public eigen_inspector<Eigen::Matrix<T, M, N, Options>> {
0115 private:
0116 using super = eigen_inspector<Eigen::Matrix<T, M, N, Options>>;
0117
0118 public:
0119 using type = typename super::type;
0120 using value_type = typename super::value_type;
0121 using base_type = typename super::base_type;
0122 using hdf5_type = typename super::hdf5_type;
0123 };
0124
0125 template <typename T, int M, int N, int Options>
0126 struct inspector<Eigen::Array<T, M, N, Options>>
0127 : public eigen_inspector<Eigen::Array<T, M, N, Options>> {
0128 private:
0129 using super = eigen_inspector<Eigen::Array<T, M, N, Options>>;
0130
0131 public:
0132 using type = typename super::type;
0133 using value_type = typename super::value_type;
0134 using base_type = typename super::base_type;
0135 using hdf5_type = typename super::hdf5_type;
0136 };
0137
0138
0139 template <typename PlainObjectType, int MapOptions>
0140 struct inspector<Eigen::Map<PlainObjectType, MapOptions>>
0141 : public eigen_inspector<Eigen::Map<PlainObjectType, MapOptions>> {
0142 private:
0143 using super = eigen_inspector<Eigen::Map<PlainObjectType, MapOptions>>;
0144
0145 public:
0146 using type = typename super::type;
0147 using value_type = typename super::value_type;
0148 using base_type = typename super::base_type;
0149 using hdf5_type = typename super::hdf5_type;
0150
0151 static void prepare(type& val, const std::vector<size_t>& dims) {
0152 if (dims[0] != static_cast<size_t>(val.rows()) ||
0153 dims[1] != static_cast<size_t>(val.cols())) {
0154 throw DataSetException("Eigen::Map has invalid shape and can't be resized.");
0155 }
0156 }
0157 };
0158
0159
0160 }
0161 }