File indexing completed on 2026-05-10 08:42:09
0001 #pragma once
0002
0003 #include "bits/H5Inspector_decl.hpp"
0004 #include "H5Exception.hpp"
0005
0006 #include <boost/multi_array.hpp>
0007
0008 namespace HighFive {
0009 namespace details {
0010
0011 template <typename T, size_t Dims>
0012 struct inspector<boost::multi_array<T, Dims>> {
0013 using type = boost::multi_array<T, Dims>;
0014 using value_type = T;
0015 using base_type = typename inspector<value_type>::base_type;
0016 using hdf5_type = typename inspector<value_type>::hdf5_type;
0017
0018 static constexpr size_t ndim = Dims;
0019 static constexpr size_t min_ndim = ndim + inspector<value_type>::min_ndim;
0020 static constexpr size_t max_ndim = ndim + inspector<value_type>::max_ndim;
0021
0022 static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
0023 inspector<value_type>::is_trivially_nestable;
0024 static constexpr bool is_trivially_nestable = false;
0025
0026
0027 static size_t getRank(const type& val) {
0028 return ndim + inspector<value_type>::getRank(val.data()[0]);
0029 }
0030
0031 static std::vector<size_t> getDimensions(const type& val) {
0032 auto rank = getRank(val);
0033 std::vector<size_t> sizes(rank, 1ul);
0034 for (size_t i = 0; i < ndim; ++i) {
0035 sizes[i] = val.shape()[i];
0036 }
0037 if (val.size() != 0) {
0038 auto s = inspector<value_type>::getDimensions(val.data()[0]);
0039 sizes.resize(ndim + s.size());
0040 for (size_t i = 0; i < s.size(); ++i) {
0041 sizes[ndim + i] = s[i];
0042 }
0043 }
0044 return sizes;
0045 }
0046
0047 static void prepare(type& val, const std::vector<size_t>& dims) {
0048 if (dims.size() < ndim) {
0049 std::ostringstream os;
0050 os << "Only '" << dims.size() << "' given but boost::multi_array is of size '" << ndim
0051 << "'.";
0052 throw DataSpaceException(os.str());
0053 }
0054 boost::array<typename type::index, Dims> ext;
0055 std::copy(dims.begin(), dims.begin() + ndim, ext.begin());
0056 val.resize(ext);
0057 std::vector<size_t> next_dims(dims.begin() + Dims, dims.end());
0058 std::size_t size = std::accumulate(dims.begin(),
0059 dims.begin() + Dims,
0060 std::size_t{1},
0061 std::multiplies<size_t>());
0062 for (size_t i = 0; i < size; ++i) {
0063 inspector<value_type>::prepare(*(val.origin() + i), next_dims);
0064 }
0065 }
0066
0067 static void assert_c_order(const type& val) {
0068 if (!(val.storage_order() == boost::c_storage_order())) {
0069 throw DataTypeException("Only C storage order is supported for 'boost::multi_array'.");
0070 }
0071 }
0072
0073 static hdf5_type* data(type& val) {
0074 assert_c_order(val);
0075 return inspector<value_type>::data(*val.data());
0076 }
0077
0078 static const hdf5_type* data(const type& val) {
0079 assert_c_order(val);
0080 return inspector<value_type>::data(*val.data());
0081 }
0082
0083 template <class It>
0084 static void serialize(const type& val, const std::vector<size_t>& dims, It m) {
0085 assert_c_order(val);
0086 size_t size = val.num_elements();
0087 auto subdims = std::vector<size_t>(dims.begin() + ndim, dims.end());
0088 size_t subsize = compute_total_size(subdims);
0089 for (size_t i = 0; i < size; ++i) {
0090 inspector<value_type>::serialize(*(val.origin() + i), subdims, m + i * subsize);
0091 }
0092 }
0093
0094 template <class It>
0095 static void unserialize(It vec_align, const std::vector<size_t>& dims, type& val) {
0096 assert_c_order(val);
0097 std::vector<size_t> next_dims(dims.begin() + ndim, dims.end());
0098 size_t subsize = compute_total_size(next_dims);
0099 for (size_t i = 0; i < val.num_elements(); ++i) {
0100 inspector<value_type>::unserialize(vec_align + i * subsize,
0101 next_dims,
0102 *(val.origin() + i));
0103 }
0104 }
0105 };
0106
0107 }
0108 }