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