From 4f75a312513b68ac192c056b8ad6f9b93d7e0a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Fri, 21 Oct 2022 13:08:54 +0200 Subject: [PATCH] keep fixing things hehehe --- include/openPMD/RecordComponent.hpp | 2 + include/openPMD/backend/BaseRecord.hpp | 71 +++++++++++++++++++++++--- include/openPMD/backend/Container.hpp | 6 +-- src/Iteration.cpp | 3 +- src/Mesh.cpp | 16 ++---- src/ParticleSpecies.cpp | 6 +-- src/Record.cpp | 17 ++---- src/RecordComponent.cpp | 16 ++++-- 8 files changed, 91 insertions(+), 46 deletions(-) diff --git a/include/openPMD/RecordComponent.hpp b/include/openPMD/RecordComponent.hpp index 0e57798876..047a8b445a 100644 --- a/include/openPMD/RecordComponent.hpp +++ b/include/openPMD/RecordComponent.hpp @@ -339,6 +339,8 @@ OPENPMD_protected BaseRecordComponent::setData(m_recordComponentData); } + void datasetDefined() override; + void readBase(); }; // RecordComponent diff --git a/include/openPMD/backend/BaseRecord.hpp b/include/openPMD/backend/BaseRecord.hpp index 584e34588b..82f70c73e3 100644 --- a/include/openPMD/backend/BaseRecord.hpp +++ b/include/openPMD/backend/BaseRecord.hpp @@ -71,12 +71,17 @@ namespace internal */ template < typename T_elem_maybe_void, - typename T_RecordComponent = T_elem_maybe_void> + typename T_RecordComponent_ = T_elem_maybe_void> class BaseRecord : public Container< typename auxiliary::OkOr >::type> - , public T_RecordComponent + , public T_RecordComponent_ { +protected: + // make it available for child classes + +private: + using T_RecordComponent = T_RecordComponent_; using T_elem = typename auxiliary::OkOr >::type; using T_Container = Container; @@ -138,9 +143,12 @@ class BaseRecord mapped_type &operator[](key_type const &key) override; mapped_type &operator[](key_type &&key) override; + mapped_type &at(key_type const &key) override; + mapped_type const &at(key_type const &key) const override; size_type erase(key_type const &key) override; iterator erase(iterator res) override; bool empty() const noexcept; + size_type count(key_type const &key) const override; //! @todo add also, as soon as added in Container: // iterator erase(const_iterator first, const_iterator last) override; @@ -264,13 +272,43 @@ BaseRecord::operator[](key_type &&key) } /* * datasetDefined() inits the container entry + * is this object slicing???? JA */ - mapped_type &ret = keyScalar ? T_Container::at(std::move(key)) + mapped_type &ret = keyScalar ? static_cast(*this) : T_Container::operator[](std::move(key)); return ret; } } +template +inline auto BaseRecord::at(key_type const &key) + -> mapped_type & +{ + return const_cast( + static_cast const *>(this)->at( + key)); +} + +template +inline auto BaseRecord::at(key_type const &key) const + -> mapped_type const & +{ + bool const keyScalar = (key == RecordComponent::SCALAR); + if (keyScalar) + { + if (!get().m_containsScalar) + { + throw std::out_of_range( + "[at()] Requested scalar entry from non-scalar record."); + } + return static_cast(*this); + } + else + { + return at(key); + } +} + template inline typename BaseRecord::size_type BaseRecord::erase(key_type const &key) @@ -337,6 +375,20 @@ bool BaseRecord::empty() const noexcept return T_Container::empty(); } +template +auto BaseRecord::count(key_type const &key) const + -> size_type +{ + if (key == RecordComponent::SCALAR) + { + return get().m_containsScalar ? 1 : 0; + } + else + { + return T_Container::count(key); + } +} + template inline std::array BaseRecord::unitDimension() const @@ -400,7 +452,7 @@ template inline void BaseRecord::flush( std::string const &name, internal::FlushParams const &flushParams) { - if (!this->written() && this->empty()) + if (!this->written() && this->empty() && !get().m_containsScalar) throw std::runtime_error( "A Record can not be written without any contained " "RecordComponents: " + @@ -433,9 +485,14 @@ void BaseRecord::datasetDefined() { // If the RecordComponent API of this object has been used, then the record // is a scalar one - T_RecordComponent copy; - copy.setData(m_baseRecordData); - T_Container::emplace(RecordComponent::SCALAR, std::move(copy)); + T_RecordComponent &rc = *this; + /* + * No need to do any of the hierarchy linking business, + * rc and *this are the same object, so everything is linked already. + * Just need to init the RC-specific stuff. + */ + traits::GenerationPolicy gen; + gen(rc); get().m_containsScalar = true; T_RecordComponent::datasetDefined(); } diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index f466ae4674..074dcc5873 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -263,11 +263,11 @@ class Container : virtual public Attributable container().swap(other.m_container); } - mapped_type &at(key_type const &key) + virtual mapped_type &at(key_type const &key) { return container().at(key); } - mapped_type const &at(key_type const &key) const + virtual mapped_type const &at(key_type const &key) const { return container().at(key); } @@ -357,7 +357,7 @@ class Container : virtual public Attributable * @param key key value of the element to count * @return since keys are unique in this container, returns 0 or 1 */ - size_type count(key_type const &key) const + virtual size_type count(key_type const &key) const { return container().count(key); } diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 9fd8a84522..6c8da04151 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -601,8 +601,7 @@ void Iteration::readMeshes(std::string const &meshesPath) dOpen.name = mesh_name; IOHandler()->enqueue(IOTask(&m, dOpen)); IOHandler()->flush(internal::defaultFlushParams); - MeshRecordComponent &mrc = m[MeshRecordComponent::SCALAR]; - mrc.parent() = m.parent(); + MeshRecordComponent &mrc = m; IOHandler()->enqueue(IOTask(&mrc, dOpen)); IOHandler()->flush(internal::defaultFlushParams); mrc.written() = false; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index aa5dd045dc..947f1fc36f 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -229,12 +229,8 @@ void Mesh::flush_impl( { if (scalar()) { - MeshRecordComponent &mrc = at(RecordComponent::SCALAR); - mrc.parent() = parent(); + MeshRecordComponent &mrc = *this; mrc.flush(name, flushParams); - Parameter pSynchronize; - pSynchronize.otherWritable = &mrc.writable(); - IOHandler()->enqueue(IOTask(this, pSynchronize)); } else { @@ -252,12 +248,7 @@ void Mesh::flush_impl( { if (scalar()) { - for (auto &comp : *this) - { - comp.second.flush(name, flushParams); - writable().abstractFilePosition = - comp.second.writable().abstractFilePosition; - } + T_RecordComponent::flush(name, flushParams); } else { @@ -384,8 +375,7 @@ void Mesh::read() if (scalar()) { - /* using operator[] will incorrectly update parent */ - map.at(MeshRecordComponent::SCALAR).read(); + T_RecordComponent::read(); } else { diff --git a/src/ParticleSpecies.cpp b/src/ParticleSpecies.cpp index a413e8ef5a..eadaf4ec4c 100644 --- a/src/ParticleSpecies.cpp +++ b/src/ParticleSpecies.cpp @@ -80,8 +80,7 @@ void ParticleSpecies::read() if (value != att_end && shape != att_end) { internal::EraseStaleEntries scalarMap(r); - RecordComponent &rc = scalarMap[RecordComponent::SCALAR]; - rc.parent() = r.parent(); + RecordComponent &rc = r; IOHandler()->enqueue(IOTask(&rc, pOpen)); IOHandler()->flush(internal::defaultFlushParams); rc.get().m_isConstant = true; @@ -125,8 +124,7 @@ void ParticleSpecies::read() IOHandler()->enqueue(IOTask(&r, dOpen)); IOHandler()->flush(internal::defaultFlushParams); internal::EraseStaleEntries scalarMap(r); - RecordComponent &rc = scalarMap[RecordComponent::SCALAR]; - rc.parent() = r.parent(); + RecordComponent &rc = r; IOHandler()->enqueue(IOTask(&rc, dOpen)); IOHandler()->flush(internal::defaultFlushParams); rc.written() = false; diff --git a/src/Record.cpp b/src/Record.cpp index b886af2cd4..02d358b1b7 100644 --- a/src/Record.cpp +++ b/src/Record.cpp @@ -57,12 +57,8 @@ void Record::flush_impl( { if (scalar()) { - RecordComponent &rc = at(RecordComponent::SCALAR); - rc.parent() = parent(); + RecordComponent &rc = *this; rc.flush(name, flushParams); - Parameter pSynchronize; - pSynchronize.otherWritable = &rc.writable(); - IOHandler()->enqueue(IOTask(this, pSynchronize)); } else { @@ -81,12 +77,7 @@ void Record::flush_impl( if (scalar()) { - for (auto &comp : *this) - { - comp.second.flush(name, flushParams); - writable().abstractFilePosition = - comp.second.writable().abstractFilePosition; - } + T_RecordComponent::flush(name, flushParams); } else { @@ -104,17 +95,15 @@ void Record::read() if (scalar()) { /* using operator[] will incorrectly update parent */ - auto &scalarComponent = this->at(RecordComponent::SCALAR); try { - scalarComponent.read(); + T_RecordComponent::read(); } catch (error::ReadError const &err) { std::cerr << "Cannot read scalar record component and will skip it " "due to read error:\n" << err.what() << std::endl; - this->container().erase(RecordComponent::SCALAR); } } else diff --git a/src/RecordComponent.cpp b/src/RecordComponent.cpp index 811d6c295b..53598e3507 100644 --- a/src/RecordComponent.cpp +++ b/src/RecordComponent.cpp @@ -37,14 +37,15 @@ namespace openPMD { namespace internal { - RecordComponentData::RecordComponentData() = default; + RecordComponentData::RecordComponentData() + { + m_dataset = Dataset(Datatype::CHAR, {1}); + }; } // namespace internal RecordComponent::RecordComponent() { BaseRecordComponent::setData(m_recordComponentData); - setUnitSI(1); - resetDataset(Dataset(Datatype::CHAR, {1})); } // We need to instantiate this somewhere otherwise there might be linker issues @@ -272,6 +273,15 @@ void RecordComponent::flush( } } +void RecordComponent::datasetDefined() +{ + if (!containsAttribute("unitSI")) + { + setUnitSI(1); + } + BaseRecordComponent::datasetDefined(); +} + void RecordComponent::read() { readBase();