File indexing completed on 2025-04-19 08:55:35
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 FixedLengthStringType(size_t size,
0168 StringPadding padding,
0169 CharacterSet character_set = CharacterSet::Ascii);
0170 };
0171
0172 class VariableLengthStringType: public StringType {
0173 public:
0174
0175
0176
0177 VariableLengthStringType(CharacterSet character_set = CharacterSet::Ascii);
0178 };
0179
0180
0181
0182
0183
0184
0185
0186 template <typename T>
0187 class AtomicType: public DataType {
0188 public:
0189 AtomicType();
0190
0191 using basic_type = T;
0192 };
0193
0194
0195
0196
0197
0198 class CompoundType: public DataType {
0199 public:
0200
0201
0202 struct member_def {
0203 member_def(std::string t_name, DataType t_base_type, size_t t_offset = 0)
0204 : name(std::move(t_name))
0205 , base_type(std::move(t_base_type))
0206 , offset(t_offset) {}
0207 std::string name;
0208 DataType base_type;
0209 size_t offset;
0210 };
0211
0212 CompoundType(const CompoundType& other) = default;
0213
0214
0215
0216
0217
0218 inline CompoundType(const std::vector<member_def>& t_members, size_t size = 0)
0219 : members(t_members) {
0220 create(size);
0221 }
0222 inline CompoundType(std::vector<member_def>&& t_members, size_t size = 0)
0223 : members(std::move(t_members)) {
0224 create(size);
0225 }
0226 inline CompoundType(const std::initializer_list<member_def>& t_members, size_t size = 0)
0227 : members(t_members) {
0228 create(size);
0229 }
0230
0231
0232
0233
0234 inline CompoundType(DataType&& type)
0235 : DataType(type) {
0236 if (getClass() != DataTypeClass::Compound) {
0237 std::ostringstream ss;
0238 ss << "hid " << _hid << " does not refer to a compound data type";
0239 throw DataTypeException(ss.str());
0240 }
0241 size_t n_members = static_cast<size_t>(detail::h5t_get_nmembers(_hid));
0242 members.reserve(n_members);
0243 for (unsigned i = 0; i < n_members; i++) {
0244 char* name = detail::h5t_get_member_name(_hid, i);
0245 size_t offset = detail::h5t_get_member_offset(_hid, i);
0246 hid_t member_hid = detail::h5t_get_member_type(_hid, i);
0247 DataType member_type{member_hid};
0248 members.emplace_back(std::string(name), member_type, offset);
0249
0250 detail::h5_free_memory(name);
0251 }
0252 }
0253
0254
0255
0256
0257 inline void commit(const Object& object, const std::string& name) const;
0258
0259
0260 inline const std::vector<member_def>& getMembers() const noexcept {
0261 return members;
0262 }
0263
0264 private:
0265
0266 std::vector<member_def> members;
0267
0268
0269
0270
0271 void create(size_t size = 0);
0272 };
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295 template <typename T>
0296 class EnumType: public DataType {
0297 public:
0298
0299
0300 struct member_def {
0301 member_def(const std::string& t_name, T t_value)
0302 : name(t_name)
0303 , value(std::move(t_value)) {}
0304 std::string name;
0305 T value;
0306 };
0307
0308 EnumType(const EnumType& other) = default;
0309
0310 EnumType(const std::vector<member_def>& t_members)
0311 : members(t_members) {
0312 static_assert(std::is_enum<T>::value, "EnumType<T>::create takes only enum");
0313 if (members.empty()) {
0314 HDF5ErrMapper::ToException<DataTypeException>(
0315 "Could not create an enum without members");
0316 }
0317 create();
0318 }
0319
0320 EnumType(std::initializer_list<member_def> t_members)
0321 : EnumType(std::vector<member_def>(t_members)) {}
0322
0323
0324
0325
0326 void commit(const Object& object, const std::string& name) const;
0327
0328 private:
0329 std::vector<member_def> members;
0330
0331 void create();
0332 };
0333
0334
0335
0336 template <typename T>
0337 DataType create_datatype();
0338
0339
0340
0341 template <typename T>
0342 DataType create_and_check_datatype();
0343
0344
0345 namespace deprecated {
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355 template <std::size_t N>
0356 class FixedLenStringArray {
0357 public:
0358 FixedLenStringArray() = default;
0359
0360
0361
0362
0363
0364
0365 FixedLenStringArray(const char array[][N], std::size_t n_strings);
0366
0367
0368
0369
0370
0371
0372 explicit FixedLenStringArray(const std::vector<std::string>& vec);
0373
0374 FixedLenStringArray(const std::string* iter_begin, const std::string* iter_end);
0375
0376 FixedLenStringArray(const std::initializer_list<std::string>&);
0377
0378
0379
0380
0381 void push_back(const std::string&);
0382
0383 void push_back(const std::array<char, N>&);
0384
0385
0386
0387
0388 std::string getString(std::size_t index) const;
0389
0390
0391 inline const char* operator[](std::size_t i) const noexcept {
0392 return datavec[i].data();
0393 }
0394 inline const char* at(std::size_t i) const {
0395 return datavec.at(i).data();
0396 }
0397 inline bool empty() const noexcept {
0398 return datavec.empty();
0399 }
0400 inline std::size_t size() const noexcept {
0401 return datavec.size();
0402 }
0403 inline void resize(std::size_t n) {
0404 datavec.resize(n);
0405 }
0406 inline const char* front() const {
0407 return datavec.front().data();
0408 }
0409 inline const char* back() const {
0410 return datavec.back().data();
0411 }
0412 inline char* data() noexcept {
0413 return datavec[0].data();
0414 }
0415 inline const char* data() const noexcept {
0416 return datavec[0].data();
0417 }
0418
0419 private:
0420 using vector_t = typename std::vector<std::array<char, N>>;
0421
0422 public:
0423
0424 using iterator = typename vector_t::iterator;
0425 using const_iterator = typename vector_t::const_iterator;
0426 using reverse_iterator = typename vector_t::reverse_iterator;
0427 using const_reverse_iterator = typename vector_t::const_reverse_iterator;
0428 using value_type = typename vector_t::value_type;
0429
0430 inline iterator begin() noexcept {
0431 return datavec.begin();
0432 }
0433 inline iterator end() noexcept {
0434 return datavec.end();
0435 }
0436 inline const_iterator begin() const noexcept {
0437 return datavec.begin();
0438 }
0439 inline const_iterator cbegin() const noexcept {
0440 return datavec.cbegin();
0441 }
0442 inline const_iterator end() const noexcept {
0443 return datavec.end();
0444 }
0445 inline const_iterator cend() const noexcept {
0446 return datavec.cend();
0447 }
0448 inline reverse_iterator rbegin() noexcept {
0449 return datavec.rbegin();
0450 }
0451 inline reverse_iterator rend() noexcept {
0452 return datavec.rend();
0453 }
0454 inline const_reverse_iterator rbegin() const noexcept {
0455 return datavec.rbegin();
0456 }
0457 inline const_reverse_iterator rend() const noexcept {
0458 return datavec.rend();
0459 }
0460
0461 private:
0462 vector_t datavec;
0463 };
0464 }
0465
0466 template <size_t N>
0467 using FixedLenStringArray H5_DEPRECATED_USING("Use 'std::vector<std::string>'.") =
0468 deprecated::FixedLenStringArray<N>;
0469
0470 }
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 #define HIGHFIVE_REGISTER_TYPE(type, function) \
0489 template <> \
0490 inline HighFive::DataType HighFive::create_datatype<type>() { \
0491 return function(); \
0492 }
0493
0494 #include "bits/H5DataType_misc.hpp"