Templatized instantiation of H5_NATIVE_XXX types

Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

I would like the template instantiation to then return the correct H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae, there in bold red with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded to cover all primitive types) and am wondering if others find this useful enough (or something like it) that it ought to be included in HDF5 C++ interface?

// base class
template <class T> class HDF5TypeBase {
  public:
             HDF5TypeBase() {} ;
    virtual ~HDF5TypeBase() {};
};

// base class for type-specific template specializations to follow
template <class T> class HDF5Type : public HDF5TypeBase<T> {
  public:
    HDF5Type() : HDF5TypeBase<T>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_HERR; };
};

// int, H5T_NATIVE_INT specialization
template <> class HDF5Type<int> : public HDF5TypeBase<int> {
  public:
    HDF5Type() : HDF5TypeBase<int>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_INT; };
};

// float, H5T_NATIVE_FLOAT specialization
template <> class HDF5Type<float> : public HDF5TypeBase<float> {
  public:
    HDF5Type() : HDF5TypeBase<float>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };
};

// double, H5T_NATIVE_DOUBLE specialization
template <> class HDF5Type<double> : public HDF5TypeBase<double> {
  public:
    HDF5Type() : HDF5TypeBase<double>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };
};

This permits in the HDF5Type<T>().Type(), bold red, in the snipit above, to actually work

···

--
Mark C. Miller, LLNL

"In the end, we will remember not the words of
our enemies but the silence of our friends" - MLK

I had a similar need, but I think you are overthinking. No need to involve
any classes at all.

Try this:

inline hid_t hid_from_type(const char &) { return H5T_NATIVE_CHAR; }
inline hid_t hid_from_type(const signed char &) { return H5T_NATIVE_SCHAR; }
inline hid_t hid_from_type(const unsigned char &) { return
H5T_NATIVE_UCHAR; }

inline hid_t hid_from_type(const short &) { return H5T_NATIVE_SHORT; }
inline hid_t hid_from_type(const unsigned short &) { return
H5T_NATIVE_USHORT; }

inline hid_t hid_from_type(const int &) { return H5T_NATIVE_INT; }
inline hid_t hid_from_type(const unsigned &) { return H5T_NATIVE_UINT; }

inline hid_t hid_from_type(const long &) { return H5T_NATIVE_LONG; }
inline hid_t hid_from_type(const unsigned long &) { return
H5T_NATIVE_ULONG; }

inline hid_t hid_from_type(const long long &) { return H5T_NATIVE_LLONG; }
inline hid_t hid_from_type(const unsigned long long &) { return
H5T_NATIVE_ULLONG; }

inline hid_t hid_from_type(const float &) { return H5T_NATIVE_FLOAT; }
inline hid_t hid_from_type(const double &) { return H5T_NATIVE_DOUBLE; }

// And the coup de grace:

template <typename T>
inline hid_t hid_from_type() { return hid_from_type(T()); }

// Usage for your example:

hid_t dsid = H5Dcreate(fid, name, hid_from_type<T>(), spid, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT);

Kevin

···

On Mon, Feb 5, 2018 at 9:03 AM, Miller, Mark C. <miller86@llnl.gov> wrote:

Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the
following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name,
std::vector<T> const &vec, int d2size)

{

    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};

    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);

    hid_t dsid = H5Dcreate(fid, name, *HDF5Type<T>().Type()*, spid,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);

    H5Dclose(dsid);

    H5Sclose(spid);

}

I would like the template instantiation to then return the correct
H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae,
there in *bold red* with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for
this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded
to cover all primitive types) and am wondering if others find this useful
enough (or something like it) that it ought to be included in HDF5 C++
interface?

// base class

template <class T> class HDF5TypeBase {

  public:

             HDF5TypeBase() {} ;

    virtual ~HDF5TypeBase() {};

};

// base class for type-specific template specializations to follow

template <class T> class HDF5Type : public HDF5TypeBase<T> {

  public:

    HDF5Type() : HDF5TypeBase<T>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_HERR; };

};

