HighFive 2.7.1
HighFive - Header-only C++ HDF5 interface
Loading...
Searching...
No Matches
H5ReadWrite_misc.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Blue Brain Project
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#pragma once
10
11#include <H5Tpublic.h>
12#include "H5Utils.hpp"
13
14namespace HighFive {
15
16namespace details {
17
18template <typename T>
19using unqualified_t = typename std::remove_const<typename std::remove_reference<T>::type>::type;
20
21// Find the type of an eventual char array, otherwise void
22template <typename>
23struct type_char_array {
24 using type = void;
25};
26
27template <typename T>
28struct type_char_array<T*> {
29 using type = typename std::conditional<std::is_same<unqualified_t<T>, char>::value,
30 char*,
31 typename type_char_array<T>::type>::type;
32};
33
34template <typename T, std::size_t N>
35struct type_char_array<T[N]> {
36 using type = typename std::conditional<std::is_same<unqualified_t<T>, char>::value,
37 char[N],
38 typename type_char_array<T>::type>::type;
39};
40
41template <typename T>
42struct BufferInfo {
43 using type_no_const = typename std::remove_const<T>::type;
44 using elem_type = typename details::inspector<type_no_const>::base_type;
45 using char_array_t = typename details::type_char_array<type_no_const>::type;
46 static constexpr bool is_char_array = !std::is_same<char_array_t, void>::value;
47
48 enum Operation { read, write };
49 const Operation op;
50
51 template <class F>
52 BufferInfo(const DataType& dtype, F getName, Operation _op);
53
54 // member data for info depending on the destination dataset type
55 const bool is_fixed_len_string;
56 const size_t n_dimensions;
57 const DataType data_type;
58};
59
60// details implementation
61template <typename SrcStrT>
62struct string_type_checker {
63 static DataType getDataType(const DataType&, const DataType&);
64};
65
66template <>
67struct string_type_checker<void> {
68 inline static DataType getDataType(const DataType& element_type, const DataType& dtype) {
69 // TEMP. CHANGE: Ensure that the character set is properly configured to prevent
70 // converter issues on HDF5 <=v1.12.0 when loading ASCII strings first.
71 // See https://github.com/HDFGroup/hdf5/issues/544 for further information.
72 if (H5Tget_class(element_type.getId()) == H5T_STRING &&
73 H5Tget_cset(dtype.getId()) == H5T_CSET_ASCII) {
74 H5Tset_cset(element_type.getId(), H5T_CSET_ASCII);
75 }
76 return element_type;
77 }
78};
79
80template <std::size_t FixedLen>
81struct string_type_checker<char[FixedLen]> {
82 inline static DataType getDataType(const DataType& element_type, const DataType& dtype) {
83 DataType return_type = (dtype.isFixedLenStr()) ? AtomicType<char[FixedLen]>()
84 : element_type;
85 // TEMP. CHANGE: See string_type_checker<void> definition
86 if (H5Tget_cset(dtype.getId()) == H5T_CSET_ASCII) {
87 H5Tset_cset(return_type.getId(), H5T_CSET_ASCII);
88 }
89 return return_type;
90 }
91};
92
93template <>
94struct string_type_checker<char*> {
95 inline static DataType getDataType(const DataType&, const DataType& dtype) {
96 if (dtype.isFixedLenStr())
97 throw DataSetException("Can't output variable-length to fixed-length strings");
98 // TEMP. CHANGE: See string_type_checker<void> definition
99 DataType return_type = AtomicType<std::string>();
100 if (H5Tget_cset(dtype.getId()) == H5T_CSET_ASCII) {
101 H5Tset_cset(return_type.getId(), H5T_CSET_ASCII);
102 }
103 return return_type;
104 }
105};
106
107template <typename T>
108template <class F>
109BufferInfo<T>::BufferInfo(const DataType& dtype, F getName, Operation _op)
110 : op(_op)
111 , is_fixed_len_string(dtype.isFixedLenStr())
112 // In case we are using Fixed-len strings we need to subtract one dimension
113 , n_dimensions(details::inspector<type_no_const>::recursive_ndim -
114 ((is_fixed_len_string && is_char_array) ? 1 : 0))
115 , data_type(
116 string_type_checker<char_array_t>::getDataType(create_datatype<elem_type>(), dtype)) {
117 if (is_fixed_len_string && std::is_same<elem_type, std::string>::value) {
118 throw DataSetException(
119 "Can't output std::string as fixed-length. "
120 "Use raw arrays or FixedLenStringArray");
121 }
122 // We warn. In case they are really not convertible an exception will rise on read/write
123 if (dtype.getClass() != data_type.getClass()) {
124 HIGHFIVE_LOG_WARN(getName() + "\": data and hdf5 dataset have different types: " +
125 data_type.string() + " -> " + dtype.string());
126 } else if ((dtype.getClass() & data_type.getClass()) == DataTypeClass::Float) {
128 (op == read) && (dtype.getSize() > data_type.getSize()),
129 getName() + "\": hdf5 dataset has higher floating point precision than data on read: " +
130 dtype.string() + " -> " + data_type.string());
131
133 (op == write) && (dtype.getSize() < data_type.getSize()),
134 getName() +
135 "\": data has higher floating point precision than hdf5 dataset on write: " +
136 data_type.string() + " -> " + dtype.string());
137 }
138}
139
140} // namespace details
141
142} // namespace HighFive
#define HIGHFIVE_LOG_WARN_IF(cond, message)
Definition H5Utility.hpp:190
#define HIGHFIVE_LOG_WARN(message)
Definition H5Utility.hpp:186
Definition H5_definitions.hpp:15
DataType create_datatype()
Create a DataType instance representing type T.
Definition H5DataType_misc.hpp:472
typename std::remove_const< typename std::remove_reference< T >::type >::type unqualified_t
Definition H5Converter_misc.hpp:123