Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*
0002  *  Copyright (c), 2017-2018, Adrien Devresse <adrien.devresse@epfl.ch>
0003  *                            Juan Hernando <juan.hernando@epfl.ch>
0004  *  Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  */
0009 #pragma once
0010 
0011 #include <vector>
0012 
0013 #include <H5Ppublic.h>
0014 
0015 // Required by MPIOFileAccess
0016 #ifdef H5_HAVE_PARALLEL
0017 #include <H5FDmpi.h>
0018 #endif
0019 
0020 #include "H5Exception.hpp"
0021 #include "H5Object.hpp"
0022 
0023 namespace HighFive {
0024 
0025 /// \defgroup PropertyLists Property Lists
0026 /// HDF5 is configured through what they call property lists. In HDF5 the
0027 /// process has four steps:
0028 ///
0029 /// 1. Create a property list. As users we now have an `hid_t` identifying the
0030 /// property list.
0031 /// 2. Set properties as desired.
0032 /// 3. Pass the HID to the HDF5 function to be configured.
0033 /// 4. Free the property list.
0034 ///
0035 /// Note that the mental picture is that one creates a settings object, and
0036 /// then passes those settings to a function such as `H5Dwrite`. In and of
0037 /// themselves the settings don't change the behaviour of HDF5. Rather they
0038 /// need to be used to take affect.
0039 ///
0040 /// The second aspect is that property lists represent any number of related
0041 /// settings, e.g. there's property lists anything related to creating files
0042 /// and another for accessing files, same for creating and accessing datasets,
0043 /// etc. Settings that affect creating files, must be passed a file creation
0044 /// property list, while settings that affect file access require a file access
0045 /// property list.
0046 ///
0047 /// In HighFive the `PropertyList` works similar in that it's a object
0048 /// representing the settings, i.e. internally it's just the property lists
0049 /// HID. Just like in HDF5 one adds the settings to the settings object; and
0050 /// then passes the settings object to the respective method. Example:
0051 ///
0052 ///
0053 ///     // Create an object which contains the setting to
0054 ///     // open files with MPI-IO.
0055 ///     auto fapl = FileAccessProps();
0056 ///     fapl.add(MPIOFileAccess(MPI_COMM_WORLD, MPI_INFO_NULL);
0057 ///
0058 ///     // To open a specific file with MPI-IO, we do:
0059 ///     auto file = File("foo.h5", File::ReadOnly, fapl);
0060 ///
0061 /// Note that the `MPIOFileAccess` object by itself doesn't affect the
0062 /// `FileAccessProps`. Rather it needs to be explicitly added to the `fapl`
0063 /// (the group of file access related settings), and then the `fapl` needs to
0064 /// be passed to the constructor of `File` for the settings to take affect.
0065 ///
0066 /// This is important to understand when reading properties. Example:
0067 ///
0068 ///     // Obtain the file access property list:
0069 ///     auto fapl = file.getAccessPropertyList()
0070 ///
0071 ///     // Extracts a copy of the collective MPI-IO metadata settings from
0072 ///     // the group of file access related setting, i.e. the `fapl`:
0073 ///     auto mpio_metadata = MPIOCollectiveMetadata(fapl);
0074 ///
0075 ///     if(mpio_metadata.isCollectiveRead()) {
0076 ///       // something specific if meta data is read collectively.
0077 ///     }
0078 ///
0079 ///     // Careful, this only affects the `mpio_metadata` object, but not the
0080 ///     //  `fapl`, and also not whether `file` uses collective MPI-IO for
0081 ///     // metadata.
0082 ///     mpio_metadata = MPIOCollectiveMetadata(false, false);
0083 ///
0084 /// @{
0085 
0086 ///
0087 /// \brief Types of property lists
0088 ///
0089 enum class PropertyType : int {
0090     OBJECT_CREATE,
0091     FILE_CREATE,
0092     FILE_ACCESS,
0093     DATASET_CREATE,
0094     DATASET_ACCESS,
0095     DATASET_XFER,
0096     GROUP_CREATE,
0097     GROUP_ACCESS,
0098     DATATYPE_CREATE,
0099     DATATYPE_ACCESS,
0100     STRING_CREATE,
0101     ATTRIBUTE_CREATE,
0102     OBJECT_COPY,
0103     LINK_CREATE,
0104     LINK_ACCESS,
0105 };
0106 
0107 namespace details {
0108 template <typename T, typename U>
0109 T get_plist(const U& obj, hid_t (*f)(hid_t)) {
0110     auto hid = f(obj.getId());
0111     if (hid < 0) {
0112         HDF5ErrMapper::ToException<PropertyException>("Unable to get property list");
0113     }
0114     T t{};
0115     t._hid = hid;
0116     return t;
0117 }
0118 }  // namespace details
0119 
0120 ///
0121 /// \brief Base Class for Property lists, providing global default
0122 class PropertyListBase: public Object {
0123   public:
0124     PropertyListBase() noexcept;
0125 
0126     static const PropertyListBase& Default() noexcept {
0127         static const PropertyListBase plist{};
0128         return plist;
0129     }
0130 
0131   private:
0132     template <typename T, typename U>
0133     friend T details::get_plist(const U&, hid_t (*f)(hid_t));
0134 };
0135 
0136 /// \interface PropertyInterface
0137 /// \brief HDF5 file property object
0138 ///
0139 /// A property is an object which is expected to have a method with the
0140 /// following signature `void apply(hid_t hid) const`
0141 ///
0142 /// \sa Instructions to document C++20 concepts with Doxygen: https://github.com/doxygen/doxygen/issues/2732#issuecomment-509629967
0143 ///
0144 /// \cond
0145 #if HIGHFIVE_HAS_CONCEPTS && __cplusplus >= 202002L
0146 template <typename P>
0147 concept PropertyInterface = requires(P p, const hid_t hid) {
0148     {p.apply(hid)};
0149 };
0150 
0151 #else
0152 #define PropertyInterface typename
0153 #endif
0154 /// \endcond
0155 
0156 ///
0157 /// \brief HDF5 property Lists
0158 ///
0159 template <PropertyType T>
0160 class PropertyList: public PropertyListBase {
0161   public:
0162     ///
0163     /// \brief return the type of this PropertyList
0164     constexpr PropertyType getType() const noexcept {
0165         return T;
0166     }
0167 
0168     ///
0169     /// Add a property to this property list.
0170     /// A property is an object which is expected to have a method with the
0171     /// following signature void apply(hid_t hid) const
0172     /// \tparam PropertyInterface
0173     template <PropertyInterface P>
0174     void add(const P& property);
0175 
0176     ///
0177     /// Return the Default property type object
0178     static const PropertyList<T>& Default() noexcept {
0179         return static_cast<const PropertyList<T>&>(PropertyListBase::Default());
0180     }
0181 
0182     /// Return a property list created via a call to `H5Pcreate`.
0183     ///
0184     /// An empty property is needed when one wants `getId()` to immediately
0185     /// point at a valid HID. This is important when interfacing directly with
0186     /// HDF5 to set properties that haven't been wrapped by HighFive.
0187     static PropertyList<T> Empty() {
0188         auto plist = PropertyList<T>();
0189         plist._initializeIfNeeded();
0190 
0191         return plist;
0192     }
0193 
0194   protected:
0195     void _initializeIfNeeded();
0196 };
0197 
0198 using ObjectCreateProps = PropertyList<PropertyType::OBJECT_CREATE>;
0199 using FileCreateProps = PropertyList<PropertyType::FILE_CREATE>;
0200 using FileAccessProps = PropertyList<PropertyType::FILE_ACCESS>;
0201 using DataSetCreateProps = PropertyList<PropertyType::DATASET_CREATE>;
0202 using DataSetAccessProps = PropertyList<PropertyType::DATASET_ACCESS>;
0203 using DataTransferProps = PropertyList<PropertyType::DATASET_XFER>;
0204 using GroupCreateProps = PropertyList<PropertyType::GROUP_CREATE>;
0205 using GroupAccessProps = PropertyList<PropertyType::GROUP_ACCESS>;
0206 using DataTypeCreateProps = PropertyList<PropertyType::DATATYPE_CREATE>;
0207 using DataTypeAccessProps = PropertyList<PropertyType::DATATYPE_ACCESS>;
0208 using StringCreateProps = PropertyList<PropertyType::STRING_CREATE>;
0209 using AttributeCreateProps = PropertyList<PropertyType::ATTRIBUTE_CREATE>;
0210 using ObjectCopyProps = PropertyList<PropertyType::OBJECT_COPY>;
0211 using LinkCreateProps = PropertyList<PropertyType::LINK_CREATE>;
0212 using LinkAccessProps = PropertyList<PropertyType::LINK_ACCESS>;
0213 
0214 ///
0215 /// RawPropertyLists are to be used when advanced H5 properties
0216 /// are desired and are not part of the HighFive API.
0217 /// Therefore this class is mainly for internal use.
0218 template <PropertyType T>
0219 class RawPropertyList: public PropertyList<T> {
0220   public:
0221     template <typename F, typename... Args>
0222     void add(const F& funct, const Args&... args);
0223 };
0224 
0225 #ifdef H5_HAVE_PARALLEL
0226 ///
0227 /// \brief Configure MPI access for the file
0228 ///
0229 /// All further modifications to the structure of the file will have to be
0230 /// done with collective operations
0231 ///
0232 class MPIOFileAccess {
0233   public:
0234     MPIOFileAccess(MPI_Comm comm, MPI_Info info);
0235 
0236   private:
0237     friend FileAccessProps;
0238     void apply(const hid_t list) const;
0239 
0240     MPI_Comm _comm;
0241     MPI_Info _info;
0242 };
0243 
0244 
0245 #if H5_VERSION_GE(1, 10, 0)
0246 ///
0247 /// \brief Use collective MPI-IO for metadata read and write.
0248 ///
0249 /// See `MPIOCollectiveMetadataRead` and `MPIOCollectiveMetadataWrite`.
0250 ///
0251 class MPIOCollectiveMetadata {
0252   public:
0253     explicit MPIOCollectiveMetadata(bool collective = true);
0254     explicit MPIOCollectiveMetadata(const FileAccessProps& plist);
0255 
0256     bool isCollectiveRead() const;
0257     bool isCollectiveWrite() const;
0258 
0259 
0260   private:
0261     friend FileAccessProps;
0262     void apply(hid_t plist) const;
0263 
0264     bool collective_read_;
0265     bool collective_write_;
0266 };
0267 
0268 ///
0269 /// \brief Use collective MPI-IO for metadata read?
0270 ///
0271 /// Note that when used in a file access property list, this will force all reads
0272 /// of meta data to be collective. HDF5 function may implicitly perform metadata
0273 /// reads. These functions would become collective. A list of functions that
0274 /// perform metadata reads can be found in the HDF5 documentation, e.g.
0275 ///    https://docs.hdfgroup.org/hdf5/v1_12/group___g_a_c_p_l.html
0276 ///
0277 /// In HighFive setting collective read is (currently) only supported on file level.
0278 ///
0279 /// Please also consult upstream documentation of `H5Pset_all_coll_metadata_ops`.
0280 ///
0281 class MPIOCollectiveMetadataRead {
0282   public:
0283     explicit MPIOCollectiveMetadataRead(bool collective = true);
0284     explicit MPIOCollectiveMetadataRead(const FileAccessProps& plist);
0285 
0286     bool isCollective() const;
0287 
0288   private:
0289     friend FileAccessProps;
0290     friend MPIOCollectiveMetadata;
0291 
0292     void apply(hid_t plist) const;
0293 
0294     bool collective_;
0295 };
0296 
0297 ///
0298 /// \brief Use collective MPI-IO for metadata write?
0299 ///
0300 /// In order to keep the in-memory representation of the file structure
0301 /// consistent across MPI ranks, writing meta data is always a collective
0302 /// operation. Meaning all MPI ranks must participate. Passing this setting
0303 /// enables using MPI-IO collective operations for metadata writes.
0304 ///
0305 /// Please also consult upstream documentation of `H5Pset_coll_metadata_write`.
0306 ///
0307 class MPIOCollectiveMetadataWrite {
0308   public:
0309     explicit MPIOCollectiveMetadataWrite(bool collective = true);
0310     explicit MPIOCollectiveMetadataWrite(const FileAccessProps& plist);
0311 
0312     bool isCollective() const;
0313 
0314   private:
0315     friend FileAccessProps;
0316     friend MPIOCollectiveMetadata;
0317 
0318     void apply(hid_t plist) const;
0319 
0320     bool collective_;
0321 };
0322 
0323 #endif
0324 #endif
0325 
0326 ///
0327 /// \brief Configure the version bounds for the file
0328 ///
0329 /// Used to define the compatibility of objects created within HDF5 files,
0330 /// and affects the format of groups stored in the file.
0331 ///
0332 /// See also the documentation of \c H5P_SET_LIBVER_BOUNDS in HDF5.
0333 ///
0334 /// Possible values for \c low and \c high are:
0335 /// * \c H5F_LIBVER_EARLIEST
0336 /// * \c H5F_LIBVER_V18
0337 /// * \c H5F_LIBVER_V110
0338 /// * \c H5F_LIBVER_NBOUNDS
0339 /// * \c H5F_LIBVER_LATEST currently defined as \c H5F_LIBVER_V110 within
0340 ///   HDF5
0341 ///
0342 class FileVersionBounds {
0343   public:
0344     FileVersionBounds(H5F_libver_t low, H5F_libver_t high);
0345     explicit FileVersionBounds(const FileAccessProps& fapl);
0346 
0347     std::pair<H5F_libver_t, H5F_libver_t> getVersion() const;
0348 
0349   private:
0350     friend FileAccessProps;
0351     void apply(const hid_t list) const;
0352 
0353     H5F_libver_t _low;
0354     H5F_libver_t _high;
0355 };
0356 
0357 ///
0358 /// \brief Configure the metadata block size to use writing to files
0359 ///
0360 /// \param size Metadata block size in bytes
0361 ///
0362 class MetadataBlockSize {
0363   public:
0364     explicit MetadataBlockSize(hsize_t size);
0365     explicit MetadataBlockSize(const FileAccessProps& fapl);
0366 
0367     hsize_t getSize() const;
0368 
0369   private:
0370     friend FileAccessProps;
0371     void apply(const hid_t list) const;
0372     hsize_t _size;
0373 };
0374 
0375 #if H5_VERSION_GE(1, 10, 1)
0376 ///
0377 /// \brief Configure the file space strategy.
0378 ///
0379 /// See the upstream documentation of `H5Pget_file_space_strategy` for more details. Essentially,
0380 /// it enables configuring how space is allocate in the file.
0381 ///
0382 class FileSpaceStrategy {
0383   public:
0384     ///
0385     /// \brief Create a file space strategy property.
0386     ///
0387     /// \param strategy The HDF5 free space strategy.
0388     /// \param persist Should free space managers be persisted across file closing and reopening.
0389     /// \param threshold The free-space manager wont track sections small than this threshold.
0390     FileSpaceStrategy(H5F_fspace_strategy_t strategy, hbool_t persist, hsize_t threshold);
0391     explicit FileSpaceStrategy(const FileCreateProps& fcpl);
0392 
0393     H5F_fspace_strategy_t getStrategy() const;
0394     hbool_t getPersist() const;
0395     hsize_t getThreshold() const;
0396 
0397   private:
0398     friend FileCreateProps;
0399 
0400     void apply(const hid_t list) const;
0401 
0402     H5F_fspace_strategy_t _strategy;
0403     hbool_t _persist;
0404     hsize_t _threshold;
0405 };
0406 
0407 ///
0408 /// \brief Configure the page size for paged allocation.
0409 ///
0410 /// See the upstream documentation of `H5Pset_file_space_page_size` for more details. Essentially,
0411 /// it enables configuring the page size when paged allocation is used.
0412 ///
0413 /// General information about paged allocation can be found in the upstream documentation "RFC: Page
0414 /// Buffering".
0415 ///
0416 class FileSpacePageSize {
0417   public:
0418     ///
0419     /// \brief Create a file space strategy property.
0420     ///
0421     /// \param page_size The page size in bytes.
0422     explicit FileSpacePageSize(hsize_t page_size);
0423     explicit FileSpacePageSize(const FileCreateProps& fcpl);
0424 
0425     hsize_t getPageSize() const;
0426 
0427   private:
0428     friend FileCreateProps;
0429     void apply(const hid_t list) const;
0430 
0431     hsize_t _page_size;
0432 };
0433 
0434 #ifndef H5_HAVE_PARALLEL
0435 /// \brief Set size of the page buffer.
0436 ///
0437 /// Please, consult the upstream documentation of
0438 ///    H5Pset_page_buffer_size
0439 ///    H5Pget_page_buffer_size
0440 /// Note that this setting is only valid for page allocated/aggregated
0441 /// files, i.e. those that have file space strategy "Page".
0442 ///
0443 /// Tests suggest this doesn't work in the parallel version of the
0444 /// library. Hence, this isn't available at compile time if the parallel
0445 /// library was selected.
0446 class PageBufferSize {
0447   public:
0448     /// Property to set page buffer sizes.
0449     ///
0450     /// @param page_buffer_size maximum size of the page buffer in bytes.
0451     /// @param min_meta_percent fraction of the page buffer dedicated to meta data, in percent.
0452     /// @param min_raw_percent fraction of the page buffer dedicated to raw data, in percent.
0453     explicit PageBufferSize(size_t page_buffer_size,
0454                             unsigned min_meta_percent = 0,
0455                             unsigned min_raw_percent = 0);
0456 
0457     explicit PageBufferSize(const FileAccessProps& fapl);
0458 
0459     size_t getPageBufferSize() const;
0460     unsigned getMinMetaPercent() const;
0461     unsigned getMinRawPercent() const;
0462 
0463   private:
0464     friend FileAccessProps;
0465 
0466     void apply(hid_t list) const;
0467 
0468     size_t _page_buffer_size;
0469     unsigned _min_meta;
0470     unsigned _min_raw;
0471 };
0472 #endif
0473 #endif
0474 
0475 /// \brief Set hints as to how many links to expect and their average length
0476 /// \implements PropertyInterface
0477 ///
0478 class EstimatedLinkInfo {
0479   public:
0480     /// \brief Create a property with the request parameters.
0481     ///
0482     /// @param entries The estimated number of links in a group.
0483     /// @param length The estimated length of the names of links.
0484     explicit EstimatedLinkInfo(unsigned entries, unsigned length);
0485 
0486     explicit EstimatedLinkInfo(const GroupCreateProps& gcpl);
0487 
0488     /// \brief The estimated number of links in a group.
0489     unsigned getEntries() const;
0490 
0491     /// \brief The estimated length of the names of links.
0492     unsigned getNameLength() const;
0493 
0494   private:
0495     friend GroupCreateProps;
0496     void apply(hid_t hid) const;
0497     unsigned _entries;
0498     unsigned _length;
0499 };
0500 
0501 
0502 /// \implements PropertyInterface
0503 class Chunking {
0504   public:
0505     explicit Chunking(const std::vector<hsize_t>& dims);
0506     Chunking(const std::initializer_list<hsize_t>& items);
0507 
0508     template <typename... Args>
0509     explicit Chunking(hsize_t item, Args... args);
0510 
0511     explicit Chunking(DataSetCreateProps& plist, size_t max_dims = 32);
0512 
0513     const std::vector<hsize_t>& getDimensions() const noexcept;
0514 
0515   private:
0516     friend DataSetCreateProps;
0517     void apply(hid_t hid) const;
0518     std::vector<hsize_t> _dims;
0519 };
0520 
0521 /// \implements PropertyInterface
0522 class Deflate {
0523   public:
0524     explicit Deflate(unsigned level);
0525 
0526   private:
0527     friend DataSetCreateProps;
0528     friend GroupCreateProps;
0529     void apply(hid_t hid) const;
0530     const unsigned _level;
0531 };
0532 
0533 /// \implements PropertyInterface
0534 class Szip {
0535   public:
0536     explicit Szip(unsigned options_mask = H5_SZIP_EC_OPTION_MASK,
0537                   unsigned pixels_per_block = H5_SZIP_MAX_PIXELS_PER_BLOCK);
0538 
0539     unsigned getOptionsMask() const;
0540     unsigned getPixelsPerBlock() const;
0541 
0542   private:
0543     friend DataSetCreateProps;
0544     void apply(hid_t hid) const;
0545     const unsigned _options_mask;
0546     const unsigned _pixels_per_block;
0547 };
0548 
0549 /// \implements PropertyInterface
0550 class Shuffle {
0551   public:
0552     Shuffle() = default;
0553 
0554   private:
0555     friend DataSetCreateProps;
0556     void apply(hid_t hid) const;
0557 };
0558 
0559 /// \brief When are datasets allocated?
0560 ///
0561 /// The precise time of when HDF5 requests space to store the dataset
0562 /// can be configured. Please, consider the upstream documentation for
0563 /// `H5Pset_alloc_time`.
0564 /// \implements PropertyInterface
0565 class AllocationTime {
0566   public:
0567     explicit AllocationTime(H5D_alloc_time_t alloc_time);
0568     explicit AllocationTime(const DataSetCreateProps& dcpl);
0569 
0570     H5D_alloc_time_t getAllocationTime();
0571 
0572   private:
0573     friend DataSetCreateProps;
0574     void apply(hid_t dcpl) const;
0575 
0576     H5D_alloc_time_t _alloc_time;
0577 };
0578 
0579 /// Dataset access property to control chunk cache configuration.
0580 /// Do not confuse with the similar file access property for H5Pset_cache
0581 /// \implements PropertyInterface
0582 class Caching {
0583   public:
0584     /// https://support.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_chunk_cache.html for
0585     /// details.
0586     Caching(const size_t numSlots,
0587             const size_t cacheSize,
0588             const double w0 = static_cast<double>(H5D_CHUNK_CACHE_W0_DEFAULT));
0589 
0590     explicit Caching(const DataSetCreateProps& dcpl);
0591 
0592     size_t getNumSlots() const;
0593     size_t getCacheSize() const;
0594     double getW0() const;
0595 
0596   private:
0597     friend DataSetAccessProps;
0598     void apply(hid_t hid) const;
0599     size_t _numSlots;
0600     size_t _cacheSize;
0601     double _w0;
0602 };
0603 
0604 /// \implements PropertyInterface
0605 class CreateIntermediateGroup {
0606   public:
0607     explicit CreateIntermediateGroup(bool create = true);
0608 
0609     explicit CreateIntermediateGroup(const ObjectCreateProps& ocpl);
0610     explicit CreateIntermediateGroup(const LinkCreateProps& lcpl);
0611 
0612     bool isSet() const;
0613 
0614   protected:
0615     void fromPropertyList(hid_t hid);
0616 
0617   private:
0618     friend ObjectCreateProps;
0619     friend LinkCreateProps;
0620     void apply(hid_t hid) const;
0621     bool _create;
0622 };
0623 
0624 #ifdef H5_HAVE_PARALLEL
0625 /// \implements PropertyInterface
0626 class UseCollectiveIO {
0627   public:
0628     explicit UseCollectiveIO(bool enable = true);
0629 
0630     explicit UseCollectiveIO(const DataTransferProps& dxpl);
0631 
0632     /// \brief Does the property request collective IO?
0633     bool isCollective() const;
0634 
0635   private:
0636     friend DataTransferProps;
0637     void apply(hid_t hid) const;
0638     bool _enable;
0639 };
0640 
0641 
0642 /// \brief The cause for non-collective I/O.
0643 ///
0644 /// The cause refers to the most recent I/O with data transfer property list  `dxpl` at time of
0645 /// creation of this object. This object will not update automatically for later data transfers,
0646 /// i.e. `H5Pget_mpio_no_collective_cause` is called in the constructor, and not when fetching
0647 /// a value, such as `wasCollective`.
0648 /// \implements PropertyInterface
0649 class MpioNoCollectiveCause {
0650   public:
0651     explicit MpioNoCollectiveCause(const DataTransferProps& dxpl);
0652 
0653     /// \brief Was the datatransfer collective?
0654     bool wasCollective() const;
0655 
0656     /// \brief The local cause for a non-collective I/O.
0657     uint32_t getLocalCause() const;
0658 
0659     /// \brief The global cause for a non-collective I/O.
0660     uint32_t getGlobalCause() const;
0661 
0662     /// \brief A pair of the local and global cause for non-collective I/O.
0663     std::pair<uint32_t, uint32_t> getCause() const;
0664 
0665   private:
0666     friend DataTransferProps;
0667     uint32_t _local_cause;
0668     uint32_t _global_cause;
0669 };
0670 #endif
0671 
0672 struct CreationOrder {
0673     enum _CreationOrder {
0674         Tracked = H5P_CRT_ORDER_TRACKED,
0675         Indexed = H5P_CRT_ORDER_INDEXED,
0676     };
0677 };
0678 
0679 ///
0680 /// \brief Track and index creation order time
0681 ///
0682 /// Let user retrieve objects by creation order time instead of name.
0683 ///
0684 /// \implements PropertyInterface
0685 class LinkCreationOrder {
0686   public:
0687     ///
0688     /// \brief Create the property
0689     /// \param flags Should be a composition of HighFive::CreationOrder.
0690     ///
0691     explicit LinkCreationOrder(unsigned flags)
0692         : _flags(flags) {}
0693 
0694     explicit LinkCreationOrder(const FileCreateProps& fcpl);
0695     explicit LinkCreationOrder(const GroupCreateProps& gcpl);
0696 
0697     unsigned getFlags() const;
0698 
0699   protected:
0700     void fromPropertyList(hid_t hid);
0701 
0702   private:
0703     friend FileCreateProps;
0704     friend GroupCreateProps;
0705     void apply(hid_t hid) const;
0706     unsigned _flags;
0707 };
0708 
0709 
0710 ///
0711 /// \brief Set threshold for attribute storage.
0712 ///
0713 /// HDF5 can store Attributes in the object header (compact) or in the B-tree
0714 /// (dense). This property sets the threshold when attributes are moved to one
0715 /// or the other storage format.
0716 ///
0717 /// Please refer to the upstream documentation of `H5Pset_attr_phase_change` or
0718 /// Section 8 (Attributes) in the User Guide, in particular Subsection 8.5.
0719 ///
0720 /// \implements PropertyInterface
0721 class AttributePhaseChange {
0722   public:
0723     ///
0724     /// \brief Create the property from the threshold values.
0725     ///
0726     /// When the number of attributes hits `max_compact` the attributes are
0727     /// moved to dense storage, once the number drops to below `min_dense` the
0728     /// attributes are moved to compact storage.
0729     AttributePhaseChange(unsigned max_compact, unsigned min_dense);
0730 
0731     /// \brief Extract threshold values from property list.
0732     explicit AttributePhaseChange(const GroupCreateProps& gcpl);
0733 
0734     unsigned max_compact() const;
0735     unsigned min_dense() const;
0736 
0737   private:
0738     friend GroupCreateProps;
0739     void apply(hid_t hid) const;
0740 
0741     unsigned _max_compact;
0742     unsigned _min_dense;
0743 };
0744 
0745 /// @}
0746 
0747 }  // namespace HighFive
0748 
0749 #include "bits/H5PropertyList_misc.hpp"