Program Listing for File h5utils.hpp

↰ Return to documentation for file (include/dx2/h5/h5utils.hpp)

#pragma once

#include <hdf5.h>
#include <utility>

namespace h5utils {

template <herr_t(D)(hid_t)> struct H5Cleanup {
  H5Cleanup() : id(-1) {}
  explicit H5Cleanup(hid_t id) : id(id) {}
  H5Cleanup(const H5Cleanup &) = delete;
  H5Cleanup(H5Cleanup &&other) noexcept : id(other.id) { other.id = -1; }
  H5Cleanup &operator=(H5Cleanup &&other) noexcept {
    std::swap(id, other.id);
    return *this;
  }
  ~H5Cleanup() {
    if (id >= 0) {
      D(id);
    }
  }

  operator hid_t() const { return id; }
  explicit operator bool() const { return id >= 0; }
  hid_t id;
};

// Common aliases for specific HDF5 object types
using H5File = H5Cleanup<H5Fclose>;
using H5Group = H5Cleanup<H5Gclose>;
using H5Dataset = H5Cleanup<H5Dclose>;
using H5Attr = H5Cleanup<H5Aclose>;
using H5Space = H5Cleanup<H5Sclose>;
using H5Type = H5Cleanup<H5Tclose>;
using H5Plist = H5Cleanup<H5Pclose>;

inline H5Plist make_v18_file_access_plist() {
  H5Plist fapl(H5Pcreate(H5P_FILE_ACCESS));
  if (fapl &&
      H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0) {
    return H5Plist();
  }
  return fapl;
}

class H5ErrorSilencer {
public:
  H5ErrorSilencer() {
    H5Eget_auto2(H5E_DEFAULT, &old_func, &old_client_data);
    H5Eset_auto2(H5E_DEFAULT, nullptr, nullptr);
  }

  ~H5ErrorSilencer() { H5Eset_auto2(H5E_DEFAULT, old_func, old_client_data); }

private:
  H5E_auto2_t old_func = nullptr;
  void *old_client_data = nullptr;
};

} // namespace h5utils