mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added as<JsonArray>() as a synonym for as<JsonArray&>()... (issue #291)
				
					
				
			This commit is contained in:
		| @@ -5,6 +5,7 @@ HEAD | ||||
| ---- | ||||
|  | ||||
| * Improved speed of float serialization (about twice faster) | ||||
| * Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291) | ||||
|  | ||||
| v5.6.2 | ||||
| ------ | ||||
|   | ||||
							
								
								
									
										45
									
								
								include/ArduinoJson/Internals/JsonVariantAs.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								include/ArduinoJson/Internals/JsonVariantAs.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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<T>() | ||||
| template <typename T> | ||||
| struct JsonVariantAs { | ||||
|   typedef T type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct JsonVariantAs<char*> { | ||||
|   typedef const char* type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct JsonVariantAs<JsonArray> { | ||||
|   typedef JsonArray& type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct JsonVariantAs<const JsonArray> { | ||||
|   typedef const JsonArray& type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct JsonVariantAs<JsonObject> { | ||||
|   typedef JsonObject& type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct JsonVariantAs<const JsonObject> { | ||||
|   typedef const JsonObject& type; | ||||
| }; | ||||
| } | ||||
| } | ||||
| @@ -137,7 +137,7 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|  | ||||
|   // Gets the value at the specified index. | ||||
|   template <typename T> | ||||
|   T get(size_t index) const { | ||||
|   typename Internals::JsonVariantAs<T>::type get(size_t index) const { | ||||
|     node_type *node = getNodeAt(index); | ||||
|     return node ? node->content.as<T>() : JsonVariant::defaultValue<T>(); | ||||
|   } | ||||
|   | ||||
| @@ -21,13 +21,23 @@ inline bool JsonArray::setNodeValue(node_type *node, String &value) { | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline JsonArray &JsonVariant::defaultValue<JsonArray>() { | ||||
|   return JsonArray::invalid(); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline JsonArray &JsonVariant::defaultValue<JsonArray &>() { | ||||
|   return JsonArray::invalid(); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline JsonArray const &JsonVariant::defaultValue<JsonArray const &>() { | ||||
| inline const JsonArray &JsonVariant::defaultValue<const JsonArray>() { | ||||
|   return JsonArray::invalid(); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline const JsonArray &JsonVariant::defaultValue<const JsonArray &>() { | ||||
|   return JsonArray::invalid(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -42,12 +42,16 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|     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 <typename T> | ||||
|   FORCE_INLINE T as() const { | ||||
|   FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const { | ||||
|     return _array.get<T>(_index); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -106,7 +106,7 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   template <typename T> | ||||
|   T get(JsonObjectKey key) const { | ||||
|   typename Internals::JsonVariantAs<T>::type get(JsonObjectKey key) const { | ||||
|     node_type* node = getNodeAt(key.c_str()); | ||||
|     return node ? node->content.value.as<T>() : JsonVariant::defaultValue<T>(); | ||||
|   } | ||||
|   | ||||
| @@ -26,7 +26,12 @@ inline bool JsonObject::setNodeValue(node_type *node, const String &value) { | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline JsonObject const &JsonVariant::defaultValue<JsonObject const &>() { | ||||
| inline const JsonObject &JsonVariant::defaultValue<const JsonObject &>() { | ||||
|   return JsonObject::invalid(); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline const JsonObject &JsonVariant::defaultValue<const JsonObject>() { | ||||
|   return JsonObject::invalid(); | ||||
| } | ||||
|  | ||||
| @@ -35,6 +40,11 @@ inline JsonObject &JsonVariant::defaultValue<JsonObject &>() { | ||||
|   return JsonObject::invalid(); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline JsonObject &JsonVariant::defaultValue<JsonObject>() { | ||||
|   return JsonObject::invalid(); | ||||
| } | ||||
|  | ||||
| inline JsonObject &JsonVariant::asObject() const { | ||||
|   if (_type == Internals::JSON_OBJECT) return *_content.asObject; | ||||
|   return JsonObject::invalid(); | ||||
|   | ||||
| @@ -54,7 +54,7 @@ class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > { | ||||
|   } | ||||
|  | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE TValue as() const { | ||||
|   FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const { | ||||
|     return _object.get<TValue>(_key); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -177,28 +177,43 @@ class JsonVariant : public JsonVariantBase<JsonVariant> { | ||||
|   // | ||||
|   // JsonArray& as<JsonArray> const; | ||||
|   // JsonArray& as<JsonArray&> const; | ||||
|   // JsonArray& as<const JsonArray&> const; | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       TypeTraits::IsSame< | ||||
|           typename TypeTraits::RemoveConst< | ||||
|               typename TypeTraits::RemoveReference<T>::type>::type, | ||||
|           JsonArray>::value, | ||||
|       TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type, | ||||
|                          JsonArray>::value, | ||||
|       JsonArray &>::type | ||||
|   as() const { | ||||
|     return asArray(); | ||||
|   } | ||||
|   // | ||||
|   // const JsonArray& as<const JsonArray&> const; | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type, | ||||
|                          const JsonArray>::value, | ||||
|       const JsonArray &>::type | ||||
|   as() const { | ||||
|     return asArray(); | ||||
|   } | ||||
|   // | ||||
|   // JsonObject& as<JsonObject> const; | ||||
|   // JsonObject& as<JsonObject&> const; | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type, | ||||
|                          JsonObject>::value, | ||||
|       JsonObject &>::type | ||||
|   as() const { | ||||
|     return asObject(); | ||||
|   } | ||||
|   // | ||||
|   // JsonObject& as<const JsonObject> const; | ||||
|   // JsonObject& as<const JsonObject&> const; | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       TypeTraits::IsSame< | ||||
|           typename TypeTraits::RemoveConst< | ||||
|               typename TypeTraits::RemoveReference<T>::type>::type, | ||||
|           JsonObject>::value, | ||||
|       JsonObject &>::type | ||||
|       TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type, | ||||
|                          const JsonObject>::value, | ||||
|       const JsonObject &>::type | ||||
|   as() const { | ||||
|     return asObject(); | ||||
|   } | ||||
| @@ -281,7 +296,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> { | ||||
|  | ||||
|   // Value returned if the variant has an incompatible type | ||||
|   template <typename T> | ||||
|   static T defaultValue() { | ||||
|   static typename Internals::JsonVariantAs<T>::type defaultValue() { | ||||
|     return T(); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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 <typename TImpl> | ||||
| class JsonVariantBase : public Internals::JsonPrintable<TImpl> { | ||||
|  public: | ||||
|   FORCE_INLINE const char *asString() const { return as<const char *>(); } | ||||
|   // DEPRECATED: use as<char*>() instead | ||||
|   FORCE_INLINE const char *asString() const { | ||||
|     return as<const char *>(); | ||||
|   } | ||||
|  | ||||
|   // 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<JsonArray &>(); } | ||||
|   FORCE_INLINE JsonArray &asArray() const { return as<JsonArray &>(); } | ||||
|   FORCE_INLINE operator JsonArray &() const { | ||||
|     return as<JsonArray &>(); | ||||
|   } | ||||
|  | ||||
|   // DEPRECATED: use as<JsonArray>() instead | ||||
|   FORCE_INLINE JsonArray &asArray() const { | ||||
|     return as<JsonArray &>(); | ||||
|   } | ||||
|  | ||||
|   // 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<JsonObject &>(); } | ||||
|   FORCE_INLINE JsonObject &asObject() const { return as<JsonObject &>(); } | ||||
|   FORCE_INLINE operator JsonObject &() const { | ||||
|     return as<JsonObject &>(); | ||||
|   } | ||||
|  | ||||
|   // DEPRECATED: use as<JsonObject>() instead | ||||
|   FORCE_INLINE JsonObject &asObject() const { | ||||
|     return as<JsonObject &>(); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE operator T() const { | ||||
| @@ -41,14 +57,16 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> { | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE const T as() const { | ||||
|   FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const { | ||||
|     return impl()->template as<T>(); | ||||
|   } | ||||
|  | ||||
|   // 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<TImpl> { | ||||
|   void writeTo(Internals::JsonWriter &writer) const; | ||||
|  | ||||
|  private: | ||||
|   const TImpl *impl() const { return static_cast<const TImpl *>(this); } | ||||
|   const TImpl *impl() const { | ||||
|     return static_cast<const TImpl *>(this); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TImpl, typename TComparand> | ||||
|   | ||||
| @@ -59,6 +59,7 @@ TEST_(StoreBoolean) { | ||||
| TEST_(StoreString) { | ||||
|   _array[0] = "hello"; | ||||
|   EXPECT_STREQ("hello", _array[0].as<const char*>()); | ||||
|   EXPECT_STREQ("hello", _array[0].as<char*>());  // <- short hand | ||||
|   EXPECT_TRUE(_array[0].is<const char*>()); | ||||
|   EXPECT_FALSE(_array[0].is<int>()); | ||||
| } | ||||
| @@ -69,6 +70,9 @@ TEST_(StoreNestedArray) { | ||||
|   _array[0] = arr; | ||||
|  | ||||
|   EXPECT_EQ(&arr, &_array[0].as<JsonArray&>()); | ||||
|   EXPECT_EQ(&arr, &_array[0].as<JsonArray>());  // <- short hand | ||||
|   EXPECT_EQ(&arr, &_array[0].as<const JsonArray&>()); | ||||
|   EXPECT_EQ(&arr, &_array[0].as<const JsonArray>());  // <- short hand | ||||
|   EXPECT_TRUE(_array[0].is<JsonArray&>()); | ||||
|   EXPECT_FALSE(_array[0].is<int>()); | ||||
| } | ||||
| @@ -79,6 +83,9 @@ TEST_(StoreNestedObject) { | ||||
|   _array[0] = obj; | ||||
|  | ||||
|   EXPECT_EQ(&obj, &_array[0].as<JsonObject&>()); | ||||
|   EXPECT_EQ(&obj, &_array[0].as<JsonObject>());  // <- short hand | ||||
|   EXPECT_EQ(&obj, &_array[0].as<const JsonObject&>()); | ||||
|   EXPECT_EQ(&obj, &_array[0].as<const JsonObject>());  // <- short hand | ||||
|   EXPECT_TRUE(_array[0].is<JsonObject&>()); | ||||
|   EXPECT_FALSE(_array[0].is<int>()); | ||||
| } | ||||
|   | ||||
| @@ -68,6 +68,7 @@ TEST_(StoreString) { | ||||
|   EXPECT_TRUE(_object["hello"].is<const char*>()); | ||||
|   EXPECT_FALSE(_object["hello"].is<long>()); | ||||
|   EXPECT_STREQ("h3110", _object["hello"].as<const char*>()); | ||||
|   EXPECT_STREQ("h3110", _object["hello"].as<char*>());  // <- 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<JsonArray&>()); | ||||
|   EXPECT_EQ(&arr, &_object["hello"].as<JsonArray>());  // <- short hand | ||||
|   EXPECT_EQ(&arr, &_object["hello"].as<const JsonArray&>()); | ||||
|   EXPECT_EQ(&arr, &_object["hello"].as<const JsonArray>());  // <- short hand | ||||
|   EXPECT_TRUE(_object["hello"].is<JsonArray&>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<JsonArray>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<const JsonArray&>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<const JsonArray>()); | ||||
|   EXPECT_FALSE(_object["hello"].is<JsonObject&>()); | ||||
| } | ||||
|  | ||||
| @@ -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<JsonObject&>()); | ||||
|   EXPECT_EQ(&obj, &_object["hello"].as<JsonObject>());  // <- short hand | ||||
|   EXPECT_EQ(&obj, &_object["hello"].as<const JsonObject&>()); | ||||
|   EXPECT_EQ(&obj, &_object["hello"].as<const JsonObject>());  // <- short hand | ||||
|   EXPECT_TRUE(_object["hello"].is<JsonObject&>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<JsonObject>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<const JsonObject&>()); | ||||
|   EXPECT_TRUE(_object["hello"].is<const JsonObject>()); | ||||
|   EXPECT_FALSE(_object["hello"].is<JsonArray&>()); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -214,3 +214,21 @@ TEST(JsonVariant_As_Tests, ArrayAsString) { | ||||
|   JsonVariant variant = arr; | ||||
|   ASSERT_EQ(String("[4,2]"), variant.as<String>()); | ||||
| } | ||||
|  | ||||
| TEST(JsonVariant_As_Tests, ArrayAsJsonArray) { | ||||
|   DynamicJsonBuffer buffer; | ||||
|   JsonArray& arr = buffer.createArray(); | ||||
|  | ||||
|   JsonVariant variant = arr; | ||||
|   ASSERT_EQ(&arr, &variant.as<JsonArray&>()); | ||||
|   ASSERT_EQ(&arr, &variant.as<JsonArray>());  // <- shorthand | ||||
| } | ||||
|  | ||||
| TEST(JsonVariant_As_Tests, ObjectAsJsonObject) { | ||||
|   DynamicJsonBuffer buffer; | ||||
|   JsonObject& arr = buffer.createObject(); | ||||
|  | ||||
|   JsonVariant variant = arr; | ||||
|   ASSERT_EQ(&arr, &variant.as<JsonObject&>()); | ||||
|   ASSERT_EQ(&arr, &variant.as<JsonObject>());  // <- shorthand | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user