Skip to content

Commit 5b05204

Browse files
authored
add: support for checking sign of integer datatype. (#78)
An integer HDF5 datatype (i.e. one that has class `H5T_INTEGER`) can be signed or unsigned. This commit adds a class `IntegerType` which supports the method `isSigned`. Intended use: auto dtype = /* obtain datatype */; if(dtype.getClass() == DataTypeClass::Integer) { auto int_type = dtype.asIntegerType(); if(int_type.isSigned()) { // ... }
1 parent ba54669 commit 5b05204

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

include/highfive/H5DataType.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ inline DataTypeClass operator&(DataTypeClass lhs, DataTypeClass rhs) {
5454
}
5555

5656
class StringType;
57+
class IntegerType;
5758

5859
///
5960
/// \brief HDF5 Data Type
@@ -97,6 +98,11 @@ class DataType: public Object {
9798
///
9899
StringType asStringType() const;
99100

101+
///
102+
/// \brief Returns this datatype as a `IntegerType`.
103+
///
104+
IntegerType asIntegerType() const;
105+
100106
///
101107
/// \brief Check the DataType was default constructed.
102108
///
@@ -179,6 +185,22 @@ class VariableLengthStringType: public StringType {
179185
explicit VariableLengthStringType(CharacterSet character_set = CharacterSet::Ascii);
180186
};
181187

188+
///
189+
/// \brief An Integer datatype (i.e. H5T_INTEGER).
190+
///
191+
/// Provides access to the API that's only valid for integers. Use
192+
/// DataType::asIntegerType to convert from a generic DataType.
193+
///
194+
class IntegerType: public DataType {
195+
public:
196+
bool isSigned() {
197+
return detail::h5t_get_sign(getId()) != H5T_SGN_NONE;
198+
}
199+
200+
protected:
201+
using DataType::DataType;
202+
friend class DataType;
203+
};
182204

183205
///
184206
/// \brief create an HDF5 DataType from a C++ type

include/highfive/bits/H5DataType_misc.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ inline StringType DataType::asStringType() const {
7373
return StringType(_hid);
7474
}
7575

76+
inline IntegerType DataType::asIntegerType() const {
77+
if (getClass() != DataTypeClass::Integer) {
78+
throw DataTypeException("Invalid conversion to IntegerType.");
79+
}
80+
81+
if (isValid()) {
82+
detail::h5i_inc_ref(_hid);
83+
}
84+
85+
return IntegerType(_hid);
86+
}
87+
7688
inline std::string DataType::string() const {
7789
return type_class_string(getClass()) + std::to_string(getSize() * 8);
7890
}

include/highfive/bits/h5t_wrapper.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ inline hsize_t h5t_get_size(hid_t hid) {
2424
return size;
2525
}
2626

27+
inline H5T_sign_t h5t_get_sign(hid_t type_id) {
28+
auto sign = H5Tget_sign(type_id);
29+
if (sign == H5T_SGN_ERROR) {
30+
HDF5ErrMapper::ToException<DataTypeException>("Error getting the sign of datatype.");
31+
}
32+
return sign;
33+
}
34+
2735
inline H5T_cset_t h5t_get_cset(hid_t hid) {
2836
auto cset = H5Tget_cset(hid);
2937
if (cset == H5T_CSET_ERROR) {

tests/unit/tests_high_five_base.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,6 +2332,21 @@ TEST_CASE("HighFiveDataTypeClass") {
23322332
CHECK(((Float | String) & String) == String);
23332333
}
23342334

2335+
TEST_CASE("HighFiveIntegerType") {
2336+
SECTION("signed int") {
2337+
auto dtype = create_datatype<int>().asIntegerType();
2338+
CHECK(dtype.isSigned());
2339+
}
2340+
SECTION("unsigned int") {
2341+
auto dtype = create_datatype<unsigned int>().asIntegerType();
2342+
CHECK(!dtype.isSigned());
2343+
}
2344+
SECTION("invalid conversion") {
2345+
auto dtype = create_datatype<double>();
2346+
CHECK_THROWS(dtype.asIntegerType());
2347+
}
2348+
}
2349+
23352350
#ifdef HIGHFIVE_TEST_EIGEN
23362351

23372352
template <typename T>

0 commit comments

Comments
 (0)