Add CollectionIterator

This commit is contained in:
Benoit Blanchon
2023-06-26 17:41:46 +02:00
parent d921cd6d02
commit 688e21e75f
19 changed files with 269 additions and 221 deletions

View File

@ -51,7 +51,8 @@ TEST_CASE("JsonObject::remove()") {
}
SECTION("Remove last") {
it += 2;
++it;
++it;
obj.remove(it);
serializeJson(obj, result);
REQUIRE("{\"a\":0,\"b\":1}" == result);

View File

@ -59,7 +59,7 @@ class ArrayData : public CollectionData {
}
private:
VariantSlot* getSlot(size_t index) const;
iterator at(size_t index) const;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -9,6 +9,15 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline ArrayData::iterator ArrayData::at(size_t index) const {
auto it = begin();
while (it && index) {
++it;
--index;
}
return it;
}
inline VariantData* ArrayData::addElement(ResourceManager* resources) {
auto slot = resources->allocVariant();
if (!slot)
@ -21,63 +30,57 @@ inline bool ArrayData::copyFrom(const ArrayData& src,
ResourceManager* resources) {
clear(resources);
for (VariantSlot* s = src.head(); s; s = s->next()) {
for (auto it = src.begin(); it; ++it) {
auto var = addElement(resources);
if (!var)
return false;
if (!var->copyFrom(s->data(), resources))
if (!var->copyFrom(*it, resources))
return false;
}
return true;
}
inline bool ArrayData::equals(const ArrayData& other) const {
auto a = head();
auto b = other.head();
auto a = begin();
auto b = other.begin();
for (;;) {
if (!a && !b) // both ended
return true;
if (!a || !b) // one ended
return false;
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
if (compare(a.data(), b.data()) != COMPARE_RESULT_EQUAL)
return false;
a = a->next();
b = b->next();
++a;
++b;
}
}
inline VariantData* ArrayData::getOrAddElement(size_t index,
ResourceManager* resources) {
VariantSlot* slot = head();
while (slot && index > 0) {
slot = slot->next();
auto it = begin();
while (it && index > 0) {
++it;
index--;
}
if (!slot)
if (!it)
index++;
VariantData* element = it.data();
while (index > 0) {
slot = resources->allocVariant();
if (!slot)
element = addElement(resources);
if (!element)
return nullptr;
addSlot(slot);
index--;
}
return slot->data();
return element;
}
inline VariantData* ArrayData::getElement(size_t index) const {
return slotData(getSlot(index));
}
inline VariantSlot* ArrayData::getSlot(size_t index) const {
if (!head())
return 0;
return head()->next(index);
return at(index).data();
}
inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
removeSlot(getSlot(index), resources);
remove(at(index), resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -68,7 +68,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(resources_, data_->head());
return iterator(data_->begin(), resources_);
}
// Returns an iterator following the last element of the array.
@ -92,7 +92,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(iterator it) const {
detail::ArrayData::removeSlot(data_, it.slot_, resources_);
detail::ArrayData::remove(data_, it.iterator_, resources_);
}
// Removes the element at the specified index.

View File

@ -26,7 +26,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(data_->head());
return iterator(data_->begin());
}
// Returns an iterator to the element following the last element of the array.

View File

@ -30,76 +30,66 @@ class JsonArrayIterator {
friend class JsonArray;
public:
JsonArrayIterator() : slot_(0) {}
explicit JsonArrayIterator(detail::ResourceManager* resources,
detail::VariantSlot* slot)
: resources_(resources), slot_(slot) {}
JsonArrayIterator() {}
explicit JsonArrayIterator(detail::ArrayData::iterator iterator,
detail::ResourceManager* resources)
: iterator_(iterator), resources_(resources) {}
JsonVariant operator*() const {
return JsonVariant(slot_->data(), resources_);
JsonVariant operator*() {
return JsonVariant(iterator_.data(), resources_);
}
Ptr<JsonVariant> operator->() {
return operator*();
}
bool operator==(const JsonArrayIterator& other) const {
return slot_ == other.slot_;
return iterator_ == other.iterator_;
}
bool operator!=(const JsonArrayIterator& other) const {
return slot_ != other.slot_;
return iterator_ != other.iterator_;
}
JsonArrayIterator& operator++() {
slot_ = slot_->next();
return *this;
}
JsonArrayIterator& operator+=(size_t distance) {
slot_ = slot_->next(distance);
++iterator_;
return *this;
}
private:
detail::ArrayData::iterator iterator_;
detail::ResourceManager* resources_;
detail::VariantSlot* slot_;
};
class JsonArrayConstIterator {
friend class JsonArray;
public:
JsonArrayConstIterator() : slot_(0) {}
explicit JsonArrayConstIterator(const detail::VariantSlot* slot)
: slot_(slot) {}
JsonArrayConstIterator() {}
explicit JsonArrayConstIterator(detail::ArrayData::iterator iterator)
: iterator_(iterator) {}
JsonVariantConst operator*() const {
return JsonVariantConst(slot_->data());
return JsonVariantConst(iterator_.data());
}
Ptr<JsonVariantConst> operator->() {
return operator*();
}
bool operator==(const JsonArrayConstIterator& other) const {
return slot_ == other.slot_;
return iterator_ == other.iterator_;
}
bool operator!=(const JsonArrayConstIterator& other) const {
return slot_ != other.slot_;
return iterator_ != other.iterator_;
}
JsonArrayConstIterator& operator++() {
slot_ = slot_->next();
return *this;
}
JsonArrayConstIterator& operator+=(size_t distance) {
slot_ = slot_->next(distance);
++iterator_;
return *this;
}
private:
const detail::VariantSlot* slot_;
detail::ArrayData::iterator iterator_;
};
ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

@ -14,6 +14,58 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantData;
class VariantSlot;
class CollectionIterator {
friend class CollectionData;
public:
CollectionIterator() : slot_(nullptr) {}
CollectionIterator& operator++();
operator bool() const {
return slot_ != nullptr;
}
bool operator==(const CollectionIterator& other) const {
return slot_ == other.slot_;
}
bool operator!=(const CollectionIterator& other) const {
return slot_ != other.slot_;
}
VariantData* operator->() {
ARDUINOJSON_ASSERT(slot_ != nullptr);
return data();
}
VariantData& operator*() {
ARDUINOJSON_ASSERT(slot_ != nullptr);
return *data();
}
const VariantData& operator*() const {
ARDUINOJSON_ASSERT(slot_ != nullptr);
return *data();
}
const char* key() const;
bool ownsKey() const;
VariantData* data() {
return reinterpret_cast<VariantData*>(slot_);
}
const VariantData* data() const {
return reinterpret_cast<const VariantData*>(slot_);
}
private:
CollectionIterator(VariantSlot* slot) : slot_(slot) {}
VariantSlot* slot_;
};
class CollectionData {
VariantSlot* head_ = 0;
VariantSlot* tail_ = 0;
@ -26,8 +78,19 @@ class CollectionData {
static void operator delete(void*, void*) noexcept {}
using iterator = CollectionIterator;
iterator begin() const {
return iterator(head_);
}
iterator end() const {
return iterator(nullptr);
}
size_t memoryUsage() const;
size_t size() const;
size_t nesting() const;
void clear(ResourceManager* resources);
@ -37,21 +100,16 @@ class CollectionData {
collection->clear(resources);
}
void removeSlot(VariantSlot* slot, ResourceManager* resources);
static void removeSlot(CollectionData* collection, VariantSlot* slot,
ResourceManager* resources) {
if (!collection)
return;
collection->removeSlot(slot, resources);
}
VariantSlot* head() const {
return head_;
}
void movePointers(ptrdiff_t variantDistance);
void remove(iterator it, ResourceManager* resources);
static void remove(CollectionData* collection, iterator it,
ResourceManager* resources) {
if (collection)
return collection->remove(it, resources);
}
protected:
void addSlot(VariantSlot*);

View File

@ -11,6 +11,22 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline const char* CollectionIterator::key() const {
ARDUINOJSON_ASSERT(slot_ != nullptr);
return slot_->key();
}
inline bool CollectionIterator::ownsKey() const {
ARDUINOJSON_ASSERT(slot_ != nullptr);
return slot_->ownsKey();
}
inline CollectionIterator& CollectionIterator::operator++() {
ARDUINOJSON_ASSERT(slot_ != nullptr);
slot_ = slot_->next();
return *this;
}
inline void CollectionData::addSlot(VariantSlot* slot) {
ARDUINOJSON_ASSERT(slot != nullptr);
@ -41,19 +57,19 @@ inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
return 0;
}
inline void CollectionData::removeSlot(VariantSlot* slot,
ResourceManager* resources) {
if (!slot)
inline void CollectionData::remove(iterator it, ResourceManager* resources) {
if (!it)
return;
VariantSlot* prev = getPreviousSlot(slot);
VariantSlot* next = slot->next();
auto curr = it.slot_;
auto prev = getPreviousSlot(curr);
auto next = curr->next();
if (prev)
prev->setNext(next);
else
head_ = next;
if (!next)
tail_ = prev;
slotRelease(slot, resources);
slotRelease(curr, resources);
}
inline size_t CollectionData::memoryUsage() const {
@ -66,6 +82,16 @@ inline size_t CollectionData::memoryUsage() const {
return total;
}
inline size_t CollectionData::nesting() const {
size_t maxChildNesting = 0;
for (const VariantSlot* s = head_; s; s = s->next()) {
size_t childNesting = s->data()->nesting();
if (childNesting > maxChildNesting)
maxChildNesting = childNesting;
}
return maxChildNesting + 1;
}
inline size_t CollectionData::size() const {
return slotSize(head_);
}

View File

@ -21,13 +21,13 @@ class JsonSerializer : public Visitor<size_t> {
FORCE_INLINE size_t visitArray(const ArrayData& array) {
write('[');
const VariantSlot* slot = array.head();
auto it = array.begin();
while (slot != 0) {
slot->data()->accept(*this);
while (it) {
it->accept(*this);
slot = slot->next();
if (slot == 0)
++it;
if (!it)
break;
write(',');
@ -40,15 +40,15 @@ class JsonSerializer : public Visitor<size_t> {
size_t visitObject(const ObjectData& object) {
write('{');
const VariantSlot* slot = object.head();
auto it = object.begin();
while (slot != 0) {
formatter_.writeString(slot->key());
while (it) {
formatter_.writeString(it.key());
write(':');
slot->data()->accept(*this);
it->accept(*this);
slot = slot->next();
if (slot == 0)
++it;
if (!it)
break;
write(',');

View File

@ -19,16 +19,16 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
size_t visitArray(const ArrayData& array) {
const VariantSlot* slot = array.head();
if (slot) {
auto it = array.begin();
if (it) {
base::write("[\r\n");
nesting_++;
while (slot != 0) {
while (it) {
indent();
slot->data()->accept(*this);
it->accept(*this);
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
++it;
base::write(it ? ",\r\n" : "\r\n");
}
nesting_--;
indent();
@ -40,18 +40,18 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
}
size_t visitObject(const ObjectData& object) {
const VariantSlot* slot = object.head();
if (slot) {
auto it = object.begin();
if (it) {
base::write("{\r\n");
nesting_++;
while (slot != 0) {
while (it) {
indent();
base::visitString(slot->key());
base::visitString(it.key());
base::write(": ");
slot->data()->accept(*this);
it->accept(*this);
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
++it;
base::write(it ? ",\r\n" : "\r\n");
}
nesting_--;
indent();

View File

@ -55,8 +55,8 @@ class MsgPackSerializer : public Visitor<size_t> {
writeByte(0xDD);
writeInteger(uint32_t(n));
}
for (const VariantSlot* slot = array.head(); slot; slot = slot->next()) {
slot->data()->accept(*this);
for (auto it = array.begin(); it; ++it) {
it->accept(*this);
}
return bytesWritten();
}
@ -72,9 +72,9 @@ class MsgPackSerializer : public Visitor<size_t> {
writeByte(0xDF);
writeInteger(uint32_t(n));
}
for (const VariantSlot* slot = object.head(); slot; slot = slot->next()) {
visitString(slot->key());
slot->data()->accept(*this);
for (auto it = object.begin(); it; ++it) {
visitString(it.key());
it->accept(*this);
}
return bytesWritten();
}

View File

@ -76,7 +76,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(resources_, data_->head());
return iterator(data_->begin(), resources_);
}
// Returns an iterator following the last key-value pair of the object.
@ -127,7 +127,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// ⚠️ Doesn't release the memory associated with the removed member.
// https://arduinojson.org/v6/api/jsonobject/remove/
FORCE_INLINE void remove(iterator it) const {
detail::ObjectData::removeSlot(data_, it.slot_, resources_);
detail::ObjectData::remove(data_, it.iterator_, resources_);
}
// Removes the member with the specified key.

View File

@ -63,7 +63,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(data_->head());
return iterator(data_->begin());
}
// Returns an iterator following the last key-value pair of the object.

View File

@ -13,78 +13,68 @@ class JsonObjectIterator {
friend class JsonObject;
public:
JsonObjectIterator() : slot_(0) {}
JsonObjectIterator() {}
explicit JsonObjectIterator(detail::ResourceManager* resources,
detail::VariantSlot* slot)
: resources_(resources), slot_(slot) {}
explicit JsonObjectIterator(detail::ObjectData::iterator iterator,
detail::ResourceManager* resources)
: iterator_(iterator), resources_(resources) {}
JsonPair operator*() const {
return JsonPair(resources_, slot_);
return JsonPair(iterator_, resources_);
}
Ptr<JsonPair> operator->() {
return operator*();
}
bool operator==(const JsonObjectIterator& other) const {
return slot_ == other.slot_;
return iterator_ == other.iterator_;
}
bool operator!=(const JsonObjectIterator& other) const {
return slot_ != other.slot_;
return iterator_ != other.iterator_;
}
JsonObjectIterator& operator++() {
slot_ = slot_->next();
return *this;
}
JsonObjectIterator& operator+=(size_t distance) {
slot_ = slot_->next(distance);
++iterator_;
return *this;
}
private:
detail::ObjectData::iterator iterator_;
detail::ResourceManager* resources_;
detail::VariantSlot* slot_;
};
class JsonObjectConstIterator {
friend class JsonObject;
public:
JsonObjectConstIterator() : slot_(0) {}
JsonObjectConstIterator() {}
explicit JsonObjectConstIterator(const detail::VariantSlot* slot)
: slot_(slot) {}
explicit JsonObjectConstIterator(detail::ObjectData::iterator iterator)
: iterator_(iterator) {}
JsonPairConst operator*() const {
return JsonPairConst(slot_);
return JsonPairConst(iterator_);
}
Ptr<JsonPairConst> operator->() {
return operator*();
}
bool operator==(const JsonObjectConstIterator& other) const {
return slot_ == other.slot_;
return iterator_ == other.iterator_;
}
bool operator!=(const JsonObjectConstIterator& other) const {
return slot_ != other.slot_;
return iterator_ != other.iterator_;
}
JsonObjectConstIterator& operator++() {
slot_ = slot_->next();
return *this;
}
JsonObjectConstIterator& operator+=(size_t distance) {
slot_ = slot_->next(distance);
++iterator_;
return *this;
}
private:
const detail::VariantSlot* slot_;
detail::ObjectData::iterator iterator_;
};
ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

@ -15,54 +15,53 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class JsonPair {
public:
// INTERNAL USE ONLY
JsonPair(detail::ResourceManager* resources, detail::VariantSlot* slot) {
if (slot) {
key_ = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied
: JsonString::Linked);
value_ = JsonVariant(slot->data(), resources);
}
}
JsonPair(detail::ObjectData::iterator iterator,
detail::ResourceManager* resources)
: iterator_(iterator), resources_(resources) {}
// Returns the key.
JsonString key() const {
return key_;
if (iterator_)
return JsonString(iterator_.key(), iterator_.ownsKey()
? JsonString::Copied
: JsonString::Linked);
else
return JsonString();
}
// Returns the value.
JsonVariant value() const {
return value_;
JsonVariant value() {
return JsonVariant(iterator_.data(), resources_);
}
private:
JsonString key_;
JsonVariant value_;
detail::ObjectData::iterator iterator_;
detail::ResourceManager* resources_;
};
// A read-only key-value pair.
// https://arduinojson.org/v6/api/jsonobjectconst/begin_end/
class JsonPairConst {
public:
JsonPairConst(const detail::VariantSlot* slot) {
if (slot) {
key_ = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied
: JsonString::Linked);
value_ = JsonVariantConst(slot->data());
}
}
JsonPairConst(detail::ObjectData::iterator iterator) : iterator_(iterator) {}
// Returns the key.
JsonString key() const {
return key_;
if (iterator_)
return JsonString(iterator_.key(), iterator_.ownsKey()
? JsonString::Copied
: JsonString::Linked);
else
return JsonString();
}
// Returns the value.
JsonVariantConst value() const {
return value_;
return JsonVariantConst(iterator_.data());
}
private:
JsonString key_;
JsonVariantConst value_;
detail::ObjectData::iterator iterator_;
};
ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

@ -63,7 +63,7 @@ class ObjectData : public CollectionData {
private:
template <typename TAdaptedString>
VariantSlot* getSlot(TAdaptedString key) const;
iterator findKey(TAdaptedString key) const;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -44,14 +44,14 @@ inline bool ObjectData::copyFrom(const ObjectData& src,
ResourceManager* resources) {
clear(resources);
for (VariantSlot* s = src.head(); s; s = s->next()) {
ARDUINOJSON_ASSERT(s->key() != 0);
JsonString key(s->key(),
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
for (auto it = src.begin(); it; ++it) {
ARDUINOJSON_ASSERT(it.key() != 0);
JsonString key(it.key(),
it.ownsKey() ? JsonString::Copied : JsonString::Linked);
auto var = addMember(adaptString(key), resources);
if (!var)
return false;
if (!var->copyFrom(s->data(), resources))
if (!var->copyFrom(*it, resources))
return false;
}
return true;
@ -59,11 +59,12 @@ inline bool ObjectData::copyFrom(const ObjectData& src,
inline bool ObjectData::equals(const ObjectData& other) const {
size_t count = 0;
for (auto a = head(); a; a = a->next()) {
auto b = other.getMember(adaptString(a->key()));
for (auto it = begin(); it; ++it) {
auto a = it.data();
auto b = other.getMember(adaptString(it.key()));
if (!b)
return false;
if (compare(a->data(), b) != COMPARE_RESULT_EQUAL)
if (compare(a, b) != COMPARE_RESULT_EQUAL)
return false;
count++;
}
@ -72,35 +73,33 @@ inline bool ObjectData::equals(const ObjectData& other) const {
template <typename TAdaptedString>
inline VariantData* ObjectData::getMember(TAdaptedString key) const {
return slotData(getSlot(key));
return findKey(key).data();
}
template <typename TAdaptedString>
VariantData* ObjectData::getOrAddMember(TAdaptedString key,
ResourceManager* resources) {
auto slot = getSlot(key);
if (slot)
return slot->data();
auto it = findKey(key);
if (it)
return it.data();
return addMember(key, resources);
}
template <typename TAdaptedString>
inline VariantSlot* ObjectData::getSlot(TAdaptedString key) const {
inline ObjectData::iterator ObjectData::findKey(TAdaptedString key) const {
if (key.isNull())
return 0;
VariantSlot* slot = head();
while (slot) {
if (stringEquals(key, adaptString(slot->key())))
break;
slot = slot->next();
return end();
for (auto it = begin(); it; ++it) {
if (stringEquals(key, adaptString(it.key())))
return it;
}
return slot;
return end();
}
template <typename TAdaptedString>
inline void ObjectData::removeMember(TAdaptedString key,
ResourceManager* resources) {
removeSlot(getSlot(key), resources);
remove(findKey(key), resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -107,10 +107,14 @@ class VariantData {
return const_cast<VariantData*>(this)->asArray();
}
const CollectionData* asCollection() const {
CollectionData* asCollection() {
return isCollection() ? &content_.asCollection : 0;
}
const CollectionData* asCollection() const {
return const_cast<VariantData*>(this)->asCollection();
}
template <typename T>
T asFloat() const {
static_assert(is_floating_point<T>::value, "T must be a floating point");
@ -182,19 +186,15 @@ class VariantData {
}
}
bool copyFrom(const VariantData* src, ResourceManager* resources) {
bool copyFrom(const VariantData& src, ResourceManager* resources) {
release(resources);
if (!src) {
setNull();
return true;
}
switch (src->type()) {
switch (src.type()) {
case VALUE_IS_ARRAY:
return toArray().copyFrom(*src->asArray(), resources);
return toArray().copyFrom(src.content_.asArray, resources);
case VALUE_IS_OBJECT:
return toObject().copyFrom(*src->asObject(), resources);
return toObject().copyFrom(src.content_.asObject, resources);
case VALUE_IS_OWNED_STRING: {
auto str = adaptString(src->asString());
auto str = adaptString(src.asString());
auto dup = resources->saveString(str);
if (!dup)
return false;
@ -202,7 +202,7 @@ class VariantData {
return true;
}
case VALUE_IS_RAW_STRING: {
auto str = adaptString(src->asRawString());
auto str = adaptString(src.asRawString());
auto dup = resources->saveString(str);
if (!dup)
return false;
@ -210,8 +210,8 @@ class VariantData {
return true;
}
default:
content_ = src->content_;
flags_ = src->flags_;
content_ = src.content_;
flags_ = src.flags_;
return true;
}
}
@ -220,7 +220,11 @@ class VariantData {
ResourceManager* resources) {
if (!dst)
return false;
return dst->copyFrom(src, resources);
if (!src) {
dst->setNull();
return true;
}
return dst->copyFrom(*src, resources);
}
VariantData* getElement(size_t index) const {
@ -334,16 +338,10 @@ class VariantData {
size_t nesting() const {
auto collection = asCollection();
if (!collection)
if (collection)
return collection->nesting();
else
return 0;
size_t maxChildNesting = 0;
for (const VariantSlot* s = collection->head(); s; s = s->next()) {
size_t childNesting = s->data()->nesting();
if (childNesting > maxChildNesting)
maxChildNesting = childNesting;
}
return maxChildNesting + 1;
}
static size_t nesting(const VariantData* var) {
@ -550,11 +548,9 @@ class VariantData {
if (flags_ & OWNED_VALUE_BIT)
resources->dereferenceString(content_.asOwnedString->data);
auto c = asCollection();
if (c) {
for (auto slot = c->head(); slot; slot = slot->next())
slotRelease(slot, resources);
}
auto collection = asCollection();
if (collection)
collection->clear(resources);
}
void setType(uint8_t t) {

View File

@ -51,20 +51,6 @@ class VariantSlot {
return const_cast<VariantSlot*>(this)->next();
}
VariantSlot* next(size_t distance) {
VariantSlot* slot = this;
while (distance--) {
if (!slot->next_)
return 0;
slot += slot->next_;
}
return slot;
}
const VariantSlot* next(size_t distance) const {
return const_cast<VariantSlot*>(this)->next(distance);
}
void setNext(VariantSlot* slot) {
ARDUINOJSON_ASSERT(!slot || slot - this >=
numeric_limits<VariantSlotDiff>::lowest());