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