// int, H5T_NATIVE_INT specialization

template <> class HDF5Type<int> : public HDF5TypeBase<int> {

  public:

    HDF5Type() : HDF5TypeBase<int>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_INT; };

};

// float, H5T_NATIVE_FLOAT specialization

template <> class HDF5Type<float> : public HDF5TypeBase<float> {

  public:

    HDF5Type() : HDF5TypeBase<float>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };

};

// double, H5T_NATIVE_DOUBLE specialization

template <> class HDF5Type<double> : public HDF5TypeBase<double> {

  public:

    HDF5Type() : HDF5TypeBase<double>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };

};

This permits in the HDF5Type<T>().Type(), *bold red*, in the snipit
above, to actually work

--

Mark C. Miller, LLNL

"In the end, we will remember not the words of

our enemies but the silence of our friends" - MLK

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

--
Kevin B. McCarty
<kmccarty@gmail.com>

Sorry…minor correction…

"Miller, Mark C." wrote:

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, HDF5Type<T>().Type(), H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

hello,

did you try H5CPP <http://h5cpp.ca/>? You can find the implemented
functionality in the code base or freely use the C++14 template library for
vectors, and armadillo matrices. The github page is here
<https://github.com/steven-varga/h5cpp>

At this stage the profiled templates can handle armadillo vectors, matrices
and cubes, as well stl vectors and structs.

best,
steven

···

On Mon, Feb 5, 2018 at 6:03 PM, Miller, Mark C. <miller86@llnl.gov> wrote:

Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the
following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name,
std::vector<T> const &vec, int d2size)

{

    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};

    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);

    hid_t dsid = H5Dcreate(fid, name, *HDF5Type<T>().Type()*, spid,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);

    H5Dclose(dsid);

    H5Sclose(spid);

}

I would like the template instantiation to then return the correct
H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae,
there in *bold red* with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for
this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded
to cover all primitive types) and am wondering if others find this useful
enough (or something like it) that it ought to be included in HDF5 C++
interface?

// base class

template <class T> class HDF5TypeBase {

  public:

             HDF5TypeBase() {} ;

    virtual ~HDF5TypeBase() {};

};

// base class for type-specific template specializations to follow

template <class T> class HDF5Type : public HDF5TypeBase<T> {

  public:

    HDF5Type() : HDF5TypeBase<T>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_HERR; };

};

// int, H5T_NATIVE_INT specialization

template <> class HDF5Type<int> : public HDF5TypeBase<int> {

  public:

    HDF5Type() : HDF5TypeBase<int>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_INT; };

};

// float, H5T_NATIVE_FLOAT specialization

template <> class HDF5Type<float> : public HDF5TypeBase<float> {

  public:

    HDF5Type() : HDF5TypeBase<float>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };

};

// double, H5T_NATIVE_DOUBLE specialization

template <> class HDF5Type<double> : public HDF5TypeBase<double> {

  public:

    HDF5Type() : HDF5TypeBase<double>() {};

    virtual ~HDF5Type() {};

    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };

};

This permits in the HDF5Type<T>().Type(), *bold red*, in the snipit
above, to actually work

--

Mark C. Miller, LLNL

"In the end, we will remember not the words of

our enemies but the silence of our friends" - MLK

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

Oh, sheesh. Yes, that looks *a lot* better. Thanks so much!

Mark

"Hdf-forum on behalf of Kevin B. McCarty" wrote:

I had a similar need, but I think you are overthinking. No need to involve any classes at all.
Try this:
inline hid_t hid_from_type(const char &) { return H5T_NATIVE_CHAR; }
inline hid_t hid_from_type(const signed char &) { return H5T_NATIVE_SCHAR; }
inline hid_t hid_from_type(const unsigned char &) { return H5T_NATIVE_UCHAR; }

inline hid_t hid_from_type(const short &) { return H5T_NATIVE_SHORT; }
inline hid_t hid_from_type(const unsigned short &) { return H5T_NATIVE_USHORT; }

