From bd685133a625d7b3a46b265c37c47e24edbb8af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 25 Oct 2022 16:07:19 +0200 Subject: [PATCH] Further overriding Container methods --- include/openPMD/backend/BaseRecord.hpp | 387 ++++++++++++------------- include/openPMD/backend/Container.hpp | 12 +- 2 files changed, 195 insertions(+), 204 deletions(-) diff --git a/include/openPMD/backend/BaseRecord.hpp b/include/openPMD/backend/BaseRecord.hpp index 5c38eb86b3..bbed6c9ab1 100644 --- a/include/openPMD/backend/BaseRecord.hpp +++ b/include/openPMD/backend/BaseRecord.hpp @@ -268,6 +268,7 @@ class BaseRecord { return makeIterator(T_Container::end()); } + const_iterator end() const { return makeIterator(T_Container::end()); @@ -275,13 +276,169 @@ class BaseRecord virtual ~BaseRecord() = default; - 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); - bool empty() const noexcept; + mapped_type &operator[](key_type const &key) + { + auto it = this->find(key); + if (it != this->end()) + { + return std::visit( + auxiliary::overloaded{ + [](typename iterator::Left &l) -> mapped_type & { + return l->second; + }, + [this](typename iterator::Right &) -> mapped_type & { + /* + * Do not use the iterator result, as it is a non-owning + * handle + */ + return static_cast(*this); + }}, + it.m_iterator); + } + else + { + bool const keyScalar = (key == RecordComponent::SCALAR); + if ((keyScalar && !Container::empty() && !scalar()) || + (scalar() && !keyScalar)) + throw std::runtime_error( + "A scalar component can not be contained at " + "the same time as one or more regular components."); + + if (keyScalar) + { + /* + * This activates the RecordComponent API of this object. + */ + T_RecordComponent::get(); + } + mapped_type &ret = keyScalar ? static_cast(*this) + : T_Container::operator[](key); + return ret; + } + } + + mapped_type &operator[](key_type &&key) + { + auto it = this->find(key); + if (it != this->end()) + { + return std::visit( + auxiliary::overloaded{ + [](typename iterator::Left &l) -> mapped_type & { + return l->second; + }, + [this](typename iterator::Right &) -> mapped_type & { + /* + * Do not use the iterator result, as it is a non-owning + * handle + */ + return static_cast(*this); + }}, + it.m_iterator); + } + else + { + bool const keyScalar = (key == RecordComponent::SCALAR); + if ((keyScalar && !Container::empty() && !scalar()) || + (scalar() && !keyScalar)) + throw std::runtime_error( + "A scalar component can not be contained at " + "the same time as one or more regular components."); + + if (keyScalar) + { + /* + * This activates the RecordComponent API of this object. + */ + T_RecordComponent::get(); + } + mapped_type &ret = keyScalar + ? static_cast(*this) + : T_Container::operator[](std::move(key)); + return ret; + } + } + + mapped_type &at(key_type const &key) + { + return const_cast( + static_cast const *>(this) + ->at(key)); + } + + mapped_type const &at(key_type const &key) const + { + bool const keyScalar = (key == RecordComponent::SCALAR); + if (keyScalar) + { + if (!get().m_datasetDefined) + { + throw std::out_of_range( + "[at()] Requested scalar entry from non-scalar record."); + } + return static_cast(*this); + } + else + { + return T_Container::at(key); + } + } + + size_type erase(key_type const &key) + { + bool const keyScalar = (key == RecordComponent::SCALAR); + size_type res; + if (!keyScalar || (keyScalar && this->at(key).constant())) + res = Container::erase(key); + else + { + if (this->written()) + { + Parameter dDelete; + dDelete.name = "."; + this->IOHandler()->enqueue(IOTask(this, dDelete)); + this->IOHandler()->flush(internal::defaultFlushParams); + } + res = get().m_datasetDefined ? 1 : 0; + } + + if (keyScalar) + { + this->written() = false; + this->writable().abstractFilePosition.reset(); + this->get().m_datasetDefined = false; + } + return res; + } + + iterator erase(iterator it) + { + return std::visit( + auxiliary::overloaded{ + [this](typename iterator::Left &left) { + return makeIterator(T_Container::erase(left)); + }, + [this](typename iterator::Right &) { + if (this->written()) + { + Parameter dDelete; + dDelete.name = "."; + this->IOHandler()->enqueue(IOTask(this, dDelete)); + this->IOHandler()->flush(internal::defaultFlushParams); + this->written() = false; + } + this->writable().abstractFilePosition.reset(); + this->get().m_datasetDefined = false; + return end(); + }}, + it.m_iterator); + } + + bool empty() const noexcept + { + return !scalar() && T_Container::empty(); + } + iterator find(key_type const &key) { auto &r = get(); @@ -301,6 +458,7 @@ class BaseRecord return makeIterator(r.m_container.find(key)); } } + const_iterator find(key_type const &key) const { auto &r = get(); @@ -320,7 +478,30 @@ class BaseRecord return makeIterator(r.m_container.find(key)); } } - size_type count(key_type const &key) const override; + + size_type count(key_type const &key) const + { + if (key == RecordComponent::SCALAR) + { + return get().m_datasetDefined ? 1 : 0; + } + else + { + return T_Container::count(key); + } + } + + size_type size() const + { + if (scalar()) + { + return 1; + } + else + { + return T_Container::size(); + } + } //! @todo add also, as soon as added in Container: // iterator erase(const_iterator first, const_iterator last) override; @@ -400,196 +581,6 @@ BaseRecord::BaseRecord() std::make_pair(RecordComponent::SCALAR, std::move(rc))); } -template -inline typename BaseRecord::mapped_type & -BaseRecord::operator[](key_type const &key) -{ - auto it = this->find(key); - if (it != this->end()) - { - return std::visit( - auxiliary::overloaded{ - [](typename iterator::Left &l) -> mapped_type & { - return l->second; - }, - [this](typename iterator::Right &) -> mapped_type & { - /* - * Do not use the iterator result, as it is a non-owning - * handle - */ - return static_cast(*this); - }}, - it.m_iterator); - } - else - { - bool const keyScalar = (key == RecordComponent::SCALAR); - if ((keyScalar && !Container::empty() && !scalar()) || - (scalar() && !keyScalar)) - throw std::runtime_error( - "A scalar component can not be contained at " - "the same time as one or more regular components."); - - if (keyScalar) - { - /* - * This activates the RecordComponent API of this object. - */ - T_RecordComponent::get(); - } - mapped_type &ret = keyScalar ? static_cast(*this) - : T_Container::operator[](key); - return ret; - } -} - -template -inline typename BaseRecord::mapped_type & -BaseRecord::operator[](key_type &&key) -{ - auto it = this->find(key); - if (it != this->end()) - { - return std::visit( - auxiliary::overloaded{ - [](typename iterator::Left &l) -> mapped_type & { - return l->second; - }, - [this](typename iterator::Right &) -> mapped_type & { - /* - * Do not use the iterator result, as it is a non-owning - * handle - */ - return static_cast(*this); - }}, - it.m_iterator); - } - else - { - bool const keyScalar = (key == RecordComponent::SCALAR); - if ((keyScalar && !Container::empty() && !scalar()) || - (scalar() && !keyScalar)) - throw std::runtime_error( - "A scalar component can not be contained at " - "the same time as one or more regular components."); - - if (keyScalar) - { - /* - * This activates the RecordComponent API of this object. - */ - T_RecordComponent::get(); - } - 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_datasetDefined) - { - throw std::out_of_range( - "[at()] Requested scalar entry from non-scalar record."); - } - return static_cast(*this); - } - else - { - return T_Container::at(key); - } -} - -template -inline typename BaseRecord::size_type -BaseRecord::erase(key_type const &key) -{ - bool const keyScalar = (key == RecordComponent::SCALAR); - size_type res; - if (!keyScalar || (keyScalar && this->at(key).constant())) - res = Container::erase(key); - else - { - if (this->written()) - { - Parameter dDelete; - dDelete.name = "."; - this->IOHandler()->enqueue(IOTask(this, dDelete)); - this->IOHandler()->flush(internal::defaultFlushParams); - } - res = get().m_datasetDefined ? 1 : 0; - } - - if (keyScalar) - { - this->written() = false; - this->writable().abstractFilePosition.reset(); - this->get().m_datasetDefined = false; - } - return res; -} - -template -inline typename BaseRecord::iterator -BaseRecord::erase(iterator it) -{ - - return std::visit( - auxiliary::overloaded{ - [this](typename iterator::Left &left) { - return makeIterator(T_Container::erase(left)); - }, - [this](typename iterator::Right &) { - if (this->written()) - { - Parameter dDelete; - dDelete.name = "."; - this->IOHandler()->enqueue(IOTask(this, dDelete)); - this->IOHandler()->flush(internal::defaultFlushParams); - this->written() = false; - } - this->writable().abstractFilePosition.reset(); - this->get().m_datasetDefined = false; - return end(); - }}, - it.m_iterator); -} - -template -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_datasetDefined ? 1 : 0; - } - else - { - return T_Container::count(key); - } -} - template inline std::array BaseRecord::unitDimension() const diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index 6101e6ab69..bad7bcb7ca 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -264,11 +264,11 @@ class Container : virtual public Attributable container().swap(other.m_container); } - virtual mapped_type &at(key_type const &key) + mapped_type &at(key_type const &key) { return container().at(key); } - virtual mapped_type const &at(key_type const &key) const + mapped_type const &at(key_type const &key) const { return container().at(key); } @@ -283,7 +283,7 @@ class Container : virtual public Attributable * @throws std::out_of_range error if in READ_ONLY mode and key does not * exist, otherwise key will be created */ - virtual mapped_type &operator[](key_type const &key) + mapped_type &operator[](key_type const &key) { auto it = container().find(key); if (it != container().end()) @@ -318,7 +318,7 @@ class Container : virtual public Attributable * @throws std::out_of_range error if in READ_ONLY mode and key does not * exist, otherwise key will be created */ - virtual mapped_type &operator[](key_type &&key) + mapped_type &operator[](key_type &&key) { auto it = container().find(key); if (it != container().end()) @@ -358,7 +358,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 */ - virtual size_type count(key_type const &key) const + size_type count(key_type const &key) const { return container().count(key); } @@ -382,7 +382,7 @@ class Container : virtual public Attributable * @param key Key of the element to remove. * @return Number of elements removed (either 0 or 1). */ - virtual size_type erase(key_type const &key) + size_type erase(key_type const &key) { if (Access::READ_ONLY == IOHandler()->m_frontendAccess) throw std::runtime_error(