mirror of
https://github.com/eledio-devices/thirdparty-ArduinoJson.git
synced 2025-11-01 16:14:05 +01:00
JsonVariant automatically promotes to JsonObject or JsonArray on write
This commit is contained in:
@@ -15,21 +15,21 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TStringRef>
|
||||
class ObjectSubscript : public VariantOperators<ObjectSubscript<TStringRef> >,
|
||||
public Visitable {
|
||||
typedef ObjectSubscript<TStringRef> this_type;
|
||||
template <typename TObject, typename TString>
|
||||
class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >,
|
||||
public Visitable {
|
||||
typedef MemberProxy<TObject, TString> this_type;
|
||||
|
||||
public:
|
||||
FORCE_INLINE ObjectSubscript(ObjectRef object, TStringRef key)
|
||||
: _object(object), _key(key) {}
|
||||
FORCE_INLINE MemberProxy(TObject variant, TString key)
|
||||
: _object(variant), _key(key) {}
|
||||
|
||||
operator VariantConstRef() const {
|
||||
return get_impl();
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return getMember();
|
||||
}
|
||||
|
||||
FORCE_INLINE this_type &operator=(const this_type &src) {
|
||||
set_impl().set(src);
|
||||
getOrCreateMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ObjectSubscript : public VariantOperators<ObjectSubscript<TStringRef> >,
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
||||
operator=(const TValue &src) {
|
||||
set_impl().set(src);
|
||||
getOrCreateMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
//
|
||||
@@ -49,27 +49,27 @@ class ObjectSubscript : public VariantOperators<ObjectSubscript<TStringRef> >,
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE this_type &operator=(TValue *src) {
|
||||
set_impl().set(src);
|
||||
getOrCreateMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return get_impl().isNull();
|
||||
return getMember().isNull();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
||||
return get_impl().template as<TValue>();
|
||||
return getMember().template as<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool is() const {
|
||||
return get_impl().template is<TValue>();
|
||||
return getMember().template is<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||
return set_impl().template to<TValue>();
|
||||
return getOrCreateMember().template to<TValue>();
|
||||
}
|
||||
|
||||
// Sets the specified value.
|
||||
@@ -81,48 +81,73 @@ class ObjectSubscript : public VariantOperators<ObjectSubscript<TStringRef> >,
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set(
|
||||
const TValue &value) {
|
||||
return set_impl().set(value);
|
||||
return getOrCreateMember().set(value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue);
|
||||
// TValue = char*, const char, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue *value) {
|
||||
return set_impl().set(value);
|
||||
return getOrCreateMember().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor &visitor) const {
|
||||
return get_impl().accept(visitor);
|
||||
return getMember().accept(visitor);
|
||||
}
|
||||
|
||||
using ArrayShortcuts<MemberProxy>::add;
|
||||
FORCE_INLINE VariantRef add() const {
|
||||
return getOrCreateMember().add();
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
FORCE_INLINE VariantRef get(TNestedKey *key) const {
|
||||
return getMember().get(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
FORCE_INLINE VariantRef get(const TNestedKey &key) const {
|
||||
return getMember().get(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
FORCE_INLINE VariantRef getOrCreate(TNestedKey *key) const {
|
||||
return getOrCreateMember().getOrCreate(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
FORCE_INLINE VariantRef getOrCreate(const TNestedKey &key) const {
|
||||
return getOrCreateMember().getOrCreate(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef get_impl() const {
|
||||
FORCE_INLINE VariantRef getMember() const {
|
||||
return _object.get(_key);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef set_impl() const {
|
||||
return _object.set(_key);
|
||||
FORCE_INLINE VariantRef getOrCreateMember() const {
|
||||
return _object.getOrCreate(_key);
|
||||
}
|
||||
|
||||
ObjectRef _object;
|
||||
TStringRef _key;
|
||||
TObject _object;
|
||||
TString _key;
|
||||
};
|
||||
|
||||
template <typename TImpl>
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value,
|
||||
ObjectSubscript<const TString &> >::type
|
||||
VariantSubscripts<TImpl>::operator[](const TString &key) const {
|
||||
return impl()->template as<ObjectRef>()[key];
|
||||
MemberProxy<const TObject &, const TString &> >::type
|
||||
ObjectShortcuts<TObject>::operator[](const TString &key) const {
|
||||
return MemberProxy<const TObject &, const TString &>(*impl(), key);
|
||||
}
|
||||
|
||||
template <typename TImpl>
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString *>::value,
|
||||
ObjectSubscript<TString *> >::type
|
||||
VariantSubscripts<TImpl>::operator[](TString *key) const {
|
||||
return impl()->template as<ObjectRef>()[key];
|
||||
MemberProxy<const TObject &, TString *> >::type
|
||||
ObjectShortcuts<TObject>::operator[](TString *key) const {
|
||||
return MemberProxy<const TObject &, TString *>(*impl(), key);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -40,7 +40,8 @@ void objectRemove(CollectionData *obj, TKey key) {
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline VariantData *objectSet(CollectionData *obj, TKey key, MemoryPool *pool) {
|
||||
inline VariantData *objectGetOrCreate(CollectionData *obj, TKey key,
|
||||
MemoryPool *pool) {
|
||||
if (!obj) return 0;
|
||||
|
||||
// ignore null key
|
||||
|
||||
@@ -9,13 +9,31 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ArrayRef ObjectRef::createNestedArray(const TString& key) const {
|
||||
return set(key).template to<ArrayRef>();
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||
const TString& key) const {
|
||||
return impl()->getOrCreate(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ArrayRef ObjectRef::createNestedArray(TString* key) const {
|
||||
return set(key).template to<ArrayRef>();
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||
TString* key) const {
|
||||
return impl()->getOrCreate(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TKey>
|
||||
ObjectRef ObjectShortcuts<TObject>::createNestedObject(const TKey& key) const {
|
||||
return impl()->getOrCreate(key).template to<ObjectRef>();
|
||||
}
|
||||
//
|
||||
// ObjectRef createNestedObject(TKey);
|
||||
// TKey = char*, const char*, char[], const char[], const __FlashStringHelper*
|
||||
template <typename TObject>
|
||||
template <typename TKey>
|
||||
ObjectRef ObjectShortcuts<TObject>::createNestedObject(TKey* key) const {
|
||||
return impl()->getOrCreate(key).template to<ObjectRef>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename TData>
|
||||
class ObjectRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
||||
objectAccept(_data, visitor);
|
||||
@@ -127,7 +131,9 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
||||
}
|
||||
};
|
||||
|
||||
class ObjectRef : public ObjectRefBase<CollectionData>, public Visitable {
|
||||
class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
public ObjectShortcuts<ObjectRef>,
|
||||
public Visitable {
|
||||
typedef ObjectRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
@@ -164,68 +170,30 @@ class ObjectRef : public ObjectRefBase<CollectionData>, public Visitable {
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
// Creates and adds a ArrayRef.
|
||||
//
|
||||
// ArrayRef createNestedArray(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ArrayRef createNestedArray(const TKey& key) const;
|
||||
// ArrayRef createNestedArray(TKey);
|
||||
// TKey = char*, const char*, char[], const char[], const __FlashStringHelper*
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ArrayRef createNestedArray(TKey* key) const;
|
||||
|
||||
// Creates and adds a ObjectRef.
|
||||
//
|
||||
// ObjectRef createNestedObject(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ObjectRef createNestedObject(const TKey& key) const {
|
||||
return set(key).template to<ObjectRef>();
|
||||
}
|
||||
//
|
||||
// ObjectRef createNestedObject(TKey);
|
||||
// TKey = char*, const char*, char[], const char[], const __FlashStringHelper*
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ObjectRef createNestedObject(TKey* key) const {
|
||||
return set(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
//
|
||||
// TValue get<TValue>(TKey) const;
|
||||
// VariantRef get<TValue>(TKey) const;
|
||||
// TKey = const std::string&, const String&
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef get(const TKey& key) const {
|
||||
return get_impl(wrapString(key));
|
||||
}
|
||||
//
|
||||
// TValue get<TValue>(TKey) const;
|
||||
// VariantRef get<TValue>(TKey) const;
|
||||
// TKey = char*, const char*, const __FlashStringHelper*
|
||||
// TValue = bool, char, long, int, short, float, double,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef get(TKey* key) const {
|
||||
return get_impl(wrapString(key));
|
||||
}
|
||||
|
||||
// Gets or sets the value associated with the specified key.
|
||||
//
|
||||
// ObjectSubscript operator[](TKey)
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ObjectSubscript<const TKey&> operator[](const TKey& key) const {
|
||||
return ObjectSubscript<const TKey&>(*this, key);
|
||||
FORCE_INLINE VariantRef getOrCreate(TKey* key) const {
|
||||
return getOrCreate_impl(wrapString(key));
|
||||
}
|
||||
//
|
||||
// ObjectSubscript operator[](TKey)
|
||||
// TKey = char*, const char*, char[], const char[N], const
|
||||
// __FlashStringHelper*
|
||||
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ObjectSubscript<TKey*> operator[](TKey* key) const {
|
||||
return ObjectSubscript<TKey*>(*this, key);
|
||||
FORCE_INLINE VariantRef getOrCreate(const TKey& key) const {
|
||||
return getOrCreate_impl(wrapString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ObjectRef rhs) const {
|
||||
@@ -253,16 +221,6 @@ class ObjectRef : public ObjectRefBase<CollectionData>, public Visitable {
|
||||
objectRemove(_data, wrapString(key));
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef set(TKey* key) const {
|
||||
return set_impl(wrapString(key));
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef set(const TKey& key) const {
|
||||
return set_impl(wrapString(key));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef get_impl(TKey key) const {
|
||||
@@ -270,8 +228,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>, public Visitable {
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
FORCE_INLINE VariantRef set_impl(TKey key) const {
|
||||
return VariantRef(_pool, objectSet(_data, key, _pool));
|
||||
FORCE_INLINE VariantRef getOrCreate_impl(TKey key) const {
|
||||
return VariantRef(_pool, objectGetOrCreate(_data, key, _pool));
|
||||
}
|
||||
|
||||
MemoryPool* _pool;
|
||||
|
||||
61
src/ArduinoJson/Object/ObjectShortcuts.hpp
Normal file
61
src/ArduinoJson/Object/ObjectShortcuts.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/attributes.hpp"
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
#include "../Strings/StringWrappers.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename TParent, typename TKey>
|
||||
class MemberProxy;
|
||||
|
||||
template <typename TObject>
|
||||
class ObjectShortcuts {
|
||||
public:
|
||||
// MemberProxy operator[](TKey) const;
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TKey>::value,
|
||||
MemberProxy<const TObject &, const TKey &> >::type
|
||||
operator[](const TKey &key) const;
|
||||
//
|
||||
// MemberProxy operator[](TKey) const;
|
||||
// TKey = const char*, const char[N], const __FlashStringHelper*
|
||||
template <typename TKey>
|
||||
FORCE_INLINE typename enable_if<IsString<TKey *>::value,
|
||||
MemberProxy<const TObject &, TKey *> >::type
|
||||
operator[](TKey *key) const;
|
||||
|
||||
// Creates and adds a ArrayRef.
|
||||
//
|
||||
// ArrayRef createNestedArray(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ArrayRef createNestedArray(const TKey &key) const;
|
||||
// ArrayRef createNestedArray(TKey);
|
||||
// TKey = char*, const char*, char[], const char[], const __FlashStringHelper*
|
||||
template <typename TKey>
|
||||
FORCE_INLINE ArrayRef createNestedArray(TKey *key) const;
|
||||
|
||||
// Creates and adds a ObjectRef.
|
||||
//
|
||||
// ObjectRef createNestedObject(TKey);
|
||||
// TKey = const std::string&, const String&
|
||||
template <typename TKey>
|
||||
ObjectRef createNestedObject(const TKey &key) const;
|
||||
//
|
||||
// ObjectRef createNestedObject(TKey);
|
||||
// TKey = char*, const char*, char[], const char[], const __FlashStringHelper*
|
||||
template <typename TKey>
|
||||
ObjectRef createNestedObject(TKey *key) const;
|
||||
|
||||
private:
|
||||
const TObject *impl() const {
|
||||
return static_cast<const TObject *>(this);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
Reference in New Issue
Block a user