Skip to content

Commit

Permalink
Improve doc for HighFive::Attribute (#803)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Luc Grosheintz <luc.grosheintz@gmail.com>
  • Loading branch information
alkino and 1uc authored Aug 2, 2023
1 parent 2f5dc7d commit 03e2b24
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 44 deletions.
196 changes: 155 additions & 41 deletions include/highfive/H5Attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,90 +40,204 @@ namespace detail {
Attribute make_attribute(hid_t hid);
} // namespace detail

/// \brief Class representing an Attribute of a DataSet or Group
///
/// \brief Class representing an attribute of a dataset or group
///
/// \sa AnnotateTraits::createAttribute, AnnotateTraits::getAttribute, AnnotateTraits::listAttributeNames, AnnotateTraits::hasAttribute, AnnotateTraits::deleteAttribute for create, get, list, check or delete Attribute
class Attribute: public Object, public PathTraits<Attribute> {
public:
const static ObjectType type = ObjectType::Attribute;

///
/// \brief return the name of the current attribute
/// \return the name of the attribute
/// \brief Get the name of the current Attribute.
/// \code{.cpp}
/// auto attr = dset.createAttribute<std::string>("my_attribute", DataSpace::From(string_list));
/// std::cout << attr.getName() << std::endl; // Will print "my_attribute"
/// \endcode
/// \since 2.2.2
std::string getName() const;

/// \brief The number of bytes required to store the attribute in the HDF5 file.
/// \code{.cpp}
/// size_t size = dset.createAttribute<int>("foo", DataSpace(1, 2)).getStorageSize();
/// \endcode
/// \since 1.0
size_t getStorageSize() const;

///
/// \brief getDataType
/// \return return the datatype associated with this dataset
///
/// \brief Get the DataType of the Attribute.
/// \code{.cpp}
/// Attribute attr = dset.createAttribute<int>("foo", DataSpace(1, 2));
/// auto dtype = attr.getDataType(); // Will be an hdf5 type deduced from int
/// \endcode
/// \since 1.0
DataType getDataType() const;

///
/// \brief getSpace
/// \return return the dataspace associated with this dataset
///
/// \brief Get the DataSpace of the current Attribute.
/// \code{.cpp}
/// Attribute attr = dset.createAttribute<int>("foo", DataSpace(1, 2));
/// auto dspace = attr.getSpace(); // This will be a DataSpace of dimension 1 * 2
/// \endcode
/// \since 1.0
DataSpace getSpace() const;

///
/// \brief getMemSpace
/// \return same than getSpace for DataSet, compatibility with Selection
/// class
///
/// \brief Get the DataSpace of the current Attribute.
/// \note This is an alias of getSpace().
/// \since 1.0
DataSpace getMemSpace() const;

/// \brief Return the attribute
/// \brief Get the value of the Attribute.
/// \code{.cpp}
/// Attribute attr = dset.getAttribute("foo");
/// // The value will contains what have been written in the attribute
/// std::vector<int> value = attr.read<std::vector<int>>();
/// \endcode
/// \since 2.5.0
template <typename T>
T read() const;

/// \brief Get the value of the Attribute in a buffer.
///
/// Read the attribute into an existing object. Only available for
/// supported types `T`. If `array` has preallocated the correct amount of
/// memory, then this routine should not trigger reallocation. Otherwise,
/// if supported, the object will be resized.
///
/// Read the attribute into a buffer
/// An exception is raised if the numbers of dimension of the buffer and of
/// the attribute are different
/// the attribute are different.
///
/// The array type can be a N-pointer or a N-vector ( e.g int** integer two
/// dimensional array )
/// \code{.cpp}
/// // Will read into `value` avoiding memory allocation if the dimensions
/// // match, i.e. if the attribute `"foo"` has three element.
/// std::vector<int> value(3);
/// file.getAttribute("foo").read(value);
/// \endcode
/// \since 1.0
template <typename T>
void read(T& array) const;

/// \brief Read the attribute into a buffer.
/// \brief Read the attribute into a pre-allocated buffer.
/// \param array A pointer to the first byte of sufficient pre-allocated memory.
/// \param mem_datatype The DataType of the array.
///
/// \note This is the shallowest wrapper around `H5Aread`. If possible
/// prefer either Attribute::read() const or Attribute::read(T&) const.
///
/// \code{.cpp}
/// auto attr = file.getAttribute("foo");
///
/// Note, this is the shallowest wrapper around `H5Aread`.
/// // Simulate custom allocation by the application.
/// size_t n_elements = attr.getSpace().getElementCount();
/// int * ptr = (int*) malloc(n_elements*sizeof(int));
///
/// // Read into the pre-allocated memory.
/// attr.read(ptr, mem_datatype);
/// \endcode
/// \since 2.2.2
template <typename T>
void read(T* array, const DataType& mem_datatype) const;

/// \brief Read the attribute into a buffer
/// \brief Read the attribute into a buffer.
/// Behaves like Attribute::read(T*, const DataType&) const but
/// additionally this overload deduces the memory datatype from `T`.
///
/// \param array Pointer to the first byte of pre-allocated memory.
///
/// \note If possible prefer either Attribute::read() const or Attribute::read(T&) const.
///
/// This overload deduces the memory datatype from `T`.
/// \code{.cpp}
/// auto attr = file.getAttribute("foo");
///
/// // Simulate custom allocation by the application.
/// size_t n_elements = attr.getSpace().getElementCount();
/// int * ptr = (int*) malloc(n_elements*sizeof(int));
///
/// // Read into the pre-allocated memory.
/// attr.read(ptr);
/// \endcode
/// \since 2.2.2
template <typename T>
void read(T* array) const;

/// \brief Write the value into the Attribute.
///
/// Write the integrality N-dimension buffer to this attribute
/// An exception is raised if the numbers of dimension of the buffer and of
/// the attribute are different
/// Write the value to the attribute. For supported types `T`, this overload
/// will write the value to the attribute. The datatype and dataspace are
/// deduced automatically. However, since the attribute has already been
/// created, the dimensions of `value` must match those of the attribute.
///
/// \code{.cpp}
/// // Prefer the fused version if creating and writing the attribute
/// // at the same time.
/// dset.createAttribute("foo", std::vector<int>{1, 2, 3});
///
/// The array type can be a N-pointer or a N-vector ( e.g int** integer two
/// dimensional array )
/// // To overwrite the value:
/// std::vector<int> value{4, 5, 6};
/// dset.getAttribute<int>("foo").write(value);
/// \endcode
/// \since 1.0
template <typename T>
void write(const T& buffer);
void write(const T& value);

/// \brief Write to this attribute from `buffer`.
/// \brief Write from a raw pointer.
///
/// Values that have been correctly arranged memory, can be written directly
/// by passing a raw pointer.
///
/// \param buffer Pointer to the first byte of the value.
/// \param mem_datatype The DataType of the buffer.
///
/// \note This is the shallowest wrapper around `H5Awrite`. It's useful
/// if you need full control. If possible prefer Attribute::write.
///
/// \code{.cpp}
/// Attribute attr = dset.createAttribute<int>("foo", DataSpace(2, 3));
///
/// Note that this is the shallowest wrapper around `H5Awrite`. It's useful
/// if you need full control. If possible prefer `Attribute::write`.
/// // Simulate the application creating `value` and only exposing access
/// // to the raw pointer `ptr`.
/// std::vector<std::array<int, 3>> value{{1, 2, 3}, {4, 5, 6}};
/// int * ptr = (int*) value.data();
///
/// // Simply write the bytes to disk.
/// attr.write(ptr, AtomicType<int>());
/// \endcode
/// \since 2.2.2
template <typename T>
void write_raw(const T* buffer, const DataType& mem_dtype);
void write_raw(const T* buffer, const DataType& mem_datatype);

/// \brief Write to this attribute from `buffer`.
/// \brief Write from a raw pointer.
///
/// Much like Attribute::write_raw(const T*, const DataType&).
/// Additionally, this overload attempts to automatically deduce the
/// datatype of the buffer. Note, that the file datatype is already set.
///
/// \param buffer Pointer to the first byte.
///
/// \note If possible prefer Attribute::write.
///
/// This version attempts to automatically deduce the datatype
/// of the buffer. Note, that the file datatype is already set.
/// \code{.cpp}
/// // Simulate the application creating `value` and only exposing access
/// // to the raw pointer `ptr`.
/// std::vector<std::array<int, 3>> value{{1, 2, 3}, {4, 5, 6}};
/// int * ptr = (int*) value.data();
///
/// // Simply write the bytes to disk.
/// attr.write(ptr);
/// \endcode
/// \since 2.2.2
template <typename T>
void write_raw(const T* buffer);

/// \brief Get the list of properties for creation of this attribute
/// \brief The create property list used for this attribute.
///
/// Some of HDF5 properties/setting of an attribute are defined by a
/// create property list. This method returns a copy of the create
/// property list used during creation of the attribute.
///
/// \code{.cpp}
/// auto acpl = attr.getCreatePropertyList();
///
/// // For example to create another attribute with the same properties.
/// file.createAttribute("foo", 42, acpl);
/// \endcode
/// \since 2.5.0
AttributeCreateProps getCreatePropertyList() const {
return details::get_plist<AttributeCreateProps>(*this, H5Aget_create_plist);
}
Expand Down
2 changes: 1 addition & 1 deletion include/highfive/H5DataSpace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class DataSpace: public Object {
/// DataSpace(std::vector<size_t>{1, 3}, std::vector<size_t>{10, 10});
/// \endcode
///
/// \see UNLIMITED for a DataSpace that can be resize without limit.
/// \see UNLIMITED for a DataSpace that can be resized without limit.
/// \since 2.0
explicit DataSpace(const std::vector<size_t>& dims, const std::vector<size_t>& maxdims);

Expand Down
4 changes: 2 additions & 2 deletions include/highfive/bits/H5Dataspace_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ inline DataSpace::DataSpace(const std::vector<size_t>& dims, const std::vector<s
}
} // namespace HighFive

inline DataSpace::DataSpace(DataSpace::DataspaceType dtype) {
inline DataSpace::DataSpace(DataSpace::DataspaceType space_type) {
H5S_class_t h5_dataspace_type;
switch (dtype) {
switch (space_type) {
case DataSpace::dataspace_scalar:
h5_dataspace_type = H5S_SCALAR;
break;
Expand Down

0 comments on commit 03e2b24

Please sign in to comment.