File indexing completed on 2025-09-17 09:02:00
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
0058
0059
0060
0061 class DataType: public Object {
0062 public:
0063 bool operator==(const DataType& other) const;
0064
0065 bool operator!=(const DataType& other) const;
0066
0067
0068
0069
0070 DataTypeClass getClass() const;
0071
0072
0073
0074
0075
0076
0077
0078 size_t getSize() const;
0079
0080
0081
0082
0083 std::string string() const;
0084
0085
0086
0087
0088 bool isVariableStr() const;
0089
0090
0091
0092
0093 bool isFixedLenStr() const;
0094
0095
0096
0097
0098 StringType asStringType() const;
0099
0100
0101
0102
0103 bool empty() const noexcept;
0104
0105
0106 bool isReference() const;
0107
0108
0109 DataTypeCreateProps getCreatePropertyList() const {
0110 return details::get_plist<DataTypeCreateProps>(*this, H5Tget_create_plist);
0111 }
0112
0113 protected:
0114 using Object::Object;
0115
0116 friend class Attribute;
0117 friend class File;
0118 friend class DataSet;
0119 friend class CompoundType;
0120 template <typename Derivate>
0121 friend class NodeTraits;
0122 };
0123
0124
0125 enum class CharacterSet : std::underlying_type<H5T_cset_t>::type {
0126 Ascii = H5T_CSET_ASCII,
0127 Utf8 = H5T_CSET_UTF8,
0128 };
0129
0130 class StringType: public DataType {
0131 public:
0132
0133
0134
0135 CharacterSet getCharacterSet() const;
0136
0137
0138
0139
0140 StringPadding getPadding() const;
0141
0142 protected:
0143 using DataType::DataType;
0144 friend class DataType;
0145 };
0146
0147 class FixedLengthStringType: public StringType {
0148 public:
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 FixedLengthStringType(size_t size,
0170 StringPadding padding,
0171 CharacterSet character_set = CharacterSet::Ascii);
0172 };
0173
0174 class VariableLengthStringType: public StringType {
0175 public:
0176
0177
0178
0179 VariableLengthStringType(CharacterSet character_set = CharacterSet::Ascii);
0180 };
0181
0182
0183
0184
0185
0186
0187
0188 template <typename T>
0189 class AtomicType: public DataType {
0190 public:
0191 AtomicType();
0192
0193 using basic_type = T;
0194 };
0195
0196
0197
0198
0199
0200 class CompoundType: public DataType {
0201 public:
0202
0203
0204 struct member_def {
0205 member_def(std::string t_name, DataType t_base_type, size_t t_offset = 0)
0206 : name(std::move(t_name))
0207 , base_type(std::move(t_base_type))
0208 , offset(t_offset) {}
0209 std::string name;
0210 DataType base_type;
0211 size_t offset;
0212 };
0213
0214 CompoundType(const CompoundType& other) = default;
0215
0216
0217
0218
0219
0220 inline CompoundType(const std::vector<member_def>& t_members, size_t size = 0)
0221 : members(t_members) {
0222 create(size);
0223 }
0224 inline CompoundType(std::vector<member_def>&& t_members, size_t size = 0)
0225 : members(std::move(t_members)) {
0226 create(size);
0227 }
0228 inline CompoundType(const std::initializer_list<member_def>& t_members, size_t size = 0)
0229 : members(t_members) {
0230 create(size);
0231 }
0232
0233
0234
0235
0236 inline CompoundType(DataType&& type)
0237 : DataType(type) {
0238 if (getClass() != DataTypeClass::Compound) {
0239 std::ostringstream ss;
0240 ss << "hid " << _hid << " does not refer to a compound data type";
0241 throw DataTypeException(ss.str());
0242 }
0243 size_t n_members = static_cast<size_t>(detail::h5t_get_nmembers(_hid));
0244 members.reserve(n_members);
0245 for (unsigned i = 0; i < n_members; i++) {
0246 char* name = detail::h5t_get_member_name(_hid, i);
0247 size_t offset = detail::h5t_get_member_offset(_hid, i);
0248 hid_t member_hid = detail::h5t_get_member_type(_hid, i);
0249 DataType member_type{member_hid};
0250 members.emplace_back(std::string(name), member_type, offset);
0251
0252 detail::h5_free_memory(name);
0253 }
0254 }
0255
0256
0257
0258
0259 inline void commit(const Object& object, const std::string& name) const;
0260
0261
0262 inline const std::vector<member_def>& getMembers() const noexcept {
0263 return members;
0264 }
0265
0266 private:
0267
0268 std::vector<member_def> members;
0269
0270
0271
0272
0273 void create(size_t size = 0);
0274 };
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 template <typename T>
0298 class EnumType: public DataType {
0299 public:
0300
0301
0302 struct member_def {
0303 member_def(const std::string& t_name, T t_value)
0304 : name(t_name)
0305 , value(std::move(t_value)) {}
0306 std::string name;
0307 T value;
0308 };
0309
0310 EnumType(const EnumType& other) = default;
0311
0312 EnumType(const std::vector<member_def>& t_members)
0313 : members(t_members) {
0314 static_assert(std::is_enum<T>::value, "EnumType<T>::create takes only enum");
0315 if (members.empty()) {
0316 HDF5ErrMapper::ToException<DataTypeException>(
0317 "Could not create an enum without members");
0318 }
0319 create();
0320 }
0321
0322 EnumType(std::initializer_list<member_def> t_members)
0323 : EnumType(std::vector<member_def>(t_members)) {}
0324
0325
0326
0327
0328 void commit(const Object& object, const std::string& name) const;
0329
0330 private:
0331 std::vector<member_def> members;
0332
0333 void create();
0334 };
0335
0336
0337
0338 template <typename T>
0339 DataType create_datatype();
0340
0341
0342
0343 template <typename T>
0344 DataType create_and_check_datatype();
0345
0346
0347 namespace deprecated {
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 template <std::size_t N>
0358 class FixedLenStringArray {
0359 public:
0360 FixedLenStringArray() = default;
0361
0362
0363
0364
0365
0366
0367 FixedLenStringArray(const char array[][N], std::size_t n_strings);
0368
0369
0370
0371
0372
0373
0374 explicit FixedLenStringArray(const std::vector<std::string>& vec);
0375
0376 FixedLenStringArray(const std::string* iter_begin, const std::string* iter_end);
0377
0378 FixedLenStringArray(const std::initializer_list<std::string>&);
0379
0380
0381
0382
0383 void push_back(const std::string&);
0384
0385 void push_back(const std::array<char, N>&);
0386
0387
0388
0389
0390 std::string getString(std::size_t index) const;
0391
0392
0393 inline const char* operator[](std::size_t i) const noexcept {
0394 return datavec[i].data();
0395 }
0396 inline const char* at(std::size_t i) const {
0397 return datavec.at(i).data();
0398 }
0399 inline bool empty() const noexcept {
0400 return datavec.empty();
0401 }
0402 inline std::size_t size() const noexcept {
0403 return datavec.size();
0404 }
0405 inline void resize(std::size_t n) {
0406 datavec.resize(n);
0407 }
0408 inline const char* front() const {
0409 return datavec.front().data();
0410 }
0411 inline const char* back() const {
0412 return datavec.back().data();
0413 }
0414 inline char* data() noexcept {
0415 return datavec[0].data();
0416 }
0417 inline const char* data() const noexcept {
0418 return datavec[0].data();
0419 }
0420
0421 private:
0422 using vector_t = typename std::vector<std::array<char, N>>;
0423
0424 public:
0425
0426 using iterator = typename vector_t::iterator;
0427 using const_iterator = typename vector_t::const_iterator;
0428 using reverse_iterator = typename vector_t::reverse_iterator;
0429 using const_reverse_iterator = typename vector_t::const_reverse_iterator;
0430 using value_type = typename vector_t::value_type;
0431
0432 inline iterator begin() noexcept {
0433 return datavec.begin();
0434 }
0435 inline iterator end() noexcept {
0436 return datavec.end();
0437 }
0438 inline const_iterator begin() const noexcept {
0439 return datavec.begin();
0440 }
0441 inline const_iterator cbegin() const noexcept {
0442 return datavec.cbegin();
0443 }
0444 inline const_iterator end() const noexcept {
0445 return datavec.end();
0446 }
0447 inline const_iterator cend() const noexcept {
0448 return datavec.cend();
0449 }
0450 inline reverse_iterator rbegin() noexcept {
0451 return datavec.rbegin();
0452 }
0453 inline reverse_iterator rend() noexcept {
0454 return datavec.rend();
0455 }
0456 inline const_reverse_iterator rbegin() const noexcept {
0457 return datavec.rbegin();
0458 }
0459 inline const_reverse_iterator rend() const noexcept {
0460 return datavec.rend();
0461 }
0462
0463 private:
0464 vector_t datavec;
0465 };
0466 }
0467
0468 template <size_t N>
0469 using FixedLenStringArray H5_DEPRECATED_USING("Use 'std::vector<std::string>'.") =
0470 deprecated::FixedLenStringArray<N>;
0471
0472 }
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 #define HIGHFIVE_REGISTER_TYPE(type, function) \
0491 template <> \
0492 inline HighFive::DataType HighFive::create_datatype<type>() { \
0493 return function(); \
0494 }
0495
0496 #include "bits/H5DataType_misc.hpp"