H5CPP  v1.14.0
Modern C++ templates for HDF5 serial and parallel I/O
Loading...
Searching...
No Matches
Supported Types

Every type h5cpp's h5::read / h5::write / h5::create / h5::aread / h5::awrite accepts, organised by category. The storage representation column maps each entry to one of the storage_representation_t cases declared at h5cpp/H5Tmeta.hpp:164-170 — that's the value storage_representation_v<T> resolves to at compile time, and what the static-assert stoppers in H5Dwrite.hpp / H5Dread.hpp / H5Awrite.hpp / H5Aread.hpp check before dispatching.

The underlying classification mechanism is the Walter Brown detection idiom: types are recognised by their structural surface (value_type, iterator, size, data, key_type, mapped_type, …), not by name. A custom container with the right shape routes the same way as the matching std:: counterpart — see Supported container shapes in the Cook book for the canonical walkthrough.

Elementary scalars

All landed at storage_representation_t::scalar. Default-included via h5cpp/all (no extra mapper header required).

TypeHDF5 representationNotes
int8_t / int16_t / int32_t / int64_t H5T_NATIVE_INT8H5T_NATIVE_INT64 signed integer
uint8_t / uint16_t / uint32_t / uint64_t H5T_NATIVE_UINT8H5T_NATIVE_UINT64 unsigned integer
floatH5T_NATIVE_FLOAT IEEE 754 single precision
doubleH5T_NATIVE_DOUBLE IEEE 754 double precision
long doubleH5T_NATIVE_LDOUBLE platform-specific extended precision
boolH5T_NATIVE_HBOOL HDF5 boolean (NB: std::vector<bool> is NOT supported, see NOT supported (intentional stoppers))
enum E (registered)H5T_ENUM over the underlying integer register with H5CPP_REGISTER_DATATYPE(E, "E", H5Tenum_create(H5T_NATIVE_*), { H5Tenum_insert(...) })

Custom datatypes (n-bit packing, opaque blobs, strong-typedef wrappers) register through H5CPP_REGISTER_DATATYPE — see the macro documentation at h5cpp/H5Tall.hpp:514 and the examples/datatypes/ cookbook page.

Strings

h5cpp routes both fixed-length (H5T_C_S1 + H5Tset_size(N)) and variable-length (H5T_VARIABLE) HDF5 string forms depending on the C++ type used at the call site.

Typestorage_representation_tHDF5 representation
std::string / std::string_view vlen_text_datasetH5T_VARIABLE — one char* allocated by HDF5 on read
char* / const char* vlen_text_datasetsame variable-length path
char[N] fixed_length_stringH5T_C_S1 + H5Tset_size(N), scalar dataspace
std::array<char,N> fixed_length_stringsame as char[N] — wrapper-equivalent representation
std::vector<std::string> vlen_text_datasetrank-1 dataset, each element variable-length
std::vector<std::array<char,N>> fls_dataset rank-1 dataset of fixed-length strings (no VLEN overhead)

On read, fixed-length string attributes are detected via H5Aget_type + H5Tis_variable_str — HDF5 has no fixed↔VLEN conversion path, so the dispatch must branch (see h5cpp/H5Aread.hpp and examples/string/ in the cookbook).

Compound types

Typestorage_representation_tHow it's registered
POD aggregate registered via H5CPP_REGISTER_STRUCT(MyStruct); scalar (with H5T_COMPOUND type) macro at file scope; emits dt_t<MyStruct> specialisation. See examples/compound/.
Compiler-reflected tier-2 type with [[h5::*]] attributes scalar h5cpp-compiler tool emits generated.h; user #includes it. Handles heap-indirection fields (vlen strings, vlen vectors) via the scatter/gather visitor path. See examples/multi-tu/ and examples/reflection/.
std::tuple<Ts...> scalar Packed into an internal C-struct mirror, compound with fields _0, _1, …; field count = tuple arity.
std::pair<K,V> scalar Compound with fields first, second.
std::complex<float\|double\|long double> scalar Native H5T_COMPLEX on HDF5 ≥ 1.14, compound fallback (r, i) otherwise.

C arrays and <tt>std::array</tt>

Typestorage_representation_tHDF5 representation
T[N] (top-level) array_element scalar dataspace + H5T_ARRAY[N] over dt_t<T>
std::array<T,N> where T is non-char array_element same as T[N] — wrapper-equivalent
T[N][M] and higher array_element scalar dataspace + nested H5T_ARRAY

STL sequence containers

Typestorage_representation_tWrite path
std::vector<T> linear_value_datasetDirect H5Dwrite (contiguous, has data())
std::deque<T> linear_value_datasetStaged into contiguous buffer, then H5Dwrite
std::list<T> linear_value_datasetStaged into contiguous buffer, then H5Dwrite
std::forward_list<T>linear_value_datasetAppend-style; pair with h5::pt_t extensible dataset
std::valarray<T> linear_value_datasetVia h5cpp/H5Mvalarray.hpp

STL associative containers

Typestorage_representation_tHDF5 representation
std::set<T> / std::multiset<T> linear_value_datasetRank-1 of T, written in iteration order
std::unordered_set<T> / std::unordered_multiset<T>linear_value_datasetSame, but iteration order is hash-dependent
std::map<K,V> / std::multimap<K,V> key_value_dataset Rank-1 of compound { K key, V value }
std::unordered_map<K,V> / std::unordered_multimap<K,V>key_value_datasetSame compound layout, hash-iteration order

Set-like and map-like third-party containers (Abseil flat_hash_*, TSL robin_*, Folly F14*, Boost flat_*, parallel-hashmap) ride the structural fallback and route the same way — see Supported container shapes for the full third-party coverage matrix.

STL <tt>array<T,N></tt>-of containers

Typestorage_representation_tHDF5 representation
std::vector<std::array<T,N>> (T non-char) array_datasetRank-1 of H5T_ARRAY[N] elements — flat rows × N
std::vector<std::array<char,N>> fls_dataset Rank-1 of fixed-length strings — vlen-free path
std::vector<std::pair<K,V>> linear_value_datasetRank-1 of compound { first, second }
std::vector<std::tuple<Ts...>> linear_value_datasetRank-1 of packed compound

Variable-length and ragged shapes

Typestorage_representation_tHDF5 representation
std::vector<std::string> vlen_text_dataset char* relay array + H5T_VARIABLE
std::vector<std::vector<T>> ragged_vlen_dataset hvl_t relay array + H5Tvlen_create

Linear-algebra dense containers

All dense linalg containers map to linear_value_dataset (or array_dataset for the rank-aware rank-2 / rank-3 cases) and write directly via the underlying contiguous buffer the linalg library exposes. Include the matching mapper header before use.

LibraryTypes supportedMapper header
Armadilloarma::Col<T>, arma::Row<T>, arma::Mat<T>, arma::Cube<T>h5cpp/H5Marma.hpp
Eigen Eigen::Matrix<T,…>, Eigen::Vector<T,…>, Eigen::Array<T,…> (ColMajor)h5cpp/H5Meigen.hpp
Blitz++ blitz::Array<T,N>h5cpp/H5Mblitz.hpp
Blaze blaze::DynamicVector<T>, blaze::DynamicMatrix<T>h5cpp/H5Mblaze.hpp
dlib dlib::matrix<T,…>h5cpp/H5Mdlib.hpp
IT++ itpp::Vec<T>, itpp::Mat<T>h5cpp/H5Mitpp.hpp
Boost uBLASboost::numeric::ublas::vector<T>, boost::numeric::ublas::matrix<T>h5cpp/H5Mublas.hpp
xtensor xt::xarray<T>, xt::xtensor<T,N>h5cpp/H5Mxtensor.hpp

See Linear-Algebra Containers for end-to-end examples per library.

Sparse linear algebra

Sparse matrices and vectors land at a custom storage layout: HDF5 group containing four datasets in canonical Compressed Sparse Column form (indptr / indices / data / shape attribute). h5::write(...) returns h5::gr_t (not h5::ds_t); h5::read<T> of a sparse type reads the four datasets and reconstructs the matrix.

LibraryTypes supportedLayout
Armadilloarma::SpMat<T>, arma::SpCol<T>, arma::SpRow<T>CSC group
Eigen Eigen::SparseMatrix<T>, Eigen::SparseVector<T> (ColMajor only; RowMajor static_asserts)CSC group

Files are interoperable with scipy, Julia HDF5.jl, h5sparse, Loompy, and 10x Genomics. See examples/sparse/ in the cookbook.

C++23 <tt>std::mdspan</tt>

std::mdspan is a non-owning view over caller-owned storage. Round-trips through linear_value_dataset (rank-1) or array_element (rank-N) depending on the extents. Gated on __cpp_lib_mdspan >= 202207L — requires libstdc++ ≥ 15 or libc++ ≥ 19; on older toolchains the mdspan example skips gracefully and the type isn't recognised.

Write is straightforward (view supplies data_handle()). Read into mdspan requires the caller to own the storage:

std::mdspan<double, std::dextents<std::size_t, 2>> view(sink.data(), 4, 6);
h5::read<double>(fd, "/matrix/A", view.data_handle(), h5::count{24});
T aread(const hid_t &ds, const std::string &name, const h5::acpl_t &acpl=h5::default_acpl)
Read an attribute by name and return its value as type T.
Definition H5Aread.hpp:76

Mapper header: h5cpp/H5Mmdspan.hpp. See examples/mdspan/ in the cookbook.

Reference handles

Typestorage_representation_tNotes
h5::reference_t scalar Rule-of-five RAII wrapper around H5R_ref_t (HDF5 1.12+) or hdset_reg_ref_t (pre-1.12). One reference per call site; round-trip via h5::reference(fd, path, offset, count). See examples/reference/ and Reference handles in the catalog.
std::vector<h5::reference_t> linear_value_dataset Rank-1 dataset of region/object/attribute references; each entry is RAII-managed independently.

Smart pointers (forwarding overloads)

h5cpp accepts smart-pointer wrappers around contiguous buffers via forwarding overloads — the pointer is unwrapped and the underlying raw T* is routed through the regular h5::write / h5::read paths. Implementation: h5cpp/H5Mmemory_io.hpp.

TypeRoutes to
std::unique_ptr<T[]>raw T* with caller-provided h5::count{N}
std::shared_ptr<T[]>same

Caller retains ownership; h5cpp never takes the smart pointer. See examples/smart-ptr/ in the cookbook.

NOT supported (intentional stoppers)

The static-assert stoppers in H5Dwrite.hpp:737 and friends fire for these — the diagnostic includes the resolved storage_representation_t::unsupported and the offending type so the failure is informative.

TypeWhy not
std::vector<bool> Bit-packing specialisation; no real contiguous bool*. The standard's allocator-aware proxy reference doesn't survive HDF5's void* interface.
Unregistered POD aggregate No dt_t<T> specialisation. Register via H5CPP_REGISTER_STRUCT(T) or generate via h5cpp-compiler.
Arbitrary nesting: std::vector<std::list<T>>, std::vector<std::set<T>>, std::vector<std::map<K,V>>, … HDF5 can represent many of these via nested VLEN / compound, but h5cpp deliberately rejects them until the recursive packer/unpacker path is explicit.
std::array<std::string, N> / std::array<std::vector<T>, N> Fixed-rank array of variable-length elements — would require an explicit policy decision on the inner length.
Containers without T(std::size_t) constructor (iterator-pair-only allocation) Read-side structural fallback needs T(size) to pre-allocate before the staged copy.

How dispatch works

Compile-time only. storage_representation_v<T> is evaluated during template instantiation; the call site's H5Dwrite / H5Dread overload is selected by SFINAE against the resolved value. There is no runtime polymorphism, no if constexpr chain at the call site, and no virtual dispatch.

The architectural treatment — how storage_representation_t fans out across the per-container mapper headers (H5M*.hpp), where the detection-idiom fallbacks fire, and how third-party containers route without registration — is in Architecture / Type-system architecture notes (Project Reports → Architecture).

See also
link_handle_reference link_raii_idiom link_conversion_policy link_stl_template_types link_linalg_template_types reports_type_system_map example_guide_container example_guide_compound example_guide_linalg example_guide_sparse example_guide_mdspan example_guide_string