From: Roland Schulz Date: Wed, 9 Sep 2020 20:06:04 +0000 (-0700) Subject: Simpify CheckpointData X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=1281e17ca12e6b7786a0e4f8894b658f565072e1;p=alexxy%2Fgromacs.git Simpify CheckpointData --- diff --git a/src/gromacs/mdtypes/checkpointdata.h b/src/gromacs/mdtypes/checkpointdata.h index 9bc226506b..b82da7cf1e 100644 --- a/src/gromacs/mdtypes/checkpointdata.h +++ b/src/gromacs/mdtypes/checkpointdata.h @@ -134,8 +134,16 @@ struct IsSerializableEnum * objects, which interact with the checkpoint reading from / writing to * file. */ + template -class CheckpointData +class CheckpointData; + +// Shortcuts +using ReadCheckpointData = CheckpointData; +using WriteCheckpointData = CheckpointData; + +template<> +class CheckpointData { public: /*! \brief Read or write a single value from / to checkpoint @@ -151,20 +159,10 @@ public: * \param value The value to [read|write] */ //! { - // Read - template - std::enable_if_t::value, void> - scalar(const std::string& key, T* value) const; - template - std::enable_if_t::value, void> - enumScalar(const std::string& key, T* value) const; - // Write - template - std::enable_if_t::value, void> - scalar(const std::string& key, const T* value); - template - std::enable_if_t::value, void> - enumScalar(const std::string& key, const T* value); + template + std::enable_if_t::value, void> scalar(const std::string& key, T* value) const; + template + std::enable_if_t::value, void> enumScalar(const std::string& key, T* value) const; //! } /*! \brief Read or write an ArrayRef from / to checkpoint @@ -180,21 +178,11 @@ public: */ //! { // Read ArrayRef of scalar - template - std::enable_if_t::value, void> - arrayRef(const std::string& key, ArrayRef values) const; - // Write ArrayRef of scalar - template - std::enable_if_t::value, void> - arrayRef(const std::string& key, ArrayRef values); + template + std::enable_if_t::value, void> arrayRef(const std::string& key, + ArrayRef values) const; // Read ArrayRef of RVec - template - std::enable_if_t arrayRef(const std::string& key, - ArrayRef values) const; - // Write ArrayRef of RVec - template - std::enable_if_t arrayRef(const std::string& key, - ArrayRef values); + void arrayRef(const std::string& key, ArrayRef values) const; //! } /*! \brief Read or write a tensor from / to checkpoint @@ -203,16 +191,7 @@ public: * \param key The key to [read|write] the tensor [from|to] * \param values The tensor to [read|write] */ - //! { - // Read - template - std::enable_if_t tensor(const std::string& key, - ::tensor values) const; - // Write - template - std::enable_if_t tensor(const std::string& key, - const ::tensor values); - //! } + void tensor(const std::string& key, ::tensor values) const; /*! \brief Return a subset of the current CheckpointData * @@ -221,35 +200,59 @@ public: * \return A CheckpointData object representing a subset of the current object */ //!{ - // Read - template - std::enable_if_t - subCheckpointData(const std::string& key) const; - // Write - template - std::enable_if_t - subCheckpointData(const std::string& key); + CheckpointData subCheckpointData(const std::string& key) const; //!} private: //! KV tree read from checkpoint const KeyValueTreeObject* inputTree_ = nullptr; - //! Builder for the tree to be written to checkpoint - std::optional outputTreeBuilder_ = std::nullopt; //! Construct an input checkpoint data object explicit CheckpointData(const KeyValueTreeObject& inputTree); + + // Only holders should build + friend class ReadCheckpointDataHolder; +}; + +template<> +class CheckpointData +{ +public: + //! \copydoc CheckpointData::scalar + //! { + template + std::enable_if_t::value, void> scalar(const std::string& key, const T* value); + template + std::enable_if_t::value, void> enumScalar(const std::string& key, const T* value); + //! } + + //! \copydoc CheckpointData::arrayRef + //! { + // Write ArrayRef of scalar + template + std::enable_if_t::value, void> arrayRef(const std::string& key, + ArrayRef values); + // Write ArrayRef of RVec + void arrayRef(const std::string& key, ArrayRef values); + //! } + + //! \copydoc CheckpointData::tensor + void tensor(const std::string& key, const ::tensor values); + + //! \copydoc CheckpointData::subCheckpointData + CheckpointData subCheckpointData(const std::string& key); + +private: + //! Builder for the tree to be written to checkpoint + std::optional outputTreeBuilder_ = std::nullopt; + //! Construct an output checkpoint data object explicit CheckpointData(KeyValueTreeObjectBuilder&& outputTreeBuilder); // Only holders should build - friend class ReadCheckpointDataHolder; friend class WriteCheckpointDataHolder; }; -// Shortcuts -using ReadCheckpointData = CheckpointData; -using WriteCheckpointData = CheckpointData; /*! \libinternal * \brief Holder for read checkpoint data @@ -318,19 +321,17 @@ private: // Function definitions - here to avoid template-related linker problems // doxygen doesn't like these... //! \cond -template<> -template -std::enable_if_t::value, void> -ReadCheckpointData::scalar(const std::string& key, T* value) const +template +std::enable_if_t::value, void> ReadCheckpointData::scalar(const std::string& key, + T* value) const { GMX_RELEASE_ASSERT(inputTree_, "No input checkpoint data available."); *value = (*inputTree_)[key].cast(); } -template<> -template -std::enable_if_t::value, void> -ReadCheckpointData::enumScalar(const std::string& key, T* value) const +template +std::enable_if_t::value, void> ReadCheckpointData::enumScalar(const std::string& key, + T* value) const { GMX_RELEASE_ASSERT(inputTree_, "No input checkpoint data available."); std::underlying_type_t castValue; @@ -338,18 +339,16 @@ ReadCheckpointData::enumScalar(const std::string& key, T* value) const *value = static_cast(castValue); } -template<> -template -inline std::enable_if_t::value, void> +template +inline std::enable_if_t::value, void> WriteCheckpointData::scalar(const std::string& key, const T* value) { GMX_RELEASE_ASSERT(outputTreeBuilder_, "No output checkpoint data available."); outputTreeBuilder_->addValue(key, *value); } -template<> -template -inline std::enable_if_t::value, void> +template +inline std::enable_if_t::value, void> WriteCheckpointData::enumScalar(const std::string& key, const T* value) { GMX_RELEASE_ASSERT(outputTreeBuilder_, "No output checkpoint data available."); @@ -357,9 +356,8 @@ WriteCheckpointData::enumScalar(const std::string& key, const T* value) outputTreeBuilder_->addValue(key, castValue); } -template<> -template -inline std::enable_if_t::value, void> +template +inline std::enable_if_t::value, void> ReadCheckpointData::arrayRef(const std::string& key, ArrayRef values) const { GMX_RELEASE_ASSERT(inputTree_, "No input checkpoint data available."); @@ -375,9 +373,8 @@ ReadCheckpointData::arrayRef(const std::string& key, ArrayRef values) const } } -template<> -template -inline std::enable_if_t::value, void> +template +inline std::enable_if_t::value, void> WriteCheckpointData::arrayRef(const std::string& key, ArrayRef values) { GMX_RELEASE_ASSERT(outputTreeBuilder_, "No output checkpoint data available."); @@ -388,8 +385,6 @@ WriteCheckpointData::arrayRef(const std::string& key, ArrayRef values) } } -template<> -template<> inline void ReadCheckpointData::arrayRef(const std::string& key, ArrayRef values) const { GMX_RELEASE_ASSERT(values.size() >= (*inputTree_)[key].asArray().values().size(), @@ -406,8 +401,6 @@ inline void ReadCheckpointData::arrayRef(const std::string& key, ArrayRef } } -template<> -template<> inline void WriteCheckpointData::arrayRef(const std::string& key, ArrayRef values) { auto builder = outputTreeBuilder_->addObjectArray(key); @@ -418,8 +411,6 @@ inline void WriteCheckpointData::arrayRef(const std::string& key, ArrayRef -template<> inline void ReadCheckpointData::tensor(const std::string& key, ::tensor values) const { auto array = (*inputTree_)[key].asArray().values(); @@ -434,8 +425,6 @@ inline void ReadCheckpointData::tensor(const std::string& key, ::tensor values) values[ZZ][ZZ] = array[8].cast(); } -template<> -template<> inline void WriteCheckpointData::tensor(const std::string& key, const ::tensor values) { auto builder = outputTreeBuilder_->addUniformArray(key); @@ -450,34 +439,24 @@ inline void WriteCheckpointData::tensor(const std::string& key, const ::tensor v builder.addValue(values[ZZ][ZZ]); } -template<> -template<> inline ReadCheckpointData ReadCheckpointData::subCheckpointData(const std::string& key) const { return CheckpointData((*inputTree_)[key].asObject()); } -template<> -template<> inline WriteCheckpointData WriteCheckpointData::subCheckpointData(const std::string& key) { return CheckpointData(outputTreeBuilder_->addObject(key)); } -template -CheckpointData::CheckpointData(const KeyValueTreeObject& inputTree) : +inline ReadCheckpointData::CheckpointData(const KeyValueTreeObject& inputTree) : inputTree_(&inputTree) { - static_assert(operation == CheckpointDataOperation::Read, - "This constructor can only be called for a read CheckpointData"); } -template -CheckpointData::CheckpointData(KeyValueTreeObjectBuilder&& outputTreeBuilder) : +inline WriteCheckpointData::CheckpointData(KeyValueTreeObjectBuilder&& outputTreeBuilder) : outputTreeBuilder_(outputTreeBuilder) { - static_assert(operation == CheckpointDataOperation::Write, - "This constructor can only be called for a write CheckpointData"); } //! \endcond