mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added Visitable to reduce the number of definitions of operator<<
This commit is contained in:
		| @@ -6,7 +6,8 @@ | ||||
|  | ||||
| #include "../Serialization/measure.hpp" | ||||
| #include "../Serialization/serialize.hpp" | ||||
| #include "./JsonWriter.hpp" | ||||
| #include "../Visitable.hpp" | ||||
| #include "JsonWriter.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| @@ -103,32 +104,9 @@ size_t measureJson(const TSource &source) { | ||||
| } | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | ||||
| inline std::ostream &operator<<(std::ostream &os, const JsonArray &source) { | ||||
|   serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
| inline std::ostream &operator<<(std::ostream &os, const JsonObject &source) { | ||||
|   serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
| inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) { | ||||
|   serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
| inline std::ostream &operator<<(std::ostream &os, JsonVariantConst source) { | ||||
|   os << serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
|  | ||||
| inline std::ostream &operator<<(std::ostream &os, | ||||
|                                 const JsonArraySubscript &source) { | ||||
|   serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline std::ostream &operator<<(std::ostream &os, | ||||
|                                 const JsonObjectSubscript<TKey> &source) { | ||||
| template <typename T> | ||||
| inline typename enable_if<IsVisitable<T>::value, std::ostream &>::type | ||||
| operator<<(std::ostream &os, const T &source) { | ||||
|   serializeJson(source, os); | ||||
|   return os; | ||||
| } | ||||
|   | ||||
| @@ -38,13 +38,22 @@ class JsonArrayProxy { | ||||
|   TData* _data; | ||||
| }; | ||||
|  | ||||
| class JsonArrayConst : public JsonArrayProxy<const JsonArrayData> { | ||||
| class JsonArrayConst : public JsonArrayProxy<const JsonArrayData>, | ||||
|                        public Visitable { | ||||
|   friend class JsonArray; | ||||
|   typedef JsonArrayProxy<const JsonArrayData> proxy_type; | ||||
|  | ||||
|  public: | ||||
|   typedef JsonArrayConstIterator iterator; | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   FORCE_INLINE void accept(Visitor& visitor) const { | ||||
|     if (_data) | ||||
|       visitor.visitArray(*this); | ||||
|     else | ||||
|       visitor.visitNull(); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE iterator begin() const { | ||||
|     if (!_data) return iterator(); | ||||
|     return iterator(_data->head); | ||||
| @@ -62,7 +71,7 @@ class JsonArrayConst : public JsonArrayProxy<const JsonArrayData> { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class JsonArray : public JsonArrayProxy<JsonArrayData> { | ||||
| class JsonArray : public JsonArrayProxy<JsonArrayData>, public Visitable { | ||||
|   typedef JsonArrayProxy<JsonArrayData> proxy_type; | ||||
|  | ||||
|  public: | ||||
| @@ -224,10 +233,7 @@ class JsonArray : public JsonArrayProxy<JsonArrayData> { | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   FORCE_INLINE void accept(Visitor& visitor) const { | ||||
|     if (_data) | ||||
|       visitor.visitArray(*this); | ||||
|     else | ||||
|       visitor.visitNull(); | ||||
|     JsonArrayConst(_data).accept(visitor); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   | ||||
| @@ -13,7 +13,8 @@ | ||||
| #endif | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
| class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript>, | ||||
|                            public Visitable { | ||||
|  public: | ||||
|   FORCE_INLINE JsonArraySubscript(JsonArray array, size_t index) | ||||
|       : _array(array), _index(index) {} | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TMemoryPool> | ||||
| class JsonDocument { | ||||
| class JsonDocument : public Visitable { | ||||
|  public: | ||||
|   uint8_t nestingLimit; | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,10 @@ class JsonObjectProxy { | ||||
|     return objectContainsKey(_data, makeString(key)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool isNull() const { | ||||
|     return _data == 0; | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE size_t size() const { | ||||
|     return objectSize(_data); | ||||
|   } | ||||
| @@ -42,7 +46,8 @@ class JsonObjectProxy { | ||||
|   TData* _data; | ||||
| }; | ||||
|  | ||||
| class JsonObjectConst : public JsonObjectProxy<const JsonObjectData> { | ||||
| class JsonObjectConst : public JsonObjectProxy<const JsonObjectData>, | ||||
|                         public Visitable { | ||||
|   friend class JsonObject; | ||||
|   typedef JsonObjectProxy<const JsonObjectData> proxy_type; | ||||
|  | ||||
| @@ -52,6 +57,14 @@ class JsonObjectConst : public JsonObjectProxy<const JsonObjectData> { | ||||
|   JsonObjectConst() : proxy_type(0) {} | ||||
|   JsonObjectConst(const JsonObjectData* data) : proxy_type(data) {} | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   FORCE_INLINE void accept(Visitor& visitor) const { | ||||
|     if (_data) | ||||
|       visitor.visitObject(*this); | ||||
|     else | ||||
|       visitor.visitNull(); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE iterator begin() const { | ||||
|     if (!_data) return iterator(); | ||||
|     return iterator(_data->head); | ||||
| @@ -110,7 +123,7 @@ class JsonObjectConst : public JsonObjectProxy<const JsonObjectData> { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class JsonObject : public JsonObjectProxy<JsonObjectData> { | ||||
| class JsonObject : public JsonObjectProxy<JsonObjectData>, public Visitable { | ||||
|   typedef JsonObjectProxy<JsonObjectData> proxy_type; | ||||
|  | ||||
|  public: | ||||
| @@ -304,16 +317,9 @@ class JsonObject : public JsonObjectProxy<JsonObjectData> { | ||||
|     return set_impl(key); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool isNull() const { | ||||
|     return _data == 0; | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   FORCE_INLINE void accept(Visitor& visitor) const { | ||||
|     if (_data) | ||||
|       visitor.visitObject(JsonObjectConst(_data)); | ||||
|     else | ||||
|       visitor.visitNull(); | ||||
|     JsonObjectConst(_data).accept(visitor); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   | ||||
| @@ -17,7 +17,8 @@ namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TStringRef> | ||||
| class JsonObjectSubscript | ||||
|     : public JsonVariantBase<JsonObjectSubscript<TStringRef> > { | ||||
|     : public JsonVariantBase<JsonObjectSubscript<TStringRef> >, | ||||
|       public Visitable { | ||||
|   typedef JsonObjectSubscript<TStringRef> this_type; | ||||
|  | ||||
|  public: | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
| #include "Numbers/parseFloat.hpp" | ||||
| #include "Numbers/parseInteger.hpp" | ||||
| #include "Polyfills/type_traits.hpp" | ||||
| #include "Visitable.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| @@ -117,7 +118,8 @@ class JsonVariantProxy { | ||||
| // - a string (const char*) | ||||
| // - a reference to a JsonArray or JsonObject | ||||
| class JsonVariant : public JsonVariantProxy<JsonVariantData>, | ||||
|                     public JsonVariantBase<JsonVariant> { | ||||
|                     public JsonVariantBase<JsonVariant>, | ||||
|                     public Visitable { | ||||
|   typedef JsonVariantProxy<JsonVariantData> proxy_type; | ||||
|   friend class JsonVariantConst; | ||||
|  | ||||
| @@ -279,7 +281,8 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>, | ||||
| }; | ||||
|  | ||||
| class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>, | ||||
|                          public JsonVariantBase<JsonVariantConst> { | ||||
|                          public JsonVariantBase<JsonVariantConst>, | ||||
|                          public Visitable { | ||||
|   typedef JsonVariantProxy<const JsonVariantData> proxy_type; | ||||
|  | ||||
|  public: | ||||
| @@ -318,15 +321,4 @@ class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>, | ||||
|     return JsonVariantConst(objectGet(variantAsObject(_data), makeString(key))); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class JsonVariantLocal : public JsonVariant { | ||||
|  public: | ||||
|   explicit JsonVariantLocal(MemoryPool *memoryPool) | ||||
|       : JsonVariant(memoryPool, &_localData) { | ||||
|     _localData.type = JSON_NULL; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonVariantData _localData; | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -278,7 +278,8 @@ class MsgPackDeserializer { | ||||
|     if (_nestingLimit == 0) return DeserializationError::TooDeep; | ||||
|     --_nestingLimit; | ||||
|     for (; n; --n) { | ||||
|       JsonVariantLocal key(_memoryPool); | ||||
|       JsonVariantData keyData; | ||||
|       JsonVariant key(_memoryPool, &keyData); | ||||
|       DeserializationError err = parse(key); | ||||
|       if (err) return err; | ||||
|       if (!key.is<char *>()) return DeserializationError::NotSupported; | ||||
|   | ||||
| @@ -18,8 +18,7 @@ class is_base_of { | ||||
|   static No &probe(...); | ||||
|  | ||||
|  public: | ||||
|   enum { | ||||
|     value = sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes) | ||||
|   }; | ||||
|   static const bool value = | ||||
|       sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes); | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
							
								
								
									
										18
									
								
								src/ArduinoJson/Visitable.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/ArduinoJson/Visitable.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Polyfills/type_traits.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| struct Visitable { | ||||
|   // template<Visitor> | ||||
|   // void accept(Visitor&) const; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct IsVisitable : is_base_of<Visitable, T> {}; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
| @@ -6,39 +6,29 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::isNull()") { | ||||
|   SECTION("returns true for undefined JsonArray") { | ||||
|     JsonArray array; | ||||
|     REQUIRE(array.isNull() == true); | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonArray arr; | ||||
|     REQUIRE(arr.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false when allocation succeeds") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     REQUIRE(array.isNull() == false); | ||||
|   SECTION("returns false") { | ||||
|     JsonArray arr = doc.to<JsonArray>(); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   /*  SECTION("returns true when allocation fails") { | ||||
|       StaticJsonDocument<1> doc; | ||||
|       JsonArray array = doc.to<JsonArray>(); | ||||
|       REQUIRE(array.isNull() == true); | ||||
|     }*/ | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonArrayConst::isNull()") { | ||||
|   SECTION("returns true for undefined JsonArray") { | ||||
|     JsonArrayConst array; | ||||
|     REQUIRE(array.isNull() == true); | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonArrayConst arr; | ||||
|     REQUIRE(arr.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false when allocation succeeds") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; | ||||
|     JsonArrayConst array = doc.to<JsonArray>(); | ||||
|     REQUIRE(array.isNull() == false); | ||||
|   SECTION("returns false") { | ||||
|     JsonArrayConst arr = doc.to<JsonArray>(); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   /*  SECTION("returns true when allocation fails") { | ||||
|       StaticJsonDocument<1> doc; | ||||
|       JsonArray array = doc.to<JsonArray>(); | ||||
|       REQUIRE(array.isNull() == true); | ||||
|     }*/ | ||||
| } | ||||
|   | ||||
| @@ -6,20 +6,29 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::isNull()") { | ||||
|   SECTION("returns true for undefined JsonObject") { | ||||
|     JsonObject array; | ||||
|     REQUIRE(array.isNull() == true); | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonObject obj; | ||||
|     REQUIRE(obj.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false when allocation succeeds") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc; | ||||
|     JsonObject array = doc.to<JsonObject>(); | ||||
|     REQUIRE(array.isNull() == false); | ||||
|   SECTION("returns false") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonObjectConst::isNull()") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonObjectConst obj; | ||||
|     REQUIRE(obj.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false") { | ||||
|     JsonObjectConst obj = doc.to<JsonObject>(); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   /*  SECTION("returns true when allocation fails") { | ||||
|       StaticJsonDocument<1> doc; | ||||
|       JsonObject array = doc.to<JsonObject>(); | ||||
|       REQUIRE(array.isNull() == true); | ||||
|     }*/ | ||||
| } | ||||
|   | ||||
| @@ -50,4 +50,19 @@ TEST_CASE("Polyfills/type_traits") { | ||||
|     CHECK(is_unsigned<float>::value == false); | ||||
|     CHECK(is_unsigned<double>::value == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("IsVisitable") { | ||||
|     CHECK(IsVisitable<DeserializationError>::value == false); | ||||
|     CHECK(IsVisitable<JsonPair>::value == false); | ||||
|     CHECK(IsVisitable<JsonVariant>::value == true); | ||||
|     CHECK(IsVisitable<JsonVariantConst>::value == true); | ||||
|     CHECK(IsVisitable<JsonArray>::value == true); | ||||
|     CHECK(IsVisitable<JsonArraySubscript>::value == true); | ||||
|     CHECK(IsVisitable<JsonArrayConst>::value == true); | ||||
|     CHECK(IsVisitable<JsonObject>::value == true); | ||||
|     CHECK(IsVisitable<JsonObjectSubscript<const char*> >::value == true); | ||||
|     CHECK(IsVisitable<JsonObjectConst>::value == true); | ||||
|     CHECK(IsVisitable<DynamicJsonDocument>::value == true); | ||||
|     CHECK(IsVisitable<StaticJsonDocument<10> >::value == true); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user