From c6fa8c1c1f3e360e3239742707c6c0a08af0eff1 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 11 Jul 2025 18:19:35 +0200 Subject: [PATCH] Add `VariantImpl` in `CollectionIterator` --- src/ArduinoJson/Array/ArrayImpl.hpp | 7 ++++ src/ArduinoJson/Array/JsonArrayIterator.hpp | 1 + src/ArduinoJson/Collection/CollectionImpl.hpp | 34 ++++++++++--------- .../Collection/CollectionIterator.hpp | 30 +++++++++------- src/ArduinoJson/Object/ObjectImpl.hpp | 4 +++ src/ArduinoJson/Variant/VariantImpl.hpp | 30 ++++------------ 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/ArduinoJson/Array/ArrayImpl.hpp b/src/ArduinoJson/Array/ArrayImpl.hpp index 03df10cd..d2467fb5 100644 --- a/src/ArduinoJson/Array/ArrayImpl.hpp +++ b/src/ArduinoJson/Array/ArrayImpl.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include #include @@ -53,6 +54,12 @@ inline VariantData* VariantImpl::getElement(size_t index) const { return at(index).data(); } +inline void VariantImpl::removeElement(iterator it) { + if (!isArray()) + return; + removeOne(it); +} + inline void VariantImpl::removeElement(size_t index) { removeElement(at(index)); } diff --git a/src/ArduinoJson/Array/JsonArrayIterator.hpp b/src/ArduinoJson/Array/JsonArrayIterator.hpp index 2132f51b..8c01d13a 100644 --- a/src/ArduinoJson/Array/JsonArrayIterator.hpp +++ b/src/ArduinoJson/Array/JsonArrayIterator.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index 37d3d05a..4212d2da 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include @@ -12,18 +11,6 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -inline void CollectionIterator::next() { - ARDUINOJSON_ASSERT(slot_); - auto nextId = slot_->next; - slot_ = resources_->getVariant(nextId); - currentId_ = nextId; -} - -inline VariantImpl CollectionIterator::value() const { - ARDUINOJSON_ASSERT(slot_ != nullptr); - return VariantImpl(slot_, resources_); -} - inline VariantImpl::iterator VariantImpl::createIterator() const { if (!data_ || !data_->isCollection()) return iterator(); @@ -78,7 +65,7 @@ inline void VariantImpl::removeOne(iterator it) { if (it.done()) return; auto coll = getCollectionData(); - auto curr = it.slot_; + auto curr = it.data(); auto prev = getPreviousSlot(curr); auto next = curr->next; if (prev) @@ -87,14 +74,14 @@ inline void VariantImpl::removeOne(iterator it) { coll->head = next; if (next == NULL_SLOT) coll->tail = prev.id(); - freeVariant({it.slot_, it.currentId_}); + freeVariant({it.data(), it.currentId_}); } inline void VariantImpl::removePair(VariantImpl::iterator it) { if (it.done()) return; - auto keySlot = it.slot_; + auto keySlot = it.data(); auto valueId = keySlot->next; auto valueSlot = getVariant(valueId); @@ -119,4 +106,19 @@ inline size_t VariantImpl::nesting() const { return maxChildNesting + 1; } +inline size_t VariantImpl::size() const { + if (!data_) + return 0; + + size_t count = 0; + + for (auto it = createIterator(); !it.done(); it.next()) + count++; + + if (data_->type == VariantType::Object) + count /= 2; // TODO: do this in JsonObject? + + return count; +} + ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Collection/CollectionIterator.hpp b/src/ArduinoJson/Collection/CollectionIterator.hpp index 2fc4a9f5..203508ce 100644 --- a/src/ArduinoJson/Collection/CollectionIterator.hpp +++ b/src/ArduinoJson/Collection/CollectionIterator.hpp @@ -6,6 +6,7 @@ #include #include +#include #include // size_t @@ -21,39 +22,44 @@ class CollectionIterator { public: CollectionIterator() {} - void next(); + void next() { + ARDUINOJSON_ASSERT(!done()); + auto nextId = value_.getData()->next; + auto resources = value_.getResourceManager(); + value_ = VariantImpl(resources->getVariant(nextId), resources); + currentId_ = nextId; + } - VariantImpl value() const; + const VariantImpl& value() const { + return value_; + } bool done() const { - return slot_ == nullptr; + return value_.isUnbound(); } bool operator==(const CollectionIterator& other) const { - return slot_ == other.slot_; + return data() == other.data(); } bool operator!=(const CollectionIterator& other) const { - return slot_ != other.slot_; + return !operator==(other); } VariantData* data() { - return slot_; + return value_.getData(); } const VariantData* data() const { - return slot_; + return value_.getData(); } private: CollectionIterator(SlotId slotId, ResourceManager* resources) - : slot_(resources->getVariant(slotId)), - currentId_(slotId), - resources_(resources) {} + : value_(resources->getVariant(slotId), resources), currentId_(slotId) {} - VariantData* slot_ = nullptr; + VariantImpl value_; SlotId currentId_ = NULL_SLOT; - ResourceManager* resources_ = nullptr; }; ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Object/ObjectImpl.hpp b/src/ArduinoJson/Object/ObjectImpl.hpp index 939a42f7..66855292 100644 --- a/src/ArduinoJson/Object/ObjectImpl.hpp +++ b/src/ArduinoJson/Object/ObjectImpl.hpp @@ -46,6 +46,10 @@ inline void VariantImpl::removeMember(TAdaptedString key) { removeMember(findKey(key)); } +inline void VariantImpl::removeMember(iterator it) { + removePair(it); +} + template inline VariantData* VariantImpl::addMember(TAdaptedString key) { if (!isObject()) diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index 9068fdba..2d965813 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include @@ -14,6 +13,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE +class CollectionIterator; + class VariantImpl { VariantData* data_; ResourceManager* resources_; @@ -35,7 +36,7 @@ class VariantImpl { } template - typename TVisitor::result_type accept(TVisitor& visit) { + typename TVisitor::result_type accept(TVisitor& visit) const { if (!data_) return visit.visit(nullptr); @@ -337,20 +338,14 @@ class VariantImpl { size_t nesting() const; - void removeElement(iterator it) { - if (!isArray()) - return; - removeOne(it); - } + void removeElement(iterator it); void removeElement(size_t index); template void removeMember(TAdaptedString key); - void removeMember(iterator it) { - removePair(it); - } + void removeMember(iterator it); bool setBoolean(bool value) { if (!data_) @@ -455,20 +450,7 @@ class VariantImpl { void empty(); - size_t size() const { - if (!data_) - return 0; - - size_t count = 0; - - for (auto it = createIterator(); !it.done(); it.next()) - count++; - - if (data_->type == VariantType::Object) - count /= 2; // TODO: do this in JsonObject? - - return count; - } + size_t size() const; VariantType type() const { return data_ ? data_->type : VariantType::Null;