HighFive 2.3.1
HighFive - Header-only C++ HDF5 interface
Loading...
Searching...
No Matches
H5Utils.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 H5UTILS_HPP
10#define H5UTILS_HPP
11
12// internal utilities functions
13#include <algorithm>
14#include <array>
15#include <cstddef> // __GLIBCXX__
16#include <exception>
17#include <string>
18#include <type_traits>
19#include <vector>
20
21#ifdef H5_USE_BOOST
22# include <boost/multi_array.hpp>
23# include <boost/numeric/ublas/matrix.hpp>
24#endif
25#ifdef H5_USE_EIGEN
26# include <Eigen/Eigen>
27#endif
28
29#include <H5public.h>
30
31#include "../H5Exception.hpp"
32
33namespace HighFive {
34
35// If ever used, recognize dimensions of FixedLenStringArray
36template <std::size_t N>
37class FixedLenStringArray;
38
39
40template <typename T>
41using unqualified_t = typename std::remove_const<typename std::remove_reference<T>::type
42 >::type;
43
44namespace details {
45template <typename T>
46struct inspector {
47 using type = T;
48 using base_type = unqualified_t<T>;
49
50 static constexpr size_t ndim = 0;
51 static constexpr size_t recursive_ndim = ndim;
52
53 static std::array<size_t, recursive_ndim> getDimensions(const type& /* val */) {
54 return std::array<size_t, recursive_ndim>();
55 }
56};
57
58template <size_t N>
59struct inspector<FixedLenStringArray<N>> {
60 using type = FixedLenStringArray<N>;
61 using base_type = FixedLenStringArray<N>;
62
63 static constexpr size_t ndim = 1;
64 static constexpr size_t recursive_ndim = ndim;
65
66 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
67 return std::array<size_t, recursive_ndim>{val.size()};
68 }
69};
70
71template <typename T>
72struct inspector<std::vector<T>> {
73 using type = std::vector<T>;
74 using value_type = T;
75 using base_type = typename inspector<value_type>::base_type;
76
77 static constexpr size_t ndim = 1;
78 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
79
80 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
81 std::array<size_t, recursive_ndim> sizes{val.size()};
82 size_t index = ndim;
83 for (const auto& s: inspector<value_type>::getDimensions(val[0])) {
84 sizes[index++] = s;
85 }
86 return sizes;
87 }
88};
89
90template <typename T>
91struct inspector<T*> {
92 using type = T*;
93 using value_type = T;
94 using base_type = typename inspector<value_type>::base_type;
95
96 static constexpr size_t ndim = 1;
97 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
98
99 static std::array<size_t, recursive_ndim> getDimensions(const type& /* val */) {
100 throw std::string("Not possible to have size of a T*");
101 }
102};
103
104template <typename T, size_t N>
105struct inspector<T[N]> {
106 using type = T[N];
107 using value_type = T;
108 using base_type = typename inspector<value_type>::base_type;
109
110 static constexpr size_t ndim = 1;
111 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
112
113 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
114 std::array<size_t, recursive_ndim> sizes{N};
115 size_t index = ndim;
116 for (const auto& s: inspector<value_type>::getDimensions(val[0])) {
117 sizes[index++] = s;
118 }
119 return sizes;
120 }
121};
122
123template <typename T, size_t N>
124struct inspector<std::array<T, N>> {
125 using type = std::array<T, N>;
126 using value_type = T;
127 using base_type = typename inspector<value_type>::base_type;
128
129 static constexpr size_t ndim = 1;
130 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
131
132 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
133 std::array<size_t, recursive_ndim> sizes{N};
134 size_t index = ndim;
135 for (const auto& s: inspector<value_type>::getDimensions(val[0])) {
136 sizes[index++] = s;
137 }
138 return sizes;
139 }
140};
141
142#ifdef H5_USE_EIGEN
143template <typename T, int M, int N>
144struct inspector<Eigen::Matrix<T, M, N>> {
145 using type = Eigen::Matrix<T, M, N>;
146 using value_type = T;
147 using base_type = typename inspector<value_type>::base_type;
148
149 static constexpr size_t ndim = 2;
150 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
151
152 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
153 std::array<size_t, recursive_ndim> sizes{static_cast<size_t>(val.rows()), static_cast<size_t>(val.cols())};
154 size_t index = ndim;
155 for (const auto& s: inspector<value_type>::getDimensions(val.data()[0])) {
156 sizes[index++] = s;
157 }
158 return sizes;
159 }
160};
161#endif
162
163#ifdef H5_USE_BOOST
164template <typename T, size_t Dims>
165struct inspector<boost::multi_array<T, Dims>> {
166 using type = boost::multi_array<T, Dims>;
167 using value_type = T;
168 using base_type = typename inspector<value_type>::base_type;
169
170 static constexpr size_t ndim = Dims;
171 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
172
173 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
174 std::array<size_t, recursive_ndim> sizes;
175 for (size_t i = 0; i < ndim; ++i) {
176 sizes[i] = val.shape()[i];
177 }
178
179 size_t index = ndim;
180 for (const auto& s: inspector<value_type>::getDimensions(val.data()[0])) {
181 sizes[index++] = s;
182 }
183 return sizes;
184 }
185};
186
187template <typename T>
188struct inspector<boost::numeric::ublas::matrix<T>> {
189 using type = boost::numeric::ublas::matrix<T>;
190 using value_type = T;
191 using base_type = typename inspector<value_type>::base_type;
192
193 static constexpr size_t ndim = 2;
194 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
195
196 static std::array<size_t, recursive_ndim> getDimensions(const type& val) {
197 std::array<size_t, recursive_ndim> sizes{val.size1(), val.size2()};
198 size_t index = ndim;
199 for (const auto& s: inspector<value_type>::getDimensions(val(0, 0))) {
200 sizes[index++] = s;
201 }
202 return sizes;
203 }
204};
205#endif
206
207
208// Find the type of an eventual char array, otherwise void
209template <typename>
210struct type_char_array {
211 typedef void type;
212};
213
214template <typename T>
215struct type_char_array<T*> {
216 typedef typename std::conditional<
217 std::is_same<unqualified_t<T>, char>::value,
218 char*,
219 typename type_char_array<T>::type
220 >::type type;
221};
222
223template <typename T, std::size_t N>
224struct type_char_array<T[N]> {
225 typedef typename std::conditional<
226 std::is_same<unqualified_t<T>, char>::value,
227 char[N],
228 typename type_char_array<T>::type
229 >::type type;
230};
231
232
233// check if the type is a container ( only vector supported for now )
234template <typename>
235struct is_container {
236 static const bool value = false;
237};
238
239template <typename T>
240struct is_container<std::vector<T> > {
241 static const bool value = true;
242};
243
244// check if the type is a basic C-Array
245template <typename>
246struct is_c_array {
247 static const bool value = false;
248};
249
250template <typename T>
251struct is_c_array<T*> {
252 static const bool value = true;
253};
254
255template <typename T, std::size_t N>
256struct is_c_array<T[N]> {
257 static const bool value = true;
258};
259
260
261// converter function for hsize_t -> size_t when hsize_t != size_t
262template <typename Size>
263inline std::vector<std::size_t> to_vector_size_t(const std::vector<Size>& vec) {
264 static_assert(std::is_same<Size, std::size_t>::value == false,
265 " hsize_t != size_t mandatory here");
266 std::vector<size_t> res(vec.size());
267 std::transform(vec.cbegin(), vec.cend(), res.begin(), [](Size e) {
268 return static_cast<size_t>(e);
269 });
270 return res;
271}
272
273// converter function for hsize_t -> size_t when size_t == hsize_t
274inline std::vector<std::size_t> to_vector_size_t(const std::vector<std::size_t>& vec) {
275 return vec;
276}
277
278// read name from a H5 object using the specified function
279template<typename T>
280inline std::string get_name(T fct) {
281 const size_t maxLength = 255;
282 char buffer[maxLength + 1];
283 ssize_t retcode = fct(buffer, static_cast<hsize_t>(maxLength) + 1);
284 if (retcode < 0) {
285 HDF5ErrMapper::ToException<GroupException>("Error accessing object name");
286 }
287 const size_t length = static_cast<std::size_t>(retcode);
288 if (length <= maxLength) {
289 return std::string(buffer, length);
290 }
291 std::vector<char> bigBuffer(length + 1, 0);
292 fct(bigBuffer.data(), static_cast<hsize_t>(length) + 1);
293 return std::string(bigBuffer.data(), length);
294}
295
296} // namespace details
297} // namespace HighFive
298
299#endif // H5UTILS_HPP
A structure representing a set of fixed-length strings.
Definition: H5DataType.hpp:239
std::size_t size() const noexcept
Definition: H5DataType.hpp:281
Definition: H5_definitions.hpp:15
typename std::remove_const< typename std::remove_reference< T >::type >::type unqualified_t
Definition: H5Utils.hpp:42