Add VariantImpl in CollectionIterator

This commit is contained in:
Benoit Blanchon
2025-07-11 18:19:35 +02:00
parent 5589633697
commit c6fa8c1c1f
6 changed files with 54 additions and 52 deletions

View File

@ -4,6 +4,7 @@
#pragma once
#include <ArduinoJson/Collection/CollectionIterator.hpp>
#include <ArduinoJson/Variant/VariantCompare.hpp>
#include <ArduinoJson/Variant/VariantImpl.hpp>
@ -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));
}

View File

@ -4,6 +4,7 @@
#pragma once
#include <ArduinoJson/Collection/CollectionIterator.hpp>
#include <ArduinoJson/Variant/JsonVariant.hpp>
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE

View File

@ -4,7 +4,6 @@
#pragma once
#include <ArduinoJson/Collection/CollectionIterator.hpp>
#include <ArduinoJson/Memory/Alignment.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/VariantCompare.hpp>
@ -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

View File

@ -6,6 +6,7 @@
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Variant/VariantImpl.hpp>
#include <stddef.h> // 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

View File

@ -46,6 +46,10 @@ inline void VariantImpl::removeMember(TAdaptedString key) {
removeMember(findKey(key));
}
inline void VariantImpl::removeMember(iterator it) {
removePair(it);
}
template <typename TAdaptedString>
inline VariantData* VariantImpl::addMember(TAdaptedString key) {
if (!isObject())

View File

@ -4,7 +4,6 @@
#pragma once
#include <ArduinoJson/Collection/CollectionIterator.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Misc/SerializedValue.hpp>
#include <ArduinoJson/Numbers/convertNumber.hpp>
@ -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>
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 <typename TAdaptedString>
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;