Remove most FORCE_INLINEs

I kept only the ones that had a positive impact on code size AND no negative impact on stack memory.

Fixes #2046
This commit is contained in:
Benoit Blanchon
2024-02-05 11:26:55 +01:00
parent 72642e3090
commit cb0dc94db4
12 changed files with 145 additions and 152 deletions

View File

@ -5,7 +5,7 @@ HEAD
---- ----
* Improve error messages when using `char` or `char*` (issue #2043) * Improve error messages when using `char` or `char*` (issue #2043)
* Reduce `serializeJson()`'s size and stack usage (issue #2046) * Reduce stack consumption (issue #2046)
* Fix compatibility with GCC 4.8 (issue #2045) * Fix compatibility with GCC 4.8 (issue #2045)
v7.0.2 (2024-01-19) v7.0.2 (2024-01-19)

View File

@ -22,25 +22,25 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
ElementProxy(const ElementProxy& src) ElementProxy(const ElementProxy& src)
: upstream_(src.upstream_), index_(src.index_) {} : upstream_(src.upstream_), index_(src.index_) {}
FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { ElementProxy& operator=(const ElementProxy& src) {
this->set(src); this->set(src);
return *this; return *this;
} }
template <typename T> template <typename T>
FORCE_INLINE ElementProxy& operator=(const T& src) { ElementProxy& operator=(const T& src) {
this->set(src); this->set(src);
return *this; return *this;
} }
template <typename T> template <typename T>
FORCE_INLINE ElementProxy& operator=(T* src) { ElementProxy& operator=(T* src) {
this->set(src); this->set(src);
return *this; return *this;
} }
private: private:
FORCE_INLINE ResourceManager* getResourceManager() const { ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(upstream_); return VariantAttorney::getResourceManager(upstream_);
} }
@ -50,7 +50,7 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
VariantAttorney::getResourceManager(upstream_)); VariantAttorney::getResourceManager(upstream_));
} }
FORCE_INLINE VariantData* getOrCreateData() const { VariantData* getOrCreateData() const {
auto data = VariantAttorney::getOrCreateData(upstream_); auto data = VariantAttorney::getOrCreateData(upstream_);
if (!data) if (!data)
return nullptr; return nullptr;

View File

@ -20,11 +20,10 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
typedef JsonArrayIterator iterator; typedef JsonArrayIterator iterator;
// Constructs an unbound reference. // Constructs an unbound reference.
FORCE_INLINE JsonArray() : data_(0), resources_(0) {} JsonArray() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArray(detail::ArrayData* data, JsonArray(detail::ArrayData* data, detail::ResourceManager* resources)
detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
// Returns a JsonVariant pointing to the array. // Returns a JsonVariant pointing to the array.
@ -63,20 +62,20 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v7/api/jsonarray/add/ // https://arduinojson.org/v7/api/jsonarray/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(const T& value) const { bool add(const T& value) const {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(value);
} }
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v7/api/jsonarray/add/ // https://arduinojson.org/v7/api/jsonarray/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(T* value) const { bool add(T* value) const {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(value);
} }
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v7/api/jsonarray/begin/ // https://arduinojson.org/v7/api/jsonarray/begin/
FORCE_INLINE iterator begin() const { iterator begin() const {
if (!data_) if (!data_)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(data_->createIterator(resources_), resources_);
@ -84,13 +83,13 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns an iterator following the last element of the array. // Returns an iterator following the last element of the array.
// https://arduinojson.org/v7/api/jsonarray/end/ // https://arduinojson.org/v7/api/jsonarray/end/
FORCE_INLINE iterator end() const { iterator end() const {
return iterator(); return iterator();
} }
// Copies an array. // Copies an array.
// https://arduinojson.org/v7/api/jsonarray/set/ // https://arduinojson.org/v7/api/jsonarray/set/
FORCE_INLINE bool set(JsonArrayConst src) const { bool set(JsonArrayConst src) const {
if (!data_) if (!data_)
return false; return false;
@ -105,13 +104,13 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Removes the element at the specified iterator. // Removes the element at the specified iterator.
// https://arduinojson.org/v7/api/jsonarray/remove/ // https://arduinojson.org/v7/api/jsonarray/remove/
FORCE_INLINE void remove(iterator it) const { void remove(iterator it) const {
detail::ArrayData::remove(data_, it.iterator_, resources_); detail::ArrayData::remove(data_, it.iterator_, resources_);
} }
// Removes the element at the specified index. // Removes the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/remove/ // https://arduinojson.org/v7/api/jsonarray/remove/
FORCE_INLINE void remove(size_t index) const { void remove(size_t index) const {
detail::ArrayData::removeElement(data_, index, resources_); detail::ArrayData::removeElement(data_, index, resources_);
} }
@ -123,7 +122,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Gets or sets the element at the specified index. // Gets or sets the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/subscript/ // https://arduinojson.org/v7/api/jsonarray/subscript/
FORCE_INLINE detail::ElementProxy<JsonArray> operator[](size_t index) const { detail::ElementProxy<JsonArray> operator[](size_t index) const {
return {*this, index}; return {*this, index};
} }
@ -133,25 +132,25 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonarray/isnull/ // https://arduinojson.org/v7/api/jsonarray/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return data_ == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonarray/isnull/ // https://arduinojson.org/v7/api/jsonarray/isnull/
FORCE_INLINE operator bool() const { operator bool() const {
return data_ != 0; return data_ != 0;
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v7/api/jsonarray/nesting/ // https://arduinojson.org/v7/api/jsonarray/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_), resources_); return detail::VariantData::nesting(collectionToVariant(data_), resources_);
} }
// Returns the number of elements in the array. // Returns the number of elements in the array.
// https://arduinojson.org/v7/api/jsonarray/size/ // https://arduinojson.org/v7/api/jsonarray/size/
FORCE_INLINE size_t size() const { size_t size() const {
return data_ ? data_->size(resources_) : 0; return data_ ? data_->size(resources_) : 0;
} }

View File

@ -23,7 +23,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v7/api/jsonarrayconst/begin/ // https://arduinojson.org/v7/api/jsonarrayconst/begin/
FORCE_INLINE iterator begin() const { iterator begin() const {
if (!data_) if (!data_)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(data_->createIterator(resources_), resources_);
@ -31,21 +31,21 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns an iterator to the element following the last element of the array. // Returns an iterator to the element following the last element of the array.
// https://arduinojson.org/v7/api/jsonarrayconst/end/ // https://arduinojson.org/v7/api/jsonarrayconst/end/
FORCE_INLINE iterator end() const { iterator end() const {
return iterator(); return iterator();
} }
// Creates an unbound reference. // Creates an unbound reference.
FORCE_INLINE JsonArrayConst() : data_(0) {} JsonArrayConst() : data_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArrayConst(const detail::ArrayData* data, JsonArrayConst(const detail::ArrayData* data,
const detail::ResourceManager* resources) const detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
// Returns the element at the specified index. // Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/ // https://arduinojson.org/v7/api/jsonarrayconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { JsonVariantConst operator[](size_t index) const {
return JsonVariantConst( return JsonVariantConst(
detail::ArrayData::getElement(data_, index, resources_), resources_); detail::ArrayData::getElement(data_, index, resources_), resources_);
} }
@ -56,25 +56,25 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/ // https://arduinojson.org/v7/api/jsonarrayconst/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return data_ == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/ // https://arduinojson.org/v7/api/jsonarrayconst/isnull/
FORCE_INLINE operator bool() const { operator bool() const {
return data_ != 0; return data_ != 0;
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v7/api/jsonarrayconst/nesting/ // https://arduinojson.org/v7/api/jsonarrayconst/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(getData(), resources_); return detail::VariantData::nesting(getData(), resources_);
} }
// Returns the number of elements in the array. // Returns the number of elements in the array.
// https://arduinojson.org/v7/api/jsonarrayconst/size/ // https://arduinojson.org/v7/api/jsonarrayconst/size/
FORCE_INLINE size_t size() const { size_t size() const {
return data_ ? data_->size(resources_) : 0; return data_ ? data_->size(resources_) : 0;
} }

View File

@ -170,8 +170,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root object's member. // Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE typename detail::enable_if< typename detail::enable_if<detail::IsString<TString>::value,
detail::IsString<TString>::value,
detail::MemberProxy<JsonDocument&, TString>>::type detail::MemberProxy<JsonDocument&, TString>>::type
operator[](const TString& key) { operator[](const TString& key) {
return {*this, key}; return {*this, key};
@ -180,8 +179,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root object's member. // Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if< typename detail::enable_if<detail::IsString<TChar*>::value,
detail::IsString<TChar*>::value,
detail::MemberProxy<JsonDocument&, TChar*>>::type detail::MemberProxy<JsonDocument&, TChar*>>::type
operator[](TChar* key) { operator[](TChar* key) {
return {*this, key}; return {*this, key};
@ -190,7 +188,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root object's member. // Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value, typename detail::enable_if<detail::IsString<TString>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst( return JsonVariantConst(
@ -200,7 +198,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root object's member. // Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value, typename detail::enable_if<detail::IsString<TChar*>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst( return JsonVariantConst(
@ -209,13 +207,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root array's element. // Gets or sets a root array's element.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
FORCE_INLINE detail::ElementProxy<JsonDocument&> operator[](size_t index) { detail::ElementProxy<JsonDocument&> operator[](size_t index) {
return {*this, index}; return {*this, index};
} }
// Gets a root array's member. // Gets a root array's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(data_.getElement(index, &resources_), &resources_); return JsonVariantConst(data_.getElement(index, &resources_), &resources_);
} }
@ -240,28 +238,28 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// 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>
FORCE_INLINE bool add(const TValue& value) { bool add(const TValue& value) {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(value);
} }
// 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 TChar> template <typename TChar>
FORCE_INLINE bool add(TChar* value) { bool add(TChar* value) {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(value);
} }
// Removes an element of the root array. // Removes an element of the root array.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
FORCE_INLINE void remove(size_t index) { void remove(size_t index) {
detail::VariantData::removeElement(getData(), index, getResourceManager()); detail::VariantData::removeElement(getData(), index, getResourceManager());
} }
// Removes a member of the root object. // Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value>::type typename detail::enable_if<detail::IsString<TChar*>::value>::type remove(
remove(TChar* key) { TChar* key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key), detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager()); getResourceManager());
} }
@ -269,18 +267,18 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Removes a member of the root object. // Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TString> template <typename TString>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value>::type typename detail::enable_if<detail::IsString<TString>::value>::type remove(
remove(const TString& key) { const TString& key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key), detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager()); getResourceManager());
} }
FORCE_INLINE operator JsonVariant() { operator JsonVariant() {
return getVariant(); return getVariant();
} }
FORCE_INLINE operator JsonVariantConst() const { operator JsonVariantConst() const {
return getVariant(); return getVariant();
} }

View File

@ -20,11 +20,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
typedef JsonObjectIterator iterator; typedef JsonObjectIterator iterator;
// Creates an unbound reference. // Creates an unbound reference.
FORCE_INLINE JsonObject() : data_(0), resources_(0) {} JsonObject() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonObject(detail::ObjectData* data, JsonObject(detail::ObjectData* data, detail::ResourceManager* resource)
detail::ResourceManager* resource)
: data_(data), resources_(resource) {} : data_(data), resources_(resource) {}
operator JsonVariant() const { operator JsonVariant() const {
@ -43,31 +42,31 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonobject/isnull/ // https://arduinojson.org/v7/api/jsonobject/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return data_ == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonobject/isnull/ // https://arduinojson.org/v7/api/jsonobject/isnull/
FORCE_INLINE operator bool() const { operator bool() const {
return data_ != 0; return data_ != 0;
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
// https://arduinojson.org/v7/api/jsonobject/nesting/ // https://arduinojson.org/v7/api/jsonobject/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_), resources_); return detail::VariantData::nesting(collectionToVariant(data_), resources_);
} }
// Returns the number of members in the object. // Returns the number of members in the object.
// https://arduinojson.org/v7/api/jsonobject/size/ // https://arduinojson.org/v7/api/jsonobject/size/
FORCE_INLINE size_t size() const { size_t size() const {
return data_ ? data_->size(resources_) : 0; return data_ ? data_->size(resources_) : 0;
} }
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobject/begin/ // https://arduinojson.org/v7/api/jsonobject/begin/
FORCE_INLINE iterator begin() const { iterator begin() const {
if (!data_) if (!data_)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(data_->createIterator(resources_), resources_);
@ -75,7 +74,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobject/end/ // https://arduinojson.org/v7/api/jsonobject/end/
FORCE_INLINE iterator end() const { iterator end() const {
return iterator(); return iterator();
} }
@ -87,7 +86,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Copies an object. // Copies an object.
// https://arduinojson.org/v7/api/jsonobject/set/ // https://arduinojson.org/v7/api/jsonobject/set/
FORCE_INLINE bool set(JsonObjectConst src) { bool set(JsonObjectConst src) {
if (!data_ || !src.data_) if (!data_ || !src.data_)
return false; return false;
@ -103,7 +102,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value, typename detail::enable_if<detail::IsString<TString>::value,
detail::MemberProxy<JsonObject, TString>>::type detail::MemberProxy<JsonObject, TString>>::type
operator[](const TString& key) const { operator[](const TString& key) const {
@ -113,7 +112,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TChar*>::value, typename detail::enable_if<detail::IsString<TChar*>::value,
detail::MemberProxy<JsonObject, TChar*>>::type detail::MemberProxy<JsonObject, TChar*>>::type
operator[](TChar* key) const { operator[](TChar* key) const {
@ -145,7 +144,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobject/containskey/ // https://arduinojson.org/v7/api/jsonobject/containskey/
template <typename TString> template <typename TString>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value, bool>::type typename detail::enable_if<detail::IsString<TString>::value, bool>::type
containsKey(const TString& key) const { containsKey(const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
@ -155,7 +154,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobject/containskey/ // https://arduinojson.org/v7/api/jsonobject/containskey/
template <typename TChar> template <typename TChar>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
containsKey(TChar* key) const { containsKey(TChar* key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),

View File

@ -32,31 +32,31 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/ // https://arduinojson.org/v7/api/jsonobjectconst/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return data_ == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/ // https://arduinojson.org/v7/api/jsonobjectconst/isnull/
FORCE_INLINE operator bool() const { operator bool() const {
return data_ != 0; return data_ != 0;
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
// https://arduinojson.org/v7/api/jsonobjectconst/nesting/ // https://arduinojson.org/v7/api/jsonobjectconst/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(getData(), resources_); return detail::VariantData::nesting(getData(), resources_);
} }
// Returns the number of members in the object. // Returns the number of members in the object.
// https://arduinojson.org/v7/api/jsonobjectconst/size/ // https://arduinojson.org/v7/api/jsonobjectconst/size/
FORCE_INLINE size_t size() const { size_t size() const {
return data_ ? data_->size(resources_) : 0; return data_ ? data_->size(resources_) : 0;
} }
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobjectconst/begin/ // https://arduinojson.org/v7/api/jsonobjectconst/begin/
FORCE_INLINE iterator begin() const { iterator begin() const {
if (!data_) if (!data_)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(data_->createIterator(resources_), resources_);
@ -64,14 +64,14 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobjectconst/end/ // https://arduinojson.org/v7/api/jsonobjectconst/end/
FORCE_INLINE iterator end() const { iterator end() const {
return iterator(); return iterator();
} }
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/ // https://arduinojson.org/v7/api/jsonobjectconst/containskey/
template <typename TString> template <typename TString>
FORCE_INLINE bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@ -79,7 +79,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/ // https://arduinojson.org/v7/api/jsonobjectconst/containskey/
template <typename TChar> template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@ -87,7 +87,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Gets the member with specified key. // Gets the member with specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/ // https://arduinojson.org/v7/api/jsonobjectconst/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value, typename detail::enable_if<detail::IsString<TString>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::ObjectData::getMember(
@ -98,7 +98,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Gets the member with specified key. // Gets the member with specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/ // https://arduinojson.org/v7/api/jsonobjectconst/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value, typename detail::enable_if<detail::IsString<TChar*>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::ObjectData::getMember(

View File

@ -17,41 +17,41 @@ class MemberProxy
friend class VariantAttorney; friend class VariantAttorney;
public: public:
FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key) MemberProxy(TUpstream upstream, TStringRef key)
: upstream_(upstream), key_(key) {} : upstream_(upstream), key_(key) {}
MemberProxy(const MemberProxy& src) MemberProxy(const MemberProxy& src)
: upstream_(src.upstream_), key_(src.key_) {} : upstream_(src.upstream_), key_(src.key_) {}
FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) { MemberProxy& operator=(const MemberProxy& src) {
this->set(src); this->set(src);
return *this; return *this;
} }
template <typename T> template <typename T>
FORCE_INLINE MemberProxy& operator=(const T& src) { MemberProxy& operator=(const T& src) {
this->set(src); this->set(src);
return *this; return *this;
} }
template <typename T> template <typename T>
FORCE_INLINE MemberProxy& operator=(T* src) { MemberProxy& operator=(T* src) {
this->set(src); this->set(src);
return *this; return *this;
} }
private: private:
FORCE_INLINE ResourceManager* getResourceManager() const { ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(upstream_); return VariantAttorney::getResourceManager(upstream_);
} }
FORCE_INLINE VariantData* getData() const { VariantData* getData() const {
return VariantData::getMember( return VariantData::getMember(
VariantAttorney::getData(upstream_), adaptString(key_), VariantAttorney::getData(upstream_), adaptString(key_),
VariantAttorney::getResourceManager(upstream_)); VariantAttorney::getResourceManager(upstream_));
} }
FORCE_INLINE VariantData* getOrCreateData() const { VariantData* getOrCreateData() const {
auto data = VariantAttorney::getOrCreateData(upstream_); auto data = VariantAttorney::getOrCreateData(upstream_);
if (!data) if (!data)
return nullptr; return nullptr;

View File

@ -23,15 +23,15 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
private: private:
FORCE_INLINE detail::ResourceManager* getResourceManager() const { detail::ResourceManager* getResourceManager() const {
return resources_; return resources_;
} }
FORCE_INLINE detail::VariantData* getData() const { detail::VariantData* getData() const {
return data_; return data_;
} }
FORCE_INLINE detail::VariantData* getOrCreateData() const { detail::VariantData* getOrCreateData() const {
return data_; return data_;
} }

View File

@ -38,18 +38,18 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if the value is null or the reference is unbound. // Returns true if the value is null or the reference is unbound.
// https://arduinojson.org/v7/api/jsonvariantconst/isnull/ // https://arduinojson.org/v7/api/jsonvariantconst/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return detail::VariantData::isNull(data_); return detail::VariantData::isNull(data_);
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
FORCE_INLINE bool isUnbound() const { bool isUnbound() const {
return !data_; return !data_;
} }
// Returns the depth (nesting level) of the value. // Returns the depth (nesting level) of the value.
// https://arduinojson.org/v7/api/jsonvariantconst/nesting/ // https://arduinojson.org/v7/api/jsonvariantconst/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(data_, resources_); return detail::VariantData::nesting(data_, resources_);
} }
@ -62,7 +62,7 @@ class JsonVariantConst : public detail::VariantTag,
// Casts the value to the specified type. // Casts the value to the specified type.
// https://arduinojson.org/v7/api/jsonvariantconst/as/ // https://arduinojson.org/v7/api/jsonvariantconst/as/
template <typename T> template <typename T>
FORCE_INLINE typename detail::enable_if<!detail::is_same<T, char*>::value && typename detail::enable_if<!detail::is_same<T, char*>::value &&
!detail::is_same<T, char>::value, !detail::is_same<T, char>::value,
T>::type T>::type
as() const { as() const {
@ -72,7 +72,7 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if the value is of the specified type. // Returns true if the value is of the specified type.
// https://arduinojson.org/v7/api/jsonvariantconst/is/ // https://arduinojson.org/v7/api/jsonvariantconst/is/
template <typename T> template <typename T>
FORCE_INLINE typename detail::enable_if<!detail::is_same<T, char*>::value && typename detail::enable_if<!detail::is_same<T, char*>::value &&
!detail::is_same<T, char>::value, !detail::is_same<T, char>::value,
bool>::type bool>::type
is() const { is() const {
@ -80,13 +80,13 @@ class JsonVariantConst : public detail::VariantTag,
} }
template <typename T> template <typename T>
FORCE_INLINE operator T() const { operator T() const {
return as<T>(); return as<T>();
} }
// Gets array's element at specified index. // Gets array's element at specified index.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { JsonVariantConst operator[](size_t index) const {
return JsonVariantConst( return JsonVariantConst(
detail::VariantData::getElement(data_, index, resources_), resources_); detail::VariantData::getElement(data_, index, resources_), resources_);
} }
@ -94,7 +94,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets object's member with specified key. // Gets object's member with specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value, typename detail::enable_if<detail::IsString<TString>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(detail::VariantData::getMember( return JsonVariantConst(detail::VariantData::getMember(
@ -105,7 +105,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets object's member with specified key. // Gets object's member with specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value, typename detail::enable_if<detail::IsString<TChar*>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(detail::VariantData::getMember( return JsonVariantConst(detail::VariantData::getMember(
@ -116,7 +116,7 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if tge object contains the specified key. // Returns true if tge object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/ // https://arduinojson.org/v7/api/jsonvariantconst/containskey/
template <typename TString> template <typename TString>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value, bool>::type typename detail::enable_if<detail::IsString<TString>::value, bool>::type
containsKey(const TString& key) const { containsKey(const TString& key) const {
return detail::VariantData::getMember(getData(), detail::adaptString(key), return detail::VariantData::getMember(getData(), detail::adaptString(key),
@ -126,7 +126,7 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if tge object contains the specified key. // Returns true if tge object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/ // https://arduinojson.org/v7/api/jsonvariantconst/containskey/
template <typename TChar> template <typename TChar>
FORCE_INLINE
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
containsKey(TChar* key) const { containsKey(TChar* key) const {
return detail::VariantData::getMember(getData(), detail::adaptString(key), return detail::VariantData::getMember(getData(), detail::adaptString(key),

View File

@ -16,19 +16,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantAttorney { class VariantAttorney {
public: public:
template <typename TClient> template <typename TClient>
FORCE_INLINE static auto getResourceManager(TClient& client) static auto getResourceManager(TClient& client)
-> decltype(client.getResourceManager()) { -> decltype(client.getResourceManager()) {
return client.getResourceManager(); return client.getResourceManager();
} }
template <typename TClient> template <typename TClient>
FORCE_INLINE static auto getData(TClient& client) static auto getData(TClient& client) -> decltype(client.getData()) {
-> decltype(client.getData()) {
return client.getData(); return client.getData();
} }
template <typename TClient> template <typename TClient>
FORCE_INLINE static VariantData* getOrCreateData(TClient& client) { static VariantData* getOrCreateData(TClient& client) {
return client.getOrCreateData(); return client.getOrCreateData();
} }
}; };

View File

@ -28,39 +28,38 @@ class VariantRefBase : public VariantTag {
public: public:
// Sets the value to null. // Sets the value to null.
// https://arduinojson.org/v7/api/jsonvariant/clear/ // https://arduinojson.org/v7/api/jsonvariant/clear/
FORCE_INLINE void clear() const { void clear() const {
VariantData::setNull(getOrCreateData(), getResourceManager()); VariantData::setNull(getOrCreateData(), getResourceManager());
} }
// Returns true if the value is null or the reference is unbound. // Returns true if the value is null or the reference is unbound.
// https://arduinojson.org/v7/api/jsonvariant/isnull/ // https://arduinojson.org/v7/api/jsonvariant/isnull/
FORCE_INLINE bool isNull() const { bool isNull() const {
return VariantData::isNull(getData()); return VariantData::isNull(getData());
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
FORCE_INLINE bool isUnbound() const { bool isUnbound() const {
return !getData(); return !getData();
} }
// Casts the value to the specified type. // Casts the value to the specified type.
// https://arduinojson.org/v7/api/jsonvariant/as/ // https://arduinojson.org/v7/api/jsonvariant/as/
template <typename T> template <typename T>
FORCE_INLINE
typename enable_if<!ConverterNeedsWriteableRef<T>::value, T>::type typename enable_if<!ConverterNeedsWriteableRef<T>::value, T>::type as()
as() const { const {
return Converter<T>::fromJson(getVariantConst()); return Converter<T>::fromJson(getVariantConst());
} }
// Casts the value to the specified type. // Casts the value to the specified type.
// https://arduinojson.org/v7/api/jsonvariant/as/ // https://arduinojson.org/v7/api/jsonvariant/as/
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type as() const;
as() const;
template <typename T, template <typename T,
typename = typename enable_if<!is_same<T, TDerived>::value>::type> typename = typename enable_if<!is_same<T, TDerived>::value>::type>
FORCE_INLINE operator T() const { operator T() const {
return as<T>(); return as<T>();
} }
@ -100,22 +99,22 @@ class VariantRefBase : public VariantTag {
// Copies the specified value. // Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/ // https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T> template <typename T>
FORCE_INLINE bool set(const T& value) const; bool set(const T& value) const;
// Copies the specified value. // Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/ // https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T> template <typename T>
FORCE_INLINE bool set(T* value) const; bool set(T* value) const;
// Returns the size of the array or object. // Returns the size of the array or object.
// https://arduinojson.org/v7/api/jsonvariant/size/ // https://arduinojson.org/v7/api/jsonvariant/size/
FORCE_INLINE size_t size() const { size_t size() const {
return VariantData::size(getData(), getResourceManager()); return VariantData::size(getData(), getResourceManager());
} }
// Returns the depth (nesting level) of the value. // Returns the depth (nesting level) of the value.
// https://arduinojson.org/v7/api/jsonvariant/nesting/ // https://arduinojson.org/v7/api/jsonvariant/nesting/
FORCE_INLINE size_t nesting() const { size_t nesting() const {
return VariantData::nesting(getData(), getResourceManager()); return VariantData::nesting(getData(), getResourceManager());
} }
@ -136,28 +135,27 @@ class VariantRefBase : public VariantTag {
// 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> template <typename T>
FORCE_INLINE bool add(const T& value) const { bool add(const T& value) const {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(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> template <typename T>
FORCE_INLINE bool add(T* value) const { bool add(T* value) const {
return add<JsonVariant>().set(value); return add<JsonVariant>().set(value);
} }
// Removes an element of the array. // Removes an element of the array.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
FORCE_INLINE void remove(size_t index) const { void remove(size_t index) const {
VariantData::removeElement(getData(), index, getResourceManager()); VariantData::removeElement(getData(), index, getResourceManager());
} }
// Removes a member of the object. // Removes a member of the object.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( typename enable_if<IsString<TChar*>::value>::type remove(TChar* key) const {
TChar* key) const {
VariantData::removeMember(getData(), adaptString(key), VariantData::removeMember(getData(), adaptString(key),
getResourceManager()); getResourceManager());
} }
@ -165,7 +163,7 @@ class VariantRefBase : public VariantTag {
// Removes a member of the object. // Removes a member of the object.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
template <typename TString> template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const { const TString& key) const {
VariantData::removeMember(getData(), adaptString(key), VariantData::removeMember(getData(), adaptString(key),
getResourceManager()); getResourceManager());
@ -173,19 +171,19 @@ class VariantRefBase : public VariantTag {
// Gets or sets an array element. // Gets or sets an array element.
// https://arduinojson.org/v7/api/jsonvariant/subscript/ // https://arduinojson.org/v7/api/jsonvariant/subscript/
FORCE_INLINE ElementProxy<TDerived> operator[](size_t index) const; ElementProxy<TDerived> operator[](size_t index) const;
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariant/containskey/ // https://arduinojson.org/v7/api/jsonvariant/containskey/
template <typename TString> template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type typename enable_if<IsString<TString>::value, bool>::type containsKey(
containsKey(const TString& key) const; const TString& key) const;
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariant/containskey/ // https://arduinojson.org/v7/api/jsonvariant/containskey/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value, bool>::type typename enable_if<IsString<TChar*>::value, bool>::type containsKey(
containsKey(TChar* key) const; TChar* key) const;
// Gets or sets an object member. // Gets or sets an object member.
// https://arduinojson.org/v7/api/jsonvariant/subscript/ // https://arduinojson.org/v7/api/jsonvariant/subscript/
@ -254,15 +252,15 @@ class VariantRefBase : public VariantTag {
return static_cast<const TDerived&>(*this); return static_cast<const TDerived&>(*this);
} }
FORCE_INLINE ResourceManager* getResourceManager() const { ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(derived()); return VariantAttorney::getResourceManager(derived());
} }
FORCE_INLINE VariantData* getData() const { VariantData* getData() const {
return VariantAttorney::getData(derived()); return VariantAttorney::getData(derived());
} }
FORCE_INLINE VariantData* getOrCreateData() const { VariantData* getOrCreateData() const {
return VariantAttorney::getOrCreateData(derived()); return VariantAttorney::getOrCreateData(derived());
} }
@ -272,7 +270,7 @@ class VariantRefBase : public VariantTag {
return ArduinoJson::JsonVariantConst(getData(), getResourceManager()); return ArduinoJson::JsonVariantConst(getData(), getResourceManager());
} }
FORCE_INLINE ArduinoJson::JsonVariant getOrCreateVariant() const; ArduinoJson::JsonVariant getOrCreateVariant() const;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE