9#ifndef H5DATATYPE_MISC_HPP
10#define H5DATATYPE_MISC_HPP
23inline DataTypeClass convert_type_class(
const H5T_class_t& tclass);
24inline std::string type_class_string(DataTypeClass);
25inline hid_t create_string(std::size_t length);
29 return _hid == H5I_INVALID_HID;
33 return convert_type_class(H5Tget_class(_hid));
37 return H5Tget_size(_hid);
43 htri_t isT1_VarLen = H5Tis_variable_str(_hid);
44 htri_t isT2_VarLen = H5Tis_variable_str(other._hid);
45 if (isT1_VarLen > 0 && isT2_VarLen > 0)
48 if (isT1_VarLen > 0 && isT1_VarLen <= 0 ||
49 isT1_VarLen <= 0 && isT1_VarLen > 0)
52 return (H5Tequal(_hid, other._hid) > 0);
56 auto var_value = H5Tis_variable_str(_hid);
58 HDF5ErrMapper::ToException<DataTypeException>(
59 "Unable to define datatype size to variable");
61 return static_cast<bool>(var_value);
69 return H5Tequal(_hid, H5T_STD_REF_OBJ) > 0;
76inline bool DataType::operator!=(
const DataType& other)
const {
77 return !(*
this == other);
87 if (endian == Little){
88 _hid = H5Tcopy(H5T_STD_I8LE);
89 }
else if (endian == Big){
90 _hid = H5Tcopy(H5T_STD_I8BE);
92 _hid = H5Tcopy(H5T_NATIVE_CHAR);
97inline AtomicType<signed char>::AtomicType(Endian endian) {
98 if (endian == Little){
99 _hid = H5Tcopy(H5T_STD_I8LE);
100 }
else if (endian == Big){
101 _hid = H5Tcopy(H5T_STD_I8BE);
103 _hid = H5Tcopy(H5T_NATIVE_CHAR);
108inline AtomicType<unsigned char>::AtomicType(Endian endian) {
109 if (endian == Little){
110 _hid = H5Tcopy(H5T_STD_U8LE);
111 }
else if (endian == Big){
112 _hid = H5Tcopy(H5T_STD_U8BE);
114 _hid = H5Tcopy(H5T_NATIVE_UCHAR);
120inline AtomicType<short>::AtomicType(Endian endian) {
121 if (endian == Little){
122 _hid = H5Tcopy(H5T_STD_I16LE);
123 }
else if (endian == Big){
124 _hid = H5Tcopy(H5T_STD_I16BE);
126 _hid = H5Tcopy(H5T_NATIVE_SHORT);
131inline AtomicType<unsigned short>::AtomicType(Endian endian) {
132 if (endian == Little){
133 _hid = H5Tcopy(H5T_STD_U16LE);
134 }
else if (endian == Big){
135 _hid = H5Tcopy(H5T_STD_U16BE);
137 _hid = H5Tcopy(H5T_NATIVE_USHORT);
143inline AtomicType<int>::AtomicType(Endian endian) {
144 if (endian == Little){
145 _hid = H5Tcopy(H5T_STD_I32LE);
146 }
else if (endian == Big){
147 _hid = H5Tcopy(H5T_STD_I32BE);
149 _hid = H5Tcopy(H5T_NATIVE_INT);
154inline AtomicType<unsigned>::AtomicType(Endian endian) {
155 if (endian == Little){
156 _hid = H5Tcopy(H5T_STD_U32LE);
157 }
else if (endian == Big){
158 _hid = H5Tcopy(H5T_STD_U32BE);
160 _hid = H5Tcopy(H5T_NATIVE_UINT);
166inline AtomicType<long>::AtomicType(Endian endian) {
167 if (endian == Little){
168 _hid = H5Tcopy(H5T_STD_I32LE);
169 }
else if (endian == Big){
170 _hid = H5Tcopy(H5T_STD_I32BE);
172 _hid = H5Tcopy(H5T_NATIVE_LONG);
177inline AtomicType<unsigned long>::AtomicType(Endian endian) {
178 if (endian == Little){
179 _hid = H5Tcopy(H5T_STD_U32LE);
180 }
else if (endian == Big){
181 _hid = H5Tcopy(H5T_STD_U32BE);
183 _hid = H5Tcopy(H5T_NATIVE_ULONG);
189inline AtomicType<long long>::AtomicType(Endian endian) {
190 if (endian == Little){
191 _hid = H5Tcopy(H5T_STD_I64LE);
192 }
else if (endian == Big){
193 _hid = H5Tcopy(H5T_STD_I64BE);
195 _hid = H5Tcopy(H5T_NATIVE_LLONG);
200inline AtomicType<unsigned long long>::AtomicType(Endian endian) {
201 if (endian == Little){
202 _hid = H5Tcopy(H5T_STD_U64LE);
203 }
else if (endian == Big){
204 _hid = H5Tcopy(H5T_STD_U64BE);
206 _hid = H5Tcopy(H5T_NATIVE_ULLONG);
212inline AtomicType<float>::AtomicType(Endian endian) {
213 if (endian == Little){
214 _hid = H5Tcopy(H5T_IEEE_F32LE);
215 }
else if (endian == Big){
216 _hid = H5Tcopy(H5T_IEEE_F32BE);
218 _hid = H5Tcopy(H5T_NATIVE_FLOAT);
223inline AtomicType<double>::AtomicType(Endian endian) {
224 if (endian == Little){
225 _hid = H5Tcopy(H5T_IEEE_F64LE);
226 }
else if (endian == Big){
227 _hid = H5Tcopy(H5T_IEEE_F64BE);
229 _hid = H5Tcopy(H5T_NATIVE_DOUBLE);
235inline AtomicType<bool>::AtomicType(Endian endian) {
236 if (endian == Little){
237 _hid = H5Tcopy(H5T_STD_I8LE);
238 }
else if (endian == Big){
239 _hid = H5Tcopy(H5T_STD_I8BE);
241 _hid = H5Tcopy(H5T_NATIVE_HBOOL);
247inline AtomicType<std::string>::AtomicType(Endian endian) {
248 _hid = create_string(H5T_VARIABLE);
253inline AtomicType<const char*>::AtomicType(Endian endian) {
254 _hid = create_string(H5T_VARIABLE);
259template <
size_t StrLen>
265template <
size_t StrLen>
273 if (endian == Little){
274 static struct ComplexType :
public Object {
276 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<double>));
278 H5Tinsert(_hid,
"r", 0, H5T_IEEE_F64LE);
279 H5Tinsert(_hid,
"i",
sizeof(
double), H5T_IEEE_F64LE);
282 _hid = H5Tcopy(complexType.getId(
false));
283 }
else if (endian == Big){
284 static struct ComplexType :
public Object {
286 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<double>));
288 H5Tinsert(_hid,
"r", 0, H5T_IEEE_F64BE);
289 H5Tinsert(_hid,
"i",
sizeof(
double), H5T_IEEE_F64BE);
292 _hid = H5Tcopy(complexType.getId(
false));
294 static struct ComplexType :
public Object {
296 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<double>));
298 H5Tinsert(_hid,
"r", 0, H5T_NATIVE_DOUBLE);
299 H5Tinsert(_hid,
"i",
sizeof(
double), H5T_NATIVE_DOUBLE);
302 _hid = H5Tcopy(complexType.getId(
false));
307inline AtomicType<std::complex<float> >::AtomicType(Endian endian) {
308 if (endian == Little){
309 static struct ComplexType :
public Object {
311 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<float>));
313 H5Tinsert(_hid,
"r", 0, H5T_IEEE_F32LE);
314 H5Tinsert(_hid,
"i",
sizeof(
float), H5T_IEEE_F32LE);
317 _hid = H5Tcopy(complexType.getId(
false));
318 }
else if (endian == Big){
319 static struct ComplexType :
public Object {
321 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<float>));
323 H5Tinsert(_hid,
"r", 0, H5T_IEEE_F32BE);
324 H5Tinsert(_hid,
"i",
sizeof(
float), H5T_IEEE_F32BE);
327 _hid = H5Tcopy(complexType.getId(
false));
329 static struct ComplexType :
public Object {
331 _hid = H5Tcreate(H5T_COMPOUND,
sizeof(std::complex<float>));
333 H5Tinsert(_hid,
"r", 0, H5T_NATIVE_FLOAT);
334 H5Tinsert(_hid,
"i",
sizeof(
float), H5T_NATIVE_FLOAT);
337 _hid = H5Tcopy(complexType.getId(
false));
343AtomicType<T>::AtomicType(Endian endian) {
344 static_assert(details::inspector<T>::recursive_ndim == 0,
345 "Atomic types cant be arrays, except for char[] (fixed-len strings)");
346 static_assert(details::inspector<T>::recursive_ndim > 0,
"Type not supported");
352template <std::
size_t N>
353inline FixedLenStringArray<N>
354::FixedLenStringArray(
const char array[][N], std::size_t length) {
355 datavec.resize(length);
356 std::memcpy(datavec[0].data(), array[0].data(), N * length);
359template <std::
size_t N>
362 datavec.resize(
static_cast<std::size_t
>(iter_end - iter_begin));
363 for (
auto& dst_array : datavec) {
364 const char* src = (iter_begin++)->c_str();
365 const size_t length = std::min(N - 1 , std::strlen(src));
366 std::memcpy(dst_array.data(), src, length);
367 dst_array[length] = 0;
371template <std::
size_t N>
372inline FixedLenStringArray<N>
373::FixedLenStringArray(
const std::vector<std::string> & vec)
376template <std::
size_t N>
381template <std::
size_t N>
383 datavec.emplace_back();
384 const size_t length = std::min(N - 1 , src.length());
385 std::memcpy(datavec.back().data(), src.c_str(), length);
386 datavec.back()[length] = 0;
389template <std::
size_t N>
391 datavec.emplace_back();
392 std::copy(src.begin(), src.end(), datavec.back().data());
395template <std::
size_t N>
397 return std::string(datavec[i].data());
404 _hid = H5Tcopy(H5T_STD_REF_OBJ);
409#define _H5_STRUCT_PADDING(current_size, member_size) (((member_size) - (current_size)) % (member_size))
411inline void CompoundType::create(
size_t size) {
413 size_t current_size = 0, max_type_size = 0;
416 for (
auto& member: members) {
417 size_t member_size = H5Tget_size(member.base_type.getId(
false));
418 if (member_size == 0) {
419 throw DataTypeException(
"Cannot get size of DataType with hid: " +
420 std::to_string(member.base_type.getId(
false)));
425 member.offset = current_size + _H5_STRUCT_PADDING(current_size, member_size);
428 current_size = member.offset + member_size;
430 max_type_size = std::max(max_type_size, member_size);
433 size = current_size + _H5_STRUCT_PADDING(current_size, max_type_size);
437 if((_hid = H5Tcreate(H5T_COMPOUND, size)) < 0) {
438 HDF5ErrMapper::ToException<DataTypeException>(
439 "Could not create new compound datatype");
443 for (
const auto& member: members) {
444 if(H5Tinsert(_hid, member.name.c_str(), member.offset, member.base_type.getId(
false)) < 0) {
445 HDF5ErrMapper::ToException<DataTypeException>(
446 "Could not add new member to datatype"
452#undef _H5_STRUCT_PADDING
455 H5Tcommit2(
object.
getId(
false), name.c_str(),
getId(
false), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
458inline DataTypeClass CompoundType::getMemberClass(
const unsigned& member_no)
const {
459 return convert_type_class(H5Tget_member_class(_hid, member_no));
462inline int CompoundType::getMemberIndex(
const std::string& field_name)
const {
463 return H5Tget_member_index(_hid, field_name.c_str());
466inline std::string CompoundType::getMemberName(
const unsigned& field_idx)
const {
467 return std::string(H5Tget_member_name(_hid, field_idx));
470inline size_t CompoundType::getMemberOffset(
const unsigned& memb_no)
const {
471 return H5Tget_member_offset(_hid, memb_no);
475 return H5Tget_member_type(_hid, field_idx);
478inline int CompoundType::getNMembers()
const {
479 return H5Tget_nmembers(_hid);
485inline void EnumType<T>::create() {
487 if((_hid = H5Tenum_create(AtomicType<T>{}.getId(
false))) < 0) {
488 HDF5ErrMapper::ToException<DataTypeException>(
489 "Could not create new enum datatype");
493 for (
const auto& member: members) {
494 if(H5Tenum_insert(_hid, member.name.c_str(), &(member.value)) < 0) {
495 HDF5ErrMapper::ToException<DataTypeException>(
496 "Could not add new member to this enum datatype"
504 H5Tcommit2(
object.getId(
false), name.c_str(), getId(
false), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
509 return H5Tget_member_index(_hid, field_name.c_str());
513inline std::string EnumType<T>::getMemberName(
const unsigned& field_idx)
const {
514 return std::string(H5Tget_member_name(_hid, field_idx));
518inline void EnumType<T>::getMemberValue(
const unsigned& memb_no,
void *value)
const {
519 if (H5Tget_member_value(_hid, memb_no, value) < 0){
520 HDF5ErrMapper::ToException<DataTypeException>(
521 "Could not get member value for this enum datatype"
527inline int EnumType<T>::getNMembers()
const {
528 return H5Tget_nmembers(_hid);
535inline hid_t create_string(
size_t length){
536 hid_t _hid = H5Tcopy(H5T_C_S1);
537 if (H5Tset_size(_hid, length) < 0) {
538 HDF5ErrMapper::ToException<DataTypeException>(
539 "Unable to define datatype size to variable");
542 H5Tset_cset(_hid, H5T_CSET_UTF8);
547inline DataTypeClass convert_type_class(
const H5T_class_t& tclass) {
550 return DataTypeClass::Time;
552 return DataTypeClass::Integer;
554 return DataTypeClass::Float;
556 return DataTypeClass::String;
558 return DataTypeClass::BitField;
560 return DataTypeClass::Opaque;
562 return DataTypeClass::Compound;
564 return DataTypeClass::Reference;
566 return DataTypeClass::Enum;
568 return DataTypeClass::VarLen;
570 return DataTypeClass::Array;
574 return DataTypeClass::Invalid;
579inline std::string type_class_string(DataTypeClass tclass) {
581 case DataTypeClass::Time:
583 case DataTypeClass::Integer:
585 case DataTypeClass::Float:
587 case DataTypeClass::String:
589 case DataTypeClass::BitField:
591 case DataTypeClass::Opaque:
593 case DataTypeClass::Compound:
595 case DataTypeClass::Reference:
597 case DataTypeClass::Enum:
599 case DataTypeClass::VarLen:
601 case DataTypeClass::Array:
613inline DataType create_datatype() {
614 return AtomicType<T>();
619inline DataType create_and_check_datatype() {
621 DataType t = create_datatype<T>();
623 throw DataTypeException(
"Type given to create_and_check_datatype is not valid");
627 if (t.isVariableStr()) {
633 if(!t.isReference() && (
sizeof(T) != t.getSize())) {
634 std::ostringstream ss;
635 ss <<
"Size of array type " <<
sizeof(T)
636 <<
" != that of memory datatype " << t.getSize()
638 throw DataTypeException(ss.str());
create an HDF5 DataType from a C++ type
Definition H5DataType.hpp:124
void commit(const Object &object, const std::string &name) const
Commit datatype into the given Object.
Definition H5DataType_misc.hpp:454
hid_t getMemberType(const unsigned &field_idx) const
return predefined type specified by hdf5 macro like: H5T_C_S1, H5T_NATIVE_INT, H5T_IEEE_F32BE etc.
Definition H5DataType_misc.hpp:474
HDF5 Data Type.
Definition H5DataType.hpp:48
size_t getSize() const
Returns the length (in bytes) of this type elements.
Definition H5DataType_misc.hpp:36
std::string string() const
Returns a friendly description of the type (e.g. Float32)
Definition H5DataType_misc.hpp:80
bool operator==(const DataType &other) const
operator == Check if objects reside in the same file and equal to each other
Definition H5DataType_misc.hpp:72
bool isReference() const
Returns whether the type is a Reference.
Definition H5DataType_misc.hpp:68
bool empty() const noexcept
Check the DataType was default constructed. Such value might represent auto-detection of the datatype...
Definition H5DataType_misc.hpp:28
DataTypeClass getClass() const
Return the fundamental type.
Definition H5DataType_misc.hpp:32
virtual bool isTypeEqual(const DataType &other) const
isTypeEqual Unlike == operator this only checks if the data types are equal and do not check if they ...
Definition H5DataType_misc.hpp:42
bool isVariableStr() const
Returns whether the type is a variable-length string.
Definition H5DataType_misc.hpp:55
bool isFixedLenStr() const
Returns whether the type is a fixed-length string.
Definition H5DataType_misc.hpp:64
Create a enum HDF5 datatype.
Definition H5DataType.hpp:241
void commit(const Object &object, const std::string &name) const
Commit datatype into the given Object.
Definition H5DataType_misc.hpp:503
A structure representing a set of fixed-length strings.
Definition H5DataType.hpp:305
void push_back(const std::string &)
Append an std::string to the buffer structure.
Definition H5DataType_misc.hpp:382
std::string getString(std::size_t index) const
Retrieve a string from the structure as std::string.
Definition H5DataType_misc.hpp:396
Definition H5Object.hpp:55
hid_t getId(const bool &increaseRefCount=false) const noexcept
getId
Definition H5Object_misc.hpp:172
bool operator==(const Object &other) const
When coparing objects h5gt::File must be open.
Definition H5Object_misc.hpp:105