HighFive  2.3.1
HighFive - Header-only C++ HDF5 interface
H5Dataspace_misc.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
3  *
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  */
9 #ifndef H5DATASPACE_MISC_HPP
10 #define H5DATASPACE_MISC_HPP
11 
12 #include <array>
13 #include <initializer_list>
14 #include <vector>
15 #include <numeric>
16 
17 #include <H5Spublic.h>
18 
19 #include "H5Utils.hpp"
20 
21 namespace HighFive {
22 
23 inline DataSpace::DataSpace(const std::vector<size_t>& dims)
24  : DataSpace(dims.begin(), dims.end()) {}
25 
26 template <size_t N>
27 inline DataSpace::DataSpace(const std::array<size_t, N>& dims)
28  : DataSpace(dims.begin(), dims.end()) {}
29 
30 inline DataSpace::DataSpace(const std::initializer_list<size_t>& items)
31  : DataSpace(std::vector<size_t>(items)) {}
32 
33 template<typename... Args>
34  inline DataSpace::DataSpace(size_t dim1, Args... dims)
35  : DataSpace(std::vector<size_t>{dim1, static_cast<size_t>(dims)...}) {}
36 
37 template <class IT, typename>
38 inline DataSpace::DataSpace(const IT begin, const IT end) {
39  std::vector<hsize_t> real_dims(begin, end);
40 
41  if ((_hid = H5Screate_simple(int(real_dims.size()), real_dims.data(),
42  NULL)) < 0) {
43  throw DataSpaceException("Impossible to create dataspace");
44  }
45 }
46 
47 inline DataSpace::DataSpace(const std::vector<size_t>& dims,
48  const std::vector<size_t>& maxdims) {
49 
50  if (dims.size() != maxdims.size()) {
51  throw DataSpaceException("dims and maxdims must be the same length.");
52  }
53 
54  std::vector<hsize_t> real_dims(dims.begin(), dims.end());
55  std::vector<hsize_t> real_maxdims(maxdims.begin(), maxdims.end());
56 
57  // Replace unlimited flag with actual HDF one
58  std::replace(real_maxdims.begin(), real_maxdims.end(),
59  static_cast<hsize_t>(DataSpace::UNLIMITED), H5S_UNLIMITED);
60 
61  if ((_hid = H5Screate_simple(int(dims.size()), real_dims.data(),
62  real_maxdims.data())) < 0) {
63  throw DataSpaceException("Impossible to create dataspace");
64  }
65 } // namespace HighFive
66 
68  H5S_class_t h5_dataspace_type;
69  switch (dtype) {
71  h5_dataspace_type = H5S_SCALAR;
72  break;
74  h5_dataspace_type = H5S_NULL;
75  break;
76  default:
77  throw DataSpaceException("Invalid dataspace type: should be "
78  "datascape_scalar or datascape_null");
79  }
80 
81  if ((_hid = H5Screate(h5_dataspace_type)) < 0) {
82  throw DataSpaceException("Unable to create dataspace");
83  }
84 }
85 
86 inline DataSpace DataSpace::clone() const {
87  DataSpace res;
88  if ((res._hid = H5Scopy(_hid)) < 0) {
89  throw DataSpaceException("Unable to copy dataspace");
90  }
91  return res;
92 }
93 
94 inline size_t DataSpace::getNumberDimensions() const {
95  const int ndim = H5Sget_simple_extent_ndims(_hid);
96  if (ndim < 0) {
97  HDF5ErrMapper::ToException<DataSetException>(
98  "Unable to get dataspace number of dimensions");
99  }
100  return size_t(ndim);
101 }
102 
103 inline std::vector<size_t> DataSpace::getDimensions() const {
104  std::vector<hsize_t> dims(getNumberDimensions());
105  if (!dims.empty()) {
106  if (H5Sget_simple_extent_dims(_hid, dims.data(), NULL) < 0) {
107  HDF5ErrMapper::ToException<DataSetException>(
108  "Unable to get dataspace dimensions");
109  }
110  }
111  return details::to_vector_size_t(std::move(dims));
112 }
113 
114 inline size_t DataSpace::getElementCount() const {
115  const std::vector<size_t>& dims = getDimensions();
116  return std::accumulate(dims.begin(), dims.end(), size_t{1u},
117  std::multiplies<size_t>());
118 }
119 
120 inline std::vector<size_t> DataSpace::getMaxDimensions() const {
121  std::vector<hsize_t> maxdims(getNumberDimensions());
122  if (H5Sget_simple_extent_dims(_hid, NULL, maxdims.data()) < 0) {
123  HDF5ErrMapper::ToException<DataSetException>(
124  "Unable to get dataspace dimensions");
125  }
126 
127  std::replace(maxdims.begin(), maxdims.end(), H5S_UNLIMITED,
128  static_cast<hsize_t>(DataSpace::UNLIMITED));
129  return details::to_vector_size_t(maxdims);
130 }
131 
132 template <typename T>
133 inline DataSpace DataSpace::From(const T& value) {
134  auto dims = details::inspector<T>::getDimensions(value);
135  return DataSpace(dims);
136 }
137 
138 template <std::size_t N, std::size_t Width>
139 inline DataSpace DataSpace::FromCharArrayStrings(const char(&)[N][Width]) {
140  return DataSpace(N);
141 }
142 
143 namespace details {
144 
146 inline bool checkDimensions(const DataSpace& mem_space, size_t input_dims) {
147  size_t dataset_dims = mem_space.getNumberDimensions();
148  if (input_dims == dataset_dims)
149  return true;
150 
151  const std::vector<size_t>& dims = mem_space.getDimensions();
152  for (auto i = dims.crbegin(); i != --dims.crend() && *i == 1; ++i)
153  --dataset_dims;
154 
155  if (input_dims == dataset_dims)
156  return true;
157 
158  dataset_dims = dims.size();
159  for (auto i = dims.cbegin(); i != --dims.cend() && *i == 1; ++i)
160  --dataset_dims;
161 
162  if (input_dims == dataset_dims)
163  return true;
164 
165  // The final tests is for scalars
166  return input_dims == 0 && dataset_dims == 1 && dims[dims.size() - 1] == 1;
167 }
168 
169 } // namespace details
170 } // namespace HighFive
171 
172 #endif // H5DATASPACE_MISC_HPP
Exception specific to HighFive DataSpace interface.
Definition: H5Exception.hpp:99
Class representing the space (dimensions) of a dataset.
Definition: H5DataSpace.hpp:37
static DataSpace FromCharArrayStrings(const char(&)[N][Width])
Definition: H5Dataspace_misc.hpp:139
static DataSpace From(const T &value)
Create a dataspace matching a type accepted by details::inspector.
Definition: H5Dataspace_misc.hpp:133
size_t getNumberDimensions() const
getNumberDimensions
Definition: H5Dataspace_misc.hpp:94
std::vector< size_t > getMaxDimensions() const
getMaxDimensions
Definition: H5Dataspace_misc.hpp:120
DataspaceType
dataspace type
Definition: H5DataSpace.hpp:45
@ datascape_null
Definition: H5DataSpace.hpp:47
@ datascape_scalar
Definition: H5DataSpace.hpp:46
size_t getElementCount() const
getElementCount
Definition: H5Dataspace_misc.hpp:114
std::vector< size_t > getDimensions() const
getDimensions
Definition: H5Dataspace_misc.hpp:103
DataSpace clone() const
Definition: H5Dataspace_misc.hpp:86
static const size_t UNLIMITED
Definition: H5DataSpace.hpp:42
hid_t _hid
Definition: H5Object.hpp:87
Definition: H5_definitions.hpp:15