mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Simplified JsonVariant::as<T>() to always return T
				
					
				
			This commit is contained in:
		
							
								
								
									
										31
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -11,9 +11,12 @@ HEAD | |||||||
| * Added `JsonVariant::is<JsonArrayConst/JsonObjectConst>()` (issue #1412) | * Added `JsonVariant::is<JsonArrayConst/JsonObjectConst>()` (issue #1412) | ||||||
| * Added `JsonVariant::is<JsonVariant/JsonVariantConst>()` (issue #1412) | * Added `JsonVariant::is<JsonVariant/JsonVariantConst>()` (issue #1412) | ||||||
| * Changed `JsonVariantConst::is<JsonArray/JsonObject>()` to return `false` (issue #1412) | * Changed `JsonVariantConst::is<JsonArray/JsonObject>()` to return `false` (issue #1412) | ||||||
|  | * Simplified `JsonVariant::as<T>()` to always return `T` (see below) | ||||||
|  |  | ||||||
| > ### BREAKING CHANGES | > ### BREAKING CHANGES | ||||||
| > | > | ||||||
|  | > #### Support for `char` removed | ||||||
|  | > | ||||||
| > We cannot cast a `JsonVariant` to a `char` anymore, so the following will break: | > We cannot cast a `JsonVariant` to a `char` anymore, so the following will break: | ||||||
| > ```c++ | > ```c++ | ||||||
| > char age = doc["age"];  //  error: no matching function for call to 'variantAs(VariantData*&)' | > char age = doc["age"];  //  error: no matching function for call to 'variantAs(VariantData*&)' | ||||||
| @@ -34,13 +37,39 @@ HEAD | |||||||
| > doc["age"] = age;  // OK | > doc["age"] = age;  // OK | ||||||
| > ``` | > ``` | ||||||
| > | > | ||||||
|  | > #### `as<T>()` always returns `T` | ||||||
|  | > | ||||||
|  | > Previously, `JsonVariant::as<T>()` could return a type different from `T`. | ||||||
|  | > The most common example is `as<char*>()` that returned a `const char*`. | ||||||
|  | > While this feature simplified a few use cases, it was confusing and complicated the | ||||||
|  | > implementation of custom converters. | ||||||
|  | > | ||||||
|  | > Starting from this version, `as<T>` doesn't try to auto-correct the return type and always return `T`, | ||||||
|  | > which means that you cannot write this anymore: | ||||||
|  | > | ||||||
|  | > ```c++ | ||||||
|  | > Serial.println(doc["sensor"].as<char*>());  // error: invalid conversion from 'const char*' to 'char*' [-fpermissive] | ||||||
|  |  | ||||||
|  | > ``` | ||||||
|  | >  | ||||||
|  | > Instead, you must write: | ||||||
|  | > | ||||||
|  | > ```c++ | ||||||
|  | > Serial.println(doc["sensor"].as<const char*>());  // OK | ||||||
|  | > ``` | ||||||
|  | > | ||||||
|  | > | ||||||
|  | > #### `DeserializationError::NotSupported` removed | ||||||
|  | > | ||||||
| > On a different topic, `DeserializationError::NotSupported` has been removed. | > On a different topic, `DeserializationError::NotSupported` has been removed. | ||||||
| > Instead of returning this error: | > Instead of returning this error: | ||||||
| > | > | ||||||
| > * `deserializeJson()` leaves `\uXXXX` unchanged (only when `ARDUINOJSON_DECODE_UNICODE` is `0`) | > * `deserializeJson()` leaves `\uXXXX` unchanged (only when `ARDUINOJSON_DECODE_UNICODE` is `0`) | ||||||
| > * `deserializeMsgPack()` replaces unsupported values with `null`s | > * `deserializeMsgPack()` replaces unsupported values with `null`s | ||||||
| > | > | ||||||
| > Lastly, a very minor change conserns `JsonVariantConst::is<T>()`. | > #### Const-aware `is<T>()` | ||||||
|  | > | ||||||
|  | > Lastly, a very minor change concerns `JsonVariantConst::is<T>()`. | ||||||
| > It used to return `true` for `JsonArray` and `JsonOject`, but now it returns `false`. | > It used to return `true` for `JsonArray` and `JsonOject`, but now it returns `false`. | ||||||
| > Instead, you must use `JsonArrayConst` and `JsonObjectConst`. | > Instead, you must use `JsonArrayConst` and `JsonObjectConst`. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ void setup() { | |||||||
|  |  | ||||||
|   // Extract values |   // Extract values | ||||||
|   Serial.println(F("Response:")); |   Serial.println(F("Response:")); | ||||||
|   Serial.println(doc["sensor"].as<char*>()); |   Serial.println(doc["sensor"].as<const char*>()); | ||||||
|   Serial.println(doc["time"].as<long>()); |   Serial.println(doc["time"].as<long>()); | ||||||
|   Serial.println(doc["data"][0].as<float>(), 6); |   Serial.println(doc["data"][0].as<float>(), 6); | ||||||
|   Serial.println(doc["data"][1].as<float>(), 6); |   Serial.println(doc["data"][1].as<float>(), 6); | ||||||
|   | |||||||
| @@ -60,7 +60,6 @@ TEST_CASE("JsonArray::operator[]") { | |||||||
|  |  | ||||||
|     array[0] = str; |     array[0] = str; | ||||||
|     REQUIRE(str == array[0].as<const char*>()); |     REQUIRE(str == array[0].as<const char*>()); | ||||||
|     REQUIRE(str == array[0].as<char*>());  // <- short hand |  | ||||||
|     REQUIRE(true == array[0].is<const char*>()); |     REQUIRE(true == array[0].is<const char*>()); | ||||||
|     REQUIRE(false == array[0].is<int>()); |     REQUIRE(false == array[0].is<int>()); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -99,8 +99,8 @@ TEST_CASE("deserialize JSON array") { | |||||||
|  |  | ||||||
|       REQUIRE(err == DeserializationError::Ok); |       REQUIRE(err == DeserializationError::Ok); | ||||||
|       REQUIRE(2 == arr.size()); |       REQUIRE(2 == arr.size()); | ||||||
|       REQUIRE(arr[0].as<char*>() == 0); |       REQUIRE(arr[0].as<const char*>() == 0); | ||||||
|       REQUIRE(arr[1].as<char*>() == 0); |       REQUIRE(arr[1].as<const char*>() == 0); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -182,8 +182,8 @@ TEST_CASE("deserialize JSON object") { | |||||||
|       REQUIRE(err == DeserializationError::Ok); |       REQUIRE(err == DeserializationError::Ok); | ||||||
|       REQUIRE(doc.is<JsonObject>()); |       REQUIRE(doc.is<JsonObject>()); | ||||||
|       REQUIRE(obj.size() == 2); |       REQUIRE(obj.size() == 2); | ||||||
|       REQUIRE(obj["key1"].as<char*>() == 0); |       REQUIRE(obj["key1"].as<const char*>() == 0); | ||||||
|       REQUIRE(obj["key2"].as<char*>() == 0); |       REQUIRE(obj["key2"].as<const char*>() == 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("Array") { |     SECTION("Array") { | ||||||
|   | |||||||
| @@ -48,7 +48,6 @@ TEST_CASE("JsonObject::operator[]") { | |||||||
|     REQUIRE(true == obj["hello"].is<const char*>()); |     REQUIRE(true == obj["hello"].is<const char*>()); | ||||||
|     REQUIRE(false == obj["hello"].is<long>()); |     REQUIRE(false == obj["hello"].is<long>()); | ||||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<const char*>()); |     REQUIRE(std::string("h3110") == obj["hello"].as<const char*>()); | ||||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<char*>());  // <- short hand |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("array") { |   SECTION("array") { | ||||||
| @@ -189,7 +188,7 @@ TEST_CASE("JsonObject::operator[]") { | |||||||
|  |  | ||||||
|     obj["hello"] = vla; |     obj["hello"] = vla; | ||||||
|  |  | ||||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); |     REQUIRE(std::string("world") == obj["hello"].as<const char*>()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("obj.set(VLA, str)") { |   SECTION("obj.set(VLA, str)") { | ||||||
| @@ -209,7 +208,7 @@ TEST_CASE("JsonObject::operator[]") { | |||||||
|  |  | ||||||
|     obj["hello"].set(vla); |     obj["hello"].set(vla); | ||||||
|  |  | ||||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); |     REQUIRE(std::string("world") == obj["hello"].as<const char*>()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("obj[VLA]") { |   SECTION("obj[VLA]") { | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ TEST_CASE("JsonVariant::as()") { | |||||||
|     REQUIRE(false == variant.as<bool>()); |     REQUIRE(false == variant.as<bool>()); | ||||||
|     REQUIRE(0 == variant.as<int>()); |     REQUIRE(0 == variant.as<int>()); | ||||||
|     REQUIRE(0.0f == variant.as<float>()); |     REQUIRE(0.0f == variant.as<float>()); | ||||||
|     REQUIRE(0 == variant.as<char*>()); |     REQUIRE(0 == variant.as<const char*>()); | ||||||
|     REQUIRE("null" == variant.as<std::string>()); |     REQUIRE("null" == variant.as<std::string>()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -104,7 +104,7 @@ TEST_CASE("JsonVariant::as()") { | |||||||
|     REQUIRE(variant.as<bool>() == true); |     REQUIRE(variant.as<bool>() == true); | ||||||
|     REQUIRE(variant.as<long>() == 0L); |     REQUIRE(variant.as<long>() == 0L); | ||||||
|     REQUIRE(variant.as<const char*>() == std::string("hello")); |     REQUIRE(variant.as<const char*>() == std::string("hello")); | ||||||
|     REQUIRE(variant.as<char*>() == std::string("hello")); |     REQUIRE(variant.as<const char*>() == std::string("hello")); | ||||||
|     REQUIRE(variant.as<std::string>() == std::string("hello")); |     REQUIRE(variant.as<std::string>() == std::string("hello")); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -114,7 +114,7 @@ TEST_CASE("JsonVariant::as()") { | |||||||
|     REQUIRE(variant.as<bool>() == true); |     REQUIRE(variant.as<bool>() == true); | ||||||
|     REQUIRE(variant.as<long>() == 4L); |     REQUIRE(variant.as<long>() == 4L); | ||||||
|     REQUIRE(variant.as<double>() == 4.2); |     REQUIRE(variant.as<double>() == 4.2); | ||||||
|     REQUIRE(variant.as<char*>() == std::string("4.2")); |     REQUIRE(variant.as<const char*>() == std::string("4.2")); | ||||||
|     REQUIRE(variant.as<std::string>() == std::string("4.2")); |     REQUIRE(variant.as<std::string>() == std::string("4.2")); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -211,8 +211,7 @@ TEST_CASE("JsonVariant::as()") { | |||||||
|     REQUIRE(cvar.as<bool>() == true); |     REQUIRE(cvar.as<bool>() == true); | ||||||
|     REQUIRE(cvar.as<long>() == 0L); |     REQUIRE(cvar.as<long>() == 0L); | ||||||
|     REQUIRE(cvar.as<const char*>() == std::string("hello")); |     REQUIRE(cvar.as<const char*>() == std::string("hello")); | ||||||
|     REQUIRE(cvar.as<char*>() == std::string("hello")); |     REQUIRE(cvar.as<std::string>() == std::string("hello")); | ||||||
|     // REQUIRE(cvar.as<std::string>() == std::string("hello")); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("as<enum>()") { |   SECTION("as<enum>()") { | ||||||
|   | |||||||
| @@ -17,8 +17,8 @@ TEST_CASE("JsonVariant undefined") { | |||||||
|       REQUIRE(variant.as<unsigned>() == 0); |       REQUIRE(variant.as<unsigned>() == 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("char*") { |     SECTION("const char*") { | ||||||
|       REQUIRE(variant.as<char*>() == 0); |       REQUIRE(variant.as<const char*>() == 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("double") { |     SECTION("double") { | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { | |||||||
|       deserializeJson(doc, "[\"example\",\"example\"]"); |       deserializeJson(doc, "[\"example\",\"example\"]"); | ||||||
|  |  | ||||||
|       CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); |       CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); | ||||||
|       CHECK(doc[0].as<char*>() != doc[1].as<char*>()); |       CHECK(doc[0].as<const char*>() != doc[1].as<const char*>()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("Deduplicate keys") { |     SECTION("Deduplicate keys") { | ||||||
| @@ -42,7 +42,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { | |||||||
|         doc.add(std::string("example")); |         doc.add(std::string("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); | ||||||
|         CHECK(doc[0].as<char*>() != doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() != doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("char*") { |       SECTION("char*") { | ||||||
| @@ -51,7 +51,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { | |||||||
|         doc.add(value); |         doc.add(value); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); | ||||||
|         CHECK(doc[0].as<char*>() != doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() != doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("Arduino String") { |       SECTION("Arduino String") { | ||||||
| @@ -59,7 +59,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { | |||||||
|         doc.add(String("example")); |         doc.add(String("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); | ||||||
|         CHECK(doc[0].as<char*>() != doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() != doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("Flash string") { |       SECTION("Flash string") { | ||||||
| @@ -67,7 +67,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { | |||||||
|         doc.add(F("example")); |         doc.add(F("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 16); | ||||||
|         CHECK(doc[0].as<char*>() != doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() != doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { | |||||||
|       deserializeJson(doc, "[\"example\",\"example\"]"); |       deserializeJson(doc, "[\"example\",\"example\"]"); | ||||||
|  |  | ||||||
|       CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); |       CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); | ||||||
|       CHECK(doc[0].as<char*>() == doc[1].as<char*>()); |       CHECK(doc[0].as<const char*>() == doc[1].as<const char*>()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("Deduplicate keys") { |     SECTION("Deduplicate keys") { | ||||||
| @@ -41,7 +41,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { | |||||||
|         doc.add(std::string("example")); |         doc.add(std::string("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); | ||||||
|         CHECK(doc[0].as<char*>() == doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() == doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("char*") { |       SECTION("char*") { | ||||||
| @@ -50,7 +50,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { | |||||||
|         doc.add(value); |         doc.add(value); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); | ||||||
|         CHECK(doc[0].as<char*>() == doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() == doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("Arduino String") { |       SECTION("Arduino String") { | ||||||
| @@ -58,7 +58,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { | |||||||
|         doc.add(String("example")); |         doc.add(String("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); | ||||||
|         CHECK(doc[0].as<char*>() == doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() == doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       SECTION("Flash string") { |       SECTION("Flash string") { | ||||||
| @@ -66,7 +66,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { | |||||||
|         doc.add(F("example")); |         doc.add(F("example")); | ||||||
|  |  | ||||||
|         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); |         CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); | ||||||
|         CHECK(doc[0].as<char*>() == doc[1].as<char*>()); |         CHECK(doc[0].as<const char*>() == doc[1].as<const char*>()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   FORCE_INLINE typename VariantAs<T>::type as() const { |   FORCE_INLINE T as() const { | ||||||
|     return getUpstreamElement().template as<T>(); |     return getUpstreamElement().template as<T>(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,12 +21,12 @@ class JsonDocument : public Visitable { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   typename VariantAs<T>::type as() { |   T as() { | ||||||
|     return getVariant().template as<T>(); |     return getVariant().template as<T>(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   typename VariantConstAs<T>::type as() const { |   T as() const { | ||||||
|     return getVariant().template as<T>(); |     return getVariant().template as<T>(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -70,7 +70,7 @@ class JsonDocument : public Visitable { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool set(const JsonDocument& src) { |   bool set(const JsonDocument& src) { | ||||||
|     return to<VariantRef>().set(src.as<VariantRef>()); |     return to<VariantRef>().set(src.as<VariantConstRef>()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename TValue> |   template <typename TValue> | ||||||
|   FORCE_INLINE typename VariantAs<TValue>::type as() const { |   FORCE_INLINE TValue as() const { | ||||||
|     return getUpstreamMember().template as<TValue>(); |     return getUpstreamMember().template as<TValue>(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,42 +16,6 @@ class ObjectConstRef; | |||||||
| class VariantRef; | class VariantRef; | ||||||
| class VariantConstRef; | class VariantConstRef; | ||||||
|  |  | ||||||
| // A metafunction that returns the type of the value returned by |  | ||||||
| // VariantRef::as<T>() |  | ||||||
| template <typename T> |  | ||||||
| struct VariantAs { |  | ||||||
|   typedef T type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct VariantAs<char*> { |  | ||||||
|   typedef const char* type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // A metafunction that returns the type of the value returned by |  | ||||||
| // VariantRef::as<T>() |  | ||||||
| template <typename T> |  | ||||||
| struct VariantConstAs { |  | ||||||
|   typedef typename VariantAs<T>::type type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct VariantConstAs<VariantRef> { |  | ||||||
|   typedef VariantConstRef type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct VariantConstAs<ObjectRef> { |  | ||||||
|   typedef ObjectConstRef type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct VariantConstAs<ArrayRef> { |  | ||||||
|   typedef ArrayConstRef type; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // --- |  | ||||||
|  |  | ||||||
| template <typename T> | template <typename T> | ||||||
| inline typename enable_if<is_integral<T>::value && !is_same<bool, T>::value && | inline typename enable_if<is_integral<T>::value && !is_same<bool, T>::value && | ||||||
|                               !is_same<char, T>::value, |                               !is_same<char, T>::value, | ||||||
| @@ -80,10 +44,8 @@ inline typename enable_if<is_floating_point<T>::value, T>::type variantAs( | |||||||
| } | } | ||||||
|  |  | ||||||
| template <typename T> | template <typename T> | ||||||
| inline typename enable_if<is_same<T, const char*>::value || | inline typename enable_if<is_same<T, const char*>::value, T>::type variantAs( | ||||||
|                               is_same<T, char*>::value, |     const VariantData* data) { | ||||||
|                           const char*>::type |  | ||||||
| variantAs(const VariantData* data) { |  | ||||||
|   return data != 0 ? data->asString() : 0; |   return data != 0 ? data->asString() : 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,18 +23,25 @@ struct VariantOperators { | |||||||
|   // int operator|(JsonVariant, int) |   // int operator|(JsonVariant, int) | ||||||
|   // float operator|(JsonVariant, float) |   // float operator|(JsonVariant, float) | ||||||
|   // bool operator|(JsonVariant, bool) |   // bool operator|(JsonVariant, bool) | ||||||
|   // const char* operator|(JsonVariant, const char*) |  | ||||||
|   // char* operator|(JsonVariant, const char*) |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   friend typename enable_if<!IsVariant<T>::value, |   friend | ||||||
|                             typename VariantAs<T>::type>::type |       typename enable_if<!IsVariant<T>::value && !is_array<T>::value, T>::type | ||||||
|   operator|(const TVariant &variant, T defaultValue) { |       operator|(const TVariant &variant, const T &defaultValue) { | ||||||
|     if (variant.template is<T>()) |     if (variant.template is<T>()) | ||||||
|       return variant.template as<T>(); |       return variant.template as<T>(); | ||||||
|     else |     else | ||||||
|       return defaultValue; |       return defaultValue; | ||||||
|   } |   } | ||||||
|   // |   // | ||||||
|  |   // const char* operator|(JsonVariant, const char*) | ||||||
|  |   friend const char *operator|(const TVariant &variant, | ||||||
|  |                                const char *defaultValue) { | ||||||
|  |     if (variant.template is<const char *>()) | ||||||
|  |       return variant.template as<const char *>(); | ||||||
|  |     else | ||||||
|  |       return defaultValue; | ||||||
|  |   } | ||||||
|  |   // | ||||||
|   // JsonVariant operator|(JsonVariant, JsonVariant) |   // JsonVariant operator|(JsonVariant, JsonVariant) | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   friend typename enable_if<IsVariant<T>::value, typename T::variant_type>::type |   friend typename enable_if<IsVariant<T>::value, typename T::variant_type>::type | ||||||
|   | |||||||
| @@ -176,7 +176,7 @@ class VariantRef : public VariantRefBase<VariantData>, | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   FORCE_INLINE typename VariantAs<T>::type as() const { |   FORCE_INLINE T as() const { | ||||||
|     /******************************************************************** |     /******************************************************************** | ||||||
|      **                THIS IS NOT A BUG IN THE LIBRARY                ** |      **                THIS IS NOT A BUG IN THE LIBRARY                ** | ||||||
|      **                --------------------------------                ** |      **                --------------------------------                ** | ||||||
| @@ -187,11 +187,13 @@ class VariantRef : public VariantRefBase<VariantData>, | |||||||
|      **  For example:                                                  ** |      **  For example:                                                  ** | ||||||
|      **    char* name = doc["name"];                                   ** |      **    char* name = doc["name"];                                   ** | ||||||
|      **    char age = doc["age"];                                      ** |      **    char age = doc["age"];                                      ** | ||||||
|  |      **    auto city = doc["city"].as<char*>()                         ** | ||||||
|      **  Instead, use:                                                 ** |      **  Instead, use:                                                 ** | ||||||
|      **    const char* name = doc["name"];                             ** |      **    const char* name = doc["name"];                             ** | ||||||
|      **    int8_t age = doc["age"];                                    ** |      **    int8_t age = doc["age"];                                    ** | ||||||
|  |      **    auto city = doc["city"].as<const char*>()                   ** | ||||||
|      ********************************************************************/ |      ********************************************************************/ | ||||||
|     return variantAs<typename VariantAs<T>::type>(_data, _pool); |     return variantAs<T>(_data, _pool); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
| @@ -291,8 +293,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   FORCE_INLINE typename VariantConstAs<T>::type as() const { |   FORCE_INLINE T as() const { | ||||||
|     return variantAs<typename VariantConstAs<T>::type>(_data); |     return variantAs<T>(_data); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user