Replace add() with add<T>() (add(T) is still supported)

This commit is contained in:
Benoit Blanchon
2023-08-09 10:57:52 +02:00
parent 7a587ac2e2
commit f422b7b37d
12 changed files with 133 additions and 28 deletions

View File

@ -27,3 +27,4 @@ HEAD
* Add `deserializeJson(JsonVariant, ...)` and `deserializeMsgPack(JsonVariant, ...)` (#1226) * Add `deserializeJson(JsonVariant, ...)` and `deserializeMsgPack(JsonVariant, ...)` (#1226)
* Call `shrinkToFit()` in `deserializeJson()` and `deserializeMsgPack()` * Call `shrinkToFit()` in `deserializeJson()` and `deserializeMsgPack()`
* `serializeJson()` and `serializeMsgPack()` replace the content of `std::string` and `String` instead of appending to it * `serializeJson()` and `serializeMsgPack()` replace the content of `std::string` and `String` instead of appending to it
* Replace `add()` with `add<T>()` (`add(T)` is still supported)

View File

@ -9,7 +9,7 @@
using ArduinoJson::detail::sizeofArray; using ArduinoJson::detail::sizeofArray;
TEST_CASE("JsonArray::add()") { TEST_CASE("JsonArray::add(T)") {
SpyingAllocator spy; SpyingAllocator spy;
JsonDocument doc(&spy); JsonDocument doc(&spy);
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -154,3 +154,28 @@ TEST_CASE("JsonArray::add()") {
}); });
} }
} }
TEST_CASE("JsonArray::add<T>()") {
JsonDocument doc;
JsonArray array = doc.to<JsonArray>();
SECTION("add<JsonArray>()") {
JsonArray nestedArray = array.add<JsonArray>();
nestedArray.add(1);
nestedArray.add(2);
REQUIRE(doc.as<std::string>() == "[[1,2]]");
}
SECTION("add<JsonObject>()") {
JsonObject nestedObject = array.add<JsonObject>();
nestedObject["a"] = 1;
nestedObject["b"] = 2;
REQUIRE(doc.as<std::string>() == "[{\"a\":1,\"b\":2}]");
}
SECTION("add<JsonVariant>()") {
JsonVariant nestedVariant = array.add<JsonVariant>();
nestedVariant.set(42);
REQUIRE(doc.as<std::string>() == "[42]");
}
}

View File

@ -9,7 +9,7 @@ typedef ArduinoJson::detail::ElementProxy<JsonDocument&> ElementProxy;
TEST_CASE("ElementProxy::add()") { TEST_CASE("ElementProxy::add()") {
JsonDocument doc; JsonDocument doc;
doc.add(); doc.add<JsonVariant>();
ElementProxy ep = doc[0]; ElementProxy ep = doc[0];
SECTION("add(int)") { SECTION("add(int)") {
@ -35,7 +35,7 @@ TEST_CASE("ElementProxy::add()") {
TEST_CASE("ElementProxy::clear()") { TEST_CASE("ElementProxy::clear()") {
JsonDocument doc; JsonDocument doc;
doc.add(); doc.add<JsonVariant>();
ElementProxy ep = doc[0]; ElementProxy ep = doc[0];
SECTION("size goes back to zero") { SECTION("size goes back to zero") {
@ -95,7 +95,7 @@ TEST_CASE("ElementProxy::operator==()") {
TEST_CASE("ElementProxy::remove()") { TEST_CASE("ElementProxy::remove()") {
JsonDocument doc; JsonDocument doc;
doc.add(); doc.add<JsonVariant>();
ElementProxy ep = doc[0]; ElementProxy ep = doc[0];
SECTION("remove(int)") { SECTION("remove(int)") {
@ -168,7 +168,7 @@ TEST_CASE("ElementProxy::set()") {
TEST_CASE("ElementProxy::size()") { TEST_CASE("ElementProxy::size()") {
JsonDocument doc; JsonDocument doc;
doc.add(); doc.add<JsonVariant>();
ElementProxy ep = doc[0]; ElementProxy ep = doc[0];
SECTION("returns 0") { SECTION("returns 0") {

View File

@ -12,7 +12,7 @@
using ArduinoJson::detail::sizeofArray; using ArduinoJson::detail::sizeofArray;
TEST_CASE("JsonDocument::add()") { TEST_CASE("JsonDocument::add(T)") {
SpyingAllocator spy; SpyingAllocator spy;
JsonDocument doc(&spy); JsonDocument doc(&spy);
@ -79,3 +79,26 @@ TEST_CASE("JsonDocument::add()") {
}); });
} }
} }
TEST_CASE("JsonDocument::add<T>()") {
JsonDocument doc;
SECTION("JsonArray") {
JsonArray array = doc.add<JsonArray>();
array.add(1);
array.add(2);
REQUIRE(doc.as<std::string>() == "[[1,2]]");
}
SECTION("JsonObject") {
JsonObject object = doc.add<JsonObject>();
object["hello"] = "world";
REQUIRE(doc.as<std::string>() == "[{\"hello\":\"world\"}]");
}
SECTION("JsonVariant") {
JsonVariant variant = doc.add<JsonVariant>();
variant.set(42);
REQUIRE(doc.as<std::string>() == "[42]");
}
}

View File

@ -6,7 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonVariant::add()") { TEST_CASE("JsonVariant::add(T)") {
JsonDocument doc; JsonDocument doc;
JsonVariant var = doc.to<JsonVariant>(); JsonVariant var = doc.to<JsonVariant>();
@ -44,3 +44,27 @@ TEST_CASE("JsonVariant::add()") {
REQUIRE(var.as<std::string>() == "{\"val\":123}"); REQUIRE(var.as<std::string>() == "{\"val\":123}");
} }
} }
TEST_CASE("JsonVariant::add<T>()") {
JsonDocument doc;
JsonVariant var = doc.to<JsonVariant>();
SECTION("JsonArray") {
JsonArray array = var.add<JsonArray>();
array.add(1);
array.add(2);
REQUIRE(doc.as<std::string>() == "[[1,2]]");
}
SECTION("JsonObject") {
JsonObject object = var.add<JsonObject>();
object["hello"] = "world";
REQUIRE(doc.as<std::string>() == "[{\"hello\":\"world\"}]");
}
SECTION("JsonVariant") {
JsonVariant variant = var.add<JsonVariant>();
variant.set(42);
REQUIRE(doc.as<std::string>() == "[42]");
}
}

View File

@ -10,7 +10,7 @@
TEST_CASE("Compare JsonVariant with value") { TEST_CASE("Compare JsonVariant with value") {
JsonDocument doc; JsonDocument doc;
JsonVariant a = doc.add(); JsonVariant a = doc.add<JsonVariant>();
SECTION("null vs (char*)0") { SECTION("null vs (char*)0") {
char* b = 0; char* b = 0;
@ -38,8 +38,8 @@ TEST_CASE("Compare JsonVariant with value") {
TEST_CASE("Compare JsonVariant with JsonVariant") { TEST_CASE("Compare JsonVariant with JsonVariant") {
JsonDocument doc; JsonDocument doc;
JsonVariant a = doc.add(); JsonVariant a = doc.add<JsonVariant>();
JsonVariant b = doc.add(); JsonVariant b = doc.add<JsonVariant>();
SECTION("'abc' vs 'abc'") { SECTION("'abc' vs 'abc'") {
a.set("abc"); a.set("abc");

View File

@ -41,10 +41,21 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
return JsonArrayConst(data_, resources_); return JsonArrayConst(data_, resources_);
} }
// Appends a new (empty) element to the array.
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/
template <typename T>
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type
add() const {
return add<JsonVariant>().to<T>();
}
// Appends a new (null) element to the array. // Appends a new (null) element to the array.
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/ // https://arduinojson.org/v6/api/jsonarray/add/
JsonVariant add() const { template <typename T>
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type
add() const {
return JsonVariant(detail::ArrayData::addElement(data_, resources_), return JsonVariant(detail::ArrayData::addElement(data_, resources_),
resources_); resources_);
} }
@ -53,14 +64,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// https://arduinojson.org/v6/api/jsonarray/add/ // https://arduinojson.org/v6/api/jsonarray/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(const T& value) const { FORCE_INLINE bool add(const T& value) const {
return add().set(value); return add<JsonVariant>().set(value);
} }
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v6/api/jsonarray/add/ // https://arduinojson.org/v6/api/jsonarray/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(T* value) const { FORCE_INLINE bool add(T* value) const {
return add().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.
@ -126,7 +137,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Creates an array and appends it to the array. // Creates an array and appends it to the array.
// https://arduinojson.org/v6/api/jsonarray/createnestedarray/ // https://arduinojson.org/v6/api/jsonarray/createnestedarray/
FORCE_INLINE JsonArray createNestedArray() const { FORCE_INLINE JsonArray createNestedArray() const {
return add().to<JsonArray>(); return add<JsonArray>();
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {

View File

@ -10,7 +10,7 @@
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
inline JsonObject JsonArray::createNestedObject() const { inline JsonObject JsonArray::createNestedObject() const {
return add().to<JsonObject>(); return add<JsonObject>();
} }
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE
@ -19,12 +19,12 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDerived> template <typename TDerived>
inline JsonArray VariantRefBase<TDerived>::createNestedArray() const { inline JsonArray VariantRefBase<TDerived>::createNestedArray() const {
return add().template to<JsonArray>(); return add<JsonArray>();
} }
template <typename TDerived> template <typename TDerived>
inline JsonObject VariantRefBase<TDerived>::createNestedObject() const { inline JsonObject VariantRefBase<TDerived>::createNestedObject() const {
return add().template to<JsonObject>(); return add<JsonObject>();
} }
template <typename TDerived> template <typename TDerived>

View File

@ -34,7 +34,7 @@ inline typename detail::enable_if<
copyArray(const T* src, size_t len, const TDestination& dst) { copyArray(const T* src, size_t len, const TDestination& dst) {
bool ok = true; bool ok = true;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
ok &= copyArray(src[i], dst.add()); ok &= copyArray(src[i], dst.template add<JsonVariant>());
} }
return ok; return ok;
} }

View File

@ -161,7 +161,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Creates an array and appends it to the root array. // Creates an array and appends it to the root array.
// https://arduinojson.org/v6/api/jsondocument/createnestedarray/ // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
JsonArray createNestedArray() { JsonArray createNestedArray() {
return add().to<JsonArray>(); return add<JsonArray>();
} }
// Creates an array and adds it to the root object. // Creates an array and adds it to the root object.
@ -181,7 +181,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Creates an object and appends it to the root array. // Creates an object and appends it to the root array.
// https://arduinojson.org/v6/api/jsondocument/createnestedobject/ // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
JsonObject createNestedObject() { JsonObject createNestedObject() {
return add().to<JsonObject>(); return add<JsonObject>();
} }
// Creates an object and adds it to the root object. // Creates an object and adds it to the root object.
@ -264,10 +264,21 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
return JsonVariantConst(data_.getElement(index, &resources_), &resources_); return JsonVariantConst(data_.getElement(index, &resources_), &resources_);
} }
// Appends a new (empty) element to the root array.
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsondocument/add/
template <typename T>
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type
add() {
return add<JsonVariant>().to<T>();
}
// Appends a new (null) element to the root array. // Appends a new (null) element to the root array.
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsondocument/add/ // https://arduinojson.org/v6/api/jsondocument/add/
FORCE_INLINE JsonVariant add() { template <typename T>
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type
add() {
return JsonVariant(data_.addElement(&resources_), &resources_); return JsonVariant(data_.addElement(&resources_), &resources_);
} }
@ -275,14 +286,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// https://arduinojson.org/v6/api/jsondocument/add/ // https://arduinojson.org/v6/api/jsondocument/add/
template <typename TValue> template <typename TValue>
FORCE_INLINE bool add(const TValue& value) { FORCE_INLINE bool add(const TValue& value) {
return add().set(value); return add<JsonVariant>().set(value);
} }
// Appends a value to the root array. // Appends a value to the root array.
// https://arduinojson.org/v6/api/jsondocument/add/ // https://arduinojson.org/v6/api/jsondocument/add/
template <typename TChar> template <typename TChar>
FORCE_INLINE bool add(TChar* value) { FORCE_INLINE bool add(TChar* value) {
return add().set(value); return add<JsonVariant>().set(value);
} }
// Removes an element of the root array. // Removes an element of the root array.

View File

@ -87,7 +87,9 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDerived> template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::add() const { template <typename T>
inline typename enable_if<is_same<T, JsonVariant>::value, T>::type
VariantRefBase<TDerived>::add() const {
return JsonVariant( return JsonVariant(
detail::VariantData::addElement(getOrCreateData(), getResourceManager()), detail::VariantData::addElement(getOrCreateData(), getResourceManager()),
getResourceManager()); getResourceManager());

View File

@ -136,23 +136,32 @@ class VariantRefBase : public VariantTag {
return VariantData::nesting(getData(), getResourceManager()); return VariantData::nesting(getData(), getResourceManager());
} }
// Appends a new (empty) element to the array.
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonvariant/add/
template <typename T>
typename enable_if<!is_same<T, JsonVariant>::value, T>::type add() const {
return add<JsonVariant>().template to<T>();
}
// Appends a new (null) element to the array. // Appends a new (null) element to the array.
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonvariant/add/ // https://arduinojson.org/v6/api/jsonvariant/add/
FORCE_INLINE JsonVariant add() const; template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, T>::type add() const;
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v6/api/jsonvariant/add/ // https://arduinojson.org/v6/api/jsonvariant/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(const T& value) const { FORCE_INLINE bool add(const T& value) const {
return add().set(value); return add<JsonVariant>().set(value);
} }
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v6/api/jsonvariant/add/ // https://arduinojson.org/v6/api/jsonvariant/add/
template <typename T> template <typename T>
FORCE_INLINE bool add(T* value) const { FORCE_INLINE bool add(T* value) const {
return add().set(value); return add<JsonVariant>().set(value);
} }
// Removes an element of the array. // Removes an element of the array.
@ -261,7 +270,6 @@ class VariantRefBase : public VariantTag {
return VariantAttorney::getOrCreateData(derived()); return VariantAttorney::getOrCreateData(derived());
} }
private:
FORCE_INLINE ArduinoJson::JsonVariant getVariant() const; FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const { FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {