mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-29 10:17:39 +02:00
VariantImpl: remove addValue()
This removes the two-way dependency between `JsonVariant` and `VariantImpl`
This commit is contained in:
@ -5,7 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionIterator.hpp>
|
||||
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
@ -28,10 +27,23 @@ inline VariantData* VariantImpl::addElement() {
|
||||
auto slot = allocVariant();
|
||||
if (!slot)
|
||||
return nullptr;
|
||||
VariantImpl::appendOne(slot);
|
||||
addElement(slot);
|
||||
return slot.ptr();
|
||||
}
|
||||
|
||||
inline void VariantImpl::addElement(Slot<VariantData> slot) {
|
||||
auto coll = getCollectionData();
|
||||
|
||||
if (coll->tail != NULL_SLOT) {
|
||||
auto tail = getVariant(coll->tail);
|
||||
tail->next = slot.id();
|
||||
coll->tail = slot.id();
|
||||
} else {
|
||||
coll->head = slot.id();
|
||||
coll->tail = slot.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline VariantData* VariantImpl::getOrAddElement(size_t index) {
|
||||
auto it = createIterator();
|
||||
while (!it.done() && index > 0) {
|
||||
@ -64,22 +76,6 @@ inline void VariantImpl::removeElement(size_t index) {
|
||||
removeElement(at(index));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool VariantImpl::addValue(const T& value) {
|
||||
if (!isArray())
|
||||
return false;
|
||||
auto slot = allocVariant();
|
||||
if (!slot)
|
||||
return false;
|
||||
JsonVariant variant(slot.ptr(), resources_);
|
||||
if (!variant.set(value)) {
|
||||
freeVariant(slot);
|
||||
return false;
|
||||
}
|
||||
appendOne(slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
constexpr size_t sizeofArray(size_t n) {
|
||||
return n * sizeof(VariantData);
|
||||
|
@ -25,6 +25,10 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(detail::VariantImpl impl) : impl_(impl) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: impl_(data, resources) {}
|
||||
|
||||
// Returns a JsonVariant pointing to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/
|
||||
operator JsonVariant() {
|
||||
@ -59,7 +63,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return impl_.addValue(value);
|
||||
return doAdd(value);
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
@ -67,7 +71,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
template <typename T,
|
||||
detail::enable_if_t<!detail::is_const<T>::value, int> = 0>
|
||||
bool add(T* value) const {
|
||||
return impl_.addValue(value);
|
||||
return doAdd(value);
|
||||
}
|
||||
|
||||
// Returns an iterator to the first element of the array.
|
||||
@ -203,6 +207,27 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
return impl_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool doAdd(const T& value) const {
|
||||
if (!impl_.isArray())
|
||||
return false;
|
||||
|
||||
auto resources = impl_.resources();
|
||||
ARDUINOJSON_ASSERT(resources != nullptr);
|
||||
|
||||
auto slot = resources->allocVariant();
|
||||
if (!slot)
|
||||
return false;
|
||||
|
||||
if (!JsonVariant(slot.ptr(), resources).set(value)) {
|
||||
detail::VariantImpl(slot.ptr(), resources).clear();
|
||||
resources->freeVariant(slot);
|
||||
return false;
|
||||
}
|
||||
impl_.addElement(slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
mutable detail::VariantImpl impl_;
|
||||
};
|
||||
|
||||
|
@ -18,19 +18,6 @@ inline VariantImpl::iterator VariantImpl::createIterator() const {
|
||||
return iterator(coll->head, resources_);
|
||||
}
|
||||
|
||||
inline void VariantImpl::appendOne(Slot<VariantData> slot) {
|
||||
auto coll = getCollectionData();
|
||||
|
||||
if (coll->tail != NULL_SLOT) {
|
||||
auto tail = getVariant(coll->tail);
|
||||
tail->next = slot.id();
|
||||
coll->tail = slot.id();
|
||||
} else {
|
||||
coll->head = slot.id();
|
||||
coll->tail = slot.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline void VariantImpl::appendPair(Slot<VariantData> key,
|
||||
Slot<VariantData> value) {
|
||||
auto coll = getCollectionData();
|
||||
|
@ -267,14 +267,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(getOrCreateArray().addElement(), &resources_);
|
||||
return getOrCreateArray().add<T>();
|
||||
}
|
||||
|
||||
// Appends a value to the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename TValue>
|
||||
bool add(const TValue& value) {
|
||||
return getOrCreateArray().addValue(value);
|
||||
return getOrCreateArray().add(value);
|
||||
}
|
||||
|
||||
// Appends a value to the root array.
|
||||
@ -282,7 +282,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 getOrCreateArray().addValue(value);
|
||||
return getOrCreateArray().add(value);
|
||||
}
|
||||
|
||||
// Removes an element of the root array.
|
||||
@ -396,8 +396,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
return {&data_, &resources_};
|
||||
}
|
||||
|
||||
detail::VariantImpl getOrCreateArray() {
|
||||
return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
|
||||
JsonArray getOrCreateArray() {
|
||||
return JsonArray(data_.getOrCreateArray(), &resources_);
|
||||
}
|
||||
|
||||
JsonVariant getVariant() {
|
||||
|
@ -97,9 +97,7 @@ class VariantImpl {
|
||||
}
|
||||
|
||||
VariantData* addElement();
|
||||
|
||||
template <typename T>
|
||||
bool addValue(const T& value);
|
||||
void addElement(Slot<VariantData> slot);
|
||||
|
||||
bool asBoolean() const {
|
||||
if (!data_)
|
||||
@ -550,7 +548,6 @@ class VariantImpl {
|
||||
|
||||
iterator at(size_t index) const;
|
||||
|
||||
void appendOne(Slot<VariantData> slot);
|
||||
void appendPair(Slot<VariantData> key, Slot<VariantData> value);
|
||||
|
||||
void removeOne(iterator it);
|
||||
|
@ -120,14 +120,14 @@ class VariantRefBase : public VariantTag {
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return getOrCreateArray().addValue(value);
|
||||
return getOrCreateArray().add(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 getOrCreateArray().addValue(value);
|
||||
return getOrCreateArray().add(value);
|
||||
}
|
||||
|
||||
// Removes an element of the array.
|
||||
@ -267,13 +267,7 @@ class VariantRefBase : public VariantTag {
|
||||
return VariantAttorney::getOrCreateImpl(derived());
|
||||
}
|
||||
|
||||
VariantImpl getOrCreateArray() const {
|
||||
auto impl = getOrCreateImpl();
|
||||
auto data = impl.data();
|
||||
if (data)
|
||||
data->getOrCreateArray();
|
||||
return impl;
|
||||
}
|
||||
JsonArray getOrCreateArray() const;
|
||||
|
||||
FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
|
||||
|
||||
|
@ -69,8 +69,7 @@ inline bool 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 {
|
||||
auto impl = getOrCreateArray();
|
||||
return JsonVariant(impl.addElement(), impl.resources());
|
||||
return getOrCreateArray().template add<T>();
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
@ -141,6 +140,15 @@ inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
|
||||
return TConverter::toJson(value, JsonVariant(impl));
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
inline JsonArray VariantRefBase<TDerived>::getOrCreateArray() const {
|
||||
auto impl = getOrCreateImpl();
|
||||
auto data = impl.data();
|
||||
if (data)
|
||||
data->getOrCreateArray();
|
||||
return JsonArray(impl);
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
|
||||
inline JsonArray VariantRefBase<TDerived>::to() const {
|
||||
|
Reference in New Issue
Block a user