inline hid_t hid_from_type(const int &) { return H5T_NATIVE_INT; }
inline hid_t hid_from_type(const unsigned &) { return H5T_NATIVE_UINT; }

inline hid_t hid_from_type(const long &) { return H5T_NATIVE_LONG; }
inline hid_t hid_from_type(const unsigned long &) { return H5T_NATIVE_ULONG; }

inline hid_t hid_from_type(const long long &) { return H5T_NATIVE_LLONG; }
inline hid_t hid_from_type(const unsigned long long &) { return H5T_NATIVE_ULLONG; }

inline hid_t hid_from_type(const float &) { return H5T_NATIVE_FLOAT; }
inline hid_t hid_from_type(const double &) { return H5T_NATIVE_DOUBLE; }
// And the coup de grace:
template <typename T>
inline hid_t hid_from_type() { return hid_from_type(T()); }
// Usage for your example:

hid_t dsid = H5Dcreate(fid, name, hid_from_type<T>(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

Kevin

···

On Mon, Feb 5, 2018 at 9:03 AM, Miller, Mark C. <miller86@llnl.gov<mailto:miller86@llnl.gov>> wrote:
Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

I would like the template instantiation to then return the correct H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae, there in bold red with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded to cover all primitive types) and am wondering if others find this useful enough (or something like it) that it ought to be included in HDF5 C++ interface?

// base class
template <class T> class HDF5TypeBase {
  public:
             HDF5TypeBase() {} ;
    virtual ~HDF5TypeBase() {};
};

// base class for type-specific template specializations to follow
template <class T> class HDF5Type : public HDF5TypeBase<T> {
  public:
    HDF5Type() : HDF5TypeBase<T>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_HERR; };
};

// int, H5T_NATIVE_INT specialization
template <> class HDF5Type<int> : public HDF5TypeBase<int> {
  public:
    HDF5Type() : HDF5TypeBase<int>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_INT; };
};

// float, H5T_NATIVE_FLOAT specialization
template <> class HDF5Type<float> : public HDF5TypeBase<float> {
  public:
    HDF5Type() : HDF5TypeBase<float>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };
};

// double, H5T_NATIVE_DOUBLE specialization
template <> class HDF5Type<double> : public HDF5TypeBase<double> {
  public:
    HDF5Type() : HDF5TypeBase<double>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };
};

This permits in the HDF5Type<T>().Type(), bold red, in the snipit above, to actually work

--
Mark C. Miller, LLNL

"In the end, we will remember not the words of
our enemies but the silence of our friends" - MLK

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org<mailto:Hdf-forum@lists.hdfgroup.org>
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

--
Kevin B. McCarty
<kmccarty@gmail.com<mailto:kmccarty@gmail.com>>

I don’t use the HDF5 C++ interface, but quite some time ago I’ve made my own (more limited) interface which works well with our Casacore library.

Your solution will also work fine when writing a dataset with a compound data type. The compiler will catch the cases where no Type() function exists.
Why do you make the functions virtual? That might preclude the compiler from inlining.
Furthermore, shouldn’t Type() return a copy of the type? It does not know what the caller will be doing with it. Otherwise it must be made very clear that the caller should not close it. That’s why I don’t like using a bare hid_t. In my own interface I’ve encapsulated it which automatically makes copies and closes them, not only for datatypes but for all types of hid_t.
BTW. Isn’t using H5T_NATIVE_INT, etc. bad in case the data can be read on a machine with a different byte ordering or on a machine with a different sizeof(int)? I am in favour of having a MemType function and a FileType function.

Cheers,
Ger

···

On 5 Feb 2018, at 18:03, Miller, Mark C. <miller86@llnl.gov> wrote:

Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

I would like the template instantiation to then return the correct H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae, there in bold red with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded to cover all primitive types) and am wondering if others find this useful enough (or something like it) that it ought to be included in HDF5 C++ interface?

// base class
template <class T> class HDF5TypeBase {
  public:
             HDF5TypeBase() {} ;
    virtual ~HDF5TypeBase() {};
};

// base class for type-specific template specializations to follow
template <class T> class HDF5Type : public HDF5TypeBase<T> {
  public:
    HDF5Type() : HDF5TypeBase<T>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_HERR; };
};

// int, H5T_NATIVE_INT specialization
template <> class HDF5Type<int> : public HDF5TypeBase<int> {
  public:
    HDF5Type() : HDF5TypeBase<int>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_INT; };
};

// float, H5T_NATIVE_FLOAT specialization
template <> class HDF5Type<float> : public HDF5TypeBase<float> {
  public:
    HDF5Type() : HDF5TypeBase<float>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };
};

// double, H5T_NATIVE_DOUBLE specialization
template <> class HDF5Type<double> : public HDF5TypeBase<double> {
  public:
    HDF5Type() : HDF5TypeBase<double>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };
};

This permits in the HDF5Type<T>().Type(), bold red, in the snipit above, to actually work

--
Mark C. Miller, LLNL

"In the end, we will remember not the words of
our enemies but the silence of our friends" - MLK
_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org <mailto:Hdf-forum@lists.hdfgroup.org>
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

Hey, that’s pretty cool! Thanks for sharing that.

Nope, I haven’t tried that.

Alas, I don’t think I can use it either because I need finer grained control over properties controlling dataset creation and transfer and type conversion.

If an hid_t for creation props and another hid_t for transfer props were provided as optional args to these routines, that could potentially make them more generally useful t cases like mine.

The H5CPP interface looks really useful for common/simple cases, but I would rather that templatization of HDF5 compile-time types NOT to be too closely coupled with other aspects of data set creation and I/O (or container classes).

Thanks again for sharing though.

Mark

"Hdf-forum on behalf of Steven Varga" wrote:

hello,

did you try H5CPP<http://h5cpp.ca/>? You can find the implemented functionality in the code base or freely use the C++14 template library for vectors, and armadillo matrices. The github page is here<https://github.com/steven-varga/h5cpp>

At this stage the profiled templates can handle armadillo vectors, matrices and cubes, as well stl vectors and structs.

best,
steven

···

On Mon, Feb 5, 2018 at 6:03 PM, Miller, Mark C. <miller86@llnl.gov<mailto:miller86@llnl.gov>> wrote:
Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

I would like the template instantiation to then return the correct H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae, there in bold red with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded to cover all primitive types) and am wondering if others find this useful enough (or something like it) that it ought to be included in HDF5 C++ interface?

// base class
template <class T> class HDF5TypeBase {
  public:
             HDF5TypeBase() {} ;
    virtual ~HDF5TypeBase() {};
};

// base class for type-specific template specializations to follow
template <class T> class HDF5Type : public HDF5TypeBase<T> {
  public:
    HDF5Type() : HDF5TypeBase<T>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_HERR; };
};

// int, H5T_NATIVE_INT specialization
template <> class HDF5Type<int> : public HDF5TypeBase<int> {
  public:
    HDF5Type() : HDF5TypeBase<int>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_INT; };
};

// float, H5T_NATIVE_FLOAT specialization
template <> class HDF5Type<float> : public HDF5TypeBase<float> {
  public:
    HDF5Type() : HDF5TypeBase<float>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };
};

// double, H5T_NATIVE_DOUBLE specialization
template <> class HDF5Type<double> : public HDF5TypeBase<double> {
  public:
    HDF5Type() : HDF5TypeBase<double>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };
};

This permits in the HDF5Type<T>().Type(), bold red, in the snipit above, to actually work

--
Mark C. Miller, LLNL

"In the end, we will remember not the words of
our enemies but the silence of our friends" - MLK

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org<mailto:Hdf-forum@lists.hdfgroup.org>
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

"Hdf-forum on behalf of Ger van Diepen" wrote:

I don’t use the HDF5 C++ interface, but quite some time ago I’ve made my own (more limited) interface which works well with our Casacore library.

Yeah, I am really not an experienced c++ programmer myself :wink:

Your solution will also work fine when writing a dataset with a compound data type. The compiler will catch the cases where no Type() function exists.
Why do you make the functions virtual?

Isn’t that necessary if some derived class might wanna override?

That might preclude the compiler from inlining.

Yeah, the inlining function-only templates another user shared were *much* better :wink: I am using that approach now. I guess I just think something like this ought to be part of the THG-supported C++ interface to HDF5, for the pre-defined primitive types at least.

Furthermore, shouldn’t Type() return a copy of the type?

Not for the simple case I needed here; *writing* datasets of just primitive types. Those or HDF5 lib-wide constants.

It does not know what the caller will be doing with it. Otherwise it must be made very clear that the caller should not close it. That’s why I don’t like using a bare hid_t. In my own interface I’ve encapsulated it which automatically makes copies and closes them, not only for datatypes but for all types of hid_t.

Yeah, I agree. I the general case, you’d wanna pay attention to type ids, make copies and close them.

BTW. Isn’t using H5T_NATIVE_INT, etc. bad in case the data can be read on a machine with a different byte ordering or on a machine with a different sizeof(int)? I am in favour of having a MemType function and a FileType function.

I wasn’t interested in reading it back into this particular data producer.

Cheers,
Ger

···

On 5 Feb 2018, at 18:03, Miller, Mark C. <miller86@llnl.gov<mailto:miller86@llnl.gov>> wrote:

Hi All,

I am wondering if anyone else in C++ coding of HDF5 has run into the following problem…

I have a templatized function that writes an HDF5 dataset…

template <class T> static void WriteVecToHDF5(hid_t fid, char const *name, std::vector<T> const &vec, int d2size)
{
    hsize_t siz2d[2] = {(hsize_t) vec.size() / d2size, d2size};
    hid_t spid = H5Screate_simple(d2size>1?2:1, siz2d, 0);
    hid_t dsid = H5Dcreate(fid, name, HDF5Type<T>().Type(), spid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vec[0]);
    H5Dclose(dsid);
    H5Sclose(spid);
}

I would like the template instantiation to then return the correct H5T_NATIVE_XXX type so WriteVecToHDF5<int>(…) produces a call to H5Dcreae, there in bold red with H5T_NATIVE_INT, etc.

There does not appear to be any support in the HDF5 implementation for this. Am I missing something?

Below is what I did (for int, float and double but can easily be expanded to cover all primitive types) and am wondering if others find this useful enough (or something like it) that it ought to be included in HDF5 C++ interface?

// base class
template <class T> class HDF5TypeBase {
  public:
             HDF5TypeBase() {} ;
    virtual ~HDF5TypeBase() {};
};

// base class for type-specific template specializations to follow
template <class T> class HDF5Type : public HDF5TypeBase<T> {
  public:
    HDF5Type() : HDF5TypeBase<T>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_HERR; };
};

// int, H5T_NATIVE_INT specialization
template <> class HDF5Type<int> : public HDF5TypeBase<int> {
  public:
    HDF5Type() : HDF5TypeBase<int>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_INT; };
};

// float, H5T_NATIVE_FLOAT specialization
template <> class HDF5Type<float> : public HDF5TypeBase<float> {
  public:
    HDF5Type() : HDF5TypeBase<float>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_FLOAT; };
};

// double, H5T_NATIVE_DOUBLE specialization
template <> class HDF5Type<double> : public HDF5TypeBase<double> {
  public:
    HDF5Type() : HDF5TypeBase<double>() {};
    virtual ~HDF5Type() {};
    virtual hid_t Type() const { return H5T_NATIVE_DOUBLE; };
};

This permits in the HDF5Type<T>().Type(), bold red, in the snipit above, to actually work

--
Mark C. Miller, LLNL

"In the end, we will remember not the words of
our enemies but the silence of our friends" - MLK
_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org<mailto:Hdf-forum@lists.hdfgroup.org>
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5