diff --git a/DESCRIPTION b/DESCRIPTION index 756c9f5..c77d80a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -8,8 +8,7 @@ Authors@R: c( role = c("cre", "aut"), comment = c(ORCID = "0000-0003-3014-6249")), person("Lorin", "Crawford", email = "lcrawford@microsoft.com", role = "aut", comment = c(ORCID = "0000-0003-0178-8242")), - person("sriramlab", role = "cph", comment = "Author of included mailman algorithm"), - person("Blue Brain Project/EPFL", role = "cph", comment = "Author of included HighFive library")) + person("sriramlab", role = "cph", comment = "Author of included mailman algorithm")) Description: The Sparse Marginal Epistasis Test is a computationally efficient genetics method which detects statistical epistasis in complex traits; see Stamp et al. (2025, ) for details. @@ -19,6 +18,7 @@ Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.2 LinkingTo: BH, + HighFive, Rcpp, RcppEigen, Rhdf5lib, diff --git a/inst/include/highfive/H5Attribute.hpp b/inst/include/highfive/H5Attribute.hpp deleted file mode 100644 index 810d388..0000000 --- a/inst/include/highfive/H5Attribute.hpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c), 2017, Ali Can Demiralp - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include - -#include "H5DataType.hpp" -#include "H5Object.hpp" -#include "bits/H5Friends.hpp" -#include "bits/H5Path_traits.hpp" - -namespace HighFive { -class DataSpace; - -namespace detail { - -/// \brief Internal hack to create an `Attribute` from an ID. -/// -/// WARNING: Creating an Attribute from an ID has implications w.r.t. the lifetime of the object -/// that got passed via its ID. Using this method careless opens up the suite of issues -/// related to C-style resource management, including the analog of double free, dangling -/// pointers, etc. -/// -/// NOTE: This is not part of the API and only serves to work around a compiler issue in GCC which -/// prevents us from using `friend`s instead. This function should only be used for internal -/// purposes. The problematic construct is: -/// -/// template -/// friend class SomeCRTP; -/// -/// \private -Attribute make_attribute(hid_t hid); -} // namespace detail - -/// \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 { - public: - const static ObjectType type = ObjectType::Attribute; - - /// \brief Get the name of the current Attribute. - /// \code{.cpp} - /// auto attr = dset.createAttribute("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("foo", DataSpace(1, 2)).getStorageSize(); - /// \endcode - /// \since 1.0 - size_t getStorageSize() const; - - /// \brief Get the DataType of the Attribute. - /// \code{.cpp} - /// Attribute attr = dset.createAttribute("foo", DataSpace(1, 2)); - /// auto dtype = attr.getDataType(); // Will be an hdf5 type deduced from int - /// \endcode - /// \since 1.0 - DataType getDataType() const; - - /// \brief Get the DataSpace of the current Attribute. - /// \code{.cpp} - /// Attribute attr = dset.createAttribute("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 Get the DataSpace of the current Attribute. - /// \note This is an alias of getSpace(). - /// \since 1.0 - DataSpace getMemSpace() const; - - /// \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 value = attr.read>(); - /// \endcode - /// \since 2.5.0 - template - 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. - /// - /// An exception is raised if the numbers of dimension of the buffer and of - /// the attribute are different. - /// - /// \code{.cpp} - /// // Will read into `value` avoiding memory allocation if the dimensions - /// // match, i.e. if the attribute `"foo"` has three element. - /// std::vector value(3); - /// file.getAttribute("foo").read(value); - /// \endcode - /// \since 1.0 - template - void read(T& array) const; - - /// \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"); - /// - /// // 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 - void read(T* array, const DataType& mem_datatype) const; - - /// \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. - /// - /// \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 - void read(T* array) const; - - /// \brief Write the value into the Attribute. - /// - /// 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{1, 2, 3}); - /// - /// // To overwrite the value: - /// std::vector value{4, 5, 6}; - /// dset.getAttribute("foo").write(value); - /// \endcode - /// \since 1.0 - template - void write(const T& value); - - /// \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("foo", DataSpace(2, 3)); - /// - /// // Simulate the application creating `value` and only exposing access - /// // to the raw pointer `ptr`. - /// std::vector> value{{1, 2, 3}, {4, 5, 6}}; - /// int * ptr = (int*) value.data(); - /// - /// // Simply write the bytes to disk. - /// attr.write(ptr, AtomicType()); - /// \endcode - /// \since 2.2.2 - template - void write_raw(const T* buffer, const DataType& mem_datatype); - - /// \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. - /// - /// \code{.cpp} - /// // Simulate the application creating `value` and only exposing access - /// // to the raw pointer `ptr`. - /// std::vector> 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 - void write_raw(const T* buffer); - - /// \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(*this, H5Aget_create_plist); - } - - // No empty attributes - Attribute() = delete; - - protected: - using Object::Object; - - private: -#if HIGHFIVE_HAS_FRIEND_DECLARATIONS - template - friend class ::HighFive::AnnotateTraits; -#endif - - friend Attribute detail::make_attribute(hid_t); -}; - -namespace detail { -inline Attribute make_attribute(hid_t hid) { - return Attribute(hid); -} -} // namespace detail - -} // namespace HighFive diff --git a/inst/include/highfive/H5DataSet.hpp b/inst/include/highfive/H5DataSet.hpp deleted file mode 100644 index 0236f06..0000000 --- a/inst/include/highfive/H5DataSet.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "H5DataSpace.hpp" -#include "H5DataType.hpp" -#include "H5Object.hpp" -#include "bits/H5_definitions.hpp" -#include "bits/H5Annotate_traits.hpp" -#include "bits/H5Slice_traits.hpp" -#include "bits/H5Path_traits.hpp" -#include "bits/H5_definitions.hpp" - -namespace HighFive { - -/// -/// \brief Class representing a dataset. -/// -class DataSet: public Object, - public SliceTraits, - public AnnotateTraits, - public PathTraits { - public: - const static ObjectType type = ObjectType::Dataset; - - /// - /// \brief getStorageSize - /// \return returns the amount of storage allocated for a dataset. - /// - uint64_t getStorageSize() const; - - /// - /// \brief getOffset - /// \return returns DataSet address in file - /// - uint64_t getOffset() const; - - /// - /// \brief getDataType - /// \return return the datatype associated with this dataset - /// - DataType getDataType() const; - - /// - /// \brief getSpace - /// \return return the dataspace associated with this dataset - /// - DataSpace getSpace() const; - - /// - /// \brief getMemSpace - /// \return same than getSpace for DataSet, compatibility with Selection - /// class - /// - DataSpace getMemSpace() const; - - - /// \brief Change the size of the dataset - /// - /// This requires that the dataset was created with chunking, and you would - /// generally want to have set a larger maxdims setting - /// \param dims New size of the dataset - void resize(const std::vector& dims); - - - /// \brief Get the dimensions of the whole DataSet. - /// This is a shorthand for getSpace().getDimensions() - /// \return The shape of the current HighFive::DataSet - /// - inline std::vector getDimensions() const { - return getSpace().getDimensions(); - } - - /// \brief Get the total number of elements in the current dataset. - /// E.g. 2x2x2 matrix has size 8. - /// This is a shorthand for getSpace().getTotalCount() - /// \return The shape of the current HighFive::DataSet - /// - inline size_t getElementCount() const { - return getSpace().getElementCount(); - } - - /// \brief Get the list of properties for creation of this dataset - DataSetCreateProps getCreatePropertyList() const { - return details::get_plist(*this, H5Dget_create_plist); - } - - /// \brief Get the list of properties for accession of this dataset - DataSetAccessProps getAccessPropertyList() const { - return details::get_plist(*this, H5Dget_access_plist); - } - - /// \deprecated Default constructor creates unsafe uninitialized objects - H5_DEPRECATED("Default constructor creates unsafe uninitialized objects") - DataSet() = default; - - protected: - using Object::Object; // bring DataSet(hid_t) - - DataSet(Object&& o) noexcept - : Object(std::move(o)) {} - - friend class Reference; - template - friend class NodeTraits; -}; - -} // namespace HighFive diff --git a/inst/include/highfive/H5DataSpace.hpp b/inst/include/highfive/H5DataSpace.hpp deleted file mode 100644 index 95d04db..0000000 --- a/inst/include/highfive/H5DataSpace.hpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#include -#include - -#include "H5Object.hpp" -#include "bits/H5_definitions.hpp" - -namespace HighFive { - -/// \brief Class representing the space (dimensions) of a DataSet -/// -/// \code{.cpp} -/// // Create a DataSpace of dimension 1 x 2 x 3 -/// DataSpace dspace(1, 2, 3); -/// std::cout << dspace.getElementCount() << std::endl; // Print 1 * 2 * 3 = 6 -/// std::cout << dspace.getNumberDimensions() << std::endl; // Print 3 -/// std::vector dims = dspace.getDimensions(); // dims is {1, 2, 3} -/// \endcode -class DataSpace: public Object { - public: - const static ObjectType type = ObjectType::DataSpace; - - /// \brief Magic value to specify that a DataSpace can grow without limit. - /// - /// This value should be used with DataSpace::DataSpace(const std::vector& dims, const - /// std::vector& maxdims); - /// - /// \since 2.0 - static const size_t UNLIMITED = SIZE_MAX; - - /// \brief An enum to create scalar and null DataSpace with DataSpace::DataSpace(DataspaceType dtype). - /// - /// This enum is needed otherwise we will not be able to distringuish between both with normal - /// constructors. Both have a dimension of 0. - /// \since 1.3 - enum DataspaceType { - dataspace_scalar, ///< Value to create scalar DataSpace - dataspace_null, ///< Value to create null DataSpace - // simple dataspace are handle directly from their dimensions - }; - - /// \brief Create a DataSpace of N-dimensions from a std::vector. - /// \param dims Dimensions of the new DataSpace - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3 - /// DataSpace(std::vector{1, 3}); - /// \endcode - /// \since 1.0 - explicit DataSpace(const std::vector& dims); - - /// \brief Create a DataSpace of N-dimensions from a std::array. - /// \param dims Dimensions of the new DataSpace - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3 - /// DataSpace(std::array{1, 3}); - /// \endcode - /// \since 2.3 - template - explicit DataSpace(const std::array& dims); - - /// \brief Create a DataSpace of N-dimensions from an initializer list. - /// \param dims Dimensions of the new DataSpace - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3 - /// DataSpace{1, 3}; - /// \endcode - /// \since 2.1 - DataSpace(const std::initializer_list& dims); - - /// \brief Create a DataSpace of N-dimensions from direct values. - /// \param dim1 The first dimension - /// \param dims The following dimensions - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3 - /// DataSpace(1, 3); - /// \endcode - /// \since 2.1 - template - explicit DataSpace(size_t dim1, Args... dims); - - /// \brief Create a DataSpace from a pair of iterators. - /// \param begin The beginning of the container - /// \param end The end of the container - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3 - /// std::vector v{1, 3}; - /// DataSpace(v.begin(), v.end()); - /// \endcode - /// - /// \since 2.0 - // Attention: Explicitly disable DataSpace(int_like, int_like) from trying - // to use this constructor - template ::value, IT>::type> - DataSpace(const IT begin, const IT end); - - /// \brief Create a resizable N-dimensional DataSpace. - /// \param dims Initial size of dataspace - /// \param maxdims Maximum size of the dataspace - /// - /// \code{.cpp} - /// // Create a DataSpace with 2 dimensions: 1 and 3. - /// // It can later be resized up to a maximum of 10 x 10 - /// DataSpace(std::vector{1, 3}, std::vector{10, 10}); - /// \endcode - /// - /// \see UNLIMITED for a DataSpace that can be resized without limit. - /// \since 2.0 - explicit DataSpace(const std::vector& dims, const std::vector& maxdims); - - /// \brief Create a scalar or a null DataSpace. - /// - /// This overload enables creating scalar or null data spaces, both have - /// dimension 0. - /// - /// \param space_type The value from the enum - /// - /// \code{.cpp} - /// DataSpace(DataspaceType::dataspace_scalar); - /// \endcode - /// - /// \attention Avoid braced intialization in these cases, i.e. - /// \code{.cpp} - /// // This is not a scalar dataset: - /// DataSpace{DataspaceType::dataspace_scalar}; - /// \endcode - /// - /// \since 1.3 - explicit DataSpace(DataspaceType space_type); - - /// \brief Create a copy of the DataSpace which will have different id. - /// - /// \code{.cpp} - /// DataSpace dspace1(1, 3); - /// auto dspace2 = dspace.clone(); - /// \endcode - /// - /// \since 1.0 - DataSpace clone() const; - - /// \brief Returns the number of dimensions of a DataSpace. - /// \code{.cpp} - /// DataSpace dspace(1, 3); - /// size_t number_of_dim = dspace.getNumberDimensions(); // returns 2 - /// \endcode - /// \since 1.0 - size_t getNumberDimensions() const; - - /// \brief Returns the size of the dataset in each dimension. - /// - /// For zero-dimensional datasets (e.g. scalar or null datasets) an empty - /// vector is returned. - /// - /// \code{.cpp} - /// DataSpace dspace(1, 3); - /// auto dims = dspace.getDimensions(); // returns {1, 3} - /// \endcode - /// - /// \sa DataSpace::getMaxDimensions - /// - /// \since 1.0 - std::vector getDimensions() const; - - /// \brief Return the number of elements in this DataSpace. - /// - /// \code{.cpp} - /// DataSpace dspace(1, 3); - /// size_t elementcount = dspace.getElementCount(); // return 1 x 3 = 3 - /// \endcode - /// \since 2.1 - size_t getElementCount() const; - - /// \brief Returns the maximum size of the dataset in each dimension. - /// - /// This is the maximum size a dataset can be extended to, which may be - /// different from the current size of the dataset. - /// - /// \code{.cpp} - /// DataSpace dspace(std::vector{1, 3}, std::vector{UNLIMITED, 10}); - /// dspace.getMaxDimensions(); // Return {UNLIMITED, 10} - /// \endcode - /// - /// \sa DataSpace::getDimensions - /// \since 2.0 - std::vector getMaxDimensions() const; - - /// \brief Automatically deduce the DataSpace from a container/value. - /// - /// Certain containers and scalar values are fully supported by HighFive. - /// For these containers, HighFive can deduce the dimensions from `value`. - /// - /// \code{.cpp} - /// double d = 42.0; - /// std::vector> v = {{4, 5, 6}, {7, 8, 9}}; - /// DataSpace::From(v); // A DataSpace of dimensions 2, 3. - /// DataSpace::From(d); // A scalar dataspace. - /// \endcode - /// - /// \since 1.0 - template - static DataSpace From(const T& value); - - /// \brief Create a DataSpace from a value of type string array. - /// \param string_array An C-array of C-string (null-terminated). - /// - /// \code{.cpp} - /// char string_array[2][10] = {"123456789", "abcdefghi"}; - /// auto dspace = DataSpace::FromCharArrayStrings(string_array); // dspace is a DataSpace of - /// dimensions 2 - /// \endcode - /// \since 2.2 - template - static DataSpace FromCharArrayStrings(const char (&string_array)[N][Width]); - - protected: - DataSpace() = default; - - friend class Attribute; - friend class File; - friend class DataSet; -}; - -} // namespace HighFive - -// We include bits right away since DataSpace is user-constructible -#include "bits/H5Dataspace_misc.hpp" diff --git a/inst/include/highfive/H5DataType.hpp b/inst/include/highfive/H5DataType.hpp deleted file mode 100644 index 8861079..0000000 --- a/inst/include/highfive/H5DataType.hpp +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include - -#include - -#include "H5Object.hpp" -#include "bits/H5Utils.hpp" - -#include "bits/string_padding.hpp" -#include "H5PropertyList.hpp" - -namespace HighFive { - - -/// -/// \brief Enum of Fundamental data classes -/// -enum class DataTypeClass { - Time = 1 << 1, - Integer = 1 << 2, - Float = 1 << 3, - String = 1 << 4, - BitField = 1 << 5, - Opaque = 1 << 6, - Compound = 1 << 7, - Reference = 1 << 8, - Enum = 1 << 9, - VarLen = 1 << 10, - Array = 1 << 11, - Invalid = 0 -}; - -inline DataTypeClass operator|(DataTypeClass lhs, DataTypeClass rhs) { - using T = std::underlying_type::type; - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -inline DataTypeClass operator&(DataTypeClass lhs, DataTypeClass rhs) { - using T = std::underlying_type::type; - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -class StringType; - -/// -/// \brief HDF5 Data Type -/// -class DataType: public Object { - public: - bool operator==(const DataType& other) const; - - bool operator!=(const DataType& other) const; - - /// - /// \brief Return the fundamental type. - /// - DataTypeClass getClass() const; - - /// - /// \brief Returns the length (in bytes) of this type elements - /// - /// Notice that the size of variable length sequences may have limited applicability - /// given that it refers to the size of the control structure. For info see - /// https://support.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetSize - size_t getSize() const; - - /// - /// \brief Returns a friendly description of the type (e.g. Float32) - /// - std::string string() const; - - /// - /// \brief Returns whether the type is a variable-length string - /// - bool isVariableStr() const; - - /// - /// \brief Returns whether the type is a fixed-length string - /// - bool isFixedLenStr() const; - - /// - /// \brief Returns this datatype as a `StringType`. - /// - StringType asStringType() const; - - /// - /// \brief Check the DataType was default constructed. - /// Such value might represent auto-detection of the datatype from a buffer - /// - bool empty() const noexcept; - - /// \brief Returns whether the type is a Reference - bool isReference() const; - - /// \brief Get the list of properties for creation of this DataType - DataTypeCreateProps getCreatePropertyList() const { - return details::get_plist(*this, H5Tget_create_plist); - } - - protected: - using Object::Object; - - friend class Attribute; - friend class File; - friend class DataSet; - friend class CompoundType; - template - friend class NodeTraits; -}; - - -enum class CharacterSet : std::underlying_type::type { - Ascii = H5T_CSET_ASCII, - Utf8 = H5T_CSET_UTF8, -}; - -class StringType: public DataType { - public: - /// - /// \brief For stings return the character set. - /// - CharacterSet getCharacterSet() const; - - /// - /// \brief For fixed length stings return the padding. - /// - StringPadding getPadding() const; - - protected: - using DataType::DataType; - friend class DataType; -}; - -class FixedLengthStringType: public StringType { - public: - /// - /// \brief Create a fixed length string datatype. - /// - /// The string will be `size` bytes long, regardless whether it's ASCII or - /// UTF8. In particular, a string with `n` UFT8 characters in general - /// requires `4*n` bytes. - /// - /// The string padding is subtle, essentially it's just a hint. A - /// nullterminated string is guaranteed to have one `'\0'` which marks the - /// semantic end of the string. The length of the buffer must be at least - /// `size` bytes regardless. HDF5 will read or write `size` bytes, - /// irrespective of the when the `\0` occurs. - /// - /// Note that when writing passing `StringPadding::NullTerminated` is a - /// guarantee to the reader that it contains a `\0`. Therefore, make sure - /// that the string really is nullterminated. Otherwise prefer a - /// null-padded string which only means states that the buffer is filled up - /// with 0 or more `\0`. - FixedLengthStringType(size_t size, - StringPadding padding, - CharacterSet character_set = CharacterSet::Ascii); -}; - -class VariableLengthStringType: public StringType { - public: - /// - /// \brief Create a variable length string HDF5 datatype. - /// - VariableLengthStringType(CharacterSet character_set = CharacterSet::Ascii); -}; - - -/// -/// \brief create an HDF5 DataType from a C++ type -/// -/// Support only basic data type -/// -template -class AtomicType: public DataType { - public: - AtomicType(); - - using basic_type = T; -}; - - -/// -/// \brief Create a compound HDF5 datatype -/// -class CompoundType: public DataType { - public: - /// - /// \brief Use for defining a sub-type of compound type - struct member_def { - member_def(std::string t_name, DataType t_base_type, size_t t_offset = 0) - : name(std::move(t_name)) - , base_type(std::move(t_base_type)) - , offset(t_offset) {} - std::string name; - DataType base_type; - size_t offset; - }; - - CompoundType(const CompoundType& other) = default; - - /// - /// \brief Initializes a compound type from a vector of member definitions - /// \param t_members - /// \param size - inline CompoundType(const std::vector& t_members, size_t size = 0) - : members(t_members) { - create(size); - } - inline CompoundType(std::vector&& t_members, size_t size = 0) - : members(std::move(t_members)) { - create(size); - } - inline CompoundType(const std::initializer_list& t_members, size_t size = 0) - : members(t_members) { - create(size); - } - - /// - /// \brief Initializes a compound type from a DataType - /// \param type - inline CompoundType(DataType&& type) - : DataType(type) { - if (getClass() != DataTypeClass::Compound) { - std::ostringstream ss; - ss << "hid " << _hid << " does not refer to a compound data type"; - throw DataTypeException(ss.str()); - } - int result = H5Tget_nmembers(_hid); - if (result < 0) { - throw DataTypeException("Could not get members of compound datatype"); - } - size_t n_members = static_cast(result); - members.reserve(n_members); - for (unsigned i = 0; i < n_members; i++) { - char* name = H5Tget_member_name(_hid, i); - size_t offset = H5Tget_member_offset(_hid, i); - hid_t member_hid = H5Tget_member_type(_hid, i); - DataType member_type{member_hid}; - members.emplace_back(std::string(name), member_type, offset); - if (H5free_memory(name) < 0) { - throw DataTypeException("Could not free names from the compound datatype"); - } - } - } - - /// \brief Commit datatype into the given Object - /// \param object Location to commit object into - /// \param name Name to give the datatype - inline void commit(const Object& object, const std::string& name) const; - - /// \brief Get read access to the CompoundType members - inline const std::vector& getMembers() const noexcept { - return members; - } - - private: - /// A vector of the member_def members of this CompoundType - std::vector members; - - /// \brief Automatically create the type from the set of members - /// using standard struct alignment. - /// \param size Total size of data type - void create(size_t size = 0); -}; - -/// -/// \brief Create a enum HDF5 datatype -/// -/// \code{.cpp} -/// enum class Position { -/// FIRST = 1, -/// SECOND = 2, -/// }; -/// -/// EnumType create_enum_position() { -/// return {{"FIRST", Position::FIRST}, -/// {"SECOND", Position::SECOND}}; -/// } -/// -/// // You have to register the type inside HighFive -/// HIGHFIVE_REGISTER_TYPE(Position, create_enum_position) -/// -/// void write_first(H5::File& file) { -/// auto dataset = file.createDataSet("/foo", Position::FIRST); -/// } -/// \endcode -template -class EnumType: public DataType { - public: - /// - /// \brief Use for defining a member of enum type - struct member_def { - member_def(const std::string& t_name, T t_value) - : name(t_name) - , value(std::move(t_value)) {} - std::string name; - T value; - }; - - EnumType(const EnumType& other) = default; - - EnumType(const std::vector& t_members) - : members(t_members) { - static_assert(std::is_enum::value, "EnumType::create takes only enum"); - if (members.empty()) { - HDF5ErrMapper::ToException( - "Could not create an enum without members"); - } - create(); - } - - EnumType(std::initializer_list t_members) - : EnumType(std::vector(t_members)) {} - - /// \brief Commit datatype into the given Object - /// \param object Location to commit object into - /// \param name Name to give the datatype - void commit(const Object& object, const std::string& name) const; - - private: - std::vector members; - - void create(); -}; - - -/// \brief Create a DataType instance representing type T -template -DataType create_datatype(); - - -/// \brief Create a DataType instance representing type T and perform a sanity check on its size -template -DataType create_and_check_datatype(); - - -/// -/// \brief A structure representing a set of fixed-length strings -/// -/// Although fixed-len arrays can be created 'raw' without the need for -/// this structure, to retrieve results efficiently it must be used. -/// -/// \tparam N Size of the string in bytes, including the null character. Note, -/// that all string must be null-terminated. -/// -template -class FixedLenStringArray { - public: - FixedLenStringArray() = default; - - /// - /// \brief Create a FixedStringArray from a raw contiguous buffer. - /// - /// The argument `n_strings` specifies the number of strings. - /// - FixedLenStringArray(const char array[][N], std::size_t n_strings); - - /// - /// \brief Create a FixedStringArray from a sequence of strings. - /// - /// Such conversion involves a copy, original vector is not modified - /// - explicit FixedLenStringArray(const std::vector& vec); - - FixedLenStringArray(const std::string* iter_begin, const std::string* iter_end); - - FixedLenStringArray(const std::initializer_list&); - - /// - /// \brief Append an std::string to the buffer structure - /// - void push_back(const std::string&); - - void push_back(const std::array&); - - /// - /// \brief Retrieve a string from the structure as std::string - /// - std::string getString(std::size_t index) const; - - // Container interface - inline const char* operator[](std::size_t i) const noexcept { - return datavec[i].data(); - } - inline const char* at(std::size_t i) const { - return datavec.at(i).data(); - } - inline bool empty() const noexcept { - return datavec.empty(); - } - inline std::size_t size() const noexcept { - return datavec.size(); - } - inline void resize(std::size_t n) { - datavec.resize(n); - } - inline const char* front() const { - return datavec.front().data(); - } - inline const char* back() const { - return datavec.back().data(); - } - inline char* data() noexcept { - return datavec[0].data(); - } - inline const char* data() const noexcept { - return datavec[0].data(); - } - - private: - using vector_t = typename std::vector>; - - public: - // Use the underlying iterator - using iterator = typename vector_t::iterator; - using const_iterator = typename vector_t::const_iterator; - using reverse_iterator = typename vector_t::reverse_iterator; - using const_reverse_iterator = typename vector_t::const_reverse_iterator; - using value_type = typename vector_t::value_type; - - inline iterator begin() noexcept { - return datavec.begin(); - } - inline iterator end() noexcept { - return datavec.end(); - } - inline const_iterator begin() const noexcept { - return datavec.begin(); - } - inline const_iterator cbegin() const noexcept { - return datavec.cbegin(); - } - inline const_iterator end() const noexcept { - return datavec.end(); - } - inline const_iterator cend() const noexcept { - return datavec.cend(); - } - inline reverse_iterator rbegin() noexcept { - return datavec.rbegin(); - } - inline reverse_iterator rend() noexcept { - return datavec.rend(); - } - inline const_reverse_iterator rbegin() const noexcept { - return datavec.rbegin(); - } - inline const_reverse_iterator rend() const noexcept { - return datavec.rend(); - } - - private: - vector_t datavec; -}; - -} // namespace HighFive - - -/// \brief Macro to extend datatype of HighFive -/// -/// This macro has to be called outside of any namespace. -/// -/// \code{.cpp} -/// enum FooBar { FOO = 1, BAR = 2 }; -/// EnumType create_enum_foobar() { -/// return EnumType({{"FOO", FooBar::FOO}, -/// {"BAR", FooBar::BAR}}); -/// } -/// HIGHFIVE_REGISTER_TYPE(FooBar, create_enum_foobar) -/// \endcode -#define HIGHFIVE_REGISTER_TYPE(type, function) \ - template <> \ - inline HighFive::DataType HighFive::create_datatype() { \ - return function(); \ - } - -#include "bits/H5DataType_misc.hpp" diff --git a/inst/include/highfive/H5Easy.hpp b/inst/include/highfive/H5Easy.hpp deleted file mode 100644 index e793fd8..0000000 --- a/inst/include/highfive/H5Easy.hpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ - -/// \brief -/// Read/dump DataSets or Attribute using a minimalistic syntax. -/// To this end, the functions are templated, and accept: -/// - Any type accepted by HighFive -/// - Eigen objects -/// - xtensor objects -/// - OpenCV objects - -#pragma once - -#include -#include - -// optionally enable xtensor plug-in and load the library -#ifdef XTENSOR_VERSION_MAJOR -#ifndef H5_USE_XTENSOR -#define H5_USE_XTENSOR -#endif -#endif - -#ifdef H5_USE_XTENSOR -#include -#include -#endif - -// optionally enable Eigen plug-in and load the library -#ifdef EIGEN_WORLD_VERSION -#ifndef H5_USE_EIGEN -#define H5_USE_EIGEN -#endif -#endif - -#ifdef H5_USE_EIGEN -#include -#endif - -// optionally enable OpenCV plug-in and load the library -#ifdef CV_MAJOR_VERSION -#ifndef H5_USE_OPENCV -#define H5_USE_OPENCV -#endif -#endif - -#ifdef H5_USE_OPENCV -#include -#endif - -#include "H5File.hpp" - -namespace H5Easy { - -using HighFive::AtomicType; -using HighFive::Attribute; -using HighFive::Chunking; -using HighFive::DataSet; -using HighFive::DataSetCreateProps; -using HighFive::DataSpace; -using HighFive::Deflate; -using HighFive::Exception; -using HighFive::File; -using HighFive::ObjectType; -using HighFive::Shuffle; - -/// -/// \brief Write mode for DataSets -enum class DumpMode { - Create = 0, /*!< Dump only if DataSet does not exist, otherwise throw. */ - Overwrite = 1 /*!< Create or overwrite if DataSet of correct shape exists, otherwise throw. */ -}; - -/// -/// \brief Signal to enable/disable automatic flushing after write operations. -enum class Flush { - False = 0, /*!< No automatic flushing. */ - True = 1 /*!< Automatic flushing. */ -}; - -/// -/// \brief Signal to set compression level for written DataSets. -class Compression { - public: - /// - /// \brief Enable compression with the highest compression level (9). - /// or disable compression (set compression level to 0). - /// - /// \param enable ``true`` to enable with highest compression level - explicit Compression(bool enable = true); - - /// - /// \brief Set compression level. - /// - /// \param level the compression level - template - Compression(T level); - - /// - /// \brief Return compression level. - inline unsigned get() const; - - private: - unsigned m_compression_level; -}; - -/// -/// \brief Define options for dumping data. -/// -/// By default: -/// - DumpMode::Create -/// - Flush::True -/// - Compression: false -/// - ChunkSize: automatic -class DumpOptions { - public: - /// - /// \brief Constructor: accept all default settings. - DumpOptions() = default; - - /// - /// \brief Constructor: overwrite (some of the) defaults. - /// \param args any of DumpMode(), Flush(), Compression() in arbitrary number and order. - template - DumpOptions(Args... args) { - set(args...); - } - - /// - /// \brief Overwrite H5Easy::DumpMode setting. - /// \param mode: DumpMode. - inline void set(DumpMode mode); - - /// - /// \brief Overwrite H5Easy::Flush setting. - /// \param mode Flush. - inline void set(Flush mode); - - /// - /// \brief Overwrite H5Easy::Compression setting. - /// \param level Compression. - inline void set(const Compression& level); - - /// - /// \brief Overwrite any setting(s). - /// \param arg any of DumpMode(), Flush(), Compression in arbitrary number and order. - /// \param args any of DumpMode(), Flush(), Compression in arbitrary number and order. - template - inline void set(T arg, Args... args); - - /// - /// \brief Set chunk-size. If the input is rank (size) zero, automatic chunking is enabled. - /// \param shape Chunk size along each dimension. - template - inline void setChunkSize(const std::vector& shape); - - /// - /// \brief Set chunk-size. If the input is rank (size) zero, automatic chunking is enabled. - /// \param shape Chunk size along each dimension. - inline void setChunkSize(std::initializer_list shape); - - /// - /// \brief Get overwrite-mode. - /// \return bool - inline bool overwrite() const; - - /// - /// \brief Get flush-mode. - /// \return bool - inline bool flush() const; - - /// - /// \brief Get compress-mode. - /// \return bool - inline bool compress() const; - - /// - /// \brief Get compression level. - /// \return [0..9] - inline unsigned getCompressionLevel() const; - - /// - /// \brief Get chunking mode: ``true`` is manually set, ``false`` if chunk-size should be - /// computed automatically. - /// \return bool - inline bool isChunked() const; - - /// - /// \brief Get chunk size. Use DumpOptions::getChunkSize to check if chunk-size should - /// be automatically computed. - inline std::vector getChunkSize() const; - - private: - bool m_overwrite = false; - bool m_flush = true; - unsigned m_compression_level = 0; - std::vector m_chunk_size = {}; -}; - -/// -/// \brief Get the size of an existing DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be readable) -/// \param path path of the DataSet -/// -/// \return Size of the DataSet -inline size_t getSize(const File& file, const std::string& path); - -/// -/// \brief Get the shape of an existing DataSet in an readable file. -/// -/// \param file opened file (has to be readable) -/// \param path Path of the DataSet -/// -/// \return the shape of the DataSet -inline std::vector getShape(const File& file, const std::string& path); - -/// -/// \brief Write object (templated) to a (new) DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param mode write mode -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - DumpMode mode = DumpMode::Create); - -/// -/// \brief Write object (templated) to a (new) DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param options dump options -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, const std::string& path, const T& data, const DumpOptions& options); - -/// -/// \brief Write a scalar to a (new, extendible) DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param idx the indices to which to write -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::vector& idx); - -/// -/// \brief Write a scalar to a (new, extendable) DataSet in an open HDF5 file. -/// -/// \param file open File (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param idx the indices to which to write -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::initializer_list& idx); - -/// -/// \brief Write a scalar to a (new, extendible) DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param idx the indices to which to write -/// \param options dump options -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::vector& idx, - const DumpOptions& options); - -/// -/// \brief Write a scalar to a (new, extendible) DataSet in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param data the data to write (any supported type) -/// \param idx the indices to which to write -/// \param options dump options -/// -/// \return The newly created DataSet -/// -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::initializer_list& idx, - const DumpOptions& options); - -/// -/// \brief Load entry ``{i, j, ...}`` from a DataSet in an open HDF5 file to a scalar. -/// -/// \param file opened file (has to be writeable) -/// \param idx the indices to load -/// \param path path of the DataSet -/// -/// \return The read data -/// -template -inline T load(const File& file, const std::string& path, const std::vector& idx); - -/// -/// \brief Load a DataSet in an open HDF5 file to an object (templated). -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// -/// \return The read data -/// -template -inline T load(const File& file, const std::string& path); - -/// -/// \brief Write object (templated) to a (new) Attribute in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param key name of the attribute -/// \param data the data to write (any supported type) -/// \param mode write mode -/// -/// \return The newly created DataSet -/// -template -inline Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - DumpMode mode = DumpMode::Create); - -/// -/// \brief Write object (templated) to a (new) Attribute in an open HDF5 file. -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param key name of the attribute -/// \param data the data to write (any supported type) -/// \param options dump options -/// -/// \return The newly created DataSet -/// -template -inline Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options); - -/// -/// \brief Load a Attribute in an open HDF5 file to an object (templated). -/// -/// \param file opened file (has to be writeable) -/// \param path path of the DataSet -/// \param key name of the attribute -/// -/// \return The read data -/// -template -inline T loadAttribute(const File& file, const std::string& path, const std::string& key); - -} // namespace H5Easy - -#include "h5easy_bits/H5Easy_Eigen.hpp" -#include "h5easy_bits/H5Easy_misc.hpp" -#include "h5easy_bits/H5Easy_opencv.hpp" -#include "h5easy_bits/H5Easy_public.hpp" -#include "h5easy_bits/H5Easy_scalar.hpp" -#include "h5easy_bits/H5Easy_vector.hpp" -#include "h5easy_bits/H5Easy_xtensor.hpp" diff --git a/inst/include/highfive/H5Exception.hpp b/inst/include/highfive/H5Exception.hpp deleted file mode 100644 index 54905aa..0000000 --- a/inst/include/highfive/H5Exception.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include - -#include - -namespace HighFive { - -/// -/// \brief Basic HighFive Exception class -/// -/// -class Exception: public std::exception { - public: - Exception(const std::string& err_msg) - : _errmsg(err_msg) - , _next() - , _err_major(0) - , _err_minor(0) {} - - virtual ~Exception() throw() {} - - /// - /// \brief get the current exception error message - /// \return - /// - inline const char* what() const throw() override { - return _errmsg.c_str(); - } - - /// - /// \brief define the error message - /// \param errmsg - /// - inline virtual void setErrorMsg(const std::string& errmsg) { - _errmsg = errmsg; - } - - /// - /// \brief nextException - /// \return pointer to the next exception in the chain, or NULL if not - /// existing - /// - inline Exception* nextException() const { - return _next.get(); - } - - /// - /// \brief HDF5 library error mapper - /// \return HDF5 major error number - /// - inline hid_t getErrMajor() const { - return _err_major; - } - - /// - /// \brief HDF5 library error mapper - /// \return HDF5 minor error number - /// - inline hid_t getErrMinor() const { - return _err_minor; - } - - protected: - std::string _errmsg; - std::shared_ptr _next; - hid_t _err_major, _err_minor; - - friend struct HDF5ErrMapper; -}; - -/// -/// \brief Exception specific to HighFive Object interface -/// -class ObjectException: public Exception { - public: - ObjectException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive DataType interface -/// -class DataTypeException: public Exception { - public: - DataTypeException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive File interface -/// -class FileException: public Exception { - public: - FileException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive DataSpace interface -/// -class DataSpaceException: public Exception { - public: - DataSpaceException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive Attribute interface -/// -class AttributeException: public Exception { - public: - AttributeException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive DataSet interface -/// -class DataSetException: public Exception { - public: - DataSetException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive Group interface -/// -class GroupException: public Exception { - public: - GroupException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive Property interface -/// -class PropertyException: public Exception { - public: - PropertyException(const std::string& err_msg) - : Exception(err_msg) {} -}; - -/// -/// \brief Exception specific to HighFive Reference interface -/// -class ReferenceException: public Exception { - public: - ReferenceException(const std::string& err_msg) - : Exception(err_msg) {} -}; -} // namespace HighFive - -#include "bits/H5Exception_misc.hpp" diff --git a/inst/include/highfive/H5File.hpp b/inst/include/highfive/H5File.hpp deleted file mode 100644 index 9b393e5..0000000 --- a/inst/include/highfive/H5File.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "H5FileDriver.hpp" -#include "H5Object.hpp" -#include "H5PropertyList.hpp" -#include "bits/H5Annotate_traits.hpp" -#include "bits/H5Node_traits.hpp" - -namespace HighFive { - -/// -/// \brief File class -/// -class File: public Object, public NodeTraits, public AnnotateTraits { - public: - const static ObjectType type = ObjectType::File; - - enum : unsigned { - /// Open flag: Read only access - ReadOnly = 0x00u, - /// Open flag: Read Write access - ReadWrite = 0x01u, - /// Open flag: Truncate a file if already existing - Truncate = 0x02u, - /// Open flag: Open will fail if file already exist - Excl = 0x04u, - /// Open flag: Open in debug mode - Debug = 0x08u, - /// Open flag: Create non existing file - Create = 0x10u, - /// Derived open flag: common write mode (=ReadWrite|Create|Truncate) - Overwrite = Truncate, - /// Derived open flag: Opens RW or exclusively creates - OpenOrCreate = ReadWrite | Create - }; - - /// - /// \brief File - /// \param filename: filepath of the HDF5 file - /// \param openFlags: Open mode / flags ( ReadOnly, ReadWrite) - /// \param fileAccessProps: the file access properties - /// - /// Open or create a new HDF5 file - explicit File(const std::string& filename, - unsigned openFlags = ReadOnly, - const FileAccessProps& fileAccessProps = FileAccessProps::Default()); - - /// - /// \brief File - /// \param filename: filepath of the HDF5 file - /// \param openFlags: Open mode / flags ( ReadOnly, ReadWrite) - /// \param fileCreateProps: the file create properties - /// \param fileAccessProps: the file access properties - /// - /// Open or create a new HDF5 file - File(const std::string& filename, - unsigned openFlags, - const FileCreateProps& fileCreateProps, - const FileAccessProps& fileAccessProps = FileAccessProps::Default()); - - /// - /// \brief Return the name of the file - /// - const std::string& getName() const noexcept; - - - /// \brief Object path of a File is always "/" - std::string getPath() const noexcept { - return "/"; - } - - /// \brief Returns the block size for metadata in bytes - hsize_t getMetadataBlockSize() const; - - /// \brief Returns the HDF5 version compatibility bounds - std::pair getVersionBounds() const; - -#if H5_VERSION_GE(1, 10, 1) - /// \brief Returns the HDF5 file space strategy. - H5F_fspace_strategy_t getFileSpaceStrategy() const; - - /// \brief Returns the page size, if paged allocation is used. - hsize_t getFileSpacePageSize() const; -#endif - - /// - /// \brief flush - /// - /// Flushes all buffers associated with a file to disk - /// - void flush(); - - /// \brief Get the list of properties for creation of this file - FileCreateProps getCreatePropertyList() const { - return details::get_plist(*this, H5Fget_create_plist); - } - - /// \brief Get the list of properties for accession of this file - FileAccessProps getAccessPropertyList() const { - return details::get_plist(*this, H5Fget_access_plist); - } - - /// \brief Get the size of this file in bytes - size_t getFileSize() const; - - /// \brief Get the amount of tracked, unused space in bytes. - /// - /// Note, this is a wrapper for `H5Fget_freespace` and returns the number - /// bytes in the free space manager. This might be different from the total - /// amount of unused space in the HDF5 file, since the free space manager - /// might not track everything or not track across open-close cycles. - size_t getFreeSpace() const; - - protected: - File() = default; - using Object::Object; - - private: - mutable std::string _filename{}; - - template - friend class PathTraits; -}; - -} // namespace HighFive - -// H5File is the main user constructible -> bring in implementation headers -#include "bits/H5Annotate_traits_misc.hpp" -#include "bits/H5File_misc.hpp" -#include "bits/H5Node_traits_misc.hpp" -#include "bits/H5Path_traits_misc.hpp" diff --git a/inst/include/highfive/H5FileDriver.hpp b/inst/include/highfive/H5FileDriver.hpp deleted file mode 100644 index 2cd4813..0000000 --- a/inst/include/highfive/H5FileDriver.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "H5PropertyList.hpp" -#include "bits/H5_definitions.hpp" - -namespace HighFive { - -/// \brief file driver base concept -/// \deprecated Use FileAccessProps directly -class H5_DEPRECATED("Use FileAccessProps directly") FileDriver: public FileAccessProps {}; - -#ifdef H5_HAVE_PARALLEL -/// \brief MPIIO Driver for Parallel HDF5 -/// \deprecated Add MPIOFileAccess directly to FileAccessProps -class H5_DEPRECATED("Add MPIOFileAccess directly to FileAccessProps") MPIOFileDriver - : public FileAccessProps { - public: - inline MPIOFileDriver(MPI_Comm mpi_comm, MPI_Info mpi_info); -}; -#endif - -} // namespace HighFive - -#include "bits/H5FileDriver_misc.hpp" diff --git a/inst/include/highfive/H5Group.hpp b/inst/include/highfive/H5Group.hpp deleted file mode 100644 index 0a6a4cd..0000000 --- a/inst/include/highfive/H5Group.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "H5Object.hpp" -#include "bits/H5Friends.hpp" -#include "bits/H5_definitions.hpp" -#include "bits/H5Annotate_traits.hpp" -#include "bits/H5Node_traits.hpp" -#include "bits/H5Path_traits.hpp" - -namespace HighFive { - -namespace detail { -/// \brief Internal hack to create an `Group` from an ID. -/// -/// WARNING: Creating an Group from an ID has implications w.r.t. the lifetime of the object -/// that got passed via its ID. Using this method careless opens up the suite of issues -/// related to C-style resource management, including the analog of double free, dangling -/// pointers, etc. -/// -/// NOTE: This is not part of the API and only serves to work around a compiler issue in GCC which -/// prevents us from using `friend`s instead. This function should only be used for internal -/// purposes. The problematic construct is: -/// -/// template -/// friend class SomeCRTP; -/// -/// \private -Group make_group(hid_t); -} // namespace detail - -/// -/// \brief Represents an hdf5 group -class Group: public Object, - public NodeTraits, - public AnnotateTraits, - public PathTraits { - public: - const static ObjectType type = ObjectType::Group; - - /// \deprecated Default constructor creates unsafe uninitialized objects - H5_DEPRECATED("Default constructor creates unsafe uninitialized objects") - Group() = default; - - std::pair getEstimatedLinkInfo() const; - - /// \brief Get the list of properties for creation of this group - GroupCreateProps getCreatePropertyList() const { - return details::get_plist(*this, H5Gget_create_plist); - } - - Group(Object&& o) noexcept - : Object(std::move(o)){}; - - protected: - using Object::Object; - - friend Group detail::make_group(hid_t); - friend class File; - friend class Reference; -#if HIGHFIVE_HAS_FRIEND_DECLARATIONS - template - friend class ::HighFive::NodeTraits; -#endif -}; - -inline std::pair Group::getEstimatedLinkInfo() const { - auto gcpl = getCreatePropertyList(); - auto eli = EstimatedLinkInfo(gcpl); - return std::make_pair(eli.getEntries(), eli.getNameLength()); -} - -namespace detail { -inline Group make_group(hid_t hid) { - return Group(hid); -} -} // namespace detail - -} // namespace HighFive diff --git a/inst/include/highfive/H5Object.hpp b/inst/include/highfive/H5Object.hpp deleted file mode 100644 index 4cf4e7d..0000000 --- a/inst/include/highfive/H5Object.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include -#include - -#include "bits/H5_definitions.hpp" -#include "bits/H5Friends.hpp" - -namespace HighFive { - -/// -/// \brief Enum of the types of objects (H5O api) -/// -enum class ObjectType { - File, - Group, - UserDataType, - DataSpace, - Dataset, - Attribute, - Other // Internal/custom object type -}; - -namespace detail { -/// \brief Internal hack to create an `Object` from an ID. -/// -/// WARNING: Creating an Object from an ID has implications w.r.t. the lifetime of the object -/// that got passed via its ID. Using this method careless opens up the suite of issues -/// related to C-style resource management, including the analog of double free, dangling -/// pointers, etc. -/// -/// NOTE: This is not part of the API and only serves to work around a compiler issue in GCC which -/// prevents us from using `friend`s instead. This function should only be used for internal -/// purposes. The problematic construct is: -/// -/// template -/// friend class SomeCRTP; -/// -/// \private -Object make_object(hid_t hid); -} // namespace detail - - -class Object { - public: - // move constructor, reuse hid - Object(Object&& other) noexcept; - - // decrease reference counter - ~Object(); - - /// - /// \brief isValid - /// \return true if current Object is a valid HDF5Object - /// - bool isValid() const noexcept; - - /// - /// \brief getId - /// \return internal HDF5 id to the object - /// provided for C API compatibility - /// - hid_t getId() const noexcept; - - /// - /// \brief Retrieve several infos about the current object (address, dates, etc) - /// - ObjectInfo getInfo() const; - - /// - /// \brief Gets the fundamental type of the object (dataset, group, etc) - /// \exception ObjectException when the _hid is negative or the type - /// is custom and not registered yet - /// - ObjectType getType() const; - - // Check if refer to same object - bool operator==(const Object& other) const noexcept { - return _hid == other._hid; - } - - protected: - // empty constructor - Object(); - - // copy constructor, increase reference counter - Object(const Object& other); - - // Init with an low-level object id - explicit Object(hid_t); - - // Copy-Assignment operator - Object& operator=(const Object& other); - - hid_t _hid; - - private: - friend Object detail::make_object(hid_t); - friend class Reference; - friend class CompoundType; - -#if HIGHFIVE_HAS_FRIEND_DECLARATIONS - template - friend class NodeTraits; - template - friend class AnnotateTraits; - template - friend class PathTraits; -#endif -}; - - -/// -/// \brief A class for accessing hdf5 objects info -/// -class ObjectInfo { - public: - /// \brief Retrieve the address of the object (within its file) - /// \deprecated Deprecated since HighFive 2.2. Soon supporting VOL tokens - H5_DEPRECATED("Deprecated since HighFive 2.2. Soon supporting VOL tokens") - haddr_t getAddress() const noexcept; - - /// \brief Retrieve the number of references to this object - size_t getRefCount() const noexcept; - - /// \brief Retrieve the object's creation time - time_t getCreationTime() const noexcept; - - /// \brief Retrieve the object's last modification time - time_t getModificationTime() const noexcept; - - protected: -#if (H5Oget_info_vers < 3) - H5O_info_t raw_info; -#else - // Use compat H5O_info1_t while getAddress() is supported (deprecated) - H5O_info1_t raw_info; -#endif - - friend class Object; -}; - -} // namespace HighFive - -#include "bits/H5Object_misc.hpp" diff --git a/inst/include/highfive/H5PropertyList.hpp b/inst/include/highfive/H5PropertyList.hpp deleted file mode 100644 index 53b3c4a..0000000 --- a/inst/include/highfive/H5PropertyList.hpp +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Copyright (c), 2017-2018, Adrien Devresse - * Juan Hernando - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include - -// Required by MPIOFileAccess -#ifdef H5_HAVE_PARALLEL -#include -#endif - -#include "H5Exception.hpp" -#include "H5Object.hpp" - -namespace HighFive { - -/// \defgroup PropertyLists Property Lists -/// HDF5 is configured through what they call property lists. In HDF5 the -/// process has four steps: -/// -/// 1. Create a property list. As users we now have an `hid_t` identifying the -/// property list. -/// 2. Set properties as desired. -/// 3. Pass the HID to the HDF5 function to be configured. -/// 4. Free the property list. -/// -/// Note that the mental picture is that one creates a settings object, and -/// then passes those settings to a function such as `H5Dwrite`. In and of -/// themselves the settings don't change the behaviour of HDF5. Rather they -/// need to be used to take affect. -/// -/// The second aspect is that property lists represent any number of related -/// settings, e.g. there's property lists anything related to creating files -/// and another for accessing files, same for creating and accessing datasets, -/// etc. Settings that affect creating files, must be passed a file creation -/// property list, while settings that affect file access require a file access -/// property list. -/// -/// In HighFive the `PropertyList` works similar in that it's a object -/// representing the settings, i.e. internally it's just the property lists -/// HID. Just like in HDF5 one adds the settings to the settings object; and -/// then passes the settings object to the respective method. Example: -/// -/// -/// // Create an object which contains the setting to -/// // open files with MPI-IO. -/// auto fapl = FileAccessProps(); -/// fapl.add(MPIOFileAccess(MPI_COMM_WORLD, MPI_INFO_NULL); -/// -/// // To open a specific file with MPI-IO, we do: -/// auto file = File("foo.h5", File::ReadOnly, fapl); -/// -/// Note that the `MPIOFileAccess` object by itself doesn't affect the -/// `FileAccessProps`. Rather it needs to be explicitly added to the `fapl` -/// (the group of file access related settings), and then the `fapl` needs to -/// be passed to the constructor of `File` for the settings to take affect. -/// -/// This is important to understand when reading properties. Example: -/// -/// // Obtain the file access property list: -/// auto fapl = file.getAccessPropertyList() -/// -/// // Extracts a copy of the collective MPI-IO metadata settings from -/// // the group of file access related setting, i.e. the `fapl`: -/// auto mpio_metadata = MPIOCollectiveMetadata(fapl); -/// -/// if(mpio_metadata.isCollectiveRead()) { -/// // something specific if meta data is read collectively. -/// } -/// -/// // Careful, this only affects the `mpio_metadata` object, but not the -/// // `fapl`, and also not whether `file` uses collective MPI-IO for -/// // metadata. -/// mpio_metadata = MPIOCollectiveMetadata(false, false); -/// -/// @{ - -/// -/// \brief Types of property lists -/// -enum class PropertyType : int { - OBJECT_CREATE, - FILE_CREATE, - FILE_ACCESS, - DATASET_CREATE, - DATASET_ACCESS, - DATASET_XFER, - GROUP_CREATE, - GROUP_ACCESS, - DATATYPE_CREATE, - DATATYPE_ACCESS, - STRING_CREATE, - ATTRIBUTE_CREATE, - OBJECT_COPY, - LINK_CREATE, - LINK_ACCESS, -}; - -namespace details { -template -T get_plist(const U& obj, hid_t (*f)(hid_t)) { - auto hid = f(obj.getId()); - if (hid < 0) { - HDF5ErrMapper::ToException("Unable to get property list"); - } - T t{}; - t._hid = hid; - return t; -} -} // namespace details - -/// -/// \brief Base Class for Property lists, providing global default -class PropertyListBase: public Object { - public: - PropertyListBase() noexcept; - - static const PropertyListBase& Default() noexcept { - static const PropertyListBase plist{}; - return plist; - } - - private: - template - friend T details::get_plist(const U&, hid_t (*f)(hid_t)); -}; - -/// \interface PropertyInterface -/// \brief HDF5 file property object -/// -/// A property is an object which is expected to have a method with the -/// following signature `void apply(hid_t hid) const` -/// -/// \sa Instructions to document C++20 concepts with Doxygen: https://github.com/doxygen/doxygen/issues/2732#issuecomment-509629967 -/// -/// \cond -#if HIGHFIVE_HAS_CONCEPTS && __cplusplus >= 202002L -template -concept PropertyInterface = requires(P p, const hid_t hid) { - {p.apply(hid)}; -}; - -#else -#define PropertyInterface typename -#endif -/// \endcond - -/// -/// \brief HDF5 property Lists -/// -template -class PropertyList: public PropertyListBase { - public: - /// - /// \brief return the type of this PropertyList - constexpr PropertyType getType() const noexcept { - return T; - } - - /// - /// Add a property to this property list. - /// A property is an object which is expected to have a method with the - /// following signature void apply(hid_t hid) const - /// \tparam PropertyInterface - template - void add(const P& property); - - /// - /// Return the Default property type object - static const PropertyList& Default() noexcept { - return static_cast&>(PropertyListBase::Default()); - } - - protected: - void _initializeIfNeeded(); -}; - -using ObjectCreateProps = PropertyList; -using FileCreateProps = PropertyList; -using FileAccessProps = PropertyList; -using DataSetCreateProps = PropertyList; -using DataSetAccessProps = PropertyList; -using DataTransferProps = PropertyList; -using GroupCreateProps = PropertyList; -using GroupAccessProps = PropertyList; -using DataTypeCreateProps = PropertyList; -using DataTypeAccessProps = PropertyList; -using StringCreateProps = PropertyList; -using AttributeCreateProps = PropertyList; -using ObjectCopyProps = PropertyList; -using LinkCreateProps = PropertyList; -using LinkAccessProps = PropertyList; - -/// -/// RawPropertyLists are to be used when advanced H5 properties -/// are desired and are not part of the HighFive API. -/// Therefore this class is mainly for internal use. -template -class RawPropertyList: public PropertyList { - public: - template - void add(const F& funct, const Args&... args); -}; - -#ifdef H5_HAVE_PARALLEL -/// -/// \brief Configure MPI access for the file -/// -/// All further modifications to the structure of the file will have to be -/// done with collective operations -/// -class MPIOFileAccess { - public: - MPIOFileAccess(MPI_Comm comm, MPI_Info info); - - private: - friend FileAccessProps; - void apply(const hid_t list) const; - - MPI_Comm _comm; - MPI_Info _info; -}; - -/// -/// \brief Use collective MPI-IO for metadata read and write. -/// -/// See `MPIOCollectiveMetadataRead` and `MPIOCollectiveMetadataWrite`. -/// -class MPIOCollectiveMetadata { - public: - explicit MPIOCollectiveMetadata(bool collective = true); - explicit MPIOCollectiveMetadata(const FileAccessProps& plist); - - bool isCollectiveRead() const; - bool isCollectiveWrite() const; - - - private: - friend FileAccessProps; - void apply(hid_t plist) const; - - bool collective_read_; - bool collective_write_; -}; - -/// -/// \brief Use collective MPI-IO for metadata read? -/// -/// Note that when used in a file access property list, this will force all reads -/// of meta data to be collective. HDF5 function may implicitly perform metadata -/// reads. These functions would become collective. A list of functions that -/// perform metadata reads can be found in the HDF5 documentation, e.g. -/// https://docs.hdfgroup.org/hdf5/v1_12/group___g_a_c_p_l.html -/// -/// In HighFive setting collective read is (currently) only supported on file level. -/// -/// Please also consult upstream documentation of `H5Pset_all_coll_metadata_ops`. -/// -class MPIOCollectiveMetadataRead { - public: - explicit MPIOCollectiveMetadataRead(bool collective = true); - explicit MPIOCollectiveMetadataRead(const FileAccessProps& plist); - - bool isCollective() const; - - private: - friend FileAccessProps; - friend MPIOCollectiveMetadata; - - void apply(hid_t plist) const; - - bool collective_; -}; - -/// -/// \brief Use collective MPI-IO for metadata write? -/// -/// In order to keep the in-memory representation of the file structure -/// consistent across MPI ranks, writing meta data is always a collective -/// operation. Meaning all MPI ranks must participate. Passing this setting -/// enables using MPI-IO collective operations for metadata writes. -/// -/// Please also consult upstream documentation of `H5Pset_coll_metadata_write`. -/// -class MPIOCollectiveMetadataWrite { - public: - explicit MPIOCollectiveMetadataWrite(bool collective = true); - explicit MPIOCollectiveMetadataWrite(const FileAccessProps& plist); - - bool isCollective() const; - - private: - friend FileAccessProps; - friend MPIOCollectiveMetadata; - - void apply(hid_t plist) const; - - bool collective_; -}; - -#endif - -/// -/// \brief Configure the version bounds for the file -/// -/// Used to define the compatibility of objects created within HDF5 files, -/// and affects the format of groups stored in the file. -/// -/// See also the documentation of \c H5P_SET_LIBVER_BOUNDS in HDF5. -/// -/// Possible values for \c low and \c high are: -/// * \c H5F_LIBVER_EARLIEST -/// * \c H5F_LIBVER_V18 -/// * \c H5F_LIBVER_V110 -/// * \c H5F_LIBVER_NBOUNDS -/// * \c H5F_LIBVER_LATEST currently defined as \c H5F_LIBVER_V110 within -/// HDF5 -/// -class FileVersionBounds { - public: - FileVersionBounds(H5F_libver_t low, H5F_libver_t high); - explicit FileVersionBounds(const FileAccessProps& fapl); - - std::pair getVersion() const; - - private: - friend FileAccessProps; - void apply(const hid_t list) const; - - H5F_libver_t _low; - H5F_libver_t _high; -}; - -/// -/// \brief Configure the metadata block size to use writing to files -/// -/// \param size Metadata block size in bytes -/// -class MetadataBlockSize { - public: - explicit MetadataBlockSize(hsize_t size); - explicit MetadataBlockSize(const FileAccessProps& fapl); - - hsize_t getSize() const; - - private: - friend FileAccessProps; - void apply(const hid_t list) const; - hsize_t _size; -}; - -#if H5_VERSION_GE(1, 10, 1) -/// -/// \brief Configure the file space strategy. -/// -/// See the upstream documentation of `H5Pget_file_space_strategy` for more details. Essentially, -/// it enables configuring how space is allocate in the file. -/// -class FileSpaceStrategy { - public: - /// - /// \brief Create a file space strategy property. - /// - /// \param strategy The HDF5 free space strategy. - /// \param persist Should free space managers be persisted across file closing and reopening. - /// \param threshold The free-space manager wont track sections small than this threshold. - FileSpaceStrategy(H5F_fspace_strategy_t strategy, hbool_t persist, hsize_t threshold); - explicit FileSpaceStrategy(const FileCreateProps& fcpl); - - H5F_fspace_strategy_t getStrategy() const; - hbool_t getPersist() const; - hsize_t getThreshold() const; - - private: - friend FileCreateProps; - - void apply(const hid_t list) const; - - H5F_fspace_strategy_t _strategy; - hbool_t _persist; - hsize_t _threshold; -}; - -/// -/// \brief Configure the page size for paged allocation. -/// -/// See the upstream documentation of `H5Pset_file_space_page_size` for more details. Essentially, -/// it enables configuring the page size when paged allocation is used. -/// -/// General information about paged allocation can be found in the upstream documentation "RFC: Page -/// Buffering". -/// -class FileSpacePageSize { - public: - /// - /// \brief Create a file space strategy property. - /// - /// \param page_size The page size in bytes. - explicit FileSpacePageSize(hsize_t page_size); - explicit FileSpacePageSize(const FileCreateProps& fcpl); - - hsize_t getPageSize() const; - - private: - friend FileCreateProps; - void apply(const hid_t list) const; - - hsize_t _page_size; -}; - -#ifndef H5_HAVE_PARALLEL -/// \brief Set size of the page buffer. -/// -/// Please, consult the upstream documentation of -/// H5Pset_page_buffer_size -/// H5Pget_page_buffer_size -/// Note that this setting is only valid for page allocated/aggregated -/// files, i.e. those that have file space strategy "Page". -/// -/// Tests suggest this doesn't work in the parallel version of the -/// library. Hence, this isn't available at compile time if the parallel -/// library was selected. -class PageBufferSize { - public: - /// Property to set page buffer sizes. - /// - /// @param page_buffer_size maximum size of the page buffer in bytes. - /// @param min_meta_percent fraction of the page buffer dedicated to meta data, in percent. - /// @param min_raw_percent fraction of the page buffer dedicated to raw data, in percent. - explicit PageBufferSize(size_t page_buffer_size, - unsigned min_meta_percent = 0, - unsigned min_raw_percent = 0); - - explicit PageBufferSize(const FileAccessProps& fapl); - - size_t getPageBufferSize() const; - unsigned getMinMetaPercent() const; - unsigned getMinRawPercent() const; - - private: - friend FileAccessProps; - - void apply(hid_t list) const; - - size_t _page_buffer_size; - unsigned _min_meta; - unsigned _min_raw; -}; -#endif -#endif - -/// \brief Set hints as to how many links to expect and their average length -/// \implements PropertyInterface -/// -class EstimatedLinkInfo { - public: - /// \brief Create a property with the request parameters. - /// - /// @param entries The estimated number of links in a group. - /// @param length The estimated length of the names of links. - explicit EstimatedLinkInfo(unsigned entries, unsigned length); - - explicit EstimatedLinkInfo(const GroupCreateProps& gcpl); - - /// \brief The estimated number of links in a group. - unsigned getEntries() const; - - /// \brief The estimated length of the names of links. - unsigned getNameLength() const; - - private: - friend GroupCreateProps; - void apply(hid_t hid) const; - unsigned _entries; - unsigned _length; -}; - - -/// \implements PropertyInterface -class Chunking { - public: - explicit Chunking(const std::vector& dims); - Chunking(const std::initializer_list& items); - - template - explicit Chunking(hsize_t item, Args... args); - - explicit Chunking(DataSetCreateProps& plist, size_t max_dims = 32); - - const std::vector& getDimensions() const noexcept; - - private: - friend DataSetCreateProps; - void apply(hid_t hid) const; - std::vector _dims; -}; - -/// \implements PropertyInterface -class Deflate { - public: - explicit Deflate(unsigned level); - - private: - friend DataSetCreateProps; - friend GroupCreateProps; - void apply(hid_t hid) const; - const unsigned _level; -}; - -/// \implements PropertyInterface -class Szip { - public: - explicit Szip(unsigned options_mask = H5_SZIP_EC_OPTION_MASK, - unsigned pixels_per_block = H5_SZIP_MAX_PIXELS_PER_BLOCK); - - unsigned getOptionsMask() const; - unsigned getPixelsPerBlock() const; - - private: - friend DataSetCreateProps; - void apply(hid_t hid) const; - const unsigned _options_mask; - const unsigned _pixels_per_block; -}; - -/// \implements PropertyInterface -class Shuffle { - public: - Shuffle() = default; - - private: - friend DataSetCreateProps; - void apply(hid_t hid) const; -}; - -/// \brief When are datasets allocated? -/// -/// The precise time of when HDF5 requests space to store the dataset -/// can be configured. Please, consider the upstream documentation for -/// `H5Pset_alloc_time`. -/// \implements PropertyInterface -class AllocationTime { - public: - explicit AllocationTime(H5D_alloc_time_t alloc_time); - explicit AllocationTime(const DataSetCreateProps& dcpl); - - H5D_alloc_time_t getAllocationTime(); - - private: - friend DataSetCreateProps; - void apply(hid_t dcpl) const; - - H5D_alloc_time_t _alloc_time; -}; - -/// Dataset access property to control chunk cache configuration. -/// Do not confuse with the similar file access property for H5Pset_cache -/// \implements PropertyInterface -class Caching { - public: - /// https://support.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_chunk_cache.html for - /// details. - Caching(const size_t numSlots, - const size_t cacheSize, - const double w0 = static_cast(H5D_CHUNK_CACHE_W0_DEFAULT)); - - explicit Caching(const DataSetCreateProps& dcpl); - - size_t getNumSlots() const; - size_t getCacheSize() const; - double getW0() const; - - private: - friend DataSetAccessProps; - void apply(hid_t hid) const; - size_t _numSlots; - size_t _cacheSize; - double _w0; -}; - -/// \implements PropertyInterface -class CreateIntermediateGroup { - public: - explicit CreateIntermediateGroup(bool create = true); - - explicit CreateIntermediateGroup(const ObjectCreateProps& ocpl); - explicit CreateIntermediateGroup(const LinkCreateProps& lcpl); - - bool isSet() const; - - protected: - void fromPropertyList(hid_t hid); - - private: - friend ObjectCreateProps; - friend LinkCreateProps; - void apply(hid_t hid) const; - bool _create; -}; - -#ifdef H5_HAVE_PARALLEL -/// \implements PropertyInterface -class UseCollectiveIO { - public: - explicit UseCollectiveIO(bool enable = true); - - explicit UseCollectiveIO(const DataTransferProps& dxpl); - - /// \brief Does the property request collective IO? - bool isCollective() const; - - private: - friend DataTransferProps; - void apply(hid_t hid) const; - bool _enable; -}; - - -/// \brief The cause for non-collective I/O. -/// -/// The cause refers to the most recent I/O with data transfer property list `dxpl` at time of -/// creation of this object. This object will not update automatically for later data transfers, -/// i.e. `H5Pget_mpio_no_collective_cause` is called in the constructor, and not when fetching -/// a value, such as `wasCollective`. -/// \implements PropertyInterface -class MpioNoCollectiveCause { - public: - explicit MpioNoCollectiveCause(const DataTransferProps& dxpl); - - /// \brief Was the datatransfer collective? - bool wasCollective() const; - - /// \brief The local cause for a non-collective I/O. - uint32_t getLocalCause() const; - - /// \brief The global cause for a non-collective I/O. - uint32_t getGlobalCause() const; - - /// \brief A pair of the local and global cause for non-collective I/O. - std::pair getCause() const; - - private: - friend DataTransferProps; - uint32_t _local_cause; - uint32_t _global_cause; -}; -#endif - -struct CreationOrder { - enum _CreationOrder { - Tracked = H5P_CRT_ORDER_TRACKED, - Indexed = H5P_CRT_ORDER_INDEXED, - }; -}; - -/// -/// \brief Track and index creation order time -/// -/// Let user retrieve objects by creation order time instead of name. -/// -/// \implements PropertyInterface -class LinkCreationOrder { - public: - /// - /// \brief Create the property - /// \param flags Should be a composition of HighFive::CreationOrder. - /// - explicit LinkCreationOrder(unsigned flags) - : _flags(flags) {} - - explicit LinkCreationOrder(const FileCreateProps& fcpl); - explicit LinkCreationOrder(const GroupCreateProps& gcpl); - - unsigned getFlags() const; - - protected: - void fromPropertyList(hid_t hid); - - private: - friend FileCreateProps; - friend GroupCreateProps; - void apply(hid_t hid) const; - unsigned _flags; -}; - - -/// -/// \brief Set threshold for attribute storage. -/// -/// HDF5 can store Attributes in the object header (compact) or in the B-tree -/// (dense). This property sets the threshold when attributes are moved to one -/// or the other storage format. -/// -/// Please refer to the upstream documentation of `H5Pset_attr_phase_change` or -/// Section 8 (Attributes) in the User Guide, in particular Subsection 8.5. -/// -/// \implements PropertyInterface -class AttributePhaseChange { - public: - /// - /// \brief Create the property from the threshold values. - /// - /// When the number of attributes hits `max_compact` the attributes are - /// moved to dense storage, once the number drops to below `min_dense` the - /// attributes are moved to compact storage. - AttributePhaseChange(unsigned max_compact, unsigned min_dense); - - /// \brief Extract threshold values from property list. - explicit AttributePhaseChange(const GroupCreateProps& gcpl); - - unsigned max_compact() const; - unsigned min_dense() const; - - private: - friend GroupCreateProps; - void apply(hid_t hid) const; - - unsigned _max_compact; - unsigned _min_dense; -}; - -/// @} - -} // namespace HighFive - -#include "bits/H5PropertyList_misc.hpp" diff --git a/inst/include/highfive/H5Reference.hpp b/inst/include/highfive/H5Reference.hpp deleted file mode 100644 index 38062e9..0000000 --- a/inst/include/highfive/H5Reference.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c), 2020, EPFL - Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ - -#pragma once - -#include -#include - -#include -#include - -#include "bits/H5_definitions.hpp" - -namespace HighFive { - -namespace details { -template -struct inspector; -} -/// -/// \brief An HDF5 (object) reference type -/// -/// HDF5 object references allow pointing to groups, datasets (and compound types). They -/// differ from links in their ability to be stored and retrieved as data from the HDF5 -/// file in datasets themselves. -/// -class Reference { - public: - /// \brief Create an empty Reference to be initialized later - Reference() = default; - - /// \brief Create a Reference to an object residing at a given location - /// - /// \param location A File or Group where the object being referenced to resides - /// \param object A Dataset or Group to be referenced - Reference(const Object& location, const Object& object); - - /// \brief Retrieve the Object being referenced by the Reference - /// - /// \tparam T the appropriate HighFive Container (either DataSet or Group) - /// \param location the location where the referenced object is to be found (a File) - /// \return the dereferenced Object (either a Group or DataSet) - template - T dereference(const Object& location) const; - - /// \brief Get only the type of the referenced Object - /// - /// \param location the location where the referenced object is to be found (a File) - /// \return the ObjectType of the referenced object - ObjectType getType(const Object& location) const; - - protected: - /// \brief Create a Reference from a low-level HDF5 object reference - inline explicit Reference(const hobj_ref_t h5_ref) - : href(h5_ref){}; - - /// \brief Create the low-level reference and store it at refptr - /// - /// \param refptr Pointer to a memory location where the created HDF5 reference will - /// be stored - void create_ref(hobj_ref_t* refptr) const; - - private: - Object get_ref(const Object& location) const; - - hobj_ref_t href{}; - std::string obj_name{}; - hid_t parent_id{}; - - friend struct details::inspector; -}; - -} // namespace HighFive - -#include "bits/H5Reference_misc.hpp" diff --git a/inst/include/highfive/H5Selection.hpp b/inst/include/highfive/H5Selection.hpp deleted file mode 100644 index c00c66d..0000000 --- a/inst/include/highfive/H5Selection.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "H5DataSet.hpp" -#include "H5DataSpace.hpp" -#include "bits/H5Slice_traits.hpp" -#include "bits/H5Friends.hpp" - -namespace HighFive { - -namespace detail { -Selection make_selection(const DataSpace&, const DataSpace&, const DataSet&); -} - -/// -/// \brief Selection: represent a view on a slice/part of a dataset -/// -/// A Selection is valid only if its parent dataset is valid -/// -class Selection: public SliceTraits { - public: - /// - /// \brief getSpace - /// \return Dataspace associated with this selection - /// - DataSpace getSpace() const noexcept; - - /// - /// \brief getMemSpace - /// \return Dataspace associated with the memory representation of this - /// selection - /// - DataSpace getMemSpace() const noexcept; - - /// - /// \brief getDataSet - /// \return parent dataset of this selection - /// - DataSet& getDataset() noexcept; - const DataSet& getDataset() const noexcept; - - /// - /// \brief return the datatype of the selection - /// \return return the datatype of the selection - const DataType getDataType() const; - - protected: - Selection(const DataSpace& memspace, const DataSpace& file_space, const DataSet& set); - - private: - DataSpace _mem_space, _file_space; - DataSet _set; - -#if HIGHFIVE_HAS_FRIEND_DECLARATIONS - template - friend class ::HighFive::SliceTraits; -#endif - friend Selection detail::make_selection(const DataSpace&, const DataSpace&, const DataSet&); -}; - -} // namespace HighFive diff --git a/inst/include/highfive/H5Utility.hpp b/inst/include/highfive/H5Utility.hpp deleted file mode 100644 index 64ac1e5..0000000 --- a/inst/include/highfive/H5Utility.hpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c), 2017, Blue Brain Project - EPFL (CH) - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ - -#pragma once - -#include -#include -#include -#include - -#include "bits/H5Friends.hpp" - -namespace HighFive { - -/// -/// \brief Utility class to disable HDF5 stack printing inside a scope. -/// -class SilenceHDF5 { - public: - inline SilenceHDF5(bool enable = true) - : _client_data(nullptr) { - H5Eget_auto2(H5E_DEFAULT, &_func, &_client_data); - if (enable) - H5Eset_auto2(H5E_DEFAULT, NULL, NULL); - } - - inline ~SilenceHDF5() { - H5Eset_auto2(H5E_DEFAULT, _func, _client_data); - } - - private: - H5E_auto2_t _func; - void* _client_data; -}; - -#define HIGHFIVE_LOG_LEVEL_DEBUG 10 -#define HIGHFIVE_LOG_LEVEL_INFO 20 -#define HIGHFIVE_LOG_LEVEL_WARN 30 -#define HIGHFIVE_LOG_LEVEL_ERROR 40 - -#ifndef HIGHFIVE_LOG_LEVEL -#define HIGHFIVE_LOG_LEVEL HIGHFIVE_LOG_LEVEL_WARN -#endif - -enum class LogSeverity { - Debug = HIGHFIVE_LOG_LEVEL_DEBUG, - Info = HIGHFIVE_LOG_LEVEL_INFO, - Warn = HIGHFIVE_LOG_LEVEL_WARN, - Error = HIGHFIVE_LOG_LEVEL_ERROR -}; - -inline std::string to_string(LogSeverity severity) { - switch (severity) { - case LogSeverity::Debug: - return "DEBUG"; - case LogSeverity::Info: - return "INFO"; - case LogSeverity::Warn: - return "WARN"; - case LogSeverity::Error: - return "ERROR"; - default: - return "??"; - } -} - -/** \brief A logger with supporting basic functionality. - * - * This logger delegates the logging task to a callback. This level of - * indirection enables using the default Python logger from C++; or - * integrating HighFive into some custom logging solution. - * - * Using this class directly to log is not intended. Rather you should use - * - `HIGHFIVE_LOG_DEBUG{,_IF}` - * - `HIGHFIVE_LOG_INFO{,_IF}` - * - `HIGHFIVE_LOG_WARNING{,_IF}` - * - `HIGHFIVE_LOG_ERROR{,_IF}` - * - * This is intended to used as a singleton, via `get_global_logger()`. - */ -class Logger { - public: - using callback_type = - std::function; - - public: - Logger() = delete; - Logger(const Logger&) = delete; - Logger(Logger&&) = delete; - - explicit Logger(callback_type cb) - : _cb(std::move(cb)) {} - - Logger& operator=(const Logger&) = delete; - Logger& operator=(Logger&&) = delete; - - inline void log(LogSeverity severity, - const std::string& message, - const std::string& file, - int line) { - _cb(severity, message, file, line); - } - - inline void set_logging_callback(callback_type cb) { - _cb = std::move(cb); - } - - private: - callback_type _cb; -}; - -inline void default_logging_callback(LogSeverity severity, - const std::string& message, - const std::string& file, - int line) { - std::clog << file << ": " << line << " :: " << to_string(severity) << message << std::endl; -} - -/// \brief Obtain a reference to the logger used by HighFive. -/// -/// This uses a Meyers singleton, to ensure that the global logger is -/// initialized with a safe default logger, before it is used. -/// -/// Note: You probably don't need to call this function explicitly. -/// -inline Logger& get_global_logger() { - static Logger logger(&default_logging_callback); - return logger; -} - -/// \brief Sets the callback that's used by the logger. -inline void register_logging_callback(Logger::callback_type cb) { - auto& logger = get_global_logger(); - logger.set_logging_callback(std::move(cb)); -} - -namespace detail { -/// \brief Log a `message` with severity `severity`. -inline void log(LogSeverity severity, - const std::string& message, - const std::string& file, - int line) { - auto& logger = get_global_logger(); - logger.log(severity, message, file, line); -} -} // namespace detail - -#if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_DEBUG -#define HIGHFIVE_LOG_DEBUG(message) \ - ::HighFive::detail::log(::HighFive::LogSeverity::Debug, (message), __FILE__, __LINE__); - -// Useful, for the common pattern: if ...; then log something. -#define HIGHFIVE_LOG_DEBUG_IF(cond, message) \ - if ((cond)) { \ - HIGHFIVE_LOG_DEBUG((message)); \ - } - -#else -#define HIGHFIVE_LOG_DEBUG(message) ; -#define HIGHFIVE_LOG_DEBUG_IF(cond, message) ; -#endif - -#if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_INFO -#define HIGHFIVE_LOG_INFO(message) \ - ::HighFive::detail::log(::HighFive::LogSeverity::Info, (message), __FILE__, __LINE__); - -// Useful, for the common pattern: if ...; then log something. -#define HIGHFIVE_LOG_INFO_IF(cond, message) \ - if ((cond)) { \ - HIGHFIVE_LOG_INFO((message)); \ - } - -#else -#define HIGHFIVE_LOG_INFO(message) ; -#define HIGHFIVE_LOG_INFO_IF(cond, message) ; -#endif - - -#if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_WARN -#define HIGHFIVE_LOG_WARN(message) \ - ::HighFive::detail::log(::HighFive::LogSeverity::Warn, (message), __FILE__, __LINE__); - -// Useful, for the common pattern: if ...; then log something. -#define HIGHFIVE_LOG_WARN_IF(cond, message) \ - if ((cond)) { \ - HIGHFIVE_LOG_WARN((message)); \ - } - -#else -#define HIGHFIVE_LOG_WARN(message) ; -#define HIGHFIVE_LOG_WARN_IF(cond, message) ; -#endif - -#if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_ERROR -#define HIGHFIVE_LOG_ERROR(message) \ - ::HighFive::detail::log(::HighFive::LogSeverity::Error, (message), __FILE__, __LINE__); - -// Useful, for the common pattern: if ...; then log something. -#define HIGHFIVE_LOG_ERROR_IF(cond, message) \ - if ((cond)) { \ - HIGHFIVE_LOG_ERROR((message)); \ - } - -#else -#define HIGHFIVE_LOG_ERROR(message) ; -#define HIGHFIVE_LOG_ERROR_IF(cond, message) ; -#endif - -} // namespace HighFive diff --git a/inst/include/highfive/H5Version.hpp b/inst/include/highfive/H5Version.hpp deleted file mode 100644 index dc23843..0000000 --- a/inst/include/highfive/H5Version.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c), 2020 - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#define HIGHFIVE_VERSION_MAJOR 2 -#define HIGHFIVE_VERSION_MINOR 8 -#define HIGHFIVE_VERSION_PATCH 0 - -/** \brief Concatenated representation of the HighFive version. - * - * \warning The macro `HIGHFIVE_VERSION` by itself isn't valid C/C++. - * - * However, it can be stringified with two layers of macros, e.g., - * \code{.cpp} - * #define STRINGIFY_VALUE(s) STRINGIFY_NAME(s) - * #define STRINGIFY_NAME(s) #s - * - * std::cout << STRINGIFY_VALUE(HIGHFIVE_VERSION) << "\n"; - * \endcode - */ -#define HIGHFIVE_VERSION 2.8.0 - -/** \brief String representation of the HighFive version. - * - * \warning This macro only exists from 2.7.1 onwards. - */ -#define HIGHFIVE_VERSION_STRING "2.8.0" diff --git a/inst/include/highfive/H5Version.hpp.in b/inst/include/highfive/H5Version.hpp.in deleted file mode 100644 index acddcff..0000000 --- a/inst/include/highfive/H5Version.hpp.in +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c), 2020 - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#define HIGHFIVE_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ -#define HIGHFIVE_VERSION_MINOR @PROJECT_VERSION_MINOR@ -#define HIGHFIVE_VERSION_PATCH @PROJECT_VERSION_PATCH@ - -/** \brief Concatenated representation of the HighFive version. - * - * \warning The macro `HIGHFIVE_VERSION` by itself isn't valid C/C++. - * - * However, it can be stringified with two layers of macros, e.g., - * \code{.cpp} - * #define STRINGIFY_VALUE(s) STRINGIFY_NAME(s) - * #define STRINGIFY_NAME(s) #s - * - * std::cout << STRINGIFY_VALUE(HIGHFIVE_VERSION) << "\n"; - * \endcode - */ -#define HIGHFIVE_VERSION @PROJECT_VERSION@ - -/** \brief String representation of the HighFive version. - * - * \warning This macro only exists from 2.7.1 onwards. - */ -#define HIGHFIVE_VERSION_STRING "@PROJECT_VERSION@" diff --git a/inst/include/highfive/bits/H5Annotate_traits.hpp b/inst/include/highfive/bits/H5Annotate_traits.hpp deleted file mode 100644 index 375b535..0000000 --- a/inst/include/highfive/bits/H5Annotate_traits.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "../H5Attribute.hpp" - -namespace HighFive { - -template -class AnnotateTraits { - public: - /// - /// \brief create a new attribute with the name attribute_name - /// \param attribute_name identifier of the attribute - /// \param space Associated \ref DataSpace - /// \param type - /// \return the attribute object - /// - Attribute createAttribute(const std::string& attribute_name, - const DataSpace& space, - const DataType& type); - - /// - /// \brief createAttribute create a new attribute on the current dataset with - /// size specified by space - /// \param attribute_name identifier of the attribute - /// \param space Associated DataSpace - /// informations - /// \return Attribute Object - template - Attribute createAttribute(const std::string& attribute_name, const DataSpace& space); - - /// - /// \brief createAttribute create a new attribute on the current dataset and - /// write to it, inferring the DataSpace from data. - /// \param attribute_name identifier of the attribute - /// \param data Associated data to write, must support DataSpace::From, see - /// \ref DataSpace for more information - /// \return Attribute Object - /// - template - Attribute createAttribute(const std::string& attribute_name, const T& data); - - /// - /// \brief deleteAttribute let you delete an attribute by its name. - /// \param attribute_name identifier of the attribute - void deleteAttribute(const std::string& attribute_name); - - /// - /// \brief open an existing attribute with the name attribute_name - /// \param attribute_name identifier of the attribute - /// \return the attribute object - Attribute getAttribute(const std::string& attribute_name) const; - - /// - /// \brief return the number of attributes of the node / group - /// \return number of attributes - size_t getNumberAttributes() const; - - /// - /// \brief list all attribute name of the node / group - /// \return number of attributes - std::vector listAttributeNames() const; - - /// - /// \brief checks an attribute exists - /// \return number of attributes - bool hasAttribute(const std::string& attr_name) const; - - private: - using derivate_type = Derivate; -}; -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Annotate_traits_misc.hpp b/inst/include/highfive/bits/H5Annotate_traits_misc.hpp deleted file mode 100644 index 85d2798..0000000 --- a/inst/include/highfive/bits/H5Annotate_traits_misc.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include - -#include -#include - -#include "H5Attribute_misc.hpp" -#include "H5Iterables_misc.hpp" - -namespace HighFive { - -template -inline Attribute AnnotateTraits::createAttribute(const std::string& attribute_name, - const DataSpace& space, - const DataType& dtype) { - auto attr_id = H5Acreate2(static_cast(this)->getId(), - attribute_name.c_str(), - dtype.getId(), - space.getId(), - H5P_DEFAULT, - H5P_DEFAULT); - if (attr_id < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to create the attribute \"") + attribute_name + "\":"); - } - return detail::make_attribute(attr_id); -} - -template -template -inline Attribute AnnotateTraits::createAttribute(const std::string& attribute_name, - const DataSpace& space) { - return createAttribute(attribute_name, space, create_and_check_datatype()); -} - -template -template -inline Attribute AnnotateTraits::createAttribute(const std::string& attribute_name, - const T& data) { - Attribute att = - createAttribute(attribute_name, - DataSpace::From(data), - create_and_check_datatype::base_type>()); - att.write(data); - return att; -} - -template -inline void AnnotateTraits::deleteAttribute(const std::string& attribute_name) { - if (H5Adelete(static_cast(this)->getId(), attribute_name.c_str()) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to delete attribute \"") + attribute_name + "\":"); - } -} - -template -inline Attribute AnnotateTraits::getAttribute(const std::string& attribute_name) const { - const auto attr_id = - H5Aopen(static_cast(this)->getId(), attribute_name.c_str(), H5P_DEFAULT); - if (attr_id < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to open the attribute \"") + attribute_name + "\":"); - } - return detail::make_attribute(attr_id); -} - -template -inline size_t AnnotateTraits::getNumberAttributes() const { - int res = H5Aget_num_attrs(static_cast(this)->getId()); - if (res < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to count attributes in existing group or file")); - } - return static_cast(res); -} - -template -inline std::vector AnnotateTraits::listAttributeNames() const { - std::vector names; - details::HighFiveIterateData iterateData(names); - - size_t num_objs = getNumberAttributes(); - names.reserve(num_objs); - - if (H5Aiterate2(static_cast(this)->getId(), - H5_INDEX_NAME, - H5_ITER_INC, - NULL, - &details::internal_high_five_iterate, - static_cast(&iterateData)) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to list attributes in group")); - } - - return names; -} - -template -inline bool AnnotateTraits::hasAttribute(const std::string& attr_name) const { - int res = H5Aexists(static_cast(this)->getId(), attr_name.c_str()); - if (res < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to check for attribute in group")); - } - return res; -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Attribute_misc.hpp b/inst/include/highfive/bits/H5Attribute_misc.hpp deleted file mode 100644 index 6516788..0000000 --- a/inst/include/highfive/bits/H5Attribute_misc.hpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c), 2017, Ali Can Demiralp - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -#include "../H5DataSpace.hpp" -#include "H5Converter_misc.hpp" -#include "H5ReadWrite_misc.hpp" -#include "H5Utils.hpp" - -namespace HighFive { - -inline std::string Attribute::getName() const { - return details::get_name( - [&](char* buffer, size_t length) { return H5Aget_name(_hid, length, buffer); }); -} - -inline size_t Attribute::getStorageSize() const { - return static_cast(H5Aget_storage_size(_hid)); -} - -inline DataType Attribute::getDataType() const { - DataType res; - res._hid = H5Aget_type(_hid); - return res; -} - -inline DataSpace Attribute::getSpace() const { - DataSpace space; - if ((space._hid = H5Aget_space(_hid)) < 0) { - HDF5ErrMapper::ToException("Unable to get DataSpace out of Attribute"); - } - return space; -} - -inline DataSpace Attribute::getMemSpace() const { - return getSpace(); -} - -template -inline T Attribute::read() const { - T array; - read(array); - return array; -} - -template -inline void Attribute::read(T& array) const { - const DataSpace& mem_space = getMemSpace(); - auto file_datatype = getDataType(); - const details::BufferInfo buffer_info( - file_datatype, - [this]() -> std::string { return this->getName(); }, - details::BufferInfo::read); - - if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) { - std::ostringstream ss; - ss << "Impossible to read DataSet of dimensions " << mem_space.getNumberDimensions() - << " into arrays of dimensions " << buffer_info.n_dimensions; - throw DataSpaceException(ss.str()); - } - auto dims = mem_space.getDimensions(); - - if (mem_space.getElementCount() == 0) { - auto effective_dims = details::squeezeDimensions(dims, - details::inspector::recursive_ndim); - - details::inspector::prepare(array, effective_dims); - return; - } - - auto r = details::data_converter::get_reader(dims, array, file_datatype); - read(r.getPointer(), buffer_info.data_type); - // re-arrange results - r.unserialize(array); - - auto t = buffer_info.data_type; - auto c = t.getClass(); - - if (c == DataTypeClass::VarLen || t.isVariableStr()) { -#if H5_VERSION_GE(1, 12, 0) - // This one have been created in 1.12.0 - (void) H5Treclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer()); -#else - // This one is deprecated since 1.12.0 - (void) H5Dvlen_reclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer()); -#endif - } -} - -template -inline void Attribute::read(T* array, const DataType& mem_datatype) const { - static_assert(!std::is_const::value, - "read() requires a non-const structure to read data into"); - - if (H5Aread(getId(), mem_datatype.getId(), static_cast(array)) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Read: "); - } -} - -template -inline void Attribute::read(T* array) const { - using element_type = typename details::inspector::base_type; - const DataType& mem_datatype = create_and_check_datatype(); - - read(array, mem_datatype); -} - -template -inline void Attribute::write(const T& buffer) { - const DataSpace& mem_space = getMemSpace(); - - if (mem_space.getElementCount() == 0) { - return; - } - - auto file_datatype = getDataType(); - - const details::BufferInfo buffer_info( - file_datatype, - [this]() -> std::string { return this->getName(); }, - details::BufferInfo::write); - - if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) { - std::ostringstream ss; - ss << "Impossible to write buffer of dimensions " << buffer_info.n_dimensions - << " into dataset of dimensions " << mem_space.getNumberDimensions(); - throw DataSpaceException(ss.str()); - } - auto w = details::data_converter::serialize(buffer, file_datatype); - write_raw(w.getPointer(), buffer_info.data_type); -} - -template -inline void Attribute::write_raw(const T* buffer, const DataType& mem_datatype) { - if (H5Awrite(getId(), mem_datatype.getId(), buffer) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Write: "); - } -} - -template -inline void Attribute::write_raw(const T* buffer) { - using element_type = typename details::inspector::base_type; - const auto& mem_datatype = create_and_check_datatype(); - - write_raw(buffer, mem_datatype); -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Converter_misc.hpp b/inst/include/highfive/bits/H5Converter_misc.hpp deleted file mode 100644 index 00749d1..0000000 --- a/inst/include/highfive/bits/H5Converter_misc.hpp +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (c) 2022 Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "H5Inspector_misc.hpp" -#include "../H5DataType.hpp" - -namespace HighFive { -namespace details { - -template -struct is_std_string { - static constexpr bool value = - std::is_same::base_type, std::string>::value; -}; - -template -struct enable_shallow_copy - : public std::enable_if::value && inspector::is_trivially_copyable, V> {}; - -template -struct enable_deep_copy - : public std::enable_if::value && !inspector::is_trivially_copyable, V> {}; - -template -struct enable_string_copy: public std::enable_if::value, V> {}; - - -template -struct ShallowCopyBuffer { - using type = unqualified_t; - using hdf5_type = - typename std::conditional::hdf5_type>::type, - typename inspector::hdf5_type>::type; - - ShallowCopyBuffer() = delete; - - explicit ShallowCopyBuffer(typename std::conditional::type val) - : ptr(inspector::data(val)){}; - - hdf5_type* getPointer() const { - return ptr; - } - - hdf5_type* begin() const { - return getPointer(); - } - - void unserialize(T& /* val */) const { - /* nothing to do. */ - } - - private: - hdf5_type* ptr; -}; - -template -struct DeepCopyBuffer { - using type = unqualified_t; - using hdf5_type = typename inspector::hdf5_type; - - explicit DeepCopyBuffer(const std::vector& _dims) - : buffer(inspector::getSize(_dims)) - , dims(_dims) {} - - hdf5_type* getPointer() { - return buffer.data(); - } - - hdf5_type const* getPointer() const { - return buffer.data(); - } - - hdf5_type* begin() { - return getPointer(); - } - - hdf5_type const* begin() const { - return getPointer(); - } - - void unserialize(T& val) const { - inspector::unserialize(buffer.data(), dims, val); - } - - private: - std::vector buffer; - std::vector dims; -}; - -enum class BufferMode { Read, Write }; - - -/// -/// \brief String length in bytes excluding the `\0`. -/// -inline size_t char_buffer_size(char const* const str, size_t max_string_length) { - for (size_t i = 0; i <= max_string_length; ++i) { - if (str[i] == '\0') { - return i; - } - } - - return max_string_length; -} - - -/// -/// \brief A buffer for reading/writing strings. -/// -/// A string in HDF5 can be represented as a fixed or variable length string. -/// The important difference for this buffer is that `H5D{read,write}` expects -/// different input depending on whether the strings are fixed or variable length. -/// For fixed length strings, it expects an array of chars, i.e. one string -/// packed after the other contiguously. While for variable length strings it -/// expects a list of pointers to the beginning of each string. Variable length -/// string must be null-terminated; because that's how their length is -/// determined. -/// -/// This buffer hides the difference between fixed and variable length strings -/// by having internal data structures available for both cases at compile time. -/// The choice which internal buffer to use is made at runtime. -/// -/// Consider an HDF5 dataset with N fixed-length strings, each of which is M -/// characters long. Then the in-memory strings are copied into an internal -/// buffer of size N*M. If null- or space-padded the buffer should be filled -/// with the appropriate character. This is important if the in-memory strings -/// are less than M characters long. -/// -/// An HDF5 dataset with N variable-length strings (all null-terminated) uses -/// the internal list of pointers to the beginning of each string. Those -/// pointers can either point to the in-memory strings themselves, if those -/// strings are known to be null-terminated. Otherwise the in-memory strings are -/// copied to an internal buffer of null-terminated strings; and the pointer -/// points to the start of the string in the internal buffer. -/// -/// This class is responsible for arranging the strings properly before passing -/// the buffers to HDF5. To keep this class generic, it provides a generic -/// read/write interface to the internal strings, i.e. a pointer with a size. -/// For reading from the buffer the proxy is called `StringConstView`. This -/// proxy object is to be used by the `inspector` to copy from the buffer into -/// the final destination, e.g. an `std::string`. Similarly, there's a proxy -/// object for serializing into the buffer, i.e. the `StringView`. Again the -/// `inspector` is responsible for obtaining the pointer, size and padding of -/// the string. -/// -/// Nomenclature: -/// - size of a string is the number of bytes required to store the string, -/// including the null character for null-terminated strings. -/// -/// - length of a string is the number of bytes without the null character. -/// -/// Note: both 'length' and 'size' are counted in number of bytes, not number -/// of symbols or characters. Even for UTF8 strings. -template -struct StringBuffer { - using type = unqualified_t; - using hdf5_type = typename inspector::hdf5_type; - - class StringView { - public: - StringView(StringBuffer& _buffer, size_t _i) - : buffer(_buffer) - , i(_i) {} - - /// - /// \brief Assign the in-memory string to the buffer. - /// - /// This method copies the in-memory string to the appropriate - /// internal buffer as needed. - /// - /// The `length` is the length of the string in bytes. - void assign(char const* data, size_t length, StringPadding padding) { - if (buffer.isVariableLengthString()) { - if (padding == StringPadding::NullTerminated) { - buffer.variable_length_pointers[i] = data; - } else { - buffer.variable_length_buffer[i] = std::string(data, length); - buffer.variable_length_pointers[i] = buffer.variable_length_buffer[i].data(); - } - } else if (buffer.isFixedLengthString()) { - // If the buffer is fixed-length and null-terminated, then - // `buffer.string_length` doesn't include the null-character. - if (length > buffer.string_length) { - throw std::invalid_argument("String length too big."); - } - - memcpy(&buffer.fixed_length_buffer[i * buffer.string_size], data, length); - } - } - - private: - StringBuffer& buffer; - size_t i; - }; - - - class StringConstView { - public: - StringConstView(const StringBuffer& _buffer, size_t _i) - : buffer(_buffer) - , i(_i) {} - - /// \brief Pointer to the first byte of the string. - /// - /// The valid indices for this pointer are: 0, ..., length() - 1. - char const* data() const { - if (buffer.isVariableLengthString()) { - return buffer.variable_length_pointers[i]; - } else { - return &buffer.fixed_length_buffer[i * buffer.string_size]; - } - } - - /// \brief Length of the string in bytes. - /// - /// Note that for null-terminated strings the "length" doesn't include - /// the null character. Hence, if storing this string as a - /// null-terminated string, the destination buffer needs to be at least - /// `length() + 1` bytes long. - size_t length() const { - if (buffer.isNullTerminated()) { - return char_buffer_size(data(), buffer.string_length); - } else { - return buffer.string_length; - } - } - - private: - const StringBuffer& buffer; - size_t i; - }; - - - class Iterator { - public: - Iterator(StringBuffer& _buffer, size_t _pos) - : buffer(_buffer) - , pos(_pos) {} - - Iterator operator+(size_t n_strings) const { - return Iterator(buffer, pos + n_strings); - } - - void operator+=(size_t n_strings) { - pos += n_strings; - } - - StringView operator*() { - return StringView(buffer, pos); - } - - StringConstView operator*() const { - return StringConstView(buffer, pos); - } - - private: - StringBuffer& buffer; - size_t pos; - }; - - StringBuffer(std::vector _dims, const DataType& _file_datatype) - : file_datatype(_file_datatype.asStringType()) - , padding(file_datatype.getPadding()) - , string_size(file_datatype.isVariableStr() ? size_t(-1) : file_datatype.getSize()) - , string_length(string_size - size_t(isNullTerminated())) - , dims(_dims) { - if (string_size == 0 && isNullTerminated()) { - throw DataTypeException( - "Fixed-length, null-terminated need at least one byte to store the " - "null-character."); - } - - auto n_strings = compute_total_size(dims); - if (isVariableLengthString()) { - variable_length_buffer.resize(n_strings); - variable_length_pointers.resize(n_strings); - } else { - char pad = padding == StringPadding::SpacePadded ? ' ' : '\0'; - fixed_length_buffer.assign(n_strings * string_size, pad); - } - } - - bool isVariableLengthString() const { - return file_datatype.isVariableStr(); - } - - bool isFixedLengthString() const { - return file_datatype.isFixedLenStr(); - } - - bool isNullTerminated() const { - return file_datatype.getPadding() == StringPadding::NullTerminated; - } - - - void* getPointer() { - if (file_datatype.isVariableStr()) { - return variable_length_pointers.data(); - } else { - return fixed_length_buffer.data(); - } - } - - Iterator begin() { - return Iterator(*this, 0ul); - } - - void unserialize(T& val) { - inspector::unserialize(begin(), dims, val); - } - - private: - StringType file_datatype; - StringPadding padding; - size_t string_size; // Size of buffer required to store the string. - // Meaningful for fixed length strings only. - size_t string_length; // Semantic length of string. - std::vector dims; - - std::vector fixed_length_buffer; - std::vector variable_length_buffer; - std::vector< - typename std::conditional::type*> - variable_length_pointers; -}; - - -template -struct Writer; - -template -struct Writer::type>: public ShallowCopyBuffer { - private: - using super = ShallowCopyBuffer; - - public: - explicit Writer(const T& val, const DataType& /* file_datatype */) - : super(val){}; -}; - -template -struct Writer::type>: public DeepCopyBuffer { - explicit Writer(const T& val, const DataType& /* file_datatype */) - : DeepCopyBuffer(inspector::getDimensions(val)) { - inspector::serialize(val, this->begin()); - } -}; - -template -struct Writer::type>: public StringBuffer { - explicit Writer(const T& val, const DataType& _file_datatype) - : StringBuffer(inspector::getDimensions(val), _file_datatype) { - inspector::serialize(val, this->begin()); - } -}; - -template -struct Reader; - -template -struct Reader::type>: public ShallowCopyBuffer { - private: - using super = ShallowCopyBuffer; - using type = typename super::type; - - public: - Reader(const std::vector&, type& val, const DataType& /* file_datatype */) - : super(val) {} -}; - -template -struct Reader::type>: public DeepCopyBuffer { - private: - using super = DeepCopyBuffer; - using type = typename super::type; - - public: - Reader(const std::vector& _dims, type&, const DataType& /* file_datatype */) - : super(_dims) {} -}; - - -template -struct Reader::type>: public StringBuffer { - public: - explicit Reader(const std::vector& _dims, - const T& /* val */, - const DataType& _file_datatype) - : StringBuffer(_dims, _file_datatype) {} -}; - -struct data_converter { - template - static Writer serialize(const typename inspector::type& val, - const DataType& file_datatype) { - return Writer(val, file_datatype); - } - - template - static Reader get_reader(const std::vector& dims, - T& val, - const DataType& file_datatype) { - // TODO Use bufferinfo for recursive_ndim - auto effective_dims = details::squeezeDimensions(dims, inspector::recursive_ndim); - inspector::prepare(val, effective_dims); - return Reader(effective_dims, val, file_datatype); - } -}; - -} // namespace details -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5DataSet_misc.hpp b/inst/include/highfive/bits/H5DataSet_misc.hpp deleted file mode 100644 index 4411b4c..0000000 --- a/inst/include/highfive/bits/H5DataSet_misc.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -#include "H5Utils.hpp" - -namespace HighFive { - -inline uint64_t DataSet::getStorageSize() const { - return H5Dget_storage_size(_hid); -} - -inline DataType DataSet::getDataType() const { - return DataType(H5Dget_type(_hid)); -} - -inline DataSpace DataSet::getSpace() const { - DataSpace space; - if ((space._hid = H5Dget_space(_hid)) < 0) { - HDF5ErrMapper::ToException("Unable to get DataSpace out of DataSet"); - } - return space; -} - -inline DataSpace DataSet::getMemSpace() const { - return getSpace(); -} - -inline uint64_t DataSet::getOffset() const { - uint64_t addr = H5Dget_offset(_hid); - if (addr == HADDR_UNDEF) { - HDF5ErrMapper::ToException("Cannot get offset of DataSet."); - } - return addr; -} - -inline void DataSet::resize(const std::vector& dims) { - const size_t numDimensions = getSpace().getDimensions().size(); - if (dims.size() != numDimensions) { - HDF5ErrMapper::ToException("Invalid dataspace dimensions, got " + - std::to_string(dims.size()) + " expected " + - std::to_string(numDimensions)); - } - - std::vector real_dims(dims.begin(), dims.end()); - - if (H5Dset_extent(getId(), real_dims.data()) < 0) { - HDF5ErrMapper::ToException("Could not resize dataset."); - } -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5DataType_misc.hpp b/inst/include/highfive/bits/H5DataType_misc.hpp deleted file mode 100644 index 8535d61..0000000 --- a/inst/include/highfive/bits/H5DataType_misc.hpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#if HIGHFIVE_CXX_STD >= 17 -#include -#endif - -#include -#include - -#ifdef H5_USE_HALF_FLOAT -#include -#endif - -#include "H5Inspector_misc.hpp" - -namespace HighFive { - -namespace detail { - -inline hid_t h5t_copy(hid_t original) { - auto copy = H5Tcopy(original); - if (copy == H5I_INVALID_HID) { - HDF5ErrMapper::ToException("Error copying datatype."); - } - - return copy; -} - -inline hsize_t h5t_get_size(hid_t hid) { - hsize_t size = H5Tget_size(hid); - if (size == 0) { - HDF5ErrMapper::ToException("Error getting size of datatype."); - } - - return size; -} - -inline H5T_cset_t h5t_get_cset(hid_t hid) { - auto cset = H5Tget_cset(hid); - if (cset == H5T_CSET_ERROR) { - HDF5ErrMapper::ToException("Error getting cset of datatype."); - } - - return cset; -} - -inline H5T_str_t h5t_get_strpad(hid_t hid) { - auto strpad = H5Tget_strpad(hid); - if (strpad == H5T_STR_ERROR) { - HDF5ErrMapper::ToException("Error getting strpad of datatype."); - } - - return strpad; -} - -inline void h5t_set_size(hid_t hid, hsize_t size) { - if (H5Tset_size(hid, size) < 0) { - HDF5ErrMapper::ToException("Error setting size of datatype."); - } -} - -inline void h5t_set_cset(hid_t hid, H5T_cset_t cset) { - if (H5Tset_cset(hid, cset) < 0) { - HDF5ErrMapper::ToException("Error setting cset of datatype."); - } -} - -inline void h5t_set_strpad(hid_t hid, H5T_str_t strpad) { - if (H5Tset_strpad(hid, strpad) < 0) { - HDF5ErrMapper::ToException("Error setting strpad of datatype."); - } -} -} // namespace detail - - -namespace { // unnamed -inline DataTypeClass convert_type_class(const H5T_class_t& tclass); -inline std::string type_class_string(DataTypeClass); -inline hid_t create_string(std::size_t length); -} // namespace - -inline bool DataType::empty() const noexcept { - return _hid == H5I_INVALID_HID; -} - -inline DataTypeClass DataType::getClass() const { - return convert_type_class(H5Tget_class(_hid)); -} - -inline size_t DataType::getSize() const { - return detail::h5t_get_size(_hid); -} - -inline bool DataType::operator==(const DataType& other) const { - return (H5Tequal(_hid, other._hid) > 0); -} - -inline bool DataType::operator!=(const DataType& other) const { - return !(*this == other); -} - -inline bool DataType::isVariableStr() const { - auto var_value = H5Tis_variable_str(_hid); - if (var_value < 0) { - HDF5ErrMapper::ToException("Unable to define datatype size to variable"); - } - return static_cast(var_value); -} - -inline bool DataType::isFixedLenStr() const { - return getClass() == DataTypeClass::String && !isVariableStr(); -} - -inline bool DataType::isReference() const { - return H5Tequal(_hid, H5T_STD_REF_OBJ) > 0; -} - -inline StringType DataType::asStringType() const { - if (getClass() != DataTypeClass::String) { - throw DataTypeException("Invalid conversion to StringType."); - } - - if (isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); - } - - return StringType(_hid); -} - -inline std::string DataType::string() const { - return type_class_string(getClass()) + std::to_string(getSize() * 8); -} - -inline StringPadding StringType::getPadding() const { - return StringPadding(detail::h5t_get_strpad(_hid)); -} - -inline CharacterSet StringType::getCharacterSet() const { - return CharacterSet(detail::h5t_get_cset(_hid)); -} - -inline FixedLengthStringType::FixedLengthStringType(size_t size, - StringPadding padding, - CharacterSet character_set) { - if (size == 0 && padding == StringPadding::NullTerminated) { - throw DataTypeException( - "Fixed-length, null-terminated need at least one byte to store the null-character."); - } - - _hid = detail::h5t_copy(H5T_C_S1); - - detail::h5t_set_size(_hid, hsize_t(size)); - detail::h5t_set_cset(_hid, H5T_cset_t(character_set)); - detail::h5t_set_strpad(_hid, H5T_str_t(padding)); -} - -inline VariableLengthStringType::VariableLengthStringType(CharacterSet character_set) { - _hid = detail::h5t_copy(H5T_C_S1); - - detail::h5t_set_size(_hid, H5T_VARIABLE); - detail::h5t_set_cset(_hid, H5T_cset_t(character_set)); -} - -// char mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_CHAR); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_SCHAR); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_UCHAR); -} - -// short mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_SHORT); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_USHORT); -} - -// integer mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_INT); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_UINT); -} - -// long mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_LONG); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_ULONG); -} - -// long long mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_LLONG); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_ULLONG); -} - -// half-float, float, double and long double mapping -#ifdef H5_USE_HALF_FLOAT -using float16_t = half_float::half; - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_FLOAT); - // Sign position, exponent position, exponent size, mantissa position, mantissa size - H5Tset_fields(_hid, 15, 10, 5, 0, 10); - // Total datatype size (in bytes) - detail::h5t_set_size(_hid, 2); - // Floating point exponent bias - H5Tset_ebias(_hid, 15); -} -#endif - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_FLOAT); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_DOUBLE); -} - -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_LDOUBLE); -} - -// std string -template <> -inline AtomicType::AtomicType() { - _hid = create_string(H5T_VARIABLE); -} - -#if HIGHFIVE_CXX_STD >= 17 -// std byte -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_NATIVE_B8); -} -#endif - -// Fixed-Length strings -// require class specialization templated for the char length -template -class AtomicType: public DataType { - public: - inline AtomicType() - : DataType(create_string(StrLen)) {} -}; - -template -class AtomicType>: public DataType { - public: - inline AtomicType() - : DataType(create_string(StrLen)) {} -}; - -template -class AtomicType>: public DataType { - public: - inline AtomicType() - : DataType( - CompoundType({{"r", create_datatype(), 0}, {"i", create_datatype(), sizeof(T)}}, - sizeof(std::complex))) { - static_assert(std::is_arithmetic::value, - "std::complex accepts only floating point and integral numbers."); - } -}; - -// For boolean we act as h5py -inline EnumType create_enum_boolean() { - return {{"FALSE", details::Boolean::HighFiveFalse}, {"TRUE", details::Boolean::HighFiveTrue}}; -} - -// Other cases not supported. Fail early with a user message -template -AtomicType::AtomicType() { - static_assert(details::inspector::recursive_ndim == 0, - "Atomic types cant be arrays, except for char[] (fixed-length strings)"); - static_assert(details::inspector::recursive_ndim > 0, "Type not supported"); -} - - -// class FixedLenStringArray - -template -inline FixedLenStringArray::FixedLenStringArray(const char array[][N], std::size_t length) { - datavec.resize(length); - std::memcpy(datavec[0].data(), array[0].data(), N * length); -} - -template -inline FixedLenStringArray::FixedLenStringArray(const std::string* iter_begin, - const std::string* iter_end) { - datavec.reserve(static_cast(iter_end - iter_begin)); - for (std::string const* it = iter_begin; it != iter_end; ++it) { - push_back(*it); - } -} - -template -inline FixedLenStringArray::FixedLenStringArray(const std::vector& vec) - : FixedLenStringArray(vec.data(), vec.data() + vec.size()) {} - -template -inline FixedLenStringArray::FixedLenStringArray( - const std::initializer_list& init_list) - : FixedLenStringArray(init_list.begin(), init_list.end()) {} - -template -inline void FixedLenStringArray::push_back(const std::string& src) { - datavec.emplace_back(); - const size_t length = std::min(N - 1, src.length()); - std::memcpy(datavec.back().data(), src.c_str(), length); - datavec.back()[length] = 0; -} - -template -inline void FixedLenStringArray::push_back(const std::array& src) { - datavec.emplace_back(); - std::copy(src.begin(), src.end(), datavec.back().data()); -} - -template -inline std::string FixedLenStringArray::getString(std::size_t i) const { - return std::string(datavec[i].data()); -} - -// Internal -// Reference mapping -template <> -inline AtomicType::AtomicType() { - _hid = detail::h5t_copy(H5T_STD_REF_OBJ); -} - -inline size_t find_first_atomic_member_size(hid_t hid) { - // Recursive exit condition - if (H5Tget_class(hid) == H5T_COMPOUND) { - auto number_of_members = H5Tget_nmembers(hid); - if (number_of_members == -1) { - throw DataTypeException("Cannot get members of CompoundType with hid: " + - std::to_string(hid)); - } - if (number_of_members == 0) { - throw DataTypeException("No members defined for CompoundType with hid: " + - std::to_string(hid)); - } - - auto member_type = H5Tget_member_type(hid, 0); - auto size = find_first_atomic_member_size(member_type); - H5Tclose(member_type); - return size; - } else if (H5Tget_class(hid) == H5T_STRING) { - return 1; - } - return detail::h5t_get_size(hid); -} - -// Calculate the padding required to align an element of a struct -// For padding see explanation here: https://en.cppreference.com/w/cpp/language/object#Alignment -// It is to compute padding following last element inserted inside a struct -// 1) We want to push back an element padded to the structure -// 'current_size' is the size of the structure before adding the new element. -// 'member_size' the size of the element we want to add. -// 2) We want to compute the final padding for the global structure -// 'current_size' is the size of the whole structure without final padding -// 'member_size' is the maximum size of all element of the struct -// -// The basic formula is only to know how much we need to add to 'current_size' to fit -// 'member_size'. -// And at the end, we do another computation because the end padding, should fit the biggest -// element of the struct. -// -// As we are with `size_t` element, we need to compute everything inside R+ -#define _H5_STRUCT_PADDING(current_size, member_size) \ - (((member_size) >= (current_size)) \ - ? (((member_size) - (current_size)) % (member_size)) \ - : ((((member_size) - (((current_size) - (member_size)) % (member_size)))) % \ - (member_size))) - -inline void CompoundType::create(size_t size) { - if (size == 0) { - size_t current_size = 0, max_atomic_size = 0; - - // Do a first pass to find the total size of the compound datatype - for (auto& member: members) { - size_t member_size = detail::h5t_get_size(member.base_type.getId()); - - if (member_size == 0) { - throw DataTypeException("Cannot get size of DataType with hid: " + - std::to_string(member.base_type.getId())); - } - - size_t first_atomic_size = find_first_atomic_member_size(member.base_type.getId()); - - // Set the offset of this member within the struct according to the - // standard alignment rules. The c++ standard specifies that: - // > objects have an alignment requirement of which their size is a multiple - member.offset = current_size + _H5_STRUCT_PADDING(current_size, first_atomic_size); - - // Set the current size to the end of the new member - current_size = member.offset + member_size; - - // Keep track of the highest atomic member size because it's needed - // for the padding of the complete compound type. - max_atomic_size = std::max(max_atomic_size, first_atomic_size); - } - - size = current_size + _H5_STRUCT_PADDING(current_size, max_atomic_size); - } - - // Create the HDF5 type - if ((_hid = H5Tcreate(H5T_COMPOUND, size)) < 0) { - HDF5ErrMapper::ToException("Could not create new compound datatype"); - } - - // Loop over all the members and insert them into the datatype - for (const auto& member: members) { - if (H5Tinsert(_hid, member.name.c_str(), member.offset, member.base_type.getId()) < 0) { - HDF5ErrMapper::ToException("Could not add new member to datatype"); - } - } -} - -#undef _H5_STRUCT_PADDING - -inline void CompoundType::commit(const Object& object, const std::string& name) const { - H5Tcommit2(object.getId(), name.c_str(), getId(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); -} - -template -inline void EnumType::create() { - // Create the HDF5 type - if ((_hid = H5Tenum_create(AtomicType::type>{}.getId())) < 0) { - HDF5ErrMapper::ToException("Could not create new enum datatype"); - } - - // Loop over all the members and insert them into the datatype - for (const auto& member: members) { - if (H5Tenum_insert(_hid, member.name.c_str(), &(member.value)) < 0) { - HDF5ErrMapper::ToException( - "Could not add new member to this enum datatype"); - } - } -} - -template -inline void EnumType::commit(const Object& object, const std::string& name) const { - H5Tcommit2(object.getId(), name.c_str(), getId(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); -} - -namespace { - -inline hid_t create_string(size_t length) { - hid_t _hid = detail::h5t_copy(H5T_C_S1); - detail::h5t_set_size(_hid, length); - detail::h5t_set_cset(_hid, H5T_CSET_UTF8); - return _hid; -} - - -inline DataTypeClass convert_type_class(const H5T_class_t& tclass) { - switch (tclass) { - case H5T_TIME: - return DataTypeClass::Time; - case H5T_INTEGER: - return DataTypeClass::Integer; - case H5T_FLOAT: - return DataTypeClass::Float; - case H5T_STRING: - return DataTypeClass::String; - case H5T_BITFIELD: - return DataTypeClass::BitField; - case H5T_OPAQUE: - return DataTypeClass::Opaque; - case H5T_COMPOUND: - return DataTypeClass::Compound; - case H5T_REFERENCE: - return DataTypeClass::Reference; - case H5T_ENUM: - return DataTypeClass::Enum; - case H5T_VLEN: - return DataTypeClass::VarLen; - case H5T_ARRAY: - return DataTypeClass::Array; - case H5T_NO_CLASS: - case H5T_NCLASSES: - default: - return DataTypeClass::Invalid; - } -} - - -inline std::string type_class_string(DataTypeClass tclass) { - switch (tclass) { - case DataTypeClass::Time: - return "Time"; - case DataTypeClass::Integer: - return "Integer"; - case DataTypeClass::Float: - return "Float"; - case DataTypeClass::String: - return "String"; - case DataTypeClass::BitField: - return "BitField"; - case DataTypeClass::Opaque: - return "Opaque"; - case DataTypeClass::Compound: - return "Compound"; - case DataTypeClass::Reference: - return "Reference"; - case DataTypeClass::Enum: - return "Enum"; - case DataTypeClass::VarLen: - return "Varlen"; - case DataTypeClass::Array: - return "Array"; - default: - return "(Invalid)"; - } -} - -} // unnamed namespace - - -/// \brief Create a DataType instance representing type T -template -inline DataType create_datatype() { - return AtomicType(); -} - - -/// \brief Create a DataType instance representing type T and perform a sanity check on its size -template -inline DataType create_and_check_datatype() { - DataType t = create_datatype(); - if (t.empty()) { - throw DataTypeException("Type given to create_and_check_datatype is not valid"); - } - - // Skip check if the base type is a variable length string - if (t.isVariableStr()) { - return t; - } - - // Check that the size of the template type matches the size that HDF5 is - // expecting. - if (t.isReference() || t.isFixedLenStr()) { - return t; - } - if (sizeof(T) != t.getSize()) { - std::ostringstream ss; - ss << "Size of array type " << sizeof(T) << " != that of memory datatype " << t.getSize() - << std::endl; - throw DataTypeException(ss.str()); - } - - return t; -} - -} // namespace HighFive -HIGHFIVE_REGISTER_TYPE(HighFive::details::Boolean, HighFive::create_enum_boolean) diff --git a/inst/include/highfive/bits/H5Dataspace_misc.hpp b/inst/include/highfive/bits/H5Dataspace_misc.hpp deleted file mode 100644 index 0fdcace..0000000 --- a/inst/include/highfive/bits/H5Dataspace_misc.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#include - -#include - -#include "H5Utils.hpp" -#include "H5Converter_misc.hpp" - -namespace HighFive { - -inline DataSpace::DataSpace(const std::vector& dims) - : DataSpace(dims.begin(), dims.end()) {} - -template -inline DataSpace::DataSpace(const std::array& dims) - : DataSpace(dims.begin(), dims.end()) {} - -inline DataSpace::DataSpace(const std::initializer_list& items) - : DataSpace(std::vector(items)) {} - -template -inline DataSpace::DataSpace(size_t dim1, Args... dims) - : DataSpace(std::vector{dim1, static_cast(dims)...}) {} - -template -inline DataSpace::DataSpace(const IT begin, const IT end) { - std::vector real_dims(begin, end); - - if ((_hid = H5Screate_simple(int(real_dims.size()), real_dims.data(), NULL)) < 0) { - throw DataSpaceException("Impossible to create dataspace"); - } -} - -inline DataSpace::DataSpace(const std::vector& dims, const std::vector& maxdims) { - if (dims.size() != maxdims.size()) { - throw DataSpaceException("dims and maxdims must be the same length."); - } - - std::vector real_dims(dims.begin(), dims.end()); - std::vector real_maxdims(maxdims.begin(), maxdims.end()); - - // Replace unlimited flag with actual HDF one - std::replace(real_maxdims.begin(), - real_maxdims.end(), - static_cast(DataSpace::UNLIMITED), - H5S_UNLIMITED); - - if ((_hid = H5Screate_simple(int(dims.size()), real_dims.data(), real_maxdims.data())) < 0) { - throw DataSpaceException("Impossible to create dataspace"); - } -} // namespace HighFive - -inline DataSpace::DataSpace(DataSpace::DataspaceType space_type) { - H5S_class_t h5_dataspace_type; - switch (space_type) { - case DataSpace::dataspace_scalar: - h5_dataspace_type = H5S_SCALAR; - break; - case DataSpace::dataspace_null: - h5_dataspace_type = H5S_NULL; - break; - default: - throw DataSpaceException( - "Invalid dataspace type: should be " - "dataspace_scalar or dataspace_null"); - } - - if ((_hid = H5Screate(h5_dataspace_type)) < 0) { - throw DataSpaceException("Unable to create dataspace"); - } -} - -inline DataSpace DataSpace::clone() const { - DataSpace res; - if ((res._hid = H5Scopy(_hid)) < 0) { - throw DataSpaceException("Unable to copy dataspace"); - } - return res; -} - -inline size_t DataSpace::getNumberDimensions() const { - const int ndim = H5Sget_simple_extent_ndims(_hid); - if (ndim < 0) { - HDF5ErrMapper::ToException( - "Unable to get dataspace number of dimensions"); - } - return size_t(ndim); -} - -inline std::vector DataSpace::getDimensions() const { - std::vector dims(getNumberDimensions()); - if (!dims.empty()) { - if (H5Sget_simple_extent_dims(_hid, dims.data(), NULL) < 0) { - HDF5ErrMapper::ToException("Unable to get dataspace dimensions"); - } - } - return details::to_vector_size_t(std::move(dims)); -} - -inline size_t DataSpace::getElementCount() const { - hssize_t nelements = H5Sget_simple_extent_npoints(_hid); - if (nelements < 0) { - HDF5ErrMapper::ToException( - "Unable to get number of elements in dataspace"); - } - - return static_cast(nelements); -} - -inline std::vector DataSpace::getMaxDimensions() const { - std::vector maxdims(getNumberDimensions()); - if (H5Sget_simple_extent_dims(_hid, NULL, maxdims.data()) < 0) { - HDF5ErrMapper::ToException("Unable to get dataspace dimensions"); - } - - std::replace(maxdims.begin(), - maxdims.end(), - H5S_UNLIMITED, - static_cast(DataSpace::UNLIMITED)); - return details::to_vector_size_t(maxdims); -} - -template -inline DataSpace DataSpace::From(const T& value) { - auto dims = details::inspector::getDimensions(value); - return DataSpace(dims); -} - -template -inline DataSpace DataSpace::FromCharArrayStrings(const char (&)[N][Width]) { - return DataSpace(N); -} - -namespace details { - -/// dimension checks @internal -inline bool checkDimensions(const DataSpace& mem_space, size_t n_dim_requested) { - return checkDimensions(mem_space.getDimensions(), n_dim_requested); -} - -} // namespace details -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Exception_misc.hpp b/inst/include/highfive/bits/H5Exception_misc.hpp deleted file mode 100644 index f7382f2..0000000 --- a/inst/include/highfive/bits/H5Exception_misc.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include - -#include - -namespace HighFive { - -struct HDF5ErrMapper { - template - static inline herr_t stackWalk(unsigned n, const H5E_error2_t* err_desc, void* client_data) { - auto** e_iter = static_cast(client_data); - (void) n; - - const char* major_err = H5Eget_major(err_desc->maj_num); - const char* minor_err = H5Eget_minor(err_desc->min_num); - - std::ostringstream oss; - oss << '(' << major_err << ") " << minor_err; - - H5free_memory((void*) major_err); - H5free_memory((void*) minor_err); - - auto* e = new ExceptionType(oss.str()); - e->_err_major = err_desc->maj_num; - e->_err_minor = err_desc->min_num; - (*e_iter)->_next.reset(e); - *e_iter = e; - return 0; - } - - template - [[noreturn]] static inline void ToException(const std::string& prefix_msg) { - hid_t err_stack = H5Eget_current_stack(); - if (err_stack >= 0) { - ExceptionType e(""); - ExceptionType* e_iter = &e; - - H5Ewalk2(err_stack, H5E_WALK_UPWARD, &HDF5ErrMapper::stackWalk, &e_iter); - H5Eclear2(err_stack); - - const char* next_err_msg = (e.nextException() != NULL) ? (e.nextException()->what()) - : (""); - - e.setErrorMsg(prefix_msg + " " + next_err_msg); - throw e; - } - // throw generic error, unrecognized error - throw ExceptionType(prefix_msg + ": Unknown HDF5 error"); - } -}; - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5FileDriver_misc.hpp b/inst/include/highfive/bits/H5FileDriver_misc.hpp deleted file mode 100644 index a6331bd..0000000 --- a/inst/include/highfive/bits/H5FileDriver_misc.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c), 2017-2018, Adrien Devresse - * Juan Hernando - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -namespace HighFive { - -#ifdef H5_HAVE_PARALLEL -inline MPIOFileDriver::MPIOFileDriver(MPI_Comm comm, MPI_Info info) { - add(MPIOFileAccess(comm, info)); -} -#endif - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5File_misc.hpp b/inst/include/highfive/bits/H5File_misc.hpp deleted file mode 100644 index b90792a..0000000 --- a/inst/include/highfive/bits/H5File_misc.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include - -#include "../H5Utility.hpp" -#include "H5Utils.hpp" - -namespace HighFive { - -namespace { // unnamed - -// libhdf5 uses a preprocessor trick on their oflags -// we can not declare them constant without a mapper -inline unsigned convert_open_flag(unsigned openFlags) { - unsigned res_open = 0; - if (openFlags & File::ReadOnly) - res_open |= H5F_ACC_RDONLY; - if (openFlags & File::ReadWrite) - res_open |= H5F_ACC_RDWR; - if (openFlags & File::Create) - res_open |= H5F_ACC_CREAT; - if (openFlags & File::Truncate) - res_open |= H5F_ACC_TRUNC; - if (openFlags & File::Excl) - res_open |= H5F_ACC_EXCL; - return res_open; -} -} // namespace - -inline File::File(const std::string& filename, - unsigned openFlags, - const FileAccessProps& fileAccessProps) - : File(filename, openFlags, FileCreateProps::Default(), fileAccessProps) {} - - -inline File::File(const std::string& filename, - unsigned openFlags, - const FileCreateProps& fileCreateProps, - const FileAccessProps& fileAccessProps) { - openFlags = convert_open_flag(openFlags); - - unsigned createMode = openFlags & (H5F_ACC_TRUNC | H5F_ACC_EXCL); - unsigned openMode = openFlags & (H5F_ACC_RDWR | H5F_ACC_RDONLY); - bool mustCreate = createMode > 0; - bool openOrCreate = (openFlags & H5F_ACC_CREAT) > 0; - - // open is default. It's skipped only if flags require creation - // If open fails it will try create() if H5F_ACC_CREAT is set - if (!mustCreate) { - // Silence open errors if create is allowed - std::unique_ptr silencer; - if (openOrCreate) - silencer.reset(new SilenceHDF5()); - - _hid = H5Fopen(filename.c_str(), openMode, fileAccessProps.getId()); - - if (isValid()) - return; // Done - - if (openOrCreate) { - // Will attempt to create ensuring wont clobber any file - createMode = H5F_ACC_EXCL; - } else { - HDF5ErrMapper::ToException( - std::string("Unable to open file " + filename)); - } - } - - auto fcpl = fileCreateProps.getId(); - auto fapl = fileAccessProps.getId(); - if ((_hid = H5Fcreate(filename.c_str(), createMode, fcpl, fapl)) < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create file " + filename)); - } -} - -inline const std::string& File::getName() const noexcept { - if (_filename.empty()) { - _filename = details::get_name( - [this](char* buffer, size_t length) { return H5Fget_name(getId(), buffer, length); }); - } - return _filename; -} - -inline hsize_t File::getMetadataBlockSize() const { - auto fapl = getAccessPropertyList(); - return MetadataBlockSize(fapl).getSize(); -} - -inline std::pair File::getVersionBounds() const { - auto fapl = getAccessPropertyList(); - auto fileVer = FileVersionBounds(fapl); - return fileVer.getVersion(); -} - -#if H5_VERSION_GE(1, 10, 1) -inline H5F_fspace_strategy_t File::getFileSpaceStrategy() const { - auto fcpl = getCreatePropertyList(); - FileSpaceStrategy spaceStrategy(fcpl); - return spaceStrategy.getStrategy(); -} - -inline hsize_t File::getFileSpacePageSize() const { - auto fcpl = getCreatePropertyList(); - - if (getFileSpaceStrategy() != H5F_FSPACE_STRATEGY_PAGE) { - HDF5ErrMapper::ToException( - std::string("Cannot obtain page size as paged allocation is not used.")); - } - - return FileSpacePageSize(fcpl).getPageSize(); -} -#endif - -inline void File::flush() { - if (H5Fflush(_hid, H5F_SCOPE_GLOBAL) < 0) { - HDF5ErrMapper::ToException(std::string("Unable to flush file " + getName())); - } -} - -inline size_t File::getFileSize() const { - hsize_t sizeValue = 0; - if (H5Fget_filesize(_hid, &sizeValue) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to retrieve size of file " + getName())); - } - return static_cast(sizeValue); -} - -inline size_t File::getFreeSpace() const { - hssize_t unusedSize = H5Fget_freespace(_hid); - if (unusedSize < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to retrieve unused space of file " + getName())); - } - return static_cast(unusedSize); -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Friends.hpp b/inst/include/highfive/bits/H5Friends.hpp deleted file mode 100644 index d19125c..0000000 --- a/inst/include/highfive/bits/H5Friends.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#ifndef HIGHFIVE_HAS_FRIEND_DECLARATIONS -#ifdef _MSC_VER -// This prevents a compiler bug on certain versions of MSVC. -// Known to fail: Toolset 141. -// See `CMakeLists.txt` for more information. -#define HIGHFIVE_HAS_FRIEND_DECLARATIONS 1 -#endif -#endif \ No newline at end of file diff --git a/inst/include/highfive/bits/H5Inspector_misc.hpp b/inst/include/highfive/bits/H5Inspector_misc.hpp deleted file mode 100644 index 05ed6bc..0000000 --- a/inst/include/highfive/bits/H5Inspector_misc.hpp +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Copyright (c) 2022 Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "../H5Reference.hpp" - -#include "string_padding.hpp" - -#ifdef H5_USE_BOOST -#include -// starting Boost 1.64, serialization header must come before ublas -#include -#include -#endif -#ifdef H5_USE_EIGEN -#include -#endif - - -namespace HighFive { - -namespace details { - -inline bool checkDimensions(const std::vector& dims, size_t n_dim_requested) { - size_t n_dim_actual = dims.size(); - - // We should allow reading scalar from shapes like `(1, 1, 1)`. - if (n_dim_requested == 0) { - if (n_dim_actual == 0ul) { - return true; - } - - return size_t(std::count(dims.begin(), dims.end(), 1ul)) == n_dim_actual; - } - - // For non-scalar datasets, we can squeeze away singleton dimension, but - // we never add any. - if (n_dim_actual < n_dim_requested) { - return false; - } - - // Special case for 1-dimensional arrays, which can squeeze `1`s from either - // side simultaneously if needed. - if (n_dim_requested == 1ul) { - return n_dim_actual >= 1ul && - size_t(std::count(dims.begin(), dims.end(), 1ul)) >= n_dim_actual - 1ul; - } - - // All other cases strip front only. This avoid unstable behaviour when - // squeezing singleton dimensions. - size_t n_dim_excess = n_dim_actual - n_dim_requested; - - bool squeeze_back = true; - for (size_t i = 1; i <= n_dim_excess; ++i) { - if (dims[n_dim_actual - i] != 1) { - squeeze_back = false; - break; - } - } - - return squeeze_back; -} - - -inline std::vector squeezeDimensions(const std::vector& dims, - size_t n_dim_requested) { - auto format_error_message = [&]() -> std::string { - return "Can't interpret dims = " + format_vector(dims) + " as " + - std::to_string(n_dim_requested) + "-dimensional."; - }; - - if (n_dim_requested == 0) { - if (!checkDimensions(dims, n_dim_requested)) { - throw std::invalid_argument(format_error_message()); - } - - return {1ul}; - } - - auto n_dim = dims.size(); - if (n_dim < n_dim_requested) { - throw std::invalid_argument(format_error_message()); - } - - if (n_dim_requested == 1ul) { - size_t non_singleton_dim = size_t(-1); - for (size_t i = 0; i < n_dim; ++i) { - if (dims[i] != 1ul) { - if (non_singleton_dim == size_t(-1)) { - non_singleton_dim = i; - } else { - throw std::invalid_argument(format_error_message()); - } - } - } - - return {dims[std::min(non_singleton_dim, n_dim - 1)]}; - } - - size_t n_dim_excess = dims.size() - n_dim_requested; - for (size_t i = 1; i <= n_dim_excess; ++i) { - if (dims[n_dim - i] != 1) { - throw std::invalid_argument(format_error_message()); - } - } - - return std::vector(dims.begin(), - dims.end() - static_cast(n_dim_excess)); -} -} // namespace details - - -inline size_t compute_total_size(const std::vector& dims) { - return std::accumulate(dims.begin(), dims.end(), size_t{1u}, std::multiplies()); -} - -template -using unqualified_t = typename std::remove_const::type>::type; - -/***** -inspector { - using type = T - // base_type is the base type inside c++ (e.g. std::vector => int) - using base_type - // hdf5_type is the base read by hdf5 (c-type) (e.g. std::vector => const char*) - using hdf5_type - - // Number of dimensions starting from here - static constexpr size_t recursive_ndim - // Is the inner type trivially copyable for optimisation - // If this value is true: data() is mandatory - // If this value is false: getSizeVal, getSize, serialize, unserialize are mandatory - static constexpr bool is_trivially_copyable - - // Reading: - // Allocate the value following dims (should be recursive) - static void prepare(type& val, const std::vector dims) - // Return the size of the vector pass to/from hdf5 from a vector of dims - static size_t getSize(const std::vector& dims) - // Return a pointer of the first value of val (for reading) - static hdf5_type* data(type& val) - // Take a serialized vector 'in', some dims and copy value to val (for reading) - static void unserialize(const hdf5_type* in, const std::vector&i, type& val) - - - // Writing: - // Return the size of the vector pass to/from hdf5 from a value - static size_t getSizeVal(const type& val) - // Return a point of the first value of val - static const hdf5_type* data(const type& val) - // Take a val and serialize it inside 'out' - static void serialize(const type& val, hdf5_type* out) - // Return an array of dimensions of the space needed for writing val - static std::vector getDimensions(const type& val) -} -*****/ - - -namespace details { -template -struct type_helper { - using type = unqualified_t; - using base_type = unqualified_t; - using hdf5_type = base_type; - - static constexpr size_t ndim = 0; - static constexpr size_t recursive_ndim = ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value; - - static std::vector getDimensions(const type& /* val */) { - return {}; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& /* val */, const std::vector& /* dims */) {} - - static hdf5_type* data(type& val) { - static_assert(is_trivially_copyable, "The type is not trivially copyable"); - return &val; - } - - static const hdf5_type* data(const type& val) { - static_assert(is_trivially_copyable, "The type is not trivially copyable"); - return &val; - } - - static void serialize(const type& val, hdf5_type* m) { - static_assert(is_trivially_copyable, "The type is not trivially copyable"); - *m = val; - } - - static void unserialize(const hdf5_type* vec, - const std::vector& /* dims */, - type& val) { - static_assert(is_trivially_copyable, "The type is not trivially copyable"); - val = vec[0]; - } -}; - -template -struct inspector: type_helper {}; - -enum class Boolean : int8_t { - HighFiveFalse = 0, - HighFiveTrue = 1, -}; - -template <> -struct inspector: type_helper { - using base_type = Boolean; - using hdf5_type = int8_t; - - static constexpr bool is_trivially_copyable = false; - - static hdf5_type* data(type& /* val */) { - throw DataSpaceException("A boolean cannot be read directly."); - } - - static const hdf5_type* data(const type& /* val */) { - throw DataSpaceException("A boolean cannot be written directly."); - } - - static void unserialize(const hdf5_type* vec, - const std::vector& /* dims */, - type& val) { - val = vec[0] != 0 ? true : false; - } - - static void serialize(const type& val, hdf5_type* m) { - *m = val ? 1 : 0; - } -}; - -template <> -struct inspector: type_helper { - using hdf5_type = const char*; - - static hdf5_type* data(type& /* val */) { - throw DataSpaceException("A std::string cannot be read directly."); - } - - static const hdf5_type* data(const type& /* val */) { - throw DataSpaceException("A std::string cannot be written directly."); - } - - template - static void serialize(const type& val, It m) { - (*m).assign(val.data(), val.size(), StringPadding::NullTerminated); - } - - template - static void unserialize(const It& vec, const std::vector& /* dims */, type& val) { - const auto& view = *vec; - val.assign(view.data(), view.length()); - } -}; - -template <> -struct inspector: type_helper { - using hdf5_type = hobj_ref_t; - - static constexpr bool is_trivially_copyable = false; - - static hdf5_type* data(type& /* val */) { - throw DataSpaceException("A Reference cannot be read directly."); - } - - static const hdf5_type* data(const type& /* val */) { - throw DataSpaceException("A Reference cannot be written directly."); - } - - static void serialize(const type& val, hdf5_type* m) { - hobj_ref_t ref; - val.create_ref(&ref); - *m = ref; - } - - static void unserialize(const hdf5_type* vec, - const std::vector& /* dims */, - type& val) { - val = type{vec[0]}; - } -}; - -template -struct inspector> { - using type = FixedLenStringArray; - using value_type = char*; - using base_type = FixedLenStringArray; - using hdf5_type = char; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim; - static constexpr bool is_trivially_copyable = false; - - static std::vector getDimensions(const type& val) { - return std::vector{val.size()}; - } - - static size_t getSizeVal(const type& val) { - return N * compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return N * compute_total_size(dims); - } - - static void prepare(type& /* val */, const std::vector& dims) { - if (dims[0] > N) { - std::ostringstream os; - os << "Size of FixedlenStringArray (" << N << ") is too small for dims (" << dims[0] - << ")."; - throw DataSpaceException(os.str()); - } - } - - static hdf5_type* data(type& val) { - return val.data(); - } - - static const hdf5_type* data(const type& val) { - return val.data(); - } - - static void serialize(const type& val, hdf5_type* m) { - for (size_t i = 0; i < val.size(); ++i) { - std::memcpy(m + i * N, val[i], N); - } - } - - static void unserialize(const hdf5_type* vec, const std::vector& dims, type& val) { - for (size_t i = 0; i < dims[0]; ++i) { - std::array s; - std::memcpy(s.data(), vec + (i * N), N); - val.push_back(s); - } - } -}; - -template -struct inspector> { - using type = std::vector; - using value_type = unqualified_t; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - static std::vector getDimensions(const type& val) { - std::vector sizes(recursive_ndim, 1ul); - sizes[0] = val.size(); - if (!val.empty()) { - auto s = inspector::getDimensions(val[0]); - assert(s.size() + ndim == sizes.size()); - for (size_t i = 0; i < s.size(); ++i) { - sizes[i + ndim] = s[i]; - } - } - return sizes; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& val, const std::vector& dims) { - val.resize(dims[0]); - std::vector next_dims(dims.begin() + 1, dims.end()); - for (auto&& e: val) { - inspector::prepare(e, next_dims); - } - } - - static hdf5_type* data(type& val) { - return inspector::data(val[0]); - } - - static const hdf5_type* data(const type& val) { - return inspector::data(val[0]); - } - - template - static void serialize(const type& val, It m) { - size_t subsize = inspector::getSizeVal(val[0]); - for (auto&& e: val) { - inspector::serialize(e, m); - m += subsize; - } - } - - template - static void unserialize(const It& vec_align, const std::vector& dims, type& val) { - std::vector next_dims(dims.begin() + 1, dims.end()); - size_t next_size = compute_total_size(next_dims); - for (size_t i = 0; i < dims[0]; ++i) { - inspector::unserialize(vec_align + i * next_size, next_dims, val[i]); - } - } -}; - -template <> -struct inspector> { - using type = std::vector; - using value_type = bool; - using base_type = Boolean; - using hdf5_type = uint8_t; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim; - static constexpr bool is_trivially_copyable = false; - - static std::vector getDimensions(const type& val) { - std::vector sizes{val.size()}; - return sizes; - } - - static size_t getSizeVal(const type& val) { - return val.size(); - } - - static size_t getSize(const std::vector& dims) { - if (dims.size() > 1) { - throw DataSpaceException("std::vector is only 1 dimension."); - } - return dims[0]; - } - - static void prepare(type& val, const std::vector& dims) { - if (dims.size() > 1) { - throw DataSpaceException("std::vector is only 1 dimension."); - } - val.resize(dims[0]); - } - - static hdf5_type* data(type& /* val */) { - throw DataSpaceException("A std::vector cannot be read directly."); - } - - static const hdf5_type* data(const type& /* val */) { - throw DataSpaceException("A std::vector cannot be written directly."); - } - - static void serialize(const type& val, hdf5_type* m) { - for (size_t i = 0; i < val.size(); ++i) { - m[i] = val[i] ? 1 : 0; - } - } - - static void unserialize(const hdf5_type* vec_align, - const std::vector& dims, - type& val) { - for (size_t i = 0; i < dims[0]; ++i) { - val[i] = vec_align[i] != 0 ? true : false; - } - } -}; - -template -struct inspector> { - using type = std::array; - using value_type = unqualified_t; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - sizeof(type) == N * sizeof(T) && - inspector::is_trivially_copyable; - - static std::vector getDimensions(const type& val) { - std::vector sizes{N}; - if (!val.empty()) { - auto s = inspector::getDimensions(val[0]); - sizes.insert(sizes.end(), s.begin(), s.end()); - } - return sizes; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& /* val */, const std::vector& dims) { - if (dims[0] > N) { - std::ostringstream os; - os << "Size of std::array (" << N << ") is too small for dims (" << dims[0] << ")."; - throw DataSpaceException(os.str()); - } - } - - static hdf5_type* data(type& val) { - return inspector::data(val[0]); - } - - static const hdf5_type* data(const type& val) { - return inspector::data(val[0]); - } - - template - static void serialize(const type& val, It m) { - size_t subsize = inspector::getSizeVal(val[0]); - for (auto& e: val) { - inspector::serialize(e, m); - m += subsize; - } - } - - template - static void unserialize(const It& vec_align, const std::vector& dims, type& val) { - if (dims[0] != N) { - std::ostringstream os; - os << "Impossible to pair DataSet with " << dims[0] << " elements into an array with " - << N << " elements."; - throw DataSpaceException(os.str()); - } - std::vector next_dims(dims.begin() + 1, dims.end()); - size_t next_size = compute_total_size(next_dims); - for (size_t i = 0; i < dims[0]; ++i) { - inspector::unserialize(vec_align + i * next_size, next_dims, val[i]); - } - } -}; - -// Cannot be use for reading -template -struct inspector { - using type = T*; - using value_type = unqualified_t; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - static size_t getSizeVal(const type& /* val */) { - throw DataSpaceException("Not possible to have size of a T*"); - } - - static std::vector getDimensions(const type& /* val */) { - throw DataSpaceException("Not possible to have size of a T*"); - } - - static const hdf5_type* data(const type& val) { - return reinterpret_cast(val); - } - - /* it works because there is only T[][][] currently - we will fix it one day */ - static void serialize(const type& /* val */, hdf5_type* /* m */) { - throw DataSpaceException("Not possible to serialize a T*"); - } -}; - -// Cannot be use for reading -template -struct inspector { - using type = T[N]; - using value_type = unqualified_t; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = 1; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static std::vector getDimensions(const type& val) { - std::vector sizes{N}; - if (N > 0) { - auto s = inspector::getDimensions(val[0]); - sizes.insert(sizes.end(), s.begin(), s.end()); - } - return sizes; - } - - static const hdf5_type* data(const type& val) { - return inspector::data(val[0]); - } - - /* it works because there is only T[][][] currently - we will fix it one day */ - static void serialize(const type& val, hdf5_type* m) { - size_t subsize = inspector::getSizeVal(val[0]); - for (size_t i = 0; i < N; ++i) { - inspector::serialize(val[i], m + i * subsize); - } - } -}; - -#ifdef H5_USE_EIGEN -template -struct inspector> { - using type = Eigen::Matrix; - using value_type = T; - using base_type = typename inspector::base_type; - using hdf5_type = base_type; - - static constexpr size_t ndim = 2; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - - static void assert_not_buggy(Eigen::Index nrows, Eigen::Index ncols) { - if (nrows > 1 && ncols > 1) { - throw std::runtime_error( - "HighFive has been broken for Eigen::Matrix. Please check " - "https://github.com/BlueBrain/HighFive/issues/532."); - } - } - - static std::vector getDimensions(const type& val) { - assert_not_buggy(val.rows(), val.cols()); - - std::vector sizes{static_cast(val.rows()), static_cast(val.cols())}; - auto s = inspector::getDimensions(val.data()[0]); - sizes.insert(sizes.end(), s.begin(), s.end()); - return sizes; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& val, const std::vector& dims) { - if (dims[0] != static_cast(val.rows()) || - dims[1] != static_cast(val.cols())) { - val.resize(static_cast(dims[0]), - static_cast(dims[1])); - } - - assert_not_buggy(val.rows(), val.cols()); - } - - static hdf5_type* data(type& val) { - assert_not_buggy(val.rows(), val.cols()); - return inspector::data(*val.data()); - } - - static const hdf5_type* data(const type& val) { - assert_not_buggy(val.rows(), val.cols()); - return inspector::data(*val.data()); - } - - static void serialize(const type& val, hdf5_type* m) { - assert_not_buggy(val.rows(), val.cols()); - std::memcpy(m, val.data(), static_cast(val.size()) * sizeof(hdf5_type)); - } - - static void unserialize(const hdf5_type* vec_align, - const std::vector& dims, - type& val) { - assert_not_buggy(val.rows(), val.cols()); - if (dims.size() < 2) { - std::ostringstream os; - os << "Impossible to pair DataSet with " << dims.size() - << " dimensions into an eigen-matrix."; - throw DataSpaceException(os.str()); - } - std::memcpy(val.data(), vec_align, compute_total_size(dims) * sizeof(hdf5_type)); - } -}; -#endif - -#ifdef H5_USE_BOOST -template -struct inspector> { - using type = boost::multi_array; - using value_type = T; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = Dims; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - static std::vector getDimensions(const type& val) { - std::vector sizes; - for (size_t i = 0; i < ndim; ++i) { - sizes.push_back(val.shape()[i]); - } - auto s = inspector::getDimensions(val.data()[0]); - sizes.insert(sizes.end(), s.begin(), s.end()); - return sizes; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& val, const std::vector& dims) { - if (dims.size() < ndim) { - std::ostringstream os; - os << "Only '" << dims.size() << "' given but boost::multi_array is of size '" << ndim - << "'."; - throw DataSpaceException(os.str()); - } - boost::array ext; - std::copy(dims.begin(), dims.begin() + ndim, ext.begin()); - val.resize(ext); - std::vector next_dims(dims.begin() + Dims, dims.end()); - std::size_t size = std::accumulate(dims.begin(), - dims.begin() + Dims, - std::size_t{1}, - std::multiplies()); - for (size_t i = 0; i < size; ++i) { - inspector::prepare(*(val.origin() + i), next_dims); - } - } - - static hdf5_type* data(type& val) { - return inspector::data(*val.data()); - } - - static const hdf5_type* data(const type& val) { - return inspector::data(*val.data()); - } - - template - static void serialize(const type& val, It m) { - size_t size = val.num_elements(); - size_t subsize = inspector::getSizeVal(*val.origin()); - for (size_t i = 0; i < size; ++i) { - inspector::serialize(*(val.origin() + i), m + i * subsize); - } - } - - template - static void unserialize(It vec_align, const std::vector& dims, type& val) { - std::vector next_dims(dims.begin() + ndim, dims.end()); - size_t subsize = compute_total_size(next_dims); - for (size_t i = 0; i < val.num_elements(); ++i) { - inspector::unserialize(vec_align + i * subsize, - next_dims, - *(val.origin() + i)); - } - } -}; - -template -struct inspector> { - using type = boost::numeric::ublas::matrix; - using value_type = unqualified_t; - using base_type = typename inspector::base_type; - using hdf5_type = typename inspector::hdf5_type; - - static constexpr size_t ndim = 2; - static constexpr size_t recursive_ndim = ndim + inspector::recursive_ndim; - static constexpr bool is_trivially_copyable = std::is_trivially_copyable::value && - inspector::is_trivially_copyable; - - static std::vector getDimensions(const type& val) { - std::vector sizes{val.size1(), val.size2()}; - auto s = inspector::getDimensions(val(0, 0)); - sizes.insert(sizes.end(), s.begin(), s.end()); - return sizes; - } - - static size_t getSizeVal(const type& val) { - return compute_total_size(getDimensions(val)); - } - - static size_t getSize(const std::vector& dims) { - return compute_total_size(dims); - } - - static void prepare(type& val, const std::vector& dims) { - if (dims.size() < ndim) { - std::ostringstream os; - os << "Impossible to pair DataSet with " << dims.size() << " dimensions into a " << ndim - << " boost::numeric::ublas::matrix"; - throw DataSpaceException(os.str()); - } - val.resize(dims[0], dims[1], false); - } - - static hdf5_type* data(type& val) { - return inspector::data(val(0, 0)); - } - - static const hdf5_type* data(const type& val) { - return inspector::data(val(0, 0)); - } - - static void serialize(const type& val, hdf5_type* m) { - size_t size = val.size1() * val.size2(); - size_t subsize = inspector::getSizeVal(val(0, 0)); - for (size_t i = 0; i < size; ++i) { - inspector::serialize(*(&val(0, 0) + i), m + i * subsize); - } - } - - static void unserialize(const hdf5_type* vec_align, - const std::vector& dims, - type& val) { - std::vector next_dims(dims.begin() + ndim, dims.end()); - size_t subsize = compute_total_size(next_dims); - size_t size = val.size1() * val.size2(); - for (size_t i = 0; i < size; ++i) { - inspector::unserialize(vec_align + i * subsize, - next_dims, - *(&val(0, 0) + i)); - } - } -}; -#endif - -} // namespace details -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Iterables_misc.hpp b/inst/include/highfive/bits/H5Iterables_misc.hpp deleted file mode 100644 index 38ebda9..0000000 --- a/inst/include/highfive/bits/H5Iterables_misc.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include - -#include - -namespace HighFive { - -namespace details { - -// iterator for H5 iterate - -struct HighFiveIterateData { - inline HighFiveIterateData(std::vector& my_names) - : names(my_names) - , err(NULL) {} - - std::vector& names; - std::exception* err; - - inline void throwIfError() { - if (err) { - throw *err; - } - } -}; - -template -inline herr_t internal_high_five_iterate(hid_t /*id*/, - const char* name, - const InfoType* /*info*/, - void* op_data) { - auto* data = static_cast(op_data); - try { - data->names.emplace_back(name); - return 0; - } catch (...) { - data->err = new ObjectException("Exception during H5Iterate, abort listing"); - } - return -1; -} - -} // namespace details -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Node_traits.hpp b/inst/include/highfive/bits/H5Node_traits.hpp deleted file mode 100644 index d53d3f0..0000000 --- a/inst/include/highfive/bits/H5Node_traits.hpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "../H5PropertyList.hpp" -#include "H5_definitions.hpp" -#include "H5Converter_misc.hpp" - -namespace HighFive { - -enum class IndexType : std::underlying_type::type { - NAME = H5_INDEX_NAME, - CRT_ORDER = H5_INDEX_CRT_ORDER, -}; - -/// -/// \brief NodeTraits: Base class for Group and File -/// -template -class NodeTraits { - public: - /// - /// \brief createDataSet Create a new dataset in the current file of - /// datatype type and of size space - /// \param dataset_name identifier of the dataset - /// \param space Associated DataSpace, see \ref DataSpace for more information - /// \param type Type of Data - /// \param createProps A property list with data set creation properties - /// \param accessProps A property list with data set access properties - /// \param parents Create intermediate groups if needed. Default: true. - /// \return DataSet Object - DataSet createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataType& type, - const DataSetCreateProps& createProps = DataSetCreateProps::Default(), - const DataSetAccessProps& accessProps = DataSetAccessProps::Default(), - bool parents = true); - - /// - /// \brief createDataSet create a new dataset in the current file with a - /// size specified by space - /// \param dataset_name identifier of the dataset - /// \param space Associated DataSpace, see \ref DataSpace for more information - /// \param createProps A property list with data set creation properties - /// \param accessProps A property list with data set access properties - /// \param parents Create intermediate groups if needed. Default: true. - /// \return DataSet Object - template ::base_type, details::Boolean>::value, - int>::type* = nullptr> - DataSet createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataSetCreateProps& createProps = DataSetCreateProps::Default(), - const DataSetAccessProps& accessProps = DataSetAccessProps::Default(), - bool parents = true); - - template ::base_type, details::Boolean>::value, - int>::type* = nullptr> - DataSet createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataSetCreateProps& createProps = DataSetCreateProps::Default(), - const DataSetAccessProps& accessProps = DataSetAccessProps::Default(), - bool parents = true); - - /// - /// \brief createDataSet create a new dataset in the current file and - /// write to it, inferring the DataSpace from the data. - /// \param dataset_name identifier of the dataset - /// \param data Associated data, must support DataSpace::From, see - /// \ref DataSpace for more information - /// \param createProps A property list with data set creation properties - /// \param accessProps A property list with data set access properties - /// \param parents Create intermediate groups if needed. Default: true. - /// \return DataSet Object - template - DataSet createDataSet(const std::string& dataset_name, - const T& data, - const DataSetCreateProps& createProps = DataSetCreateProps::Default(), - const DataSetAccessProps& accessProps = DataSetAccessProps::Default(), - bool parents = true); - - - template - DataSet createDataSet(const std::string& dataset_name, - const FixedLenStringArray& data, - const DataSetCreateProps& createProps = DataSetCreateProps::Default(), - const DataSetAccessProps& accessProps = DataSetAccessProps::Default(), - bool parents = true); - - /// - /// \brief get an existing dataset in the current file - /// \param dataset_name - /// \param accessProps property list to configure dataset chunk cache - /// \return return the named dataset, or throw exception if not found - DataSet getDataSet(const std::string& dataset_name, - const DataSetAccessProps& accessProps = DataSetAccessProps::Default()) const; - - /// - /// \brief create a new group, and eventually intermediate groups - /// \param group_name - /// \param parents Create intermediate groups if needed. Default: true. - /// \return the group object - Group createGroup(const std::string& group_name, bool parents = true); - - /// - /// \brief create a new group, and eventually intermediate groups - /// \param group_name - /// \param createProps A property list with group creation properties - /// \param parents Create intermediate groups if needed. Default: true. - /// \return the group object - Group createGroup(const std::string& group_name, - const GroupCreateProps& createProps, - bool parents = true); - - /// - /// \brief open an existing group with the name group_name - /// \param group_name - /// \return the group object - Group getGroup(const std::string& group_name) const; - - /// - /// \brief open a commited datatype with the name type_name - /// \param type_name - /// \return the datatype object - DataType getDataType( - const std::string& type_name, - const DataTypeAccessProps& accessProps = DataTypeAccessProps::Default()) const; - - /// - /// \brief return the number of leaf objects of the node / group - /// \return number of leaf objects - size_t getNumberObjects() const; - - /// - /// \brief return the name of the object with the given index - /// \return the name of the object - std::string getObjectName(size_t index) const; - - /// - /// \brief moves an object and its content within an HDF5 file. - /// \param src_path relative path of the object to current File/Group - /// \param dest_path new relative path of the object to current File/Group - /// \param parents Create intermediate groups if needed. Default: true. - /// \return boolean that is true if the move was successful - bool rename(const std::string& src_path, - const std::string& dest_path, - bool parents = true) const; - - /// - /// \brief list all leaf objects name of the node / group - /// \param idx_type tell if the list should be ordered by Name or CreationOrderTime. - /// CreationOrderTime can be use only if the file/group has been created with - /// the HighFive::LinkCreationTime property. - /// \return number of leaf objects - std::vector listObjectNames(IndexType idx_type = IndexType::NAME) const; - - /// - /// \brief check a dataset or group exists in the current node / group - /// \param node_name dataset/group name to check - /// \return true if a dataset/group with the associated name exists, or false - bool exist(const std::string& node_name) const; - - /// - /// \brief unlink the given dataset or group - /// \param node_name dataset/group name to unlink - void unlink(const std::string& node_name) const; - - /// - /// \brief Returns the kind of link of the given name (soft, hard...) - /// \param node_name The entry to check, path relative to the current group - LinkType getLinkType(const std::string& node_name) const; - - /// - /// \brief A shorthand to get the kind of object pointed to (group, dataset, type...) - /// \param node_name The entry to check, path relative to the current group - ObjectType getObjectType(const std::string& node_name) const; - - /// - /// \brief A shorthand to create softlink to any object which provides `getPath` - /// The link will be created with default properties along with required parent groups - template - void createSoftLink(const std::string& linkName, const T& obj) { - static_assert(!std::is_same::value, - "hdf5 doesn't support soft links to Attributes"); - createSoftLink(linkName, obj.getPath()); - } - - /// - /// \brief Creates softlinks - /// \param link_name The name of the link - /// \param obj_path The target object path - /// \param linkCreateProps A Link_Create property list. Notice "parents=true" overrides - /// \param linkAccessProps The Link_Access property list - /// \param parents Whether parent groups should be created: Default: true - void createSoftLink(const std::string& link_name, - const std::string& obj_path, - LinkCreateProps linkCreateProps = LinkCreateProps(), - const LinkAccessProps& linkAccessProps = LinkAccessProps(), - const bool parents = true); - - void createExternalLink(const std::string& link_name, - const std::string& h5_file, - const std::string& obj_path, - LinkCreateProps linkCreateProps = LinkCreateProps(), - const LinkAccessProps& linkAccessProps = LinkAccessProps(), - const bool parents = true); - - /// - /// \brief Creates hardlinks - /// \param link_name The name of the link - /// \param target_obj The target object - /// \param linkCreateProps A Link_Create property list. Notice "parents=true" overrides - /// \param linkAccessProps The Link_Access property list - /// \param parents Whether parent groups should be created: Default: true - template - void createHardLink(const std::string& link_name, - const T& target_obj, - LinkCreateProps linkCreateProps = LinkCreateProps(), - const LinkAccessProps& linkAccessProps = LinkAccessProps(), - const bool parents = true); - - private: - using derivate_type = Derivate; - - // A wrapper over the low-level H5Lexist - // It makes behavior consistent among versions and by default transforms - // errors to exceptions - bool _exist(const std::string& node_name, bool raise_errors = true) const; - - // Opens an arbitrary object to obtain info - Object _open(const std::string& node_name, - const DataSetAccessProps& accessProps = DataSetAccessProps::Default()) const; -}; - - -/// -/// \brief The possible types of group entries (link concept) -/// -enum class LinkType { - Hard, - Soft, - External, - Other // Reserved or User-defined -}; - - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Node_traits_misc.hpp b/inst/include/highfive/bits/H5Node_traits_misc.hpp deleted file mode 100644 index 2f75ff3..0000000 --- a/inst/include/highfive/bits/H5Node_traits_misc.hpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../H5DataSet.hpp" -#include "../H5Group.hpp" -#include "../H5Selection.hpp" -#include "../H5Utility.hpp" -#include "H5DataSet_misc.hpp" -#include "H5Iterables_misc.hpp" -#include "H5Selection_misc.hpp" -#include "H5Slice_traits_misc.hpp" - -namespace HighFive { - - -template -inline DataSet NodeTraits::createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataType& dtype, - const DataSetCreateProps& createProps, - const DataSetAccessProps& accessProps, - bool parents) { - LinkCreateProps lcpl; - lcpl.add(CreateIntermediateGroup(parents)); - const auto hid = H5Dcreate2(static_cast(this)->getId(), - dataset_name.c_str(), - dtype.getId(), - space.getId(), - lcpl.getId(), - createProps.getId(), - accessProps.getId()); - if (hid < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to create the dataset \"") + dataset_name + "\":"); - } - return DataSet(hid); -} - -template -template ::base_type, details::Boolean>::value, - int>::type*> -inline DataSet NodeTraits::createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataSetCreateProps& createProps, - const DataSetAccessProps& accessProps, - bool parents) { - return createDataSet(dataset_name, - space, - create_and_check_datatype::base_type>(), - createProps, - accessProps, - parents); -} - -template -template ::base_type, details::Boolean>::value, - int>::type*> -inline DataSet NodeTraits::createDataSet(const std::string& dataset_name, - const DataSpace& space, - const DataSetCreateProps& createProps, - const DataSetAccessProps& accessProps, - bool parents) { - return createDataSet( - dataset_name, space, create_and_check_datatype(), createProps, accessProps, parents); -} - -template -template -inline DataSet NodeTraits::createDataSet(const std::string& dataset_name, - const T& data, - const DataSetCreateProps& createProps, - const DataSetAccessProps& accessProps, - bool parents) { - DataSet ds = - createDataSet(dataset_name, - DataSpace::From(data), - create_and_check_datatype::base_type>(), - createProps, - accessProps, - parents); - ds.write(data); - return ds; -} - -template -template -inline DataSet NodeTraits::createDataSet(const std::string& dataset_name, - const FixedLenStringArray& data, - const DataSetCreateProps& createProps, - const DataSetAccessProps& accessProps, - bool parents) { - DataSet ds = createDataSet( - dataset_name, DataSpace(data.size()), createProps, accessProps, parents); - ds.write(data); - return ds; -} - -template -inline DataSet NodeTraits::getDataSet(const std::string& dataset_name, - const DataSetAccessProps& accessProps) const { - const auto hid = H5Dopen2(static_cast(this)->getId(), - dataset_name.c_str(), - accessProps.getId()); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to open the dataset \"") + - dataset_name + "\":"); - } - return DataSet(hid); -} - -template -inline Group NodeTraits::createGroup(const std::string& group_name, bool parents) { - LinkCreateProps lcpl; - lcpl.add(CreateIntermediateGroup(parents)); - const auto hid = H5Gcreate2(static_cast(this)->getId(), - group_name.c_str(), - lcpl.getId(), - H5P_DEFAULT, - H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); -} - -template -inline Group NodeTraits::createGroup(const std::string& group_name, - const GroupCreateProps& createProps, - bool parents) { - LinkCreateProps lcpl; - lcpl.add(CreateIntermediateGroup(parents)); - const auto hid = H5Gcreate2(static_cast(this)->getId(), - group_name.c_str(), - lcpl.getId(), - createProps.getId(), - H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); -} - -template -inline Group NodeTraits::getGroup(const std::string& group_name) const { - const auto hid = - H5Gopen2(static_cast(this)->getId(), group_name.c_str(), H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to open the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); -} - -template -inline DataType NodeTraits::getDataType(const std::string& type_name, - const DataTypeAccessProps& accessProps) const { - const auto hid = H5Topen2(static_cast(this)->getId(), - type_name.c_str(), - accessProps.getId()); - if (hid < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to open the datatype \"") + type_name + "\":"); - } - return DataType(hid); -} - -template -inline size_t NodeTraits::getNumberObjects() const { - hsize_t res; - if (H5Gget_num_objs(static_cast(this)->getId(), &res) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to count objects in existing group or file")); - } - return static_cast(res); -} - -template -inline std::string NodeTraits::getObjectName(size_t index) const { - return details::get_name([&](char* buffer, size_t length) { - return H5Lget_name_by_idx(static_cast(this)->getId(), - ".", - H5_INDEX_NAME, - H5_ITER_INC, - index, - buffer, - length, - H5P_DEFAULT); - }); -} - -template -inline bool NodeTraits::rename(const std::string& src_path, - const std::string& dst_path, - bool parents) const { - LinkCreateProps lcpl; - lcpl.add(CreateIntermediateGroup(parents)); - herr_t status = H5Lmove(static_cast(this)->getId(), - src_path.c_str(), - static_cast(this)->getId(), - dst_path.c_str(), - lcpl.getId(), - H5P_DEFAULT); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to move link to \"") + - dst_path + "\":"); - return false; - } - return true; -} - -template -inline std::vector NodeTraits::listObjectNames(IndexType idx_type) const { - std::vector names; - details::HighFiveIterateData iterateData(names); - - size_t num_objs = getNumberObjects(); - names.reserve(num_objs); - - if (H5Literate(static_cast(this)->getId(), - static_cast(idx_type), - H5_ITER_INC, - NULL, - &details::internal_high_five_iterate, - static_cast(&iterateData)) < 0) { - HDF5ErrMapper::ToException(std::string("Unable to list objects in group")); - } - - return names; -} - -template -inline bool NodeTraits::_exist(const std::string& node_name, bool raise_errors) const { - SilenceHDF5 silencer{}; - const auto val = - H5Lexists(static_cast(this)->getId(), node_name.c_str(), H5P_DEFAULT); - if (val < 0) { - if (raise_errors) { - HDF5ErrMapper::ToException("Invalid link for exist()"); - } else { - return false; - } - } - - // The root path always exists, but H5Lexists return 0 or 1 - // depending of the version of HDF5, so always return true for it - // We had to call H5Lexists anyway to check that there are no errors - return (node_name == "/") ? true : (val > 0); -} - -template -inline bool NodeTraits::exist(const std::string& group_path) const { - // When there are slashes, first check everything is fine - // so that subsequent errors are only due to missing intermediate groups - if (group_path.find('/') != std::string::npos) { - _exist("/"); // Shall not throw under normal circumstances - // Unless "/" (already checked), verify path exists (not throwing errors) - return (group_path == "/") ? true : _exist(group_path, false); - } - return _exist(group_path); -} - - -template -inline void NodeTraits::unlink(const std::string& node_name) const { - const herr_t val = - H5Ldelete(static_cast(this)->getId(), node_name.c_str(), H5P_DEFAULT); - if (val < 0) { - HDF5ErrMapper::ToException(std::string("Invalid name for unlink() ")); - } -} - - -// convert internal link types to enum class. -// This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context -static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept { - switch (ltype) { - case H5L_TYPE_HARD: - return LinkType::Hard; - case H5L_TYPE_SOFT: - return LinkType::Soft; - case H5L_TYPE_EXTERNAL: - return LinkType::External; - default: - // Other link types are possible but are considered strange to HighFive. - // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm - return LinkType::Other; - } -} - -template -inline LinkType NodeTraits::getLinkType(const std::string& node_name) const { - H5L_info_t linkinfo; - if (H5Lget_info(static_cast(this)->getId(), - node_name.c_str(), - &linkinfo, - H5P_DEFAULT) < 0 || - linkinfo.type == H5L_TYPE_ERROR) { - HDF5ErrMapper::ToException(std::string("Unable to obtain info for link ") + - node_name); - } - return _convert_link_type(linkinfo.type); -} - -template -inline ObjectType NodeTraits::getObjectType(const std::string& node_name) const { - return _open(node_name).getType(); -} - - -template -inline void NodeTraits::createSoftLink(const std::string& link_name, - const std::string& obj_path, - LinkCreateProps linkCreateProps, - const LinkAccessProps& linkAccessProps, - const bool parents) { - if (parents) { - linkCreateProps.add(CreateIntermediateGroup{}); - } - auto status = H5Lcreate_soft(obj_path.c_str(), - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create soft link: ")); - } -} - - -template -inline void NodeTraits::createExternalLink(const std::string& link_name, - const std::string& h5_file, - const std::string& obj_path, - LinkCreateProps linkCreateProps, - const LinkAccessProps& linkAccessProps, - const bool parents) { - if (parents) { - linkCreateProps.add(CreateIntermediateGroup{}); - } - auto status = H5Lcreate_external(h5_file.c_str(), - obj_path.c_str(), - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create external link: ")); - } -} - -template -template -inline void NodeTraits::createHardLink(const std::string& link_name, - const T& target_obj, - LinkCreateProps linkCreateProps, - const LinkAccessProps& linkAccessProps, - const bool parents) { - static_assert(!std::is_same::value, - "hdf5 doesn't support hard links to Attributes"); - if (parents) { - linkCreateProps.add(CreateIntermediateGroup{}); - } - auto status = H5Lcreate_hard(target_obj.getId(), - ".", - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create hard link: ")); - } -} - - -template -inline Object NodeTraits::_open(const std::string& node_name, - const DataSetAccessProps& accessProps) const { - const auto id = H5Oopen(static_cast(this)->getId(), - node_name.c_str(), - accessProps.getId()); - if (id < 0) { - HDF5ErrMapper::ToException(std::string("Unable to open \"") + node_name + - "\":"); - } - return detail::make_object(id); -} - - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Object_misc.hpp b/inst/include/highfive/bits/H5Object_misc.hpp deleted file mode 100644 index f477d7f..0000000 --- a/inst/include/highfive/bits/H5Object_misc.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "../H5Exception.hpp" -#include "../H5Utility.hpp" - -namespace HighFive { -namespace detail { -inline Object make_object(hid_t hid) { - return Object(hid); -} -} // namespace detail - - -inline Object::Object() - : _hid(H5I_INVALID_HID) {} - -inline Object::Object(hid_t hid) - : _hid(hid) {} - -inline Object::Object(const Object& other) - : _hid(other._hid) { - if (other.isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); - } -} - -inline Object::Object(Object&& other) noexcept - : _hid(other._hid) { - other._hid = H5I_INVALID_HID; -} - -inline Object& Object::operator=(const Object& other) { - if (this != &other) { - if (isValid()) - H5Idec_ref(_hid); - - _hid = other._hid; - if (other.isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); - } - } - return *this; -} - -inline Object::~Object() { - if (isValid() && H5Idec_ref(_hid) < 0) { - HIGHFIVE_LOG_ERROR("HighFive::~Object: reference counter decrease failure"); - } -} - -inline bool Object::isValid() const noexcept { - return (_hid != H5I_INVALID_HID) && (H5Iis_valid(_hid) != false); -} - -inline hid_t Object::getId() const noexcept { - return _hid; -} - -static inline ObjectType _convert_object_type(const H5I_type_t& h5type) { - switch (h5type) { - case H5I_FILE: - return ObjectType::File; - case H5I_GROUP: - return ObjectType::Group; - case H5I_DATATYPE: - return ObjectType::UserDataType; - case H5I_DATASPACE: - return ObjectType::DataSpace; - case H5I_DATASET: - return ObjectType::Dataset; - case H5I_ATTR: - return ObjectType::Attribute; - default: - return ObjectType::Other; - } -} - -inline ObjectType Object::getType() const { - // H5Iget_type is a very lightweight func which extracts the type from the id - H5I_type_t h5type; - if ((h5type = H5Iget_type(_hid)) == H5I_BADID) { - HDF5ErrMapper::ToException("Invalid hid or object type"); - } - return _convert_object_type(h5type); -} - -inline ObjectInfo Object::getInfo() const { - ObjectInfo info; -#if (H5Oget_info_vers < 3) - if (H5Oget_info(_hid, &info.raw_info) < 0) { -#else - if (H5Oget_info1(_hid, &info.raw_info) < 0) { -#endif - HDF5ErrMapper::ToException("Unable to obtain info for object"); - } - return info; -} - -inline haddr_t ObjectInfo::getAddress() const noexcept { - return raw_info.addr; -} -inline size_t ObjectInfo::getRefCount() const noexcept { - return raw_info.rc; -} -inline time_t ObjectInfo::getCreationTime() const noexcept { - return raw_info.btime; -} -inline time_t ObjectInfo::getModificationTime() const noexcept { - return raw_info.mtime; -} - - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Path_traits.hpp b/inst/include/highfive/bits/H5Path_traits.hpp deleted file mode 100644 index 46a038c..0000000 --- a/inst/include/highfive/bits/H5Path_traits.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c), 2020, EPFL - Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "H5_definitions.hpp" - -namespace HighFive { - -template -class PathTraits { - public: - PathTraits(); - - /// - /// \brief return the path to the current object - /// \return the path to the object - std::string getPath() const; - - /// - /// \brief Return a reference to the File object this object belongs - /// \return the File object ref - File& getFile() const noexcept; - - - protected: - std::shared_ptr _file_obj; // keep a ref to file so we keep its ref count > 0 -}; - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Path_traits_misc.hpp b/inst/include/highfive/bits/H5Path_traits_misc.hpp deleted file mode 100644 index 444e929..0000000 --- a/inst/include/highfive/bits/H5Path_traits_misc.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c), 2020, EPFL - Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -#include "H5Utils.hpp" -#include "H5Path_traits.hpp" - -namespace HighFive { - -template -inline PathTraits::PathTraits() { - static_assert(std::is_same::value || std::is_same::value || - std::is_same::value, - "PathTraits can only be applied to Group, DataSet and Attribute"); - const auto& obj = static_cast(*this); - if (!obj.isValid()) { - return; - } - const hid_t file_id = H5Iget_file_id(obj.getId()); - if (file_id < 0) { - HDF5ErrMapper::ToException("getFile(): Could not obtain file of object"); - } - _file_obj.reset(new File(file_id)); -} - -template -inline std::string PathTraits::getPath() const { - return details::get_name([this](char* buffer, size_t length) { - return H5Iget_name(static_cast(*this).getId(), buffer, length); - }); -} - -template -inline File& PathTraits::getFile() const noexcept { - return *_file_obj; -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5PropertyList_misc.hpp b/inst/include/highfive/bits/H5PropertyList_misc.hpp deleted file mode 100644 index cef301e..0000000 --- a/inst/include/highfive/bits/H5PropertyList_misc.hpp +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright (c), 2017-2018, Adrien Devresse - * Juan Hernando - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include - -namespace HighFive { - -namespace { -inline hid_t convert_plist_type(PropertyType propertyType) { - // The HP5_XXX are macros with function calls so we can't assign - // them as the enum values - switch (propertyType) { - case PropertyType::OBJECT_CREATE: - return H5P_OBJECT_CREATE; - case PropertyType::FILE_CREATE: - return H5P_FILE_CREATE; - case PropertyType::FILE_ACCESS: - return H5P_FILE_ACCESS; - case PropertyType::DATASET_CREATE: - return H5P_DATASET_CREATE; - case PropertyType::DATASET_ACCESS: - return H5P_DATASET_ACCESS; - case PropertyType::DATASET_XFER: - return H5P_DATASET_XFER; - case PropertyType::GROUP_CREATE: - return H5P_GROUP_CREATE; - case PropertyType::GROUP_ACCESS: - return H5P_GROUP_ACCESS; - case PropertyType::DATATYPE_CREATE: - return H5P_DATATYPE_CREATE; - case PropertyType::DATATYPE_ACCESS: - return H5P_DATATYPE_ACCESS; - case PropertyType::STRING_CREATE: - return H5P_STRING_CREATE; - case PropertyType::ATTRIBUTE_CREATE: - return H5P_ATTRIBUTE_CREATE; - case PropertyType::OBJECT_COPY: - return H5P_OBJECT_COPY; - case PropertyType::LINK_CREATE: - return H5P_LINK_CREATE; - case PropertyType::LINK_ACCESS: - return H5P_LINK_ACCESS; - default: - HDF5ErrMapper::ToException("Unsupported property list type"); - } -} - -} // namespace - - -inline PropertyListBase::PropertyListBase() noexcept - : Object(H5P_DEFAULT) {} - - -template -inline void PropertyList::_initializeIfNeeded() { - if (_hid != H5P_DEFAULT) { - return; - } - if ((_hid = H5Pcreate(convert_plist_type(T))) < 0) { - HDF5ErrMapper::ToException("Unable to create property list"); - } -} - -template -template -inline void PropertyList::add(const P& property) { - _initializeIfNeeded(); - property.apply(_hid); -} - -template -template -inline void RawPropertyList::add(const F& funct, const Args&... args) { - this->_initializeIfNeeded(); - if (funct(this->_hid, args...) < 0) { - HDF5ErrMapper::ToException("Error setting raw hdf5 property."); - } -} - -// Specific options to be added to Property Lists -#if H5_VERSION_GE(1, 10, 1) -inline FileSpaceStrategy::FileSpaceStrategy(H5F_fspace_strategy_t strategy, - hbool_t persist, - hsize_t threshold) - : _strategy(strategy) - , _persist(persist) - , _threshold(threshold) {} - -inline FileSpaceStrategy::FileSpaceStrategy(const FileCreateProps& fcpl) { - if (H5Pget_file_space_strategy(fcpl.getId(), &_strategy, &_persist, &_threshold) < 0) { - HDF5ErrMapper::ToException("Unable to get file space strategy"); - } -} - -inline void FileSpaceStrategy::apply(const hid_t list) const { - if (H5Pset_file_space_strategy(list, _strategy, _persist, _threshold) < 0) { - HDF5ErrMapper::ToException("Error setting file space strategy."); - } -} - -inline H5F_fspace_strategy_t FileSpaceStrategy::getStrategy() const { - return _strategy; -} - -inline hbool_t FileSpaceStrategy::getPersist() const { - return _persist; -} - -inline hsize_t FileSpaceStrategy::getThreshold() const { - return _threshold; -} - -inline FileSpacePageSize::FileSpacePageSize(hsize_t page_size) - : _page_size(page_size) {} - -inline void FileSpacePageSize::apply(const hid_t list) const { - if (H5Pset_file_space_page_size(list, _page_size) < 0) { - HDF5ErrMapper::ToException("Error setting file space page size."); - } -} - -inline FileSpacePageSize::FileSpacePageSize(const FileCreateProps& fcpl) { - if (H5Pget_file_space_page_size(fcpl.getId(), &_page_size) < 0) { - HDF5ErrMapper::ToException("Unable to get file space page size"); - } -} - -inline hsize_t FileSpacePageSize::getPageSize() const { - return _page_size; -} - -#ifndef H5_HAVE_PARALLEL -inline PageBufferSize::PageBufferSize(size_t page_buffer_size, - unsigned min_meta_percent, - unsigned min_raw_percent) - : _page_buffer_size(page_buffer_size) - , _min_meta(min_meta_percent) - , _min_raw(min_raw_percent) {} - -inline PageBufferSize::PageBufferSize(const FileAccessProps& plist) { - if (H5Pget_page_buffer_size(plist.getId(), &_page_buffer_size, &_min_meta, &_min_raw) < 0) { - HDF5ErrMapper::ToException("Error setting page buffer size."); - } -} - -inline void PageBufferSize::apply(const hid_t list) const { - if (H5Pset_page_buffer_size(list, _page_buffer_size, _min_meta, _min_raw) < 0) { - HDF5ErrMapper::ToException("Error setting page buffer size."); - } -} - -inline size_t PageBufferSize::getPageBufferSize() const { - return _page_buffer_size; -} - -inline unsigned PageBufferSize::getMinMetaPercent() const { - return _min_meta; -} - -inline unsigned PageBufferSize::getMinRawPercent() const { - return _min_raw; -} -#endif -#endif - -#ifdef H5_HAVE_PARALLEL - -inline MPIOFileAccess::MPIOFileAccess(MPI_Comm comm, MPI_Info info) - : _comm(comm) - , _info(info) {} - -inline void MPIOFileAccess::apply(const hid_t list) const { - if (H5Pset_fapl_mpio(list, _comm, _info) < 0) { - HDF5ErrMapper::ToException("Unable to set-up MPIO Driver configuration"); - } -} - -inline void MPIOCollectiveMetadata::apply(const hid_t plist) const { - auto read = MPIOCollectiveMetadataRead{collective_read_}; - auto write = MPIOCollectiveMetadataWrite{collective_write_}; - - read.apply(plist); - write.apply(plist); -} - -inline MPIOCollectiveMetadata::MPIOCollectiveMetadata(bool collective) - : collective_read_(collective) - , collective_write_(collective) {} - - -inline MPIOCollectiveMetadata::MPIOCollectiveMetadata(const FileAccessProps& plist) - : collective_read_(MPIOCollectiveMetadataRead(plist).isCollective()) - , collective_write_(MPIOCollectiveMetadataWrite(plist).isCollective()) {} - -inline bool MPIOCollectiveMetadata::isCollectiveRead() const { - return collective_read_; -} - -inline bool MPIOCollectiveMetadata::isCollectiveWrite() const { - return collective_write_; -} - - -inline void MPIOCollectiveMetadataRead::apply(const hid_t plist) const { - if (H5Pset_all_coll_metadata_ops(plist, collective_) < 0) { - HDF5ErrMapper::ToException("Unable to request collective metadata reads"); - } -} - -inline bool MPIOCollectiveMetadataRead::isCollective() const { - return collective_; -} - -inline MPIOCollectiveMetadataRead::MPIOCollectiveMetadataRead(const FileAccessProps& plist) { - if (H5Pget_all_coll_metadata_ops(plist.getId(), &collective_) < 0) { - HDF5ErrMapper::ToException("Error loading MPI metadata read."); - } -} - -inline MPIOCollectiveMetadataRead::MPIOCollectiveMetadataRead(bool collective) - : collective_(collective) {} - -inline void MPIOCollectiveMetadataWrite::apply(const hid_t plist) const { - if (H5Pset_coll_metadata_write(plist, collective_) < 0) { - HDF5ErrMapper::ToException("Unable to request collective metadata writes"); - } -} - -inline bool MPIOCollectiveMetadataWrite::isCollective() const { - return collective_; -} - -inline MPIOCollectiveMetadataWrite::MPIOCollectiveMetadataWrite(const FileAccessProps& plist) { - if (H5Pget_coll_metadata_write(plist.getId(), &collective_) < 0) { - HDF5ErrMapper::ToException("Error loading MPI metadata write."); - } -} - -inline MPIOCollectiveMetadataWrite::MPIOCollectiveMetadataWrite(bool collective) - : collective_(collective) {} - -#endif - -inline FileVersionBounds::FileVersionBounds(H5F_libver_t low, H5F_libver_t high) - : _low(low) - , _high(high) {} - -inline FileVersionBounds::FileVersionBounds(const FileAccessProps& fapl) { - if (H5Pget_libver_bounds(fapl.getId(), &_low, &_high) < 0) { - HDF5ErrMapper::ToException("Unable to access file version bounds"); - } -} - -inline std::pair FileVersionBounds::getVersion() const { - return std::make_pair(_low, _high); -} - -inline void FileVersionBounds::apply(const hid_t list) const { - if (H5Pset_libver_bounds(list, _low, _high) < 0) { - HDF5ErrMapper::ToException("Error setting file version bounds"); - } -} - -inline MetadataBlockSize::MetadataBlockSize(hsize_t size) - : _size(size) {} - -inline MetadataBlockSize::MetadataBlockSize(const FileAccessProps& fapl) { - if (H5Pget_meta_block_size(fapl.getId(), &_size) < 0) { - HDF5ErrMapper::ToException("Unable to access file metadata block size"); - } -} - -inline void MetadataBlockSize::apply(const hid_t list) const { - if (H5Pset_meta_block_size(list, _size) < 0) { - HDF5ErrMapper::ToException("Error setting metadata block size"); - } -} - -inline hsize_t MetadataBlockSize::getSize() const { - return _size; -} - -inline void EstimatedLinkInfo::apply(const hid_t hid) const { - if (H5Pset_est_link_info(hid, _entries, _length) < 0) { - HDF5ErrMapper::ToException("Error setting estimated link info"); - } -} - -inline EstimatedLinkInfo::EstimatedLinkInfo(unsigned entries, unsigned length) - : _entries(entries) - , _length(length) {} - -inline EstimatedLinkInfo::EstimatedLinkInfo(const GroupCreateProps& gcpl) { - if (H5Pget_est_link_info(gcpl.getId(), &_entries, &_length) < 0) { - HDF5ErrMapper::ToException("Unable to access group link size property"); - } -} - -inline unsigned EstimatedLinkInfo::getEntries() const { - return _entries; -} - -inline unsigned EstimatedLinkInfo::getNameLength() const { - return _length; -} - -inline void Chunking::apply(const hid_t hid) const { - if (H5Pset_chunk(hid, static_cast(_dims.size()), _dims.data()) < 0) { - HDF5ErrMapper::ToException("Error setting chunk property"); - } -} - -inline Chunking::Chunking(const std::vector& dims) - : _dims(dims) {} - -inline Chunking::Chunking(const std::initializer_list& items) - : Chunking(std::vector{items}) {} - -inline Chunking::Chunking(DataSetCreateProps& plist, size_t max_dims) - : _dims(max_dims + 1) { - auto n_loaded = H5Pget_chunk(plist.getId(), static_cast(_dims.size()), _dims.data()); - if (n_loaded < 0) { - HDF5ErrMapper::ToException("Error getting chunk size"); - } - - if (n_loaded >= static_cast(_dims.size())) { - *this = Chunking(plist, 8 * max_dims); - } else { - _dims.resize(static_cast(n_loaded)); - } -} - -inline const std::vector& Chunking::getDimensions() const noexcept { - return _dims; -} - -template -inline Chunking::Chunking(hsize_t item, Args... args) - : Chunking(std::vector{item, static_cast(args)...}) {} - -inline void Deflate::apply(const hid_t hid) const { - if (!H5Zfilter_avail(H5Z_FILTER_DEFLATE) || H5Pset_deflate(hid, _level) < 0) { - HDF5ErrMapper::ToException("Error setting deflate property"); - } -} - -inline Deflate::Deflate(unsigned int level) - : _level(level) {} - -inline void Szip::apply(const hid_t hid) const { - if (!H5Zfilter_avail(H5Z_FILTER_SZIP)) { - HDF5ErrMapper::ToException("Error setting szip property"); - } - - if (H5Pset_szip(hid, _options_mask, _pixels_per_block) < 0) { - HDF5ErrMapper::ToException("Error setting szip property"); - } -} - -inline Szip::Szip(unsigned int options_mask, unsigned int pixels_per_block) - : _options_mask(options_mask) - , _pixels_per_block(pixels_per_block) {} - -inline unsigned Szip::getOptionsMask() const { - return _options_mask; -} - -inline unsigned Szip::getPixelsPerBlock() const { - return _pixels_per_block; -} - -inline void Shuffle::apply(const hid_t hid) const { - if (!H5Zfilter_avail(H5Z_FILTER_SHUFFLE)) { - HDF5ErrMapper::ToException("Error setting shuffle property"); - } - - if (H5Pset_shuffle(hid) < 0) { - HDF5ErrMapper::ToException("Error setting shuffle property"); - } -} - -inline AllocationTime::AllocationTime(H5D_alloc_time_t alloc_time) - : _alloc_time(alloc_time) {} - -inline AllocationTime::AllocationTime(const DataSetCreateProps& dcpl) { - if (H5Pget_alloc_time(dcpl.getId(), &_alloc_time) < 0) { - HDF5ErrMapper::ToException("Error getting allocation time"); - } -} - -inline void AllocationTime::apply(hid_t dcpl) const { - if (H5Pset_alloc_time(dcpl, _alloc_time) < 0) { - HDF5ErrMapper::ToException("Error setting allocation time"); - } -} - -inline H5D_alloc_time_t AllocationTime::getAllocationTime() { - return _alloc_time; -} - -inline Caching::Caching(const DataSetCreateProps& dcpl) { - if (H5Pget_chunk_cache(dcpl.getId(), &_numSlots, &_cacheSize, &_w0) < 0) { - HDF5ErrMapper::ToException("Error getting dataset cache parameters"); - } -} - -inline void Caching::apply(const hid_t hid) const { - if (H5Pset_chunk_cache(hid, _numSlots, _cacheSize, _w0) < 0) { - HDF5ErrMapper::ToException("Error setting dataset cache parameters"); - } -} - -inline Caching::Caching(const size_t numSlots, const size_t cacheSize, const double w0) - : _numSlots(numSlots) - , _cacheSize(cacheSize) - , _w0(w0) {} - -inline size_t Caching::getNumSlots() const { - return _numSlots; -} - -inline size_t Caching::getCacheSize() const { - return _cacheSize; -} - -inline double Caching::getW0() const { - return _w0; -} - -inline CreateIntermediateGroup::CreateIntermediateGroup(bool create) - : _create(create) {} - -inline CreateIntermediateGroup::CreateIntermediateGroup(const ObjectCreateProps& ocpl) { - fromPropertyList(ocpl.getId()); -} - - -inline void CreateIntermediateGroup::apply(const hid_t hid) const { - if (H5Pset_create_intermediate_group(hid, _create ? 1 : 0) < 0) { - HDF5ErrMapper::ToException( - "Error setting property for create intermediate groups"); - } -} - -inline CreateIntermediateGroup::CreateIntermediateGroup(const LinkCreateProps& lcpl) { - fromPropertyList(lcpl.getId()); -} - -inline void CreateIntermediateGroup::fromPropertyList(hid_t hid) { - unsigned c_bool = 0; - if (H5Pget_create_intermediate_group(hid, &c_bool) < 0) { - HDF5ErrMapper::ToException( - "Error getting property for create intermediate groups"); - } - - _create = bool(c_bool); -} - -inline bool CreateIntermediateGroup::isSet() const { - return _create; -} - -#ifdef H5_HAVE_PARALLEL -inline UseCollectiveIO::UseCollectiveIO(bool enable) - : _enable(enable) {} - -inline void UseCollectiveIO::apply(const hid_t hid) const { - if (H5Pset_dxpl_mpio(hid, _enable ? H5FD_MPIO_COLLECTIVE : H5FD_MPIO_INDEPENDENT) < 0) { - HDF5ErrMapper::ToException("Error setting H5Pset_dxpl_mpio."); - } -} - -inline UseCollectiveIO::UseCollectiveIO(const DataTransferProps& dxpl) { - H5FD_mpio_xfer_t collective; - - if (H5Pget_dxpl_mpio(dxpl.getId(), &collective) < 0) { - HDF5ErrMapper::ToException("Error getting H5Pset_dxpl_mpio."); - } - - if (collective != H5FD_MPIO_COLLECTIVE && collective != H5FD_MPIO_INDEPENDENT) { - throw std::logic_error("H5Pget_dxpl_mpio returned something strange."); - } - - _enable = collective == H5FD_MPIO_COLLECTIVE; -} - -inline bool UseCollectiveIO::isCollective() const { - return _enable; -} - -inline MpioNoCollectiveCause::MpioNoCollectiveCause(const DataTransferProps& dxpl) { - if (H5Pget_mpio_no_collective_cause(dxpl.getId(), &_local_cause, &_global_cause) < 0) { - HDF5ErrMapper::ToException("Failed to check mpio_no_collective_cause."); - } -} - -inline bool MpioNoCollectiveCause::wasCollective() const { - return _local_cause == 0 && _global_cause == 0; -} - -inline uint32_t MpioNoCollectiveCause::getLocalCause() const { - return _local_cause; -} - -inline uint32_t MpioNoCollectiveCause::getGlobalCause() const { - return _global_cause; -} - -inline std::pair MpioNoCollectiveCause::getCause() const { - return {_local_cause, _global_cause}; -} -#endif - -inline LinkCreationOrder::LinkCreationOrder(const FileCreateProps& fcpl) { - fromPropertyList(fcpl.getId()); -} - -inline LinkCreationOrder::LinkCreationOrder(const GroupCreateProps& gcpl) { - fromPropertyList(gcpl.getId()); -} - -inline unsigned LinkCreationOrder::getFlags() const { - return _flags; -} - -inline void LinkCreationOrder::apply(const hid_t hid) const { - if (H5Pset_link_creation_order(hid, _flags) < 0) { - HDF5ErrMapper::ToException("Error setting LinkCreationOrder."); - } -} - -inline void LinkCreationOrder::fromPropertyList(hid_t hid) { - if (H5Pget_link_creation_order(hid, &_flags) < 0) { - HDF5ErrMapper::ToException( - "Error getting property for link creation order"); - } -} - -inline AttributePhaseChange::AttributePhaseChange(unsigned max_compact, unsigned min_dense) - : _max_compact(max_compact) - , _min_dense(min_dense) {} - -inline AttributePhaseChange::AttributePhaseChange(const GroupCreateProps& gcpl) { - if (H5Pget_attr_phase_change(gcpl.getId(), &_max_compact, &_min_dense) < 0) { - HDF5ErrMapper::ToException( - "Error getting property for attribute phase change"); - } -} - -inline unsigned AttributePhaseChange::max_compact() const { - return _max_compact; -} - -inline unsigned AttributePhaseChange::min_dense() const { - return _min_dense; -} - -inline void AttributePhaseChange::apply(hid_t hid) const { - if (H5Pset_attr_phase_change(hid, _max_compact, _min_dense) < 0) { - HDF5ErrMapper::ToException( - "Error getting property for attribute phase change"); - } -} - - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5ReadWrite_misc.hpp b/inst/include/highfive/bits/H5ReadWrite_misc.hpp deleted file mode 100644 index c8e7361..0000000 --- a/inst/include/highfive/bits/H5ReadWrite_misc.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2020 Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include "H5Utils.hpp" - -namespace HighFive { - -namespace details { - -template -using unqualified_t = typename std::remove_const::type>::type; - -// Find the type of an eventual char array, otherwise void -template -struct type_char_array { - using type = typename std::conditional< - std::is_same::base_type, std::string>::value, - std::string, - void>::type; - static constexpr bool is_char_array = false; -}; - -template -struct type_char_array { - using type = typename std::conditional, char>::value, - char*, - typename type_char_array::type>::type; - static constexpr bool is_char_array = true; -}; - -template -struct type_char_array { - using type = typename std::conditional, char>::value, - char[N], - typename type_char_array::type>::type; - static constexpr bool is_char_array = true; -}; - -template -struct BufferInfo { - using type_no_const = typename std::remove_const::type; - using elem_type = typename details::inspector::base_type; - using char_array_t = typename details::type_char_array::type; - static constexpr bool is_char_array = details::type_char_array::is_char_array; - - enum Operation { read, write }; - const Operation op; - - template - BufferInfo(const DataType& dtype, F getName, Operation _op); - - // member data for info depending on the destination dataset type - const bool is_fixed_len_string; - const size_t n_dimensions; - const DataType data_type; -}; - -// details implementation -template -struct string_type_checker { - static DataType getDataType(const DataType&, const DataType&); -}; - -inline void enforce_ascii_hack(const DataType& dst, const DataType& src) { - // Note: constness only refers to constness of the DataType object, which - // is just an ID, we can/will change properties of `dst`. - - // TEMP. CHANGE: Ensure that the character set is properly configured to prevent - // converter issues on HDF5 <=v1.12.0 when loading ASCII strings first. - // See https://github.com/HDFGroup/hdf5/issues/544 for further information. - if (H5Tget_cset(src.getId()) == H5T_CSET_ASCII) { - H5Tset_cset(dst.getId(), H5T_CSET_ASCII); - } -} - -template <> -struct string_type_checker { - inline static DataType getDataType(const DataType& element_type, const DataType& dtype) { - if (H5Tget_class(element_type.getId()) == H5T_STRING) { - enforce_ascii_hack(element_type, dtype); - } - return element_type; - } -}; - -template <> -struct string_type_checker { - inline static DataType getDataType(const DataType&, const DataType& file_datatype) { - // The StringBuffer ensures that the data is transformed such that it - // matches the datatype of the dataset, i.e. `file_datatype` and - // `mem_datatype` are the same. - return file_datatype; - } -}; - -template -struct string_type_checker { - inline static DataType getDataType(const DataType& element_type, const DataType& dtype) { - DataType return_type = (dtype.isFixedLenStr()) ? AtomicType() - : element_type; - enforce_ascii_hack(return_type, dtype); - return return_type; - } -}; - -template <> -struct string_type_checker { - inline static DataType getDataType(const DataType&, const DataType& dtype) { - if (dtype.isFixedLenStr()) { - throw DataSetException("Can't output variable-length to fixed-length strings"); - } - DataType return_type = AtomicType(); - enforce_ascii_hack(return_type, dtype); - return return_type; - } -}; - -template -template -BufferInfo::BufferInfo(const DataType& dtype, F getName, Operation _op) - : op(_op) - , is_fixed_len_string(dtype.isFixedLenStr()) - // In case we are using Fixed-len strings we need to subtract one dimension - , n_dimensions(details::inspector::recursive_ndim - - ((is_fixed_len_string && is_char_array) ? 1 : 0)) - , data_type( - string_type_checker::getDataType(create_datatype(), dtype)) { - // We warn. In case they are really not convertible an exception will rise on read/write - if (dtype.getClass() != data_type.getClass()) { - HIGHFIVE_LOG_WARN(getName() + "\": data and hdf5 dataset have different types: " + - data_type.string() + " -> " + dtype.string()); - } else if ((dtype.getClass() & data_type.getClass()) == DataTypeClass::Float) { - HIGHFIVE_LOG_WARN_IF( - (op == read) && (dtype.getSize() > data_type.getSize()), - getName() + "\": hdf5 dataset has higher floating point precision than data on read: " + - dtype.string() + " -> " + data_type.string()); - - HIGHFIVE_LOG_WARN_IF( - (op == write) && (dtype.getSize() < data_type.getSize()), - getName() + - "\": data has higher floating point precision than hdf5 dataset on write: " + - data_type.string() + " -> " + dtype.string()); - } -} - -} // namespace details - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Reference_misc.hpp b/inst/include/highfive/bits/H5Reference_misc.hpp deleted file mode 100644 index 7c8db36..0000000 --- a/inst/include/highfive/bits/H5Reference_misc.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c), 2020, EPFL - Blue Brain Project - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ - -#pragma once - -#include -#include - -#include "H5Utils.hpp" - -#include "../H5Object.hpp" - -namespace HighFive { - -inline Reference::Reference(const Object& location, const Object& object) - : parent_id(location.getId()) { - obj_name = details::get_name( - [&](char* buffer, size_t length) { return H5Iget_name(object.getId(), buffer, length); }); -} - -inline void Reference::create_ref(hobj_ref_t* refptr) const { - if (H5Rcreate(refptr, parent_id, obj_name.c_str(), H5R_OBJECT, -1) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to create the reference for \"") + obj_name + "\":"); - } -} - -inline ObjectType Reference::getType(const Object& location) const { - return get_ref(location).getType(); -} - -template -inline T Reference::dereference(const Object& location) const { - static_assert(std::is_same::value || std::is_same::value, - "We can only (de)reference HighFive::Group or HighFive:DataSet"); - auto obj = get_ref(location); - if (obj.getType() != T::type) { - HDF5ErrMapper::ToException("Trying to dereference the wrong type"); - } -#if defined __GNUC__ && __GNUC__ < 9 - return std::move(obj); -#else - return obj; -#endif -} - -inline Object Reference::get_ref(const Object& location) const { - hid_t res; -#if (H5Rdereference_vers == 2) - if ((res = H5Rdereference(location.getId(), H5P_DEFAULT, H5R_OBJECT, &href)) < 0) { - HDF5ErrMapper::ToException("Unable to dereference."); - } -#else - if ((res = H5Rdereference(location.getId(), H5R_OBJECT, &href)) < 0) { - HDF5ErrMapper::ToException("Unable to dereference."); - } -#endif - return Object(res); -} - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Selection_misc.hpp b/inst/include/highfive/bits/H5Selection_misc.hpp deleted file mode 100644 index c35b7bb..0000000 --- a/inst/include/highfive/bits/H5Selection_misc.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -namespace HighFive { - -inline Selection::Selection(const DataSpace& memspace, - const DataSpace& file_space, - const DataSet& set) - : _mem_space(memspace) - , _file_space(file_space) - , _set(set) {} - -inline DataSpace Selection::getSpace() const noexcept { - return _file_space; -} - -inline DataSpace Selection::getMemSpace() const noexcept { - return _mem_space; -} - -inline DataSet& Selection::getDataset() noexcept { - return _set; -} - -inline const DataSet& Selection::getDataset() const noexcept { - return _set; -} - -// Not only a shortcut but also for templated compat with H5Dataset -inline const DataType Selection::getDataType() const { - return _set.getDataType(); -} - -namespace detail { -inline Selection make_selection(const DataSpace& mem_space, - const DataSpace& file_space, - const DataSet& set) { - return Selection(mem_space, file_space, set); -} -} // namespace detail - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Slice_traits.hpp b/inst/include/highfive/bits/H5Slice_traits.hpp deleted file mode 100644 index 52c5271..0000000 --- a/inst/include/highfive/bits/H5Slice_traits.hpp +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include - -#include "H5_definitions.hpp" -#include "H5Utils.hpp" - -#include "../H5PropertyList.hpp" - -namespace HighFive { - -class ElementSet { - public: - /// - /// \brief Create a list of points of N-dimension for selection. - /// - /// \param list List of continuous coordinates (e.g.: in 2 dimensions space - /// `ElementSet{1, 2, 3 ,4}` creates points `(1, 2)` and `(3, 4)`). - explicit ElementSet(std::initializer_list list); - /// - /// \brief Create a list of points of N-dimension for selection. - /// - /// \param list List of N-dim points. - explicit ElementSet(std::initializer_list> list); - /// - /// \brief Create a list of points of N-dimension for selection. - /// - /// \param element_ids List of continuous coordinates (e.g.: in 2 dimensions space - /// `ElementSet{1, 2, 3 ,4}` creates points `(1, 2)` and `(3, 4)`). - explicit ElementSet(const std::vector& element_ids); - /// - /// \brief Create a list of points of N-dimension for selection. - /// - /// \param element_ids List of N-dim points. - explicit ElementSet(const std::vector>& element_ids); - - private: - std::vector _ids; - - template - friend class SliceTraits; -}; - -namespace detail { - -template -inline std::vector convertSizeVector(const std::vector& from) { - std::vector to(from.size()); - std::copy(from.cbegin(), from.cend(), to.begin()); - - return to; -} -} // namespace detail - -inline std::vector toHDF5SizeVector(const std::vector& from) { - return detail::convertSizeVector(from); -} - -inline std::vector toSTLSizeVector(const std::vector& from) { - return detail::convertSizeVector(from); -} - -struct RegularHyperSlab { - RegularHyperSlab() = default; - - RegularHyperSlab(std::vector offset_, - std::vector count_ = {}, - std::vector stride_ = {}, - std::vector block_ = {}) - : offset(toHDF5SizeVector(offset_)) - , count(toHDF5SizeVector(count_)) - , stride(toHDF5SizeVector(stride_)) - , block(toHDF5SizeVector(block_)) {} - - static RegularHyperSlab fromHDF5Sizes(std::vector offset_, - std::vector count_ = {}, - std::vector stride_ = {}, - std::vector block_ = {}) { - RegularHyperSlab slab; - slab.offset = offset_; - slab.count = count_; - slab.stride = stride_; - slab.block = block_; - - return slab; - } - - size_t rank() const { - return std::max(std::max(offset.size(), count.size()), - std::max(stride.size(), block.size())); - } - - /// Dimensions when all gaps are removed. - std::vector packedDims() const { - auto n_dims = rank(); - auto dims = std::vector(n_dims, 0); - - for (size_t i = 0; i < n_dims; ++i) { - dims[i] = count[i] * (block.empty() ? 1 : block[i]); - } - - return dims; - } - - std::vector offset; - std::vector count; - std::vector stride; - std::vector block; -}; - -class HyperSlab { - public: - HyperSlab() { - selects.emplace_back(RegularHyperSlab{}, Op::None); - }; - - explicit HyperSlab(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::Set); - } - - HyperSlab operator|(const RegularHyperSlab& sel) const { - auto ret = *this; - ret |= sel; - return ret; - } - - HyperSlab& operator|=(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::Or); - return *this; - } - - HyperSlab operator&(const RegularHyperSlab& sel) const { - auto ret = *this; - ret &= sel; - return ret; - } - - HyperSlab& operator&=(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::And); - return *this; - } - - HyperSlab operator^(const RegularHyperSlab& sel) const { - auto ret = *this; - ret ^= sel; - return ret; - } - - HyperSlab& operator^=(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::Xor); - return *this; - } - - HyperSlab& notA(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::NotA); - return *this; - } - - HyperSlab& notB(const RegularHyperSlab& sel) { - selects.emplace_back(sel, Op::NotB); - return *this; - } - - DataSpace apply(const DataSpace& space_) const { - auto space = space_.clone(); - for (const auto& sel: selects) { - if (sel.op == Op::None) { - H5Sselect_none(space.getId()); - } else { - auto error_code = - H5Sselect_hyperslab(space.getId(), - convert(sel.op), - sel.offset.empty() ? nullptr : sel.offset.data(), - sel.stride.empty() ? nullptr : sel.stride.data(), - sel.count.empty() ? nullptr : sel.count.data(), - sel.block.empty() ? nullptr : sel.block.data()); - - if (error_code < 0) { - HDF5ErrMapper::ToException("Unable to select hyperslab"); - } - } - } - return space; - } - - private: - enum class Op { - Noop, - Set, - Or, - And, - Xor, - NotB, - NotA, - Append, - Prepend, - Invalid, - None, - }; - - H5S_seloper_t convert(Op op) const { - switch (op) { - case Op::Noop: - return H5S_SELECT_NOOP; - case Op::Set: - return H5S_SELECT_SET; - case Op::Or: - return H5S_SELECT_OR; - case Op::And: - return H5S_SELECT_AND; - case Op::Xor: - return H5S_SELECT_XOR; - case Op::NotB: - return H5S_SELECT_NOTB; - case Op::NotA: - return H5S_SELECT_NOTA; - case Op::Append: - return H5S_SELECT_APPEND; - case Op::Prepend: - return H5S_SELECT_PREPEND; - case Op::Invalid: - return H5S_SELECT_INVALID; - default: - throw DataSpaceException("Invalid HyperSlab operation."); - } - } - - struct Select_: public RegularHyperSlab { - Select_(const RegularHyperSlab& sel, Op op_) - : RegularHyperSlab(sel) - , op(op_) {} - - Op op; - }; - - std::vector selects; -}; - -template -class SliceTraits { - public: - /// - /// \brief Select an \p hyperslab in the current Slice/Dataset. - /// - /// HyperSlabs can be either regular or irregular. Irregular hyperslabs are typically generated - /// by taking the union of regular hyperslabs. An irregular hyperslab, in general, does not fit - /// nicely into a multi-dimensional array, but only a subset of such an array. - /// - /// Therefore, the only memspaces supported for general hyperslabs are one-dimensional arrays. - Selection select(const HyperSlab& hyperslab) const; - - /// - /// \brief Select an \p hyperslab in the current Slice/Dataset. - /// - /// If the selection can be read into a simple, multi-dimensional dataspace, - /// then this overload enable specifying the shape of the memory dataspace - /// with `memspace`. Note, that simple implies no offsets, strides or - /// number of blocks, just the size of the block in each dimension. - Selection select(const HyperSlab& hyperslab, const DataSpace& memspace) const; - - /// - /// \brief Select a region in the current Slice/Dataset of \p count points at - /// \p offset separated by \p stride. If strides are not provided they will - /// default to 1 in all dimensions. - /// - /// vector offset and count have to be from the same dimension - /// - Selection select(const std::vector& offset, - const std::vector& count, - const std::vector& stride = {}, - const std::vector& block = {}) const; - - /// - /// \brief Select a set of columns in the last dimension of this dataset. - /// - /// The column indices must be smaller than the dimension size. - /// - Selection select(const std::vector& columns) const; - - /// - /// \brief Select a region in the current Slice/Dataset out of a list of elements. - /// - Selection select(const ElementSet& elements) const; - - template - T read(const DataTransferProps& xfer_props = DataTransferProps()) const; - - /// - /// Read the entire dataset into a buffer - /// An exception is raised is if the numbers of dimension of the buffer and - /// of the dataset are different. - /// - /// The array type can be a N-pointer or a N-vector. For plain pointers - /// not dimensionality checking will be performed, it is the user's - /// responsibility to ensure that the right amount of space has been - /// allocated. - template - void read(T& array, const DataTransferProps& xfer_props = DataTransferProps()) const; - - /// - /// Read the entire dataset into a raw buffer - /// - /// No dimensionality checks will be performed, it is the user's - /// responsibility to ensure that the right amount of space has been - /// allocated. - /// \param array: A buffer containing enough space for the data - /// \param dtype: The type of the data, in case it cannot be automatically guessed - /// \param xfer_props: Data Transfer properties - template - void read(T* array, - const DataType& dtype, - const DataTransferProps& xfer_props = DataTransferProps()) const; - - /// - /// Read the entire dataset into a raw buffer - /// - /// Same as `read(T*, const DataType&, const DataTransferProps&)`. However, - /// this overload deduces the HDF5 datatype of the element of `array` from - /// `T`. Note, that the file datatype is already fixed. - /// - /// \param array: A buffer containing enough space for the data - /// \param xfer_props: Data Transfer properties - template - void read(T* array, const DataTransferProps& xfer_props = DataTransferProps()) const; - - /// - /// Write the integrality N-dimension buffer to this dataset - /// An exception is raised is if the numbers of dimension of the buffer and - /// of the dataset are different - /// - /// The array type can be a N-pointer or a N-vector ( e.g int** integer two - /// dimensional array ) - template - void write(const T& buffer, const DataTransferProps& xfer_props = DataTransferProps()); - - /// - /// Write from a raw pointer into this dataset. - /// - /// No dimensionality checks will be performed, it is the user's - /// responsibility to ensure that the buffer holds the right amount of - /// elements. For n-dimensional matrices the buffer layout follows H5 - /// default conventions. - /// - /// Note, this is the shallowest wrapper around `H5Dwrite` and should - /// be used if full control is needed. Generally prefer `write`. - /// - /// \param buffer: A buffer containing the data to be written - /// \param dtype: The datatype of `buffer`, i.e. the memory data type. - /// \param xfer_props: The HDF5 data transfer properties, e.g. collective MPI-IO. - template - void write_raw(const T* buffer, - const DataType& mem_datatype, - const DataTransferProps& xfer_props = DataTransferProps()); - - /// - /// Write from a raw pointer into this dataset. - /// - /// Same as `write_raw(const T*, const DataTransferProps&)`. However, this - /// overload attempts to guess the data type of `buffer`, i.e. the memory - /// datatype. Note that the file datatype is already fixed. - /// - template - void write_raw(const T* buffer, const DataTransferProps& xfer_props = DataTransferProps()); -}; - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Slice_traits_misc.hpp b/inst/include/highfive/bits/H5Slice_traits_misc.hpp deleted file mode 100644 index 7b07c9a..0000000 --- a/inst/include/highfive/bits/H5Slice_traits_misc.hpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "H5ReadWrite_misc.hpp" -#include "H5Converter_misc.hpp" - -namespace HighFive { - -namespace details { - -// map the correct reference to the dataset depending of the layout -// dataset -> itself -// subselection -> parent dataset -inline const DataSet& get_dataset(const Selection& sel) { - return sel.getDataset(); -} - -inline const DataSet& get_dataset(const DataSet& ds) { - return ds; -} - -// map the correct memspace identifier depending of the layout -// dataset -> entire memspace -// selection -> resolve space id -inline hid_t get_memspace_id(const Selection& ptr) { - return ptr.getMemSpace().getId(); -} - -inline hid_t get_memspace_id(const DataSet&) { - return H5S_ALL; -} -} // namespace details - -inline ElementSet::ElementSet(std::initializer_list list) - : _ids(list) {} - -inline ElementSet::ElementSet(std::initializer_list> list) - : ElementSet(std::vector>(list)) {} - -inline ElementSet::ElementSet(const std::vector& element_ids) - : _ids(element_ids) {} - -inline ElementSet::ElementSet(const std::vector>& element_ids) { - for (const auto& vec: element_ids) { - std::copy(vec.begin(), vec.end(), std::back_inserter(_ids)); - } -} - -template -inline Selection SliceTraits::select(const HyperSlab& hyperslab, - const DataSpace& memspace) const { - // Note: The current limitation are that memspace must describe a - // packed memspace. - // - // The reason for this is that we're unable to unpack general - // hyperslabs when the memory is not contiguous, e.g. - // `std::vector>`. - const auto& slice = static_cast(*this); - auto filespace = hyperslab.apply(slice.getSpace()); - - return detail::make_selection(memspace, filespace, details::get_dataset(slice)); -} - -template -inline Selection SliceTraits::select(const HyperSlab& hyper_slab) const { - const auto& slice = static_cast(*this); - auto filespace = slice.getSpace(); - filespace = hyper_slab.apply(filespace); - - auto n_elements = H5Sget_select_npoints(filespace.getId()); - auto memspace = DataSpace(std::array{size_t(n_elements)}); - - return detail::make_selection(memspace, filespace, details::get_dataset(slice)); -} - - -template -inline Selection SliceTraits::select(const std::vector& offset, - const std::vector& count, - const std::vector& stride, - const std::vector& block) const { - auto slab = HyperSlab(RegularHyperSlab(offset, count, stride, block)); - auto memspace = DataSpace(count); - return select(slab, memspace); -} - -template -inline Selection SliceTraits::select(const std::vector& columns) const { - const auto& slice = static_cast(*this); - const DataSpace& space = slice.getSpace(); - std::vector dims = space.getDimensions(); - - std::vector counts = dims; - counts.back() = 1; - - std::vector offsets(dims.size(), 0); - - HyperSlab slab; - for (const auto& column: columns) { - offsets.back() = column; - slab |= RegularHyperSlab(offsets, counts); - } - - std::vector memdims = dims; - memdims.back() = columns.size(); - - return select(slab, DataSpace(memdims)); -} - -template -inline Selection SliceTraits::select(const ElementSet& elements) const { - const auto& slice = static_cast(*this); - const hsize_t* data = nullptr; - const DataSpace space = slice.getSpace().clone(); - const std::size_t length = elements._ids.size(); - if (length % space.getNumberDimensions() != 0) { - throw DataSpaceException( - "Number of coordinates in elements picking " - "should be a multiple of the dimensions."); - } - const std::size_t num_elements = length / space.getNumberDimensions(); - std::vector raw_elements; - - // optimised at compile time - // switch for data conversion on 32bits platforms - if (std::is_same::value) { - // `if constexpr` can't be used, thus a reinterpret_cast is needed. - data = reinterpret_cast(&(elements._ids[0])); - } else { - raw_elements.resize(length); - std::copy(elements._ids.begin(), elements._ids.end(), raw_elements.begin()); - data = raw_elements.data(); - } - - if (H5Sselect_elements(space.getId(), H5S_SELECT_SET, num_elements, data) < 0) { - HDF5ErrMapper::ToException("Unable to select elements"); - } - - return detail::make_selection(DataSpace(num_elements), space, details::get_dataset(slice)); -} - - -template -template -inline T SliceTraits::read(const DataTransferProps& xfer_props) const { - T array; - read(array, xfer_props); - return array; -} - - -template -template -inline void SliceTraits::read(T& array, const DataTransferProps& xfer_props) const { - const auto& slice = static_cast(*this); - const DataSpace& mem_space = slice.getMemSpace(); - - auto file_datatype = slice.getDataType(); - - const details::BufferInfo buffer_info( - file_datatype, - [&slice]() -> std::string { return details::get_dataset(slice).getPath(); }, - details::BufferInfo::Operation::read); - - if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) { - std::ostringstream ss; - ss << "Impossible to read DataSet of dimensions " << mem_space.getNumberDimensions() - << " into arrays of dimensions " << buffer_info.n_dimensions; - throw DataSpaceException(ss.str()); - } - auto dims = mem_space.getDimensions(); - - if (mem_space.getElementCount() == 0) { - auto effective_dims = details::squeezeDimensions(dims, - details::inspector::recursive_ndim); - - details::inspector::prepare(array, effective_dims); - return; - } - - auto r = details::data_converter::get_reader(dims, array, file_datatype); - read(r.getPointer(), buffer_info.data_type, xfer_props); - // re-arrange results - r.unserialize(array); - - auto t = buffer_info.data_type; - auto c = t.getClass(); - if (c == DataTypeClass::VarLen || t.isVariableStr()) { -#if H5_VERSION_GE(1, 12, 0) - // This one have been created in 1.12.0 - (void) H5Treclaim(t.getId(), mem_space.getId(), xfer_props.getId(), r.getPointer()); -#else - // This one is deprecated since 1.12.0 - (void) H5Dvlen_reclaim(t.getId(), mem_space.getId(), xfer_props.getId(), r.getPointer()); -#endif - } -} - - -template -template -inline void SliceTraits::read(T* array, - const DataType& mem_datatype, - const DataTransferProps& xfer_props) const { - static_assert(!std::is_const::value, - "read() requires a non-const structure to read data into"); - - const auto& slice = static_cast(*this); - - if (H5Dread(details::get_dataset(slice).getId(), - mem_datatype.getId(), - details::get_memspace_id(slice), - slice.getSpace().getId(), - xfer_props.getId(), - static_cast(array)) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Read."); - } -} - -template -template -inline void SliceTraits::read(T* array, const DataTransferProps& xfer_props) const { - using element_type = typename details::inspector::base_type; - const DataType& mem_datatype = create_and_check_datatype(); - - read(array, mem_datatype, xfer_props); -} - - -template -template -inline void SliceTraits::write(const T& buffer, const DataTransferProps& xfer_props) { - const auto& slice = static_cast(*this); - const DataSpace& mem_space = slice.getMemSpace(); - - if (mem_space.getElementCount() == 0) { - return; - } - - auto file_datatype = slice.getDataType(); - - const details::BufferInfo buffer_info( - file_datatype, - [&slice]() -> std::string { return details::get_dataset(slice).getPath(); }, - details::BufferInfo::Operation::write); - - if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) { - std::ostringstream ss; - ss << "Impossible to write buffer of dimensions " - << details::format_vector(mem_space.getDimensions()) - << " into dataset with n = " << buffer_info.n_dimensions << " dimensions."; - throw DataSpaceException(ss.str()); - } - auto w = details::data_converter::serialize(buffer, file_datatype); - write_raw(w.getPointer(), buffer_info.data_type, xfer_props); -} - - -template -template -inline void SliceTraits::write_raw(const T* buffer, - const DataType& mem_datatype, - const DataTransferProps& xfer_props) { - const auto& slice = static_cast(*this); - - if (H5Dwrite(details::get_dataset(slice).getId(), - mem_datatype.getId(), - details::get_memspace_id(slice), - slice.getSpace().getId(), - xfer_props.getId(), - static_cast(buffer)) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Write: "); - } -} - -template -template -inline void SliceTraits::write_raw(const T* buffer, const DataTransferProps& xfer_props) { - using element_type = typename details::inspector::base_type; - const auto& mem_datatype = create_and_check_datatype(); - - write_raw(buffer, mem_datatype, xfer_props); -} - - -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5Utils.hpp b/inst/include/highfive/bits/H5Utils.hpp deleted file mode 100644 index 2d9d24f..0000000 --- a/inst/include/highfive/bits/H5Utils.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -// internal utilities functions -#include -#include -#include // __GLIBCXX__ -#include -#include -#include -#include -#include - -#include - -#include "../H5Exception.hpp" -#include "H5Friends.hpp" - -namespace HighFive { - -// If ever used, recognize dimensions of FixedLenStringArray -template -class FixedLenStringArray; - -namespace details { -// converter function for hsize_t -> size_t when hsize_t != size_t -template -inline std::vector to_vector_size_t(const std::vector& vec) { - static_assert(std::is_same::value == false, - " hsize_t != size_t mandatory here"); - std::vector res(vec.size()); - std::transform(vec.cbegin(), vec.cend(), res.begin(), [](Size e) { - return static_cast(e); - }); - return res; -} - -// converter function for hsize_t -> size_t when size_t == hsize_t -inline std::vector to_vector_size_t(const std::vector& vec) { - return vec; -} - -// read name from a H5 object using the specified function -template -inline std::string get_name(T fct) { - const size_t maxLength = 255; - char buffer[maxLength + 1]; - ssize_t retcode = fct(buffer, static_cast(maxLength) + 1); - if (retcode < 0) { - HDF5ErrMapper::ToException("Error accessing object name"); - } - const size_t length = static_cast(retcode); - if (length <= maxLength) { - return std::string(buffer, length); - } - std::vector bigBuffer(length + 1, 0); - fct(bigBuffer.data(), length + 1); - return std::string(bigBuffer.data(), length); -} - -template -inline std::string format_vector(const Container& container) { - auto sout = std::stringstream{}; - - sout << "[ "; - for (size_t i = 0; i < container.size(); ++i) { - sout << container[i] << (i == container.size() - 1 ? "" : ", "); - } - sout << "]"; - - return sout.str(); -} - -} // namespace details -} // namespace HighFive diff --git a/inst/include/highfive/bits/H5_definitions.hpp b/inst/include/highfive/bits/H5_definitions.hpp deleted file mode 100644 index 746723c..0000000 --- a/inst/include/highfive/bits/H5_definitions.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#if defined(__GNUC__) || defined(__clang__) -#define H5_DEPRECATED(msg) __attribute__((deprecated(#msg))) -#elif defined(_MSC_VER) -#define H5_DEPRECATED(msg) __declspec(deprecated(#msg)) -#else -#pragma message("WARNING: Compiler doesnt support deprecation") -#define H5_DEPRECATED(msg) -#endif - - -// Forward declarations - -namespace HighFive { - -enum class LinkType; -enum class ObjectType; -enum class PropertyType; - -class Attribute; -class DataSet; -class DataSpace; -class DataType; -class Exception; -class File; -class FileDriver; -class Group; -class Object; -class ObjectInfo; -class Reference; -class Selection; -class SilenceHDF5; - -template -class AtomicType; - -template -class AnnotateTraits; - -template -class FixedLenStringArray; - -template -class NodeTraits; - -template -class PropertyList; - -} // namespace HighFive diff --git a/inst/include/highfive/bits/string_padding.hpp b/inst/include/highfive/bits/string_padding.hpp deleted file mode 100644 index e6e6908..0000000 --- a/inst/include/highfive/bits/string_padding.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace HighFive { - -enum class StringPadding : std::underlying_type::type { - NullTerminated = H5T_STR_NULLTERM, - NullPadded = H5T_STR_NULLPAD, - SpacePadded = H5T_STR_SPACEPAD -}; - - -} diff --git a/inst/include/highfive/h5easy_bits/H5Easy_Eigen.hpp b/inst/include/highfive/h5easy_bits/H5Easy_Eigen.hpp deleted file mode 100644 index 5b5d3b9..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_Eigen.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" -#include "H5Easy_misc.hpp" -#include "H5Easy_scalar.hpp" - -#ifdef H5_USE_EIGEN - -namespace H5Easy { - -namespace detail { - -template -struct io_impl, T>::value>::type> { - // abbreviate row-major <-> col-major conversions - template - struct types { - using row_major = Eigen::Ref< - const Eigen::Array::type::Scalar, - std::decay::type::RowsAtCompileTime, - std::decay::type::ColsAtCompileTime, - std::decay::type::ColsAtCompileTime == 1 ? Eigen::ColMajor - : Eigen::RowMajor, - std::decay::type::MaxRowsAtCompileTime, - std::decay::type::MaxColsAtCompileTime>, - 0, - Eigen::InnerStride<1>>; - - using col_major = - Eigen::Map::type::Scalar, - std::decay::type::RowsAtCompileTime, - std::decay::type::ColsAtCompileTime, - std::decay::type::ColsAtCompileTime == 1 ? Eigen::ColMajor - : Eigen::RowMajor, - std::decay::type::MaxRowsAtCompileTime, - std::decay::type::MaxColsAtCompileTime>>; - }; - - // return the shape of Eigen::DenseBase object as size 1 or 2 "std::vector" - inline static std::vector shape(const T& data) { - if (std::decay::type::RowsAtCompileTime == 1) { - return {static_cast(data.cols())}; - } - if (std::decay::type::ColsAtCompileTime == 1) { - return {static_cast(data.rows())}; - } - return {static_cast(data.rows()), static_cast(data.cols())}; - } - - using EigenIndex = Eigen::DenseIndex; - - // get the shape of a "DataSet" as size 2 "std::vector" - template - inline static std::vector shape(const File& file, - const std::string& path, - const D& dataset, - int RowsAtCompileTime) { - std::vector dims = dataset.getDimensions(); - - if (dims.size() == 1 && RowsAtCompileTime == 1) { - return std::vector{1u, static_cast(dims[0])}; - } - if (dims.size() == 1) { - return std::vector{static_cast(dims[0]), 1u}; - } - if (dims.size() == 2) { - return std::vector{static_cast(dims[0]), - static_cast(dims[1])}; - } - - throw detail::error(file, path, "H5Easy::load: Inconsistent rank"); - } - - inline static DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - using row_major_type = typename types::row_major; - using value_type = typename std::decay::type::Scalar; - row_major_type row_major(data); - DataSet dataset = initDataset(file, path, shape(data), options); - dataset.write_raw(row_major.data()); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load(const File& file, const std::string& path) { - DataSet dataset = file.getDataSet(path); - std::vector dims = shape(file, path, dataset, T::RowsAtCompileTime); - T data(dims[0], dims[1]); - dataset.read(data.data()); - if (data.IsVectorAtCompileTime || data.IsRowMajor) { - return data; - } - using col_major = typename types::col_major; - return col_major(data.data(), dims[0], dims[1]); - } - - inline static Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - using row_major_type = typename types::row_major; - using value_type = typename std::decay::type::Scalar; - row_major_type row_major(data); - Attribute attribute = initAttribute(file, path, key, shape(data), options); - attribute.write_raw(row_major.data()); - if (options.flush()) { - file.flush(); - } - return attribute; - } - - inline static T loadAttribute(const File& file, - const std::string& path, - const std::string& key) { - DataSet dataset = file.getDataSet(path); - Attribute attribute = dataset.getAttribute(key); - DataSpace dataspace = attribute.getSpace(); - std::vector dims = shape(file, path, dataspace, T::RowsAtCompileTime); - T data(dims[0], dims[1]); - attribute.read(data.data()); - if (data.IsVectorAtCompileTime || data.IsRowMajor) { - return data; - } - using col_major = typename types::col_major; - return col_major(data.data(), dims[0], dims[1]); - } -}; - -} // namespace detail -} // namespace H5Easy - -#endif // H5_USE_EIGEN diff --git a/inst/include/highfive/h5easy_bits/H5Easy_misc.hpp b/inst/include/highfive/h5easy_bits/H5Easy_misc.hpp deleted file mode 100644 index 69798b2..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_misc.hpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" - -namespace H5Easy { - -namespace detail { - -// Generate error-stream and return "Exception" (not yet thrown). -inline Exception error(const File& file, const std::string& path, const std::string& message) { - std::ostringstream ss; - ss << message << std::endl - << "Path: " << path << std::endl - << "Filename: " << file.getName() << std::endl; - return Exception(ss.str()); -} - -// Generate specific dump error -inline Exception dump_error(File& file, const std::string& path) { - if (file.getObjectType(path) == ObjectType::Dataset) { - return error(file, - path, - "H5Easy: Dataset already exists, dump with H5Easy::DumpMode::Overwrite " - "to overwrite (with an array of the same shape)."); - } else { - return error( - file, - path, - "H5Easy: path exists, but does not correspond to a Dataset. Dump not possible."); - } -} - -// get a opened DataSet: nd-array -template -inline DataSet initDataset(File& file, - const std::string& path, - const std::vector& shape, - const DumpOptions& options) { - if (!file.exist(path)) { - if (!options.compress() && !options.isChunked()) { - return file.createDataSet(path, DataSpace(shape), {}, {}, true); - } else { - std::vector chunks(shape.begin(), shape.end()); - if (options.isChunked()) { - chunks = options.getChunkSize(); - if (chunks.size() != shape.size()) { - throw error(file, path, "H5Easy::dump: Incorrect rank ChunkSize"); - } - } - DataSetCreateProps props; - props.add(Chunking(chunks)); - if (options.compress()) { - props.add(Shuffle()); - props.add(Deflate(options.getCompressionLevel())); - } - return file.createDataSet(path, DataSpace(shape), props, {}, true); - } - } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) { - DataSet dataset = file.getDataSet(path); - if (dataset.getDimensions() != shape) { - throw error(file, path, "H5Easy::dump: Inconsistent dimensions"); - } - return dataset; - } - throw dump_error(file, path); -} - -// get a opened DataSet: scalar -template -inline DataSet initScalarDataset(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - if (!file.exist(path)) { - return file.createDataSet(path, DataSpace::From(data), {}, {}, true); - } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) { - DataSet dataset = file.getDataSet(path); - if (dataset.getElementCount() != 1) { - throw error(file, path, "H5Easy::dump: Existing field not a scalar"); - } - return dataset; - } - throw dump_error(file, path); -} - -// get a opened Attribute: nd-array -template -inline Attribute initAttribute(File& file, - const std::string& path, - const std::string& key, - const std::vector& shape, - const DumpOptions& options) { - if (!file.exist(path)) { - throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist"); - } - if (file.getObjectType(path) != ObjectType::Dataset) { - throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet"); - } - DataSet dataset = file.getDataSet(path); - if (!dataset.hasAttribute(key)) { - return dataset.createAttribute(key, DataSpace(shape)); - } else if (options.overwrite()) { - Attribute attribute = dataset.getAttribute(key); - DataSpace dataspace = attribute.getSpace(); - if (dataspace.getDimensions() != shape) { - throw error(file, path, "H5Easy::dumpAttribute: Inconsistent dimensions"); - } - return attribute; - } - throw error(file, - path, - "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite."); -} - -// get a opened Attribute: scalar -template -inline Attribute initScalarAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - if (!file.exist(path)) { - throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist"); - } - if (file.getObjectType(path) != ObjectType::Dataset) { - throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet"); - } - DataSet dataset = file.getDataSet(path); - if (!dataset.hasAttribute(key)) { - return dataset.createAttribute(key, DataSpace::From(data)); - } else if (options.overwrite()) { - Attribute attribute = dataset.getAttribute(key); - DataSpace dataspace = attribute.getSpace(); - if (dataspace.getElementCount() != 1) { - throw error(file, path, "H5Easy::dumpAttribute: Existing field not a scalar"); - } - return attribute; - } - throw error(file, - path, - "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite."); -} - -} // namespace detail -} // namespace H5Easy diff --git a/inst/include/highfive/h5easy_bits/H5Easy_opencv.hpp b/inst/include/highfive/h5easy_bits/H5Easy_opencv.hpp deleted file mode 100644 index b640cd8..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_opencv.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" -#include "H5Easy_misc.hpp" -#include "H5Easy_scalar.hpp" - -#ifdef H5_USE_OPENCV - -namespace H5Easy { - -namespace detail { - -template -struct is_opencv: std::false_type {}; -template -struct is_opencv>: std::true_type {}; - -template -struct io_impl::value>::type> { - inline static std::vector shape(const T& data) { - return std::vector{static_cast(data.rows), static_cast(data.cols)}; - } - - inline static std::vector shape(const File& file, - const std::string& path, - std::vector dims) { - if (dims.size() == 1) { - return std::vector{static_cast(dims[0]), 1ul}; - } - if (dims.size() == 2) { - return std::vector{static_cast(dims[0]), static_cast(dims[1])}; - } - - throw detail::error(file, path, "H5Easy::load: Inconsistent rank"); - } - - inline static DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - using value_type = typename T::value_type; - DataSet dataset = initDataset(file, path, shape(data), options); - std::vector v(data.begin(), data.end()); - dataset.write_raw(v.data()); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load(const File& file, const std::string& path) { - using value_type = typename T::value_type; - DataSet dataset = file.getDataSet(path); - std::vector dims = shape(file, path, dataset.getDimensions()); - T data(dims[0], dims[1]); - dataset.read(reinterpret_cast(data.data)); - return data; - } - - inline static Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - using value_type = typename T::value_type; - Attribute attribute = initAttribute(file, path, key, shape(data), options); - std::vector v(data.begin(), data.end()); - attribute.write_raw(v.data()); - if (options.flush()) { - file.flush(); - } - return attribute; - } - - inline static T loadAttribute(const File& file, - const std::string& path, - const std::string& key) { - using value_type = typename T::value_type; - DataSet dataset = file.getDataSet(path); - Attribute attribute = dataset.getAttribute(key); - DataSpace dataspace = attribute.getSpace(); - std::vector dims = shape(file, path, dataspace.getDimensions()); - T data(dims[0], dims[1]); - attribute.read(reinterpret_cast(data.data)); - return data; - } -}; - -} // namespace detail -} // namespace H5Easy - -#endif // H5_USE_OPENCV diff --git a/inst/include/highfive/h5easy_bits/H5Easy_public.hpp b/inst/include/highfive/h5easy_bits/H5Easy_public.hpp deleted file mode 100644 index 2cc55d0..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_public.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" - -namespace H5Easy { - -inline Compression::Compression(bool enable) { - if (enable) { - m_compression_level = 9; - } else { - m_compression_level = 0; - } -} - -template -inline Compression::Compression(T level) - : m_compression_level(static_cast(level)) {} - -inline unsigned Compression::get() const { - return m_compression_level; -} - -inline void DumpOptions::set(DumpMode mode) { - m_overwrite = static_cast(mode); -} - -inline void DumpOptions::set(Flush mode) { - m_flush = static_cast(mode); -} - -inline void DumpOptions::set(const Compression& level) { - m_compression_level = level.get(); -} - -template -inline void DumpOptions::set(T arg, Args... args) { - set(arg); - set(args...); -} - -template -inline void DumpOptions::setChunkSize(const std::vector& shape) { - m_chunk_size = std::vector(shape.begin(), shape.end()); -} - -inline void DumpOptions::setChunkSize(std::initializer_list shape) { - m_chunk_size = std::vector(shape.begin(), shape.end()); -} - -inline bool DumpOptions::overwrite() const { - return m_overwrite; -} - -inline bool DumpOptions::flush() const { - return m_flush; -} - -inline bool DumpOptions::compress() const { - return m_compression_level > 0; -} - -inline unsigned DumpOptions::getCompressionLevel() const { - return m_compression_level; -} - -inline bool DumpOptions::isChunked() const { - return m_chunk_size.size() > 0; -} - -inline std::vector DumpOptions::getChunkSize() const { - return m_chunk_size; -} - -inline size_t getSize(const File& file, const std::string& path) { - return file.getDataSet(path).getElementCount(); -} - -inline std::vector getShape(const File& file, const std::string& path) { - return file.getDataSet(path).getDimensions(); -} - -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - return detail::io_impl::dump(file, path, data, options); -} - -template -inline DataSet dump(File& file, const std::string& path, const T& data, DumpMode mode) { - return detail::io_impl::dump(file, path, data, DumpOptions(mode)); -} - -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::vector& idx, - const DumpOptions& options) { - return detail::io_impl::dump_extend(file, path, data, idx, options); -} - -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::initializer_list& idx, - const DumpOptions& options) { - return detail::io_impl::dump_extend(file, path, data, idx, options); -} - -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::vector& idx) { - return detail::io_impl::dump_extend(file, path, data, idx, DumpOptions()); -} - -template -inline DataSet dump(File& file, - const std::string& path, - const T& data, - const std::initializer_list& idx) { - return detail::io_impl::dump_extend(file, path, data, idx, DumpOptions()); -} - -template -inline T load(const File& file, const std::string& path, const std::vector& idx) { - return detail::io_impl::load_part(file, path, idx); -} - -template -inline T load(const File& file, const std::string& path) { - return detail::io_impl::load(file, path); -} - -template -inline Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - DumpMode mode) { - return detail::io_impl::dumpAttribute(file, path, key, data, DumpOptions(mode)); -} - -template -inline Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - return detail::io_impl::dumpAttribute(file, path, key, data, options); -} - -template -inline T loadAttribute(const File& file, const std::string& path, const std::string& key) { - return detail::io_impl::loadAttribute(file, path, key); -} - -} // namespace H5Easy diff --git a/inst/include/highfive/h5easy_bits/H5Easy_scalar.hpp b/inst/include/highfive/h5easy_bits/H5Easy_scalar.hpp deleted file mode 100644 index 056d8f2..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_scalar.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" -#include "H5Easy_misc.hpp" - -namespace H5Easy { - -namespace detail { - -/* -Base template for partial specialization: the fallback if specialized templates don't match. -Used e.g. for scalars. -*/ -template -struct io_impl { - inline static DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - DataSet dataset = initScalarDataset(file, path, data, options); - dataset.write(data); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load(const File& file, const std::string& path) { - DataSet dataset = file.getDataSet(path); - T data; - dataset.read(data); - return data; - } - - inline static Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - Attribute attribute = initScalarAttribute(file, path, key, data, options); - attribute.write(data); - if (options.flush()) { - file.flush(); - } - return attribute; - } - - inline static T loadAttribute(const File& file, - const std::string& path, - const std::string& key) { - DataSet dataset = file.getDataSet(path); - Attribute attribute = dataset.getAttribute(key); - T data; - attribute.read(data); - return data; - } - - inline static DataSet dump_extend(File& file, - const std::string& path, - const T& data, - const std::vector& idx, - const DumpOptions& options) { - std::vector ones(idx.size(), 1); - - if (file.exist(path)) { - DataSet dataset = file.getDataSet(path); - std::vector dims = dataset.getDimensions(); - std::vector shape = dims; - if (dims.size() != idx.size()) { - throw detail::error( - file, - path, - "H5Easy::dump: Dimension of the index and the existing field do not match"); - } - for (size_t i = 0; i < dims.size(); ++i) { - shape[i] = std::max(dims[i], idx[i] + 1); - } - if (shape != dims) { - dataset.resize(shape); - } - dataset.select(idx, ones).write(data); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - std::vector shape = idx; - const size_t unlim = DataSpace::UNLIMITED; - std::vector unlim_shape(idx.size(), unlim); - std::vector chunks(idx.size(), 10); - if (options.isChunked()) { - chunks = options.getChunkSize(); - if (chunks.size() != idx.size()) { - throw error(file, path, "H5Easy::dump: Incorrect dimension ChunkSize"); - } - } - for (size_t& i: shape) { - i++; - } - DataSpace dataspace = DataSpace(shape, unlim_shape); - DataSetCreateProps props; - props.add(Chunking(chunks)); - DataSet dataset = file.createDataSet(path, dataspace, AtomicType(), props, {}, true); - dataset.select(idx, ones).write(data); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load_part(const File& file, - const std::string& path, - const std::vector& idx) { - std::vector ones(idx.size(), 1); - DataSet dataset = file.getDataSet(path); - T data; - dataset.select(idx, ones).read(data); - return data; - } -}; - -} // namespace detail -} // namespace H5Easy diff --git a/inst/include/highfive/h5easy_bits/H5Easy_vector.hpp b/inst/include/highfive/h5easy_bits/H5Easy_vector.hpp deleted file mode 100644 index 4c60f5c..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_vector.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" -#include "H5Easy_misc.hpp" -#include "H5Easy_scalar.hpp" - -namespace H5Easy { - -namespace detail { - -template -struct is_vector: std::false_type {}; -template -struct is_vector>: std::true_type {}; - -using HighFive::details::inspector; - -template -struct io_impl::value>::type> { - inline static DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - using value_type = typename inspector::base_type; - auto dims = inspector::getDimensions(data); - DataSet dataset = initDataset(file, - path, - std::vector(dims.begin(), dims.end()), - options); - dataset.write(data); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load(const File& file, const std::string& path) { - DataSet dataset = file.getDataSet(path); - T data; - dataset.read(data); - return data; - } - - inline static Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - using value_type = typename inspector::base_type; - auto dims = inspector::getDimensions(data); - std::vector shape(dims.begin(), dims.end()); - Attribute attribute = initAttribute(file, path, key, shape, options); - attribute.write(data); - if (options.flush()) { - file.flush(); - } - return attribute; - } - - inline static T loadAttribute(const File& file, - const std::string& path, - const std::string& key) { - DataSet dataset = file.getDataSet(path); - Attribute attribute = dataset.getAttribute(key); - T data; - attribute.read(data); - return data; - } -}; - -} // namespace detail -} // namespace H5Easy diff --git a/inst/include/highfive/h5easy_bits/H5Easy_xtensor.hpp b/inst/include/highfive/h5easy_bits/H5Easy_xtensor.hpp deleted file mode 100644 index 6b0238c..0000000 --- a/inst/include/highfive/h5easy_bits/H5Easy_xtensor.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c), 2017, Adrien Devresse - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - */ -#pragma once - -#include "../H5Easy.hpp" -#include "H5Easy_misc.hpp" -#include "H5Easy_scalar.hpp" - -#ifdef H5_USE_XTENSOR - -namespace H5Easy { - -namespace detail { - -template -struct io_impl::value>::type> { - inline static std::vector shape(const T& data) { - return std::vector(data.shape().cbegin(), data.shape().cend()); - } - - inline static DataSet dump(File& file, - const std::string& path, - const T& data, - const DumpOptions& options) { - using value_type = typename std::decay_t::value_type; - DataSet dataset = initDataset(file, path, shape(data), options); - dataset.write_raw(data.data()); - if (options.flush()) { - file.flush(); - } - return dataset; - } - - inline static T load(const File& file, const std::string& path) { - static_assert( - xt::has_data_interface::value, - "Cannot load to xt::xfunction or xt::xgenerator, use e.g. xt::xtensor or xt::xarray"); - DataSet dataset = file.getDataSet(path); - std::vector dims = dataset.getDimensions(); - T data = T::from_shape(dims); - dataset.read(data.data()); - return data; - } - - inline static Attribute dumpAttribute(File& file, - const std::string& path, - const std::string& key, - const T& data, - const DumpOptions& options) { - using value_type = typename std::decay_t::value_type; - Attribute attribute = initAttribute(file, path, key, shape(data), options); - attribute.write_raw(data.data()); - if (options.flush()) { - file.flush(); - } - return attribute; - } - - inline static T loadAttribute(const File& file, - const std::string& path, - const std::string& key) { - static_assert( - xt::has_data_interface::value, - "Cannot load to xt::xfunction or xt::xgenerator, use e.g. xt::xtensor or xt::xarray"); - DataSet dataset = file.getDataSet(path); - Attribute attribute = dataset.getAttribute(key); - DataSpace dataspace = attribute.getSpace(); - std::vector dims = dataspace.getDimensions(); - T data = T::from_shape(dims); - attribute.read(data.data()); - return data; - } -}; - -} // namespace detail -} // namespace H5Easy - -#endif // H5_USE_XTENSOR diff --git a/inst/include/highfive/highfive.hpp b/inst/include/highfive/highfive.hpp deleted file mode 100644 index f5e20ca..0000000 --- a/inst/include/highfive/highfive.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include