|
H5CPP
v1.14.0
Modern C++ templates for HDF5 serial and parallel I/O
|
|
A group is HDF5's directory. The point of this example is simple: building hierarchies, attaching attributes to them, listing what's inside, linking objects together, and handling the errors all fit on one page of h5cpp.
The whole vocabulary fits on one slide:
Every entry above is now wrapped — no raw H5L* / H5O* calls needed.
| File | Purpose |
|---|---|
groups.cpp | Seven sections exercising the group surface |
groups.h5 | Output container (h5dump -n groups.h5 shows the full tree) |
Nothing else needed. Groups are part of the core h5cpp surface.
An HDF5 group has two pieces of header data plus attributes:
| HDF5 concept | What it is |
|---|---|
| Header | Name + attribute list |
| Symbol table | Names of the objects that belong to the group (datasets, sub-groups, links) |
| Attributes | Small named scalars/vectors attached to the group itself |
A group's symbol table is what h5::ls returns. The header carries the attributes.
h5cpp's gcreate takes any parent that can own children (an fd_t or another gr_t), a path string, and optional property lists.
gr_t is a valid parent too. Use relative paths to extend a sub-tree without retyping the absolute prefix:
This is how you build hierarchies incrementally.
h5::exists(loc, path) returns bool (no exception on missing path). Check before opening to avoid catching exceptions in normal control flow.
loc can be any h5cpp handle (file, group, raw hid_t); path is resolved relative to it.
h5::awrite(parent, name, value) accepts scalars, strings, vectors, and initializer lists. Works on any handle that can carry attributes — groups, datasets, named datatypes.
The bracket-assignment shorthand gr["name"] = value is a ds_t-only convenience — for gr_t, use awrite directly.
Three traversal flavours, all returning std::vector<std::string> and streamable via the STL pretty-printer:
| Function | Scope | Order |
|---|---|---|
h5::ls(fd, path) | immediate children | name-sorted |
h5::dfs(fd, path) | recursive | depth-first, name-sorted |
h5::bfs(fd, path) | recursive | breadth-first |
Sample output:
dfs is H5Lvisit directly. bfs is dfs then a stable-sort by slash-count — same set of paths, BFS order. Use bfs when you want shallower paths first (e.g. depth-limited output).
HDF5 has three link flavours, all wrapped:
| Link type | Semantics | h5cpp call |
|---|---|---|
| soft | POSIX-symlink: stores a path string, resolved lazily | h5::link_soft |
| hard | Additional name pointing at the same object, same file | h5::link_hard |
| external | Soft link whose target lives in another HDF5 file | h5::link_external |
All three accept an optional trailing lcpl argument; the default is h5::default_lcpl, which has intermediate-group creation enabled — so missing parents (/shortcuts, /external) auto-create.
Soft links are followed transparently — h5::gopen(fd, "/shortcuts/imu_l") opens the target group.
Dangling soft links (broken paths) and missing external files don't fail at link-creation time. They fail at open time. Use H5Lget_info directly if you need to distinguish link type without opening the target.
Three more wrappers, same shape:
Behavior worth knowing:
h5::move** with src_loc == dst_loc is a rename. Cross-loc moves are HDF5's H5Lmove; cross-*file* moves aren't supported by HDF5 (use copy + unlink).h5::copy** copies the object's group hierarchy and attributes by default. Layout customisation (shallow, expand soft links, etc.) is available via h5::shallow_hierarchy / h5::expand_soft_link / … property-list flags from H5Pall.hpp — pass them through H5Ocopy's ocpl directly if you need them (not exposed in the wrapper yet).h5::unlink** is HDF5's H5Ldelete. The object is reclaimed when its last name drops. Hard-linked objects survive as long as one name remains.h5cpp's exception hierarchy lets you catch precisely or broadly:
h5::mute() / h5::unmute() suppress HDF5's CAPI diagnostic stack so intentional failure tests don't spray noise onto stderr.
| Operation | h5cpp call | Underlying HDF5 |
|---|---|---|
| Create group | h5::gcreate | H5Gcreate2 |
| Open group | h5::gopen | H5Gopen |
| List immediate children | h5::ls | H5Literate |
| Recursive listing (DFS) | h5::dfs | H5Lvisit |
| Recursive listing (BFS) | h5::bfs | H5Lvisit + sort |
| Attach attribute | h5::awrite | H5Awrite |
| Existence check | h5::exists | H5Lexists |
| Soft link | h5::link_soft | H5Lcreate_soft |
| Hard link | h5::link_hard | H5Lcreate_hard |
| External link | h5::link_external | H5Lcreate_external |
| Rename / move object | h5::move | H5Lmove |
| Copy object | h5::copy | H5Ocopy |
| Delete link | h5::unlink | H5Ldelete |
Every link/move/copy operation accepts h5::fd_t, h5::gr_t, or a raw hid_t as the location parameter (via the impl::is_valid_loc<L> constraint). Default lcpl carries create_intermediate_group{1} so missing parents auto-create on link writes.
Wrappers not yet exposed (use raw C API for now):
H5Ldelete_by_idx, H5Lmove_by_idx — index-based variantsH5Lget_info, H5Lget_val — link metadataH5Ocopy with custom ocpy_plist — fine-grained copy optionsCMake target examples-groups. No dependencies beyond h5cpp itself.
Groups are HDF5's namespace mechanism: they organise objects, carry annotations, and let you build cross-references via links. Everything else in HDF5 lives inside one.
groups.cpp — rendered with syntax highlighting