JsonVariant automatically promotes to JsonObject or JsonArray on write

This commit is contained in:
Benoit Blanchon
2019-01-29 14:09:09 +01:00
parent 5aea1363cc
commit 6f55d1e58f
53 changed files with 1197 additions and 541 deletions

View File

@@ -9,11 +9,14 @@
namespace ARDUINOJSON_NAMESPACE {
inline ArrayRef ArrayRef::createNestedArray() const {
return add().to<ArrayRef>();
template <typename TArray>
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
return impl()->add().template to<ArrayRef>();
}
inline ObjectRef ArrayRef::createNestedObject() const {
return add().to<ObjectRef>();
template <typename TArray>
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
return impl()->add().template to<ObjectRef>();
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@@ -16,11 +16,16 @@
namespace ARDUINOJSON_NAMESPACE {
class ObjectRef;
class ArraySubscript;
template <typename>
class ElementProxy;
template <typename TData>
class ArrayRefBase {
public:
operator VariantConstRef() const {
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
}
template <typename Visitor>
FORCE_INLINE void accept(Visitor& visitor) const {
arrayAccept(_data, visitor);
@@ -30,10 +35,6 @@ class ArrayRefBase {
return _data == 0;
}
FORCE_INLINE VariantConstRef operator[](size_t index) const {
return VariantConstRef(_data ? _data->get(index) : 0);
}
FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0;
}
@@ -74,9 +75,15 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
return arrayEquals(_data, rhs._data);
}
FORCE_INLINE VariantConstRef operator[](size_t index) const {
return VariantConstRef(_data ? _data->get(index) : 0);
}
};
class ArrayRef : public ArrayRefBase<CollectionData>, public Visitable {
class ArrayRef : public ArrayRefBase<CollectionData>,
public ArrayShortcuts<ArrayRef>,
public Visitable {
typedef ArrayRefBase<CollectionData> base_type;
public:
@@ -94,27 +101,7 @@ class ArrayRef : public ArrayRefBase<CollectionData>, public Visitable {
return ArrayConstRef(_data);
}
// Adds the specified value at the end of the array.
//
// bool add(TValue);
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
// std::string, String, ObjectRef
template <typename T>
FORCE_INLINE bool add(const T& value) const {
return add().set(value);
}
// Adds the specified value at the end of the array.
FORCE_INLINE bool add(ArrayConstRef value) const {
return add().set(value);
}
//
// bool add(TValue);
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T>
FORCE_INLINE bool add(T* value) const {
return add().set(value);
}
using ArrayShortcuts::add;
VariantRef add() const {
return VariantRef(_pool, arrayAdd(_data, _pool));
}
@@ -187,11 +174,6 @@ class ArrayRef : public ArrayRefBase<CollectionData>, public Visitable {
}
}
FORCE_INLINE ArrayRef createNestedArray() const;
FORCE_INLINE ObjectRef createNestedObject() const;
FORCE_INLINE ArraySubscript operator[](size_t index) const;
FORCE_INLINE bool operator==(ArrayRef rhs) const {
return arrayEquals(_data, rhs._data);
}

View File

@@ -0,0 +1,47 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/type_traits.hpp"
namespace ARDUINOJSON_NAMESPACE {
// Forward declarations.
template <typename>
class ElementProxy;
template <typename TArray>
class ArrayShortcuts {
public:
// Returns the element at specified index if the variant is an array.
FORCE_INLINE ElementProxy<const TArray &> operator[](size_t index) const;
FORCE_INLINE ObjectRef createNestedObject() const;
FORCE_INLINE ArrayRef createNestedArray() const;
// Adds the specified value at the end of the array.
//
// bool add(TValue);
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
// std::string, String, ObjectRef
template <typename T>
FORCE_INLINE bool add(const T &value) const {
return impl()->add().set(value);
}
//
// bool add(TValue);
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T>
FORCE_INLINE bool add(T *value) const {
return impl()->add().set(value);
}
private:
const TArray *impl() const {
return static_cast<const TArray *>(this);
}
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@@ -13,14 +13,18 @@
#endif
namespace ARDUINOJSON_NAMESPACE {
class ArraySubscript : public VariantOperators<ArraySubscript>,
public Visitable {
template <typename TArray>
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
public Visitable {
typedef ElementProxy<TArray> this_type;
public:
FORCE_INLINE ArraySubscript(ArrayRef array, size_t index)
FORCE_INLINE ElementProxy(TArray array, size_t index)
: _array(array), _index(index) {}
FORCE_INLINE ArraySubscript& operator=(const ArraySubscript& src) {
get_impl().set(src.as<VariantConstRef>());
FORCE_INLINE this_type& operator=(const this_type& src) {
getElement().set(src.as<VariantConstRef>());
return *this;
}
@@ -30,36 +34,36 @@ class ArraySubscript : public VariantOperators<ArraySubscript>,
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
// std::string, String, ArrayRef, ObjectRef
template <typename T>
FORCE_INLINE ArraySubscript& operator=(const T& src) {
get_impl().set(src);
FORCE_INLINE this_type& operator=(const T& src) {
getElement().set(src);
return *this;
}
//
// operator=(TValue)
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T>
FORCE_INLINE ArraySubscript& operator=(T* src) {
get_impl().set(src);
FORCE_INLINE this_type& operator=(T* src) {
getElement().set(src);
return *this;
}
FORCE_INLINE bool isNull() const {
return get_impl().isNull();
return getElement().isNull();
}
template <typename T>
FORCE_INLINE typename VariantAs<T>::type as() const {
return get_impl().as<T>();
return getElement().template as<T>();
}
template <typename T>
FORCE_INLINE bool is() const {
return get_impl().is<T>();
return getElement().template is<T>();
}
template <typename T>
FORCE_INLINE typename VariantTo<T>::type to() const {
return get_impl().to<T>();
return getElement().template to<T>();
}
// Replaces the value
@@ -69,42 +73,65 @@ class ArraySubscript : public VariantOperators<ArraySubscript>,
// std::string, String, ArrayRef, ObjectRef
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) const {
return get_impl().set(value);
return getElement().set(value);
}
//
// bool set(TValue)
// TValue = char*, const char*, const __FlashStringHelper*
template <typename TValue>
FORCE_INLINE bool set(TValue* value) const {
return get_impl().set(value);
return getElement().set(value);
}
template <typename Visitor>
void accept(Visitor& visitor) const {
return get_impl().accept(visitor);
return getElement().accept(visitor);
}
FORCE_INLINE size_t size() const {
return get_impl().size();
return getElement().size();
}
template <typename TNestedKey>
VariantRef get(TNestedKey* key) const {
return getElement().get(key);
}
template <typename TNestedKey>
VariantRef get(const TNestedKey& key) const {
return getElement().get(key);
}
template <typename TNestedKey>
VariantRef getOrCreate(TNestedKey* key) const {
return getElement().getOrCreate(key);
}
template <typename TNestedKey>
VariantRef getOrCreate(const TNestedKey& key) const {
return getElement().getOrCreate(key);
}
using ArrayShortcuts<ElementProxy>::add;
VariantRef add() const {
return getElement().add();
}
private:
FORCE_INLINE VariantRef get_impl() const {
FORCE_INLINE VariantRef getElement() const {
return _array.get(_index);
}
ArrayRef _array;
TArray _array;
const size_t _index;
};
template <typename TImpl>
inline ArraySubscript VariantSubscripts<TImpl>::operator[](size_t index) const {
return impl()->template as<ArrayRef>()[index];
template <typename TArray>
inline ElementProxy<const TArray&> ArrayShortcuts<TArray>::operator[](
size_t index) const {
return ElementProxy<const TArray&>(*impl(), index);
}
inline ArraySubscript ArrayRef::operator[](size_t index) const {
return ArraySubscript(*this, index);
}
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER