diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ca44885..7df0d89d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Improved speed of float serialization (about twice faster) +* Added `as()` as a synonym for `as()`... (issue #291) v5.6.2 ------ diff --git a/include/ArduinoJson/Internals/JsonVariantAs.hpp b/include/ArduinoJson/Internals/JsonVariantAs.hpp new file mode 100644 index 00000000..72431ed4 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonVariantAs.hpp @@ -0,0 +1,45 @@ +// Copyright Benoit Blanchon 2014-2016 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson +// If you like this project, please add a star! + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +// A metafunction that returns the type of the value returned by +// JsonVariant::as() +template +struct JsonVariantAs { + typedef T type; +}; + +template <> +struct JsonVariantAs { + typedef const char* type; +}; + +template <> +struct JsonVariantAs { + typedef JsonArray& type; +}; + +template <> +struct JsonVariantAs { + typedef const JsonArray& type; +}; + +template <> +struct JsonVariantAs { + typedef JsonObject& type; +}; + +template <> +struct JsonVariantAs { + typedef const JsonObject& type; +}; +} +} diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index adfb3625..9055f4be 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -137,7 +137,7 @@ class JsonArray : public Internals::JsonPrintable, // Gets the value at the specified index. template - T get(size_t index) const { + typename Internals::JsonVariantAs::type get(size_t index) const { node_type *node = getNodeAt(index); return node ? node->content.as() : JsonVariant::defaultValue(); } diff --git a/include/ArduinoJson/JsonArray.ipp b/include/ArduinoJson/JsonArray.ipp index b5268476..0507addf 100644 --- a/include/ArduinoJson/JsonArray.ipp +++ b/include/ArduinoJson/JsonArray.ipp @@ -21,13 +21,23 @@ inline bool JsonArray::setNodeValue(node_type *node, String &value) { return true; } +template <> +inline JsonArray &JsonVariant::defaultValue() { + return JsonArray::invalid(); +} + template <> inline JsonArray &JsonVariant::defaultValue() { return JsonArray::invalid(); } template <> -inline JsonArray const &JsonVariant::defaultValue() { +inline const JsonArray &JsonVariant::defaultValue() { + return JsonArray::invalid(); +} + +template <> +inline const JsonArray &JsonVariant::defaultValue() { return JsonArray::invalid(); } diff --git a/include/ArduinoJson/JsonArraySubscript.hpp b/include/ArduinoJson/JsonArraySubscript.hpp index 6076476c..d9397111 100644 --- a/include/ArduinoJson/JsonArraySubscript.hpp +++ b/include/ArduinoJson/JsonArraySubscript.hpp @@ -42,12 +42,16 @@ class JsonArraySubscript : public JsonVariantBase { return *this; } - FORCE_INLINE bool success() const { return _index < _array.size(); } + FORCE_INLINE bool success() const { + return _index < _array.size(); + } - FORCE_INLINE operator JsonVariant() const { return _array.get(_index); } + FORCE_INLINE operator JsonVariant() const { + return _array.get(_index); + } template - FORCE_INLINE T as() const { + FORCE_INLINE typename Internals::JsonVariantAs::type as() const { return _array.get(_index); } diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index 0cef1292..101da1a4 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -106,7 +106,7 @@ class JsonObject : public Internals::JsonPrintable, // Gets the value associated with the specified key. template - T get(JsonObjectKey key) const { + typename Internals::JsonVariantAs::type get(JsonObjectKey key) const { node_type* node = getNodeAt(key.c_str()); return node ? node->content.value.as() : JsonVariant::defaultValue(); } diff --git a/include/ArduinoJson/JsonObject.ipp b/include/ArduinoJson/JsonObject.ipp index 05857b26..97e79caa 100644 --- a/include/ArduinoJson/JsonObject.ipp +++ b/include/ArduinoJson/JsonObject.ipp @@ -26,7 +26,12 @@ inline bool JsonObject::setNodeValue(node_type *node, const String &value) { } template <> -inline JsonObject const &JsonVariant::defaultValue() { +inline const JsonObject &JsonVariant::defaultValue() { + return JsonObject::invalid(); +} + +template <> +inline const JsonObject &JsonVariant::defaultValue() { return JsonObject::invalid(); } @@ -35,6 +40,11 @@ inline JsonObject &JsonVariant::defaultValue() { return JsonObject::invalid(); } +template <> +inline JsonObject &JsonVariant::defaultValue() { + return JsonObject::invalid(); +} + inline JsonObject &JsonVariant::asObject() const { if (_type == Internals::JSON_OBJECT) return *_content.asObject; return JsonObject::invalid(); diff --git a/include/ArduinoJson/JsonObjectSubscript.hpp b/include/ArduinoJson/JsonObjectSubscript.hpp index 0d05a594..d3c68045 100644 --- a/include/ArduinoJson/JsonObjectSubscript.hpp +++ b/include/ArduinoJson/JsonObjectSubscript.hpp @@ -54,7 +54,7 @@ class JsonObjectSubscript : public JsonVariantBase > { } template - FORCE_INLINE TValue as() const { + FORCE_INLINE typename Internals::JsonVariantAs::type as() const { return _object.get(_key); } diff --git a/include/ArduinoJson/JsonVariant.hpp b/include/ArduinoJson/JsonVariant.hpp index 6aa6fa76..644c44cb 100644 --- a/include/ArduinoJson/JsonVariant.hpp +++ b/include/ArduinoJson/JsonVariant.hpp @@ -177,28 +177,43 @@ class JsonVariant : public JsonVariantBase { // // JsonArray& as const; // JsonArray& as const; - // JsonArray& as const; template typename TypeTraits::EnableIf< - TypeTraits::IsSame< - typename TypeTraits::RemoveConst< - typename TypeTraits::RemoveReference::type>::type, - JsonArray>::value, + TypeTraits::IsSame::type, + JsonArray>::value, JsonArray &>::type as() const { return asArray(); } // + // const JsonArray& as const; + template + typename TypeTraits::EnableIf< + TypeTraits::IsSame::type, + const JsonArray>::value, + const JsonArray &>::type + as() const { + return asArray(); + } + // // JsonObject& as const; // JsonObject& as const; + template + typename TypeTraits::EnableIf< + TypeTraits::IsSame::type, + JsonObject>::value, + JsonObject &>::type + as() const { + return asObject(); + } + // + // JsonObject& as const; // JsonObject& as const; template typename TypeTraits::EnableIf< - TypeTraits::IsSame< - typename TypeTraits::RemoveConst< - typename TypeTraits::RemoveReference::type>::type, - JsonObject>::value, - JsonObject &>::type + TypeTraits::IsSame::type, + const JsonObject>::value, + const JsonObject &>::type as() const { return asObject(); } @@ -281,7 +296,7 @@ class JsonVariant : public JsonVariantBase { // Value returned if the variant has an incompatible type template - static T defaultValue() { + static typename Internals::JsonVariantAs::type defaultValue() { return T(); } diff --git a/include/ArduinoJson/JsonVariantBase.hpp b/include/ArduinoJson/JsonVariantBase.hpp index bd4fb8da..6dfca048 100644 --- a/include/ArduinoJson/JsonVariantBase.hpp +++ b/include/ArduinoJson/JsonVariantBase.hpp @@ -7,8 +7,9 @@ #pragma once -#include "Polyfills/attributes.hpp" +#include "Internals/JsonVariantAs.hpp" #include "JsonObjectKey.hpp" +#include "Polyfills/attributes.hpp" namespace ArduinoJson { @@ -20,20 +21,35 @@ class JsonObjectSubscript; template class JsonVariantBase : public Internals::JsonPrintable { public: - FORCE_INLINE const char *asString() const { return as(); } + // DEPRECATED: use as() instead + FORCE_INLINE const char *asString() const { + return as(); + } // Gets the variant as an array. // Returns a reference to the JsonArray or JsonArray::invalid() if the // variant // is not an array. - FORCE_INLINE operator JsonArray &() const { return as(); } - FORCE_INLINE JsonArray &asArray() const { return as(); } + FORCE_INLINE operator JsonArray &() const { + return as(); + } + + // DEPRECATED: use as() instead + FORCE_INLINE JsonArray &asArray() const { + return as(); + } // Gets the variant as an object. // Returns a reference to the JsonObject or JsonObject::invalid() if the // variant is not an object. - FORCE_INLINE operator JsonObject &() const { return as(); } - FORCE_INLINE JsonObject &asObject() const { return as(); } + FORCE_INLINE operator JsonObject &() const { + return as(); + } + + // DEPRECATED: use as() instead + FORCE_INLINE JsonObject &asObject() const { + return as(); + } template FORCE_INLINE operator T() const { @@ -41,14 +57,16 @@ class JsonVariantBase : public Internals::JsonPrintable { } template - FORCE_INLINE const T as() const { + FORCE_INLINE const typename Internals::JsonVariantAs::type as() const { return impl()->template as(); } // Mimics an array or an object. // Returns the size of the array or object if the variant has that type. // Returns 0 if the variant is neither an array nor an object - size_t size() const { return asArray().size() + asObject().size(); } + size_t size() const { + return asArray().size() + asObject().size(); + } // Mimics an array. // Returns the element at specified index if the variant is an array. @@ -68,7 +86,9 @@ class JsonVariantBase : public Internals::JsonPrintable { void writeTo(Internals::JsonWriter &writer) const; private: - const TImpl *impl() const { return static_cast(this); } + const TImpl *impl() const { + return static_cast(this); + } }; template diff --git a/test/JsonArray_Subscript_Tests.cpp b/test/JsonArray_Subscript_Tests.cpp index e2da2c2d..9325ede6 100644 --- a/test/JsonArray_Subscript_Tests.cpp +++ b/test/JsonArray_Subscript_Tests.cpp @@ -59,6 +59,7 @@ TEST_(StoreBoolean) { TEST_(StoreString) { _array[0] = "hello"; EXPECT_STREQ("hello", _array[0].as()); + EXPECT_STREQ("hello", _array[0].as()); // <- short hand EXPECT_TRUE(_array[0].is()); EXPECT_FALSE(_array[0].is()); } @@ -69,6 +70,9 @@ TEST_(StoreNestedArray) { _array[0] = arr; EXPECT_EQ(&arr, &_array[0].as()); + EXPECT_EQ(&arr, &_array[0].as()); // <- short hand + EXPECT_EQ(&arr, &_array[0].as()); + EXPECT_EQ(&arr, &_array[0].as()); // <- short hand EXPECT_TRUE(_array[0].is()); EXPECT_FALSE(_array[0].is()); } @@ -79,6 +83,9 @@ TEST_(StoreNestedObject) { _array[0] = obj; EXPECT_EQ(&obj, &_array[0].as()); + EXPECT_EQ(&obj, &_array[0].as()); // <- short hand + EXPECT_EQ(&obj, &_array[0].as()); + EXPECT_EQ(&obj, &_array[0].as()); // <- short hand EXPECT_TRUE(_array[0].is()); EXPECT_FALSE(_array[0].is()); } diff --git a/test/JsonObject_Subscript_Tests.cpp b/test/JsonObject_Subscript_Tests.cpp index 0a2e8068..c16ad413 100644 --- a/test/JsonObject_Subscript_Tests.cpp +++ b/test/JsonObject_Subscript_Tests.cpp @@ -68,6 +68,7 @@ TEST_(StoreString) { EXPECT_TRUE(_object["hello"].is()); EXPECT_FALSE(_object["hello"].is()); EXPECT_STREQ("h3110", _object["hello"].as()); + EXPECT_STREQ("h3110", _object["hello"].as()); // <- short hand } TEST_(StoreArray) { @@ -75,8 +76,15 @@ TEST_(StoreArray) { _object["hello"] = arr; - EXPECT_EQ(&arr, &_object["hello"].asArray()); + EXPECT_EQ(&arr, &_object["hello"].asArray()); // <- DEPRECATED + EXPECT_EQ(&arr, &_object["hello"].as()); + EXPECT_EQ(&arr, &_object["hello"].as()); // <- short hand + EXPECT_EQ(&arr, &_object["hello"].as()); + EXPECT_EQ(&arr, &_object["hello"].as()); // <- short hand EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); EXPECT_FALSE(_object["hello"].is()); } @@ -85,8 +93,15 @@ TEST_(StoreObject) { _object["hello"] = obj; - EXPECT_EQ(&obj, &_object["hello"].asObject()); + EXPECT_EQ(&obj, &_object["hello"].asObject()); // DEPRECATED + EXPECT_EQ(&obj, &_object["hello"].as()); + EXPECT_EQ(&obj, &_object["hello"].as()); // <- short hand + EXPECT_EQ(&obj, &_object["hello"].as()); + EXPECT_EQ(&obj, &_object["hello"].as()); // <- short hand EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); + EXPECT_TRUE(_object["hello"].is()); EXPECT_FALSE(_object["hello"].is()); } diff --git a/test/JsonVariant_As_Tests.cpp b/test/JsonVariant_As_Tests.cpp index 205f04b3..06582e05 100644 --- a/test/JsonVariant_As_Tests.cpp +++ b/test/JsonVariant_As_Tests.cpp @@ -214,3 +214,21 @@ TEST(JsonVariant_As_Tests, ArrayAsString) { JsonVariant variant = arr; ASSERT_EQ(String("[4,2]"), variant.as()); } + +TEST(JsonVariant_As_Tests, ArrayAsJsonArray) { + DynamicJsonBuffer buffer; + JsonArray& arr = buffer.createArray(); + + JsonVariant variant = arr; + ASSERT_EQ(&arr, &variant.as()); + ASSERT_EQ(&arr, &variant.as()); // <- shorthand +} + +TEST(JsonVariant_As_Tests, ObjectAsJsonObject) { + DynamicJsonBuffer buffer; + JsonObject& arr = buffer.createObject(); + + JsonVariant variant = arr; + ASSERT_EQ(&arr, &variant.as()); + ASSERT_EQ(&arr, &variant.as()); // <- shorthand +}