Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 08:55:35

0001 /*
0002  *  Copyright (c), 2017, Ali Can Demiralp <ali.demiralp@rwth-aachen.de>
0003  *
0004  *  Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  */
0009 #pragma once
0010 
0011 #include <vector>
0012 
0013 #include <H5Apublic.h>
0014 
0015 #include "H5DataType.hpp"
0016 #include "H5Object.hpp"
0017 #include "bits/H5Friends.hpp"
0018 #include "bits/H5Path_traits.hpp"
0019 
0020 namespace HighFive {
0021 class DataSpace;
0022 
0023 namespace detail {
0024 
0025 /// \brief Internal hack to create an `Attribute` from an ID.
0026 ///
0027 /// WARNING: Creating an Attribute from an ID has implications w.r.t. the lifetime of the object
0028 ///          that got passed via its ID. Using this method careless opens up the suite of issues
0029 ///          related to C-style resource management, including the analog of double free, dangling
0030 ///          pointers, etc.
0031 ///
0032 /// NOTE: This is not part of the API and only serves to work around a compiler issue in GCC which
0033 ///       prevents us from using `friend`s instead. This function should only be used for internal
0034 ///       purposes. The problematic construct is:
0035 ///
0036 ///           template<class Derived>
0037 ///           friend class SomeCRTP<Derived>;
0038 ///
0039 /// \private
0040 Attribute make_attribute(hid_t hid);
0041 }  // namespace detail
0042 
0043 /// \brief Class representing an Attribute of a DataSet or Group
0044 ///
0045 /// \sa AnnotateTraits::createAttribute, AnnotateTraits::getAttribute, AnnotateTraits::listAttributeNames, AnnotateTraits::hasAttribute, AnnotateTraits::deleteAttribute for create, get, list, check or delete Attribute
0046 class Attribute: public Object, public PathTraits<Attribute> {
0047   public:
0048     const static ObjectType type = ObjectType::Attribute;
0049 
0050     /// \brief Get the name of the current Attribute.
0051     /// \code{.cpp}
0052     /// auto attr = dset.createAttribute<std::string>("my_attribute", DataSpace::From(string_list));
0053     /// std::cout << attr.getName() << std::endl; // Will print "my_attribute"
0054     /// \endcode
0055     /// \since 2.2.2
0056     std::string getName() const;
0057 
0058     /// \brief The number of bytes required to store the attribute in the HDF5 file.
0059     /// \code{.cpp}
0060     /// size_t size = dset.createAttribute<int>("foo", DataSpace(1, 2)).getStorageSize();
0061     /// \endcode
0062     /// \since 1.0
0063     size_t getStorageSize() const;
0064 
0065     /// \brief Get the DataType of the Attribute.
0066     /// \code{.cpp}
0067     /// Attribute attr = dset.createAttribute<int>("foo", DataSpace(1, 2));
0068     /// auto dtype = attr.getDataType(); // Will be an hdf5 type deduced from int
0069     /// \endcode
0070     /// \since 1.0
0071     DataType getDataType() const;
0072 
0073     /// \brief Get the DataSpace of the current Attribute.
0074     /// \code{.cpp}
0075     /// Attribute attr = dset.createAttribute<int>("foo", DataSpace(1, 2));
0076     /// auto dspace = attr.getSpace(); // This will be a DataSpace of dimension 1 * 2
0077     /// \endcode
0078     /// \since 1.0
0079     DataSpace getSpace() const;
0080 
0081     /// \brief Get the DataSpace of the current Attribute.
0082     /// \note This is an alias of getSpace().
0083     /// \since 1.0
0084     DataSpace getMemSpace() const;
0085 
0086     /// \brief Get the value of the Attribute.
0087     /// \code{.cpp}
0088     /// Attribute attr = dset.getAttribute("foo");
0089     /// // The value will contains what have been written in the attribute
0090     /// std::vector<int> value = attr.read<std::vector<int>>();
0091     /// \endcode
0092     /// \since 2.5.0
0093     template <typename T>
0094     T read() const;
0095 
0096     /// \brief Get the value of the Attribute in a buffer.
0097     ///
0098     /// Read the attribute into an existing object. Only available for
0099     /// supported types `T`. If `array` has preallocated the correct amount of
0100     /// memory, then this routine should not trigger reallocation. Otherwise,
0101     /// if supported, the object will be resized.
0102     ///
0103     /// An exception is raised if the numbers of dimension of the buffer and of
0104     /// the attribute are different.
0105     ///
0106     /// \code{.cpp}
0107     /// // Will read into `value` avoiding memory allocation if the dimensions
0108     /// // match, i.e. if the attribute `"foo"` has three element.
0109     /// std::vector<int> value(3);
0110     /// file.getAttribute("foo").read(value);
0111     /// \endcode
0112     /// \since 1.0
0113     template <typename T>
0114     void read(T& array) const;
0115 
0116     /// \brief Read the attribute into a pre-allocated buffer.
0117     /// \deprecated use `read(T&` or `read_raw`.
0118     template <typename T>
0119     void read(T* array, const DataType& mem_datatype) const;
0120 
0121     /// \brief Read the attribute into a buffer.
0122     /// \deprecated use `read(T&` or `read_raw`.
0123     template <typename T>
0124     void read(T* array) const;
0125 
0126     /// \brief Read the attribute into a pre-allocated buffer.
0127     /// \param array A pointer to the first byte of sufficient pre-allocated memory.
0128     /// \param mem_datatype The DataType of the array.
0129     ///
0130     /// \note This is the shallowest wrapper around `H5Aread`. If possible
0131     /// prefer either Attribute::read() const or Attribute::read(T&) const.
0132     ///
0133     /// \code{.cpp}
0134     /// auto attr = file.getAttribute("foo");
0135     ///
0136     /// // Simulate custom allocation by the application.
0137     /// size_t n_elements = attr.getSpace().getElementCount();
0138     /// int * ptr = (int*) malloc(n_elements*sizeof(int));
0139     ///
0140     /// // Read into the pre-allocated memory.
0141     /// attr.read(ptr, mem_datatype);
0142     /// \endcode
0143     /// \since 2.2.2
0144     template <typename T>
0145     void read_raw(T* array, const DataType& mem_datatype) const;
0146 
0147     /// \brief Read the attribute into a buffer.
0148     /// Behaves like Attribute::read(T*, const DataType&) const but
0149     /// additionally this overload deduces the memory datatype from `T`.
0150     ///
0151     /// \param array Pointer to the first byte of pre-allocated memory.
0152     ///
0153     /// \note If possible prefer either Attribute::read() const or Attribute::read(T&) const.
0154     ///
0155     /// \code{.cpp}
0156     /// auto attr = file.getAttribute("foo");
0157     ///
0158     /// // Simulate custom allocation by the application.
0159     /// size_t n_elements = attr.getSpace().getElementCount();
0160     /// int * ptr = (int*) malloc(n_elements*sizeof(int));
0161     ///
0162     /// // Read into the pre-allocated memory.
0163     /// attr.read(ptr);
0164     /// \endcode
0165     /// \since 2.2.2
0166     template <typename T>
0167     void read_raw(T* array) const;
0168 
0169     /// \brief Write the value into the Attribute.
0170     ///
0171     /// Write the value to the attribute. For supported types `T`, this overload
0172     /// will write the value to the attribute. The datatype and dataspace are
0173     /// deduced automatically. However, since the attribute has already been
0174     /// created, the dimensions of `value` must match those of the attribute.
0175     ///
0176     /// \code{.cpp}
0177     /// // Prefer the fused version if creating and writing the attribute
0178     /// // at the same time.
0179     /// dset.createAttribute("foo", std::vector<int>{1, 2, 3});
0180     ///
0181     /// // To overwrite the value:
0182     /// std::vector<int> value{4, 5, 6};
0183     /// dset.getAttribute<int>("foo").write(value);
0184     /// \endcode
0185     /// \since 1.0
0186     template <typename T>
0187     void write(const T& value);
0188 
0189     /// \brief Write from a raw pointer.
0190     ///
0191     /// Values that have been correctly arranged memory, can be written directly
0192     /// by passing a raw pointer.
0193     ///
0194     /// \param buffer Pointer to the first byte of the value.
0195     /// \param mem_datatype The DataType of the buffer.
0196     ///
0197     /// \note This is the shallowest wrapper around `H5Awrite`. It's useful
0198     /// if you need full control. If possible prefer Attribute::write.
0199     ///
0200     /// \code{.cpp}
0201     /// Attribute attr = dset.createAttribute<int>("foo", DataSpace(2, 3));
0202     ///
0203     /// // Simulate the application creating `value` and only exposing access
0204     /// // to the raw pointer `ptr`.
0205     /// std::vector<std::array<int, 3>> value{{1, 2, 3}, {4, 5, 6}};
0206     /// int * ptr = (int*) value.data();
0207     ///
0208     /// // Simply write the bytes to disk.
0209     /// attr.write(ptr, AtomicType<int>());
0210     /// \endcode
0211     /// \since 2.2.2
0212     template <typename T>
0213     void write_raw(const T* buffer, const DataType& mem_datatype);
0214 
0215     /// \brief Write from a raw pointer.
0216     ///
0217     /// Much like Attribute::write_raw(const T*, const DataType&).
0218     /// Additionally, this overload attempts to automatically deduce the
0219     /// datatype of the buffer. Note, that the file datatype is already set.
0220     ///
0221     /// \param buffer Pointer to the first byte.
0222     ///
0223     /// \note If possible prefer Attribute::write.
0224     ///
0225     /// \code{.cpp}
0226     /// // Simulate the application creating `value` and only exposing access
0227     /// // to the raw pointer `ptr`.
0228     /// std::vector<std::array<int, 3>> value{{1, 2, 3}, {4, 5, 6}};
0229     /// int * ptr = (int*) value.data();
0230     ///
0231     /// // Simply write the bytes to disk.
0232     /// attr.write(ptr);
0233     /// \endcode
0234     /// \since 2.2.2
0235     template <typename T>
0236     void write_raw(const T* buffer);
0237 
0238     /// \brief The create property list used for this attribute.
0239     ///
0240     /// Some of HDF5 properties/setting of an attribute are defined by a
0241     /// create property list. This method returns a copy of the create
0242     /// property list used during creation of the attribute.
0243     ///
0244     /// \code{.cpp}
0245     /// auto acpl = attr.getCreatePropertyList();
0246     ///
0247     /// // For example to create another attribute with the same properties.
0248     /// file.createAttribute("foo", 42, acpl);
0249     /// \endcode
0250     /// \since 2.5.0
0251     AttributeCreateProps getCreatePropertyList() const {
0252         return details::get_plist<AttributeCreateProps>(*this, H5Aget_create_plist);
0253     }
0254 
0255     // No empty attributes
0256     Attribute() = delete;
0257 
0258   protected:
0259     using Object::Object;
0260 
0261   private:
0262 #if HIGHFIVE_HAS_FRIEND_DECLARATIONS
0263     template <typename Derivate>
0264     friend class ::HighFive::AnnotateTraits;
0265 #endif
0266 
0267     friend Attribute detail::make_attribute(hid_t);
0268 };
0269 
0270 namespace detail {
0271 inline Attribute make_attribute(hid_t hid) {
0272     return Attribute(hid);
0273 }
0274 }  // namespace detail
0275 
0276 }  // namespace HighFive