9 #ifndef H5CONVERTER_MISC_HPP
10 #define H5CONVERTER_MISC_HPP
22 #include <boost/serialization/vector.hpp>
23 #include <boost/multi_array.hpp>
24 #include <boost/numeric/ublas/matrix.hpp>
27 #include <H5Dpublic.h>
28 #include <H5Ppublic.h>
30 #include "../H5Reference.hpp"
37 inline bool is_1D(
const std::vector<size_t>& dims) {
38 return std::count_if(dims.begin(), dims.end(), [](
size_t i){ return i > 1; }) < 2;
42 return std::accumulate(dims.begin(), dims.end(),
size_t{1u},
43 std::multiplies<size_t>());
49 std::ostringstream ss;
50 ss <<
"Mismatch between vector size (" << size_vec
52 ss <<
") on dimension " << dimension;
64 const std::vector<size_t>& dims,
65 const size_t current_dim,
66 std::vector<T>& buffer) {
69 buffer.insert(buffer.end(), vec_single_dim.begin(), vec_single_dim.end());
73 template <typename T, typename U = typename type_of_array<T>::type>
76 const std::vector<size_t>& dims,
78 std::vector<U>& buffer) {
81 for (
const auto& it : vec_multi_dim) {
88 inline typename std::vector<T>::const_iterator
90 typename std::vector<T>::const_iterator end_buffer,
91 const std::vector<size_t>& dims,
92 const size_t current_dim,
93 std::vector<T>& vec_single_dim) {
94 const auto n_elems =
static_cast<long>(dims[current_dim]);
95 const auto end_copy_iter = std::min(begin_buffer + n_elems, end_buffer);
96 vec_single_dim.assign(begin_buffer, end_copy_iter);
100 template <typename T, typename U = typename type_of_array<T>::type>
101 inline typename std::vector<U>::const_iterator
103 typename std::vector<U>::const_iterator end_buffer,
104 const std::vector<size_t>& dims,
105 const size_t current_dim,
106 std::vector<std::vector<T>>& vec_multi_dim) {
107 const size_t n_elems = dims[current_dim];
108 vec_multi_dim.resize(n_elems);
110 for (
auto& subvec : vec_multi_dim) {
112 begin_buffer, end_buffer, dims, current_dim + 1, subvec);
122 template <
typename Scalar,
class Enable>
123 struct data_converter {
126 static_assert((std::is_arithmetic<Scalar>::value ||
127 std::is_enum<Scalar>::value ||
128 std::is_same<std::string, Scalar>::value),
129 "supported datatype should be an arithmetic value, a "
130 "std::string or a container/array");
147 template <
typename CArray>
149 typename std::enable_if<(is_c_array<CArray>::value)>::type> {
164 template <typename Container, typename T = typename type_of_array<Container>::type>
191 template <
typename T>
194 typename std::enable_if<(
195 std::is_same<T, typename type_of_array<T>::type>::value &&
196 !std::is_same<T, Reference>::value
205 template <
typename T, std::
size_t S>
208 typename std::enable_if<(
209 std::is_same<T, typename type_of_array<T>::type>::value)>::type>
220 std::ostringstream ss;
222 <<
" elements into an array with " << S <<
" elements.";
235 template <
typename T, std::
size_t Dims>
236 struct data_converter<boost::multi_array<T, Dims>, void>
237 :
public container_converter<boost::multi_array<T, Dims>> {
238 using MultiArray = boost::multi_array<T, Dims>;
243 auto&& dims = this->_space.getDimensions();
244 if (std::equal(dims.begin(), dims.end(), array.shape()) ==
false) {
245 boost::array<typename MultiArray::index, Dims> ext;
246 std::copy(dims.begin(), dims.end(), ext.begin());
255 template <
typename T>
256 struct data_converter<boost::numeric::ublas::matrix<T>, void>
257 :
public container_converter<boost::numeric::ublas::matrix<T>> {
258 using Matrix = boost::numeric::ublas::matrix<T>;
261 inline data_converter(
const DataSpace& space) : container_converter<Matrix>(space) {
262 assert(space.getDimensions().size() == 2);
266 boost::array<std::size_t, 2> sizes = {{array.size1(), array.size2()}};
267 auto&& _dims = this->_space.getDimensions();
268 if (std::equal(_dims.begin(), _dims.end(), sizes.begin()) ==
false) {
269 array.resize(_dims[0], _dims[1],
false);
272 return &(array(0, 0));
275 inline const value_type*
transform_write(
const Matrix& array)
const noexcept {
276 return &(array(0, 0));
283 template <
typename T>
285 typename std::enable_if<(is_container<T>::value)>::type> {
289 : _dims(space.getDimensions()) {}
293 return _vec_align.data();
298 vectors_to_single_buffer<T>(vec, _dims, 0, _vec_align);
299 return _vec_align.data();
304 _vec_align.cbegin(), _vec_align.cend(), _dims, 0, vec);
328 _c_vec = str.c_str();
333 assert(_c_vec !=
nullptr);
336 if (_c_vec !=
nullptr) {
338 (void)H5Dvlen_reclaim(str_type.getId(), _space.getId(), H5P_DEFAULT,
358 _c_vec.resize(_space.getDimensions()[0], NULL);
359 return _c_vec.data();
363 _c_vec.resize(vec.size() + 1, NULL);
364 std::transform(vec.begin(), vec.end(), _c_vec.begin(),
365 [](
const std::string& str){ return str.c_str(); });
366 return _c_vec.data();
370 vec.resize(_c_vec.size());
371 for (
size_t i = 0; i < vec.size(); ++i) {
375 if (_c_vec.empty() ==
false && _c_vec[0] != NULL) {
377 (void)H5Dvlen_reclaim(str_type.getId(), _space.getId(), H5P_DEFAULT,
389 template <std::
size_t N>
398 : _dims(space.getDimensions()) {
406 _vec_align.resize(total_size);
407 vec.resize(total_size);
408 return _vec_align.data();
413 for (
size_t i = 0; i < vec.size(); ++i) {
414 vec[i].create_ref(&_vec_align[i]);
416 return _vec_align.data();
420 auto* href =
const_cast<hobj_ref_t*
>(_vec_align.data());
421 for (
auto& ref : vec) {
427 std::vector<typename type_of_array<hobj_ref_t>::type>
_vec_align;
438 #endif // H5CONVERTER_MISC_HPP