Merge ArrayImpl into VariantImpl

This commit is contained in:
Benoit Blanchon
2025-10-13 15:33:50 +02:00
parent 04823fd304
commit 76eec98efd
13 changed files with 84 additions and 139 deletions
-54
View File
@@ -1,54 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Collection/CollectionData.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class ArrayImpl : public CollectionImpl {
public:
ArrayImpl() {}
ArrayImpl(VariantData* data, ResourceManager* resources)
: CollectionImpl(data, resources) {}
bool isNull() const {
return !data_ || data_->type != VariantType::Array;
}
VariantData* addElement() {
if (isNull())
return nullptr;
return addElement(data_, resources_);
}
static VariantData* addElement(VariantData*, ResourceManager*);
template <typename T>
bool addValue(const T& value) {
if (isNull())
return false;
return addValue(value, data_, resources_);
}
template <typename T>
static bool addValue(const T& value, VariantData*, ResourceManager*);
VariantData* getOrAddElement(size_t index);
VariantData* getElement(size_t index) const;
void removeElement(size_t index);
void remove(iterator it) {
CollectionImpl::removeOne(it);
}
private:
iterator at(size_t index) const;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE
+10 -11
View File
@@ -4,14 +4,13 @@
#pragma once
#include <ArduinoJson/Array/ArrayData.hpp>
#include <ArduinoJson/Variant/VariantCompare.hpp>
#include <ArduinoJson/Variant/VariantData.hpp>
#include <ArduinoJson/Variant/VariantImpl.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
if (isNull())
inline VariantImpl::iterator VariantImpl::at(size_t index) const {
if (!isArray())
return iterator();
auto it = createIterator();
@@ -22,8 +21,8 @@ inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
return it;
}
inline VariantData* ArrayImpl::addElement(VariantData* data,
ResourceManager* resources) {
inline VariantData* VariantImpl::addElement(VariantData* data,
ResourceManager* resources) {
ARDUINOJSON_ASSERT(data != nullptr);
ARDUINOJSON_ASSERT(data->isArray());
ARDUINOJSON_ASSERT(resources != nullptr);
@@ -35,7 +34,7 @@ inline VariantData* ArrayImpl::addElement(VariantData* data,
return slot.ptr();
}
inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
inline VariantData* VariantImpl::getOrAddElement(size_t index) {
auto it = createIterator();
while (!it.done() && index > 0) {
it.next(resources_);
@@ -53,17 +52,17 @@ inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
return element;
}
inline VariantData* ArrayImpl::getElement(size_t index) const {
inline VariantData* VariantImpl::getElement(size_t index) const {
return at(index).data();
}
inline void ArrayImpl::removeElement(size_t index) {
inline void VariantImpl::removeElement(size_t index) {
remove(at(index));
}
template <typename T>
inline bool ArrayImpl::addValue(const T& value, VariantData* data,
ResourceManager* resources) {
inline bool VariantImpl::addValue(const T& value, VariantData* data,
ResourceManager* resources) {
ARDUINOJSON_ASSERT(data != nullptr);
ARDUINOJSON_ASSERT(resources != nullptr);
auto slot = resources->allocVariant();
+5 -2
View File
@@ -59,8 +59,11 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
}
VariantData* getOrCreateData() const {
return VariantAttorney::getOrCreateVariantImpl(upstream_).getOrAddElement(
index_);
auto data = VariantAttorney::getOrCreateData(upstream_);
auto resources = VariantAttorney::getResourceManager(upstream_);
if (data && data->type == VariantType::Null)
data->toArray();
return VariantImpl(data, resources).getOrAddElement(index_);
}
TUpstream upstream_;
+3 -6
View File
@@ -27,7 +27,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
: impl_(data, resources) {}
// INTERNAL USE ONLY
JsonArray(const detail::ArrayImpl& impl) : impl_(impl) {}
JsonArray(const detail::VariantImpl& impl) : impl_(impl) {}
// Returns a JsonVariant pointing to the array.
// https://arduinojson.org/v7/api/jsonvariant/
@@ -89,9 +89,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Copies an array.
// https://arduinojson.org/v7/api/jsonarray/set/
bool set(JsonArrayConst src) const {
if (isNull())
return false;
clear();
for (auto element : src) {
if (!add(element))
@@ -125,7 +122,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Removes all the elements of the array.
// https://arduinojson.org/v7/api/jsonarray/clear/
void clear() const {
impl_.clear();
impl_.empty();
}
// Gets or sets the element at the specified index.
@@ -210,7 +207,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
return impl_.getData();
}
mutable detail::ArrayImpl impl_;
mutable detail::VariantImpl impl_;
};
ARDUINOJSON_END_PUBLIC_NAMESPACE
+2 -2
View File
@@ -41,7 +41,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
: impl_(data, resources) {}
// INTERNAL USE ONLY
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
// Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
@@ -102,7 +102,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
return impl_.getData();
}
detail::ArrayImpl impl_;
detail::VariantImpl impl_;
};
// Compares the content of two arrays.
+4 -4
View File
@@ -30,7 +30,7 @@ class JsonArrayIterator {
public:
JsonArrayIterator() {}
explicit JsonArrayIterator(detail::ArrayImpl::iterator iterator,
explicit JsonArrayIterator(detail::CollectionIterator iterator,
detail::ResourceManager* resources)
: iterator_(iterator), resources_(resources) {}
@@ -55,7 +55,7 @@ class JsonArrayIterator {
}
private:
detail::ArrayImpl::iterator iterator_;
detail::CollectionIterator iterator_;
detail::ResourceManager* resources_;
};
@@ -64,7 +64,7 @@ class JsonArrayConstIterator {
public:
JsonArrayConstIterator() {}
explicit JsonArrayConstIterator(detail::ArrayImpl::iterator iterator,
explicit JsonArrayConstIterator(detail::CollectionIterator iterator,
detail::ResourceManager* resources)
: iterator_(iterator), resources_(resources) {}
@@ -89,7 +89,7 @@ class JsonArrayConstIterator {
}
private:
mutable detail::ArrayImpl::iterator iterator_;
mutable detail::CollectionIterator iterator_;
mutable detail::ResourceManager* resources_;
};
@@ -120,7 +120,6 @@ class CollectionImpl {
return data_->content.asCollection.head;
}
protected:
static void appendOne(Slot<VariantData> slot, VariantData*, ResourceManager*);
static void appendPair(Slot<VariantData> key, Slot<VariantData> value,
+9 -3
View File
@@ -287,14 +287,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename T, detail::enable_if_t<
detail::is_same<T, JsonVariant>::value, int> = 0>
JsonVariant add() {
return JsonVariant(getVariantImpl().addElement(), &resources_);
return JsonVariant(getOrCreateArray().addElement(), &resources_);
}
// Appends a value to the root array.
// https://arduinojson.org/v7/api/jsondocument/add/
template <typename TValue>
bool add(const TValue& value) {
return getVariantImpl().addValue(value);
return getOrCreateArray().addValue(value);
}
// Appends a value to the root array.
@@ -302,7 +302,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TChar,
detail::enable_if_t<!detail::is_const<TChar>::value, int> = 0>
bool add(TChar* value) {
return getVariantImpl().addValue(value);
return getOrCreateArray().addValue(value);
}
// Removes an element of the root array.
@@ -412,6 +412,12 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
return detail::VariantImpl(&data_, &resources_);
}
detail::VariantImpl getOrCreateArray() const {
if (data_.type == detail::VariantType::Null)
data_.toArray();
return detail::VariantImpl(&data_, &resources_);
}
JsonVariant getVariant() {
return JsonVariant(&data_, &resources_);
}
+1 -1
View File
@@ -174,7 +174,7 @@ class JsonDeserializer {
for (;;) {
if (elementFilter.allow()) {
// Allocate slot in array
VariantData* value = ArrayImpl::addElement(array, resources_);
VariantData* value = VariantImpl::addElement(array, resources_);
if (!value)
return DeserializationError::NoMemory;
@@ -360,7 +360,7 @@ class MsgPackDeserializer {
VariantData* value;
if (elementFilter.allow()) {
value = ArrayImpl::addElement(variant, resources_);
value = VariantImpl::addElement(variant, resources_);
if (!value)
return DeserializationError::NoMemory;
} else {
+34 -48
View File
@@ -4,7 +4,6 @@
#pragma once
#include <ArduinoJson/Array/ArrayData.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Misc/SerializedValue.hpp>
#include <ArduinoJson/Numbers/convertNumber.hpp>
@@ -19,6 +18,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// to the compiler to optimize the `this` pointer away.
class VariantImpl {
public:
using iterator = CollectionIterator;
VariantImpl() : data_(nullptr), resources_(nullptr) {}
VariantImpl(VariantData* data, ResourceManager* resources)
@@ -96,32 +97,22 @@ class VariantImpl {
}
VariantData* addElement() {
if (!isArray())
return nullptr;
return addElement(data_, resources_);
}
static VariantData* addElement(VariantData* data,
ResourceManager* resources) {
if (!data)
return nullptr;
auto array = data->type == VariantType::Null ? toArray(data, resources)
: asArray(data, resources);
return array.addElement();
}
static VariantData* addElement(VariantData*, ResourceManager*);
template <typename T>
bool addValue(const T& value) {
if (!isArray())
return false;
return addValue(value, data_, resources_);
}
template <typename T>
static bool addValue(const T& value, VariantData* data,
ResourceManager* resources) {
if (!data)
return false;
auto array = data->type == VariantType::Null ? toArray(data, resources)
: asArray(data, resources);
return array.addValue(value);
}
static bool addValue(const T& value, VariantData*, ResourceManager*);
bool asBoolean() const {
return asBoolean(data_, resources_);
@@ -158,15 +149,7 @@ class VariantImpl {
}
}
ArrayImpl asArray() {
return asArray(data_, resources_);
}
static ArrayImpl asArray(VariantData* data, ResourceManager* resources) {
return ArrayImpl(data, resources);
}
CollectionImpl asCollection() {
CollectionImpl asCollection() const {
return CollectionImpl(data_, resources_);
}
@@ -274,6 +257,12 @@ class VariantImpl {
return ObjectImpl(data, resources);
}
iterator at(size_t index) const;
iterator createIterator() const {
return asCollection().createIterator();
}
#if ARDUINOJSON_USE_8_BYTE_POOL
static const EightByteValue* getEightByte(VariantData* data,
ResourceManager* resources) {
@@ -285,20 +274,15 @@ class VariantImpl {
}
#endif
VariantData* getElement(size_t index) {
return asArray().getElement(index);
}
VariantData* getOrAddElement(size_t index);
VariantData* getElement(size_t index) const;
template <typename TAdaptedString>
VariantData* getMember(TAdaptedString key) {
return asObject().getMember(key);
}
VariantData* getOrAddElement(size_t index) {
auto array = isNull() ? toArray() : asArray();
return array.getOrAddElement(index);
}
template <typename TAdaptedString>
VariantData* getOrAddMember(TAdaptedString key) {
return getOrAddMember(key, data_, resources_);
@@ -367,12 +351,14 @@ class VariantImpl {
return type() == VariantType::Object;
}
size_t nesting() {
size_t nesting() const {
return asCollection().nesting();
}
void removeElement(size_t index) {
asArray().removeElement(index);
void removeElement(size_t index);
void remove(CollectionIterator it) {
asCollection().removeOne(it);
}
template <typename TAdaptedString>
@@ -536,7 +522,7 @@ class VariantImpl {
return false;
}
size_t size() {
size_t size() const {
if (!data_)
return 0;
@@ -557,18 +543,12 @@ class VariantImpl {
return n;
}
ArrayImpl toArray() {
bool toArray() {
if (!data_)
return ArrayImpl();
return false;
clear(data_, resources_);
return toArray(data_, resources_);
}
static ArrayImpl toArray(VariantData* data, ResourceManager* resources) {
ARDUINOJSON_ASSERT(data != nullptr);
ARDUINOJSON_ASSERT(resources != nullptr);
data->toArray();
return ArrayImpl(data, resources);
data_->toArray();
return true;
}
ObjectImpl toObject() {
@@ -613,8 +593,14 @@ class VariantImpl {
data->type = VariantType::Null;
}
void empty() {
if (isCollection())
CollectionImpl::clear(data_, resources_);
}
private:
VariantData* data_;
ResourceManager* resources_;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE
+11 -3
View File
@@ -119,20 +119,20 @@ class VariantRefBase : public VariantTag {
// https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T>
bool add(const T& value) const {
return getOrCreateVariantImpl().addValue(value);
return getOrCreateArray().addValue(value);
}
// Appends a value to the array.
// https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
bool add(T* value) const {
return getOrCreateVariantImpl().addValue(value);
return getOrCreateArray().addValue(value);
}
// Removes an element of the array.
// https://arduinojson.org/v7/api/jsonvariant/remove/
void remove(size_t index) const {
getVariantImpl().removeElement(index);
getOrCreateArray().removeElement(index);
}
// Removes a member of the object.
@@ -278,6 +278,14 @@ class VariantRefBase : public VariantTag {
return VariantImpl(getOrCreateData(), getResourceManager());
}
VariantImpl getOrCreateArray() const {
auto data = getOrCreateData();
auto resources = getResourceManager();
if (data && data->type == VariantType::Null)
data->toArray();
return VariantImpl(data, resources);
}
FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {
@@ -69,8 +69,7 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
inline T VariantRefBase<TDerived>::add() const {
return JsonVariant(getOrCreateVariantImpl().addElement(),
getResourceManager());
return JsonVariant(getOrCreateArray().addElement(), getResourceManager());
}
template <typename TDerived>
@@ -147,7 +146,9 @@ inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
inline JsonArray VariantRefBase<TDerived>::to() const {
return JsonArray(getOrCreateVariantImpl().toArray());
auto impl = getOrCreateVariantImpl();
impl.toArray();
return JsonArray(impl);
}
template <typename TDerived>