Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/highfive/H5Attribute.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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