Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 09:13:56

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