diff --git a/include/openPMD/LoadStoreChunk.hpp b/include/openPMD/LoadStoreChunk.hpp index 882b127d05..317211e9bb 100644 --- a/include/openPMD/LoadStoreChunk.hpp +++ b/include/openPMD/LoadStoreChunk.hpp @@ -11,8 +11,10 @@ namespace openPMD { class RecordComponent; -template +template class ConfigureStoreChunkFromBuffer; +template +class ConfigureLoadStoreFromBuffer; template class DynamicMemoryView; @@ -67,30 +69,28 @@ class ConfigureLoadStore : protected internal::ConfigureStoreChunkData auto offset(Offset) -> return_type &; auto extent(Extent) -> return_type &; + template + using shared_ptr_return_type = ConfigureLoadStoreFromBuffer< + std::shared_ptr const>>; + template + using unique_ptr_return_type = ConfigureStoreChunkFromBuffer< + UniquePtrWithLambda>, + void>; + // @todo rvalue references..? template - auto fromSharedPtr(std::shared_ptr) - -> ConfigureStoreChunkFromBuffer< - std::shared_ptr const>>; + auto fromSharedPtr(std::shared_ptr) -> shared_ptr_return_type; template - auto fromUniquePtr(UniquePtrWithLambda) - -> ConfigureStoreChunkFromBuffer< - UniquePtrWithLambda>>; + auto fromUniquePtr(UniquePtrWithLambda) -> unique_ptr_return_type; template - auto fromUniquePtr(std::unique_ptr) - -> ConfigureStoreChunkFromBuffer< - UniquePtrWithLambda>>; + auto fromUniquePtr(std::unique_ptr) -> unique_ptr_return_type; template - auto - fromRawPtr(T *data) -> ConfigureStoreChunkFromBuffer< - std::shared_ptr const>>; + auto fromRawPtr(T *data) -> shared_ptr_return_type; template - auto fromContiguousContainer(T_ContiguousContainer &data) -> - typename std::enable_if_t< + auto fromContiguousContainer(T_ContiguousContainer &data) + -> std::enable_if_t< auxiliary::IsContiguousContainer_v, - ConfigureStoreChunkFromBuffer< - std::shared_ptr const>>>; + shared_ptr_return_type>; template [[nodiscard]] auto enqueueStore() -> DynamicMemoryView; @@ -98,15 +98,24 @@ class ConfigureLoadStore : protected internal::ConfigureStoreChunkData // definition of class RecordComponent. template [[nodiscard]] auto enqueueStore(F &&createBuffer) -> DynamicMemoryView; + + template + [[nodiscard]] auto enqueueLoad() -> std::shared_ptr; }; -template +template class ConfigureStoreChunkFromBuffer - : public ConfigureLoadStore> + : public ConfigureLoadStore, + /*then*/ ConfigureStoreChunkFromBuffer, + /*else*/ ChildClass>> { public: - using parent_t = - ConfigureLoadStore>; + using return_type = std::conditional_t< + std::is_void_v, + /*then*/ ConfigureStoreChunkFromBuffer, + /*else*/ ChildClass>; + using parent_t = ConfigureLoadStore; private: template @@ -115,12 +124,13 @@ class ConfigureStoreChunkFromBuffer Ptr_Type m_buffer; std::optional m_mem_select; - ConfigureStoreChunkFromBuffer(Ptr_Type buffer, parent_t &&); - auto storeChunkConfig() const -> internal::StoreChunkConfigFromBuffer; +protected: + ConfigureStoreChunkFromBuffer(Ptr_Type buffer, parent_t &&); + public: - auto memorySelection(MemorySelection) -> ConfigureStoreChunkFromBuffer &; + auto memorySelection(MemorySelection) -> return_type &; auto as_parent() && -> parent_t &&; auto as_parent() & -> parent_t &; @@ -128,6 +138,24 @@ class ConfigureStoreChunkFromBuffer auto enqueueStore() -> void; }; + +template +class ConfigureLoadStoreFromBuffer + : public ConfigureStoreChunkFromBuffer< + Ptr_Type, + ConfigureLoadStoreFromBuffer> +{ + using parent_t = ConfigureStoreChunkFromBuffer< + Ptr_Type, + ConfigureLoadStoreFromBuffer>; + template + friend class ConfigureLoadStore; + ConfigureLoadStoreFromBuffer( + Ptr_Type buffer, typename parent_t::parent_t &&); + +public: + auto enqueueLoad() -> void; +}; } // namespace openPMD #include "openPMD/LoadStoreChunk.tpp" diff --git a/include/openPMD/LoadStoreChunk.tpp b/include/openPMD/LoadStoreChunk.tpp index 215df35302..8f227aea03 100644 --- a/include/openPMD/LoadStoreChunk.tpp +++ b/include/openPMD/LoadStoreChunk.tpp @@ -4,20 +4,17 @@ namespace openPMD { - template template auto ConfigureLoadStore::fromSharedPtr(std::shared_ptr data) - -> ConfigureStoreChunkFromBuffer< - std::shared_ptr const>> + -> shared_ptr_return_type { if (!data) { throw std::runtime_error( "Unallocated pointer passed during chunk store."); } - return ConfigureStoreChunkFromBuffer< - std::shared_ptr const>>( + return shared_ptr_return_type( std::static_pointer_cast const>( std::move(data)), {std::move(*this)}); @@ -25,51 +22,46 @@ auto ConfigureLoadStore::fromSharedPtr(std::shared_ptr data) template template auto ConfigureLoadStore::fromUniquePtr(UniquePtrWithLambda data) - -> ConfigureStoreChunkFromBuffer< - UniquePtrWithLambda>> + -> unique_ptr_return_type + { if (!data) { throw std::runtime_error( "Unallocated pointer passed during chunk store."); } - return ConfigureStoreChunkFromBuffer< - UniquePtrWithLambda>>( + return unique_ptr_return_type( std::move(data).template static_cast_>(), {std::move(*this)}); } template template auto ConfigureLoadStore::fromRawPtr(T *data) - -> ConfigureStoreChunkFromBuffer< - std::shared_ptr const>> + -> shared_ptr_return_type { if (!data) { throw std::runtime_error( "Unallocated pointer passed during chunk store."); } - return ConfigureStoreChunkFromBuffer< - std::shared_ptr const>>( + return shared_ptr_return_type( auxiliary::shareRaw(data), {std::move(*this)}); } template template auto ConfigureLoadStore::fromUniquePtr(std::unique_ptr data) - -> ConfigureStoreChunkFromBuffer< - UniquePtrWithLambda>> + -> unique_ptr_return_type { return fromUniquePtr(UniquePtrWithLambda(std::move(data))); } template template auto ConfigureLoadStore::fromContiguousContainer( - T_ContiguousContainer &data) -> - typename std::enable_if_t< + T_ContiguousContainer &data) + -> std::enable_if_t< auxiliary::IsContiguousContainer_v, - ConfigureStoreChunkFromBuffer const>>> + shared_ptr_return_type> { if (!m_extent.has_value() && dim() == 1) { diff --git a/include/openPMD/RecordComponent.hpp b/include/openPMD/RecordComponent.hpp index d7aeab3ec3..1ba7f940cf 100644 --- a/include/openPMD/RecordComponent.hpp +++ b/include/openPMD/RecordComponent.hpp @@ -135,7 +135,7 @@ class RecordComponent : public BaseRecordComponent friend class MeshRecordComponent; template friend class ConfigureLoadStore; - template + template friend class ConfigureStoreChunkFromBuffer; public: diff --git a/src/LoadStoreChunk.cpp b/src/LoadStoreChunk.cpp index 8b27ae7e41..69202eb91b 100644 --- a/src/LoadStoreChunk.cpp +++ b/src/LoadStoreChunk.cpp @@ -121,47 +121,49 @@ auto ConfigureLoadStore::enqueueStore() -> DynamicMemoryView return m_rc.storeChunkSpan_impl(storeChunkConfig()); } -template -ConfigureStoreChunkFromBuffer::ConfigureStoreChunkFromBuffer( - Ptr_Type buffer, parent_t &&parent) +template +ConfigureStoreChunkFromBuffer:: + ConfigureStoreChunkFromBuffer(Ptr_Type buffer, parent_t &&parent) : parent_t(std::move(parent)), m_buffer(std::move(buffer)) {} -template -auto ConfigureStoreChunkFromBuffer::as_parent() && -> parent_t && +template +auto ConfigureStoreChunkFromBuffer::as_parent() + && -> parent_t && { return std::move(*this); } -template -auto ConfigureStoreChunkFromBuffer::as_parent() & -> parent_t & +template +auto ConfigureStoreChunkFromBuffer::as_parent() + & -> parent_t & { return *this; } -template -auto ConfigureStoreChunkFromBuffer::as_parent() +template +auto ConfigureStoreChunkFromBuffer::as_parent() const & -> parent_t const & { return *this; } -template -auto ConfigureStoreChunkFromBuffer::storeChunkConfig() const - -> internal::StoreChunkConfigFromBuffer +template +auto ConfigureStoreChunkFromBuffer::storeChunkConfig() + const -> internal::StoreChunkConfigFromBuffer { return internal::StoreChunkConfigFromBuffer{ this->getOffset(), this->getExtent(), m_mem_select}; } -template -auto ConfigureStoreChunkFromBuffer::memorySelection( - MemorySelection sel) -> ConfigureStoreChunkFromBuffer & +template +auto ConfigureStoreChunkFromBuffer::memorySelection( + MemorySelection sel) -> return_type & { this->m_mem_select = std::make_optional(std::move(sel)); - return *this; + return *static_cast(this); } -template -auto ConfigureStoreChunkFromBuffer::enqueueStore() -> void +template +auto ConfigureStoreChunkFromBuffer::enqueueStore() -> void { this->m_rc.storeChunk_impl( asWriteBuffer(std::move(m_buffer)), @@ -169,6 +171,19 @@ auto ConfigureStoreChunkFromBuffer::enqueueStore() -> void storeChunkConfig()); } +template +ConfigureLoadStoreFromBuffer::ConfigureLoadStoreFromBuffer( + Ptr_Type buffer, typename parent_t::parent_t &&parent) + : parent_t(std::move(buffer), std::move(parent)) +{ + static_assert( + std::is_same_v< + Ptr_Type, + std::shared_ptr>, + "ConfigureLoadStoreFromBuffer must be instantiated with a shared_ptr " + "type."); +} + #define INSTANTIATE_METHOD_TEMPLATES(base_class, dtype) \ template auto base_class::enqueueStore() -> DynamicMemoryView; @@ -181,13 +196,15 @@ OPENPMD_FOREACH_DATASET_DATATYPE(INSTANTIATE_METHOD_TEMPLATES_FOR_BASE) #undef INSTANTIATE_METHOD_TEMPLATES_FOR_BASE #define INSTANTIATE_STORE_CHUNK_FROM_BUFFER(dtype) \ + template class ConfigureLoadStoreFromBuffer>; \ template class ConfigureStoreChunkFromBuffer< \ - std::shared_ptr>; \ + std::shared_ptr, \ + ConfigureLoadStoreFromBuffer>>; \ template class ConfigureLoadStore< \ - ConfigureStoreChunkFromBuffer>>; \ + ConfigureLoadStoreFromBuffer>>; \ INSTANTIATE_METHOD_TEMPLATES( \ ConfigureLoadStore< \ - ConfigureStoreChunkFromBuffer>>, \ + ConfigureLoadStoreFromBuffer>>, \ dtype) \ template class ConfigureStoreChunkFromBuffer>; \ template class ConfigureLoadStore< \