File indexing completed on 2026-05-21 08:26:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <type_traits>
0012 #include <vector>
0013
0014 #include <H5Tpublic.h>
0015
0016 #include "H5Object.hpp"
0017 #include "bits/H5Utils.hpp"
0018
0019 #include "bits/string_padding.hpp"
0020 #include "H5PropertyList.hpp"
0021
0022 #include "bits/h5_wrapper.hpp"
0023 #include "bits/h5t_wrapper.hpp"
0024
0025 namespace HighFive {
0026
0027
0028
0029
0030
0031 enum class DataTypeClass {
0032 Time = 1 << 1,
0033 Integer = 1 << 2,
0034 Float = 1 << 3,
0035 String = 1 << 4,
0036 BitField = 1 << 5,
0037 Opaque = 1 << 6,
0038 Compound = 1 << 7,
0039 Reference = 1 << 8,
0040 Enum = 1 << 9,
0041 VarLen = 1 << 10,
0042 Array = 1 << 11,
0043 Invalid = 0
0044 };
0045
0046 inline DataTypeClass operator|(DataTypeClass lhs, DataTypeClass rhs) {
0047 using T = std::underlying_type<DataTypeClass>::type;
0048 return static_cast<DataTypeClass>(static_cast<T>(lhs) | static_cast<T>(rhs));
0049 }
0050
0051 inline DataTypeClass operator&(DataTypeClass lhs, DataTypeClass rhs) {
0052 using T = std::underlying_type<DataTypeClass>::type;
0053 return static_cast<DataTypeClass>(static_cast<T>(lhs) & static_cast<T>(rhs));
0054 }
0055
0056 class StringType;
0057 class IntegerType;
0058
0059
0060
0061
0062 class DataType: public Object {
0063 public:
0064 bool operator==(const DataType& other) const;
0065
0066 bool operator!=(const DataType& other) const;
0067
0068
0069
0070
0071 DataTypeClass getClass() const;
0072
0073
0074
0075
0076
0077
0078
0079 size_t getSize() const;
0080
0081
0082
0083
0084 std::string string() const;
0085
0086
0087
0088
0089 bool isVariableStr() const;
0090
0091
0092
0093
0094 bool isFixedLenStr() const;
0095
0096
0097
0098
0099 StringType asStringType() const;
0100
0101
0102
0103
0104 IntegerType asIntegerType() const;
0105
0106
0107
0108
0109 bool empty() const noexcept;
0110
0111
0112 bool isReference() const;
0113
0114
0115 DataTypeCreateProps getCreatePropertyList() const {
0116 return details::get_plist<DataTypeCreateProps>(*this, H5Tget_create_plist);
0117 }
0118
0119 protected:
0120 using Object::Object;
0121
0122 friend class Attribute;
0123 friend class File;
0124 friend class DataSet;
0125 friend class CompoundType;
0126 template <typename Derivate>
0127 friend class NodeTraits;
0128 };
0129
0130
0131 enum class CharacterSet : std::underlying_type<H5T_cset_t>::type {
0132 Ascii = H5T_CSET_ASCII,
0133 Utf8 = H5T_CSET_UTF8,
0134 };
0135
0136 class StringType: public DataType {
0137 public:
0138
0139
0140
0141 CharacterSet getCharacterSet() const;
0142
0143
0144
0145
0146 StringPadding getPadding() const;
0147
0148 protected:
0149 using DataType::DataType;
0150 friend class DataType;
0151 };
0152
0153 class FixedLengthStringType: public StringType {
0154 public:
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 FixedLengthStringType(size_t size,
0176 StringPadding padding,
0177 CharacterSet character_set = CharacterSet::Ascii);
0178 };
0179
0180 class VariableLengthStringType: public StringType {
0181 public:
0182
0183
0184
0185 explicit VariableLengthStringType(CharacterSet character_set = CharacterSet::Ascii);
0186 };
0187
0188
0189
0190
0191
0192
0193
0194 class IntegerType: public DataType {
0195 public:
0196 bool isSigned() {
0197 return detail::h5t_get_sign(getId()) != H5T_SGN_NONE;
0198 }
0199
0200 protected:
0201 using DataType::DataType;
0202 friend class DataType;
0203 };
0204
0205
0206
0207
0208
0209
0210 template <typename T>
0211 class AtomicType: public DataType {
0212 public:
0213 AtomicType();
0214
0215 using basic_type = T;
0216 };
0217
0218
0219
0220
0221
0222 class CompoundType: public DataType {
0223 public:
0224
0225
0226 struct member_def {
0227 member_def(std::string t_name, DataType t_base_type, size_t t_offset = 0)
0228 : name(std::move(t_name))
0229 , base_type(std::move(t_base_type))
0230 , offset(t_offset) {}
0231 std::string name;
0232 DataType base_type;
0233 size_t offset;
0234 };
0235
0236
0237
0238
0239
0240 inline CompoundType(const std::vector<member_def>& t_members, size_t size = 0)
0241 : members(t_members) {
0242 create(size);
0243 }
0244 inline CompoundType(std::vector<member_def>&& t_members, size_t size = 0)
0245 : members(std::move(t_members)) {
0246 create(size);
0247 }
0248 inline CompoundType(const std::initializer_list<member_def>& t_members, size_t size = 0)
0249 : members(t_members) {
0250 create(size);
0251 }
0252
0253
0254
0255
0256 inline explicit CompoundType(DataType&& type)
0257 : DataType(type) {
0258 if (getClass() != DataTypeClass::Compound) {
0259 std::ostringstream ss;
0260 ss << "hid " << _hid << " does not refer to a compound data type";
0261 throw DataTypeException(ss.str());
0262 }
0263 size_t n_members = static_cast<size_t>(detail::h5t_get_nmembers(_hid));
0264 members.reserve(n_members);
0265 for (unsigned i = 0; i < n_members; i++) {
0266 char* name = detail::h5t_get_member_name(_hid, i);
0267 size_t offset = detail::h5t_get_member_offset(_hid, i);
0268 hid_t member_hid = detail::h5t_get_member_type(_hid, i);
0269 DataType member_type{member_hid};
0270 members.emplace_back(std::string(name), member_type, offset);
0271
0272 detail::h5_free_memory(name);
0273 }
0274 }
0275
0276
0277
0278
0279 inline void commit(const Object& object, const std::string& name) const;
0280
0281
0282 inline const std::vector<member_def>& getMembers() const noexcept {
0283 return members;
0284 }
0285
0286 private:
0287
0288 std::vector<member_def> members;
0289
0290
0291
0292
0293 void create(size_t size = 0);
0294 };
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 template <typename T>
0318 class EnumType: public DataType {
0319 public:
0320
0321
0322 struct member_def {
0323 member_def(const std::string& t_name, T t_value)
0324 : name(t_name)
0325 , value(std::move(t_value)) {}
0326 std::string name;
0327 T value;
0328 };
0329
0330 EnumType(const EnumType& other) = default;
0331
0332 EnumType(const std::vector<member_def>& t_members)
0333 : members(t_members) {
0334 static_assert(std::is_enum<T>::value, "EnumType<T>::create takes only enum");
0335 if (members.empty()) {
0336 HDF5ErrMapper::ToException<DataTypeException>(
0337 "Could not create an enum without members");
0338 }
0339 create();
0340 }
0341
0342 EnumType(std::initializer_list<member_def> t_members)
0343 : EnumType(std::vector<member_def>(t_members)) {}
0344
0345
0346
0347
0348 void commit(const Object& object, const std::string& name) const;
0349
0350 private:
0351 std::vector<member_def> members;
0352
0353 void create();
0354 };
0355
0356
0357
0358 template <typename T>
0359 DataType create_datatype();
0360
0361
0362
0363 template <typename T>
0364 DataType create_and_check_datatype();
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 #define HIGHFIVE_REGISTER_TYPE(type, function) \
0384 template <> \
0385 inline HighFive::DataType HighFive::create_datatype<type>() { \
0386 return function(); \
0387 }
0388
0389 #include "bits/H5DataType_misc.hpp"