forked from bblanchon/ArduinoJson
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)
|
* Improved speed of float serialization (about twice faster)
|
||||||
|
* Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291)
|
||||||
|
|
||||||
v5.6.2
|
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.
|
// Gets the value at the specified index.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T get(size_t index) const {
|
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
|
||||||
node_type *node = getNodeAt(index);
|
node_type *node = getNodeAt(index);
|
||||||
return node ? node->content.as<T>() : JsonVariant::defaultValue<T>();
|
return node ? node->content.as<T>() : JsonVariant::defaultValue<T>();
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,23 @@ inline bool JsonArray::setNodeValue(node_type *node, String &value) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline JsonArray &JsonVariant::defaultValue<JsonArray>() {
|
||||||
|
return JsonArray::invalid();
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline JsonArray &JsonVariant::defaultValue<JsonArray &>() {
|
inline JsonArray &JsonVariant::defaultValue<JsonArray &>() {
|
||||||
return JsonArray::invalid();
|
return JsonArray::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
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();
|
return JsonArray::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +42,16 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
|||||||
return *this;
|
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>
|
template <typename T>
|
||||||
FORCE_INLINE T as() const {
|
FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
|
||||||
return _array.get<T>(_index);
|
return _array.get<T>(_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
|||||||
|
|
||||||
// Gets the value associated with the specified key.
|
// Gets the value associated with the specified key.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T get(JsonObjectKey key) const {
|
typename Internals::JsonVariantAs<T>::type get(JsonObjectKey key) const {
|
||||||
node_type* node = getNodeAt(key.c_str());
|
node_type* node = getNodeAt(key.c_str());
|
||||||
return node ? node->content.value.as<T>() : JsonVariant::defaultValue<T>();
|
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 <>
|
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();
|
return JsonObject::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +40,11 @@ inline JsonObject &JsonVariant::defaultValue<JsonObject &>() {
|
|||||||
return JsonObject::invalid();
|
return JsonObject::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline JsonObject &JsonVariant::defaultValue<JsonObject>() {
|
||||||
|
return JsonObject::invalid();
|
||||||
|
}
|
||||||
|
|
||||||
inline JsonObject &JsonVariant::asObject() const {
|
inline JsonObject &JsonVariant::asObject() const {
|
||||||
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
|
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
|
||||||
return JsonObject::invalid();
|
return JsonObject::invalid();
|
||||||
|
@ -54,7 +54,7 @@ class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE TValue as() const {
|
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const {
|
||||||
return _object.get<TValue>(_key);
|
return _object.get<TValue>(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,28 +177,43 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
|||||||
//
|
//
|
||||||
// JsonArray& as<JsonArray> const;
|
// JsonArray& as<JsonArray> const;
|
||||||
// JsonArray& as<JsonArray&> const;
|
// JsonArray& as<JsonArray&> const;
|
||||||
// JsonArray& as<const JsonArray&> const;
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename TypeTraits::EnableIf<
|
typename TypeTraits::EnableIf<
|
||||||
TypeTraits::IsSame<
|
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||||
typename TypeTraits::RemoveConst<
|
JsonArray>::value,
|
||||||
typename TypeTraits::RemoveReference<T>::type>::type,
|
|
||||||
JsonArray>::value,
|
|
||||||
JsonArray &>::type
|
JsonArray &>::type
|
||||||
as() const {
|
as() const {
|
||||||
return asArray();
|
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;
|
||||||
// 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;
|
// JsonObject& as<const JsonObject&> const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename TypeTraits::EnableIf<
|
typename TypeTraits::EnableIf<
|
||||||
TypeTraits::IsSame<
|
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||||
typename TypeTraits::RemoveConst<
|
const JsonObject>::value,
|
||||||
typename TypeTraits::RemoveReference<T>::type>::type,
|
const JsonObject &>::type
|
||||||
JsonObject>::value,
|
|
||||||
JsonObject &>::type
|
|
||||||
as() const {
|
as() const {
|
||||||
return asObject();
|
return asObject();
|
||||||
}
|
}
|
||||||
@ -281,7 +296,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
|||||||
|
|
||||||
// Value returned if the variant has an incompatible type
|
// Value returned if the variant has an incompatible type
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T defaultValue() {
|
static typename Internals::JsonVariantAs<T>::type defaultValue() {
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Polyfills/attributes.hpp"
|
#include "Internals/JsonVariantAs.hpp"
|
||||||
#include "JsonObjectKey.hpp"
|
#include "JsonObjectKey.hpp"
|
||||||
|
#include "Polyfills/attributes.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
|
|
||||||
@ -20,20 +21,35 @@ class JsonObjectSubscript;
|
|||||||
template <typename TImpl>
|
template <typename TImpl>
|
||||||
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
||||||
public:
|
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.
|
// Gets the variant as an array.
|
||||||
// Returns a reference to the JsonArray or JsonArray::invalid() if the
|
// Returns a reference to the JsonArray or JsonArray::invalid() if the
|
||||||
// variant
|
// variant
|
||||||
// is not an array.
|
// is not an array.
|
||||||
FORCE_INLINE operator JsonArray &() const { return as<JsonArray &>(); }
|
FORCE_INLINE operator JsonArray &() const {
|
||||||
FORCE_INLINE JsonArray &asArray() const { return as<JsonArray &>(); }
|
return as<JsonArray &>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED: use as<JsonArray>() instead
|
||||||
|
FORCE_INLINE JsonArray &asArray() const {
|
||||||
|
return as<JsonArray &>();
|
||||||
|
}
|
||||||
|
|
||||||
// Gets the variant as an object.
|
// Gets the variant as an object.
|
||||||
// Returns a reference to the JsonObject or JsonObject::invalid() if the
|
// Returns a reference to the JsonObject or JsonObject::invalid() if the
|
||||||
// variant is not an object.
|
// variant is not an object.
|
||||||
FORCE_INLINE operator JsonObject &() const { return as<JsonObject &>(); }
|
FORCE_INLINE operator JsonObject &() const {
|
||||||
FORCE_INLINE JsonObject &asObject() const { return as<JsonObject &>(); }
|
return as<JsonObject &>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED: use as<JsonObject>() instead
|
||||||
|
FORCE_INLINE JsonObject &asObject() const {
|
||||||
|
return as<JsonObject &>();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE operator T() const {
|
FORCE_INLINE operator T() const {
|
||||||
@ -41,14 +57,16 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE const T as() const {
|
FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const {
|
||||||
return impl()->template as<T>();
|
return impl()->template as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mimics an array or an object.
|
// Mimics an array or an object.
|
||||||
// Returns the size of the array or object if the variant has that type.
|
// 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
|
// 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.
|
// Mimics an array.
|
||||||
// Returns the element at specified index if the variant is 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;
|
void writeTo(Internals::JsonWriter &writer) const;
|
||||||
|
|
||||||
private:
|
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>
|
template <typename TImpl, typename TComparand>
|
||||||
|
@ -59,6 +59,7 @@ TEST_(StoreBoolean) {
|
|||||||
TEST_(StoreString) {
|
TEST_(StoreString) {
|
||||||
_array[0] = "hello";
|
_array[0] = "hello";
|
||||||
EXPECT_STREQ("hello", _array[0].as<const char*>());
|
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_TRUE(_array[0].is<const char*>());
|
||||||
EXPECT_FALSE(_array[0].is<int>());
|
EXPECT_FALSE(_array[0].is<int>());
|
||||||
}
|
}
|
||||||
@ -69,6 +70,9 @@ TEST_(StoreNestedArray) {
|
|||||||
_array[0] = arr;
|
_array[0] = arr;
|
||||||
|
|
||||||
EXPECT_EQ(&arr, &_array[0].as<JsonArray&>());
|
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_TRUE(_array[0].is<JsonArray&>());
|
||||||
EXPECT_FALSE(_array[0].is<int>());
|
EXPECT_FALSE(_array[0].is<int>());
|
||||||
}
|
}
|
||||||
@ -79,6 +83,9 @@ TEST_(StoreNestedObject) {
|
|||||||
_array[0] = obj;
|
_array[0] = obj;
|
||||||
|
|
||||||
EXPECT_EQ(&obj, &_array[0].as<JsonObject&>());
|
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_TRUE(_array[0].is<JsonObject&>());
|
||||||
EXPECT_FALSE(_array[0].is<int>());
|
EXPECT_FALSE(_array[0].is<int>());
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ TEST_(StoreString) {
|
|||||||
EXPECT_TRUE(_object["hello"].is<const char*>());
|
EXPECT_TRUE(_object["hello"].is<const char*>());
|
||||||
EXPECT_FALSE(_object["hello"].is<long>());
|
EXPECT_FALSE(_object["hello"].is<long>());
|
||||||
EXPECT_STREQ("h3110", _object["hello"].as<const char*>());
|
EXPECT_STREQ("h3110", _object["hello"].as<const char*>());
|
||||||
|
EXPECT_STREQ("h3110", _object["hello"].as<char*>()); // <- short hand
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_(StoreArray) {
|
TEST_(StoreArray) {
|
||||||
@ -75,8 +76,15 @@ TEST_(StoreArray) {
|
|||||||
|
|
||||||
_object["hello"] = arr;
|
_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<JsonArray>());
|
||||||
|
EXPECT_TRUE(_object["hello"].is<const JsonArray&>());
|
||||||
|
EXPECT_TRUE(_object["hello"].is<const JsonArray>());
|
||||||
EXPECT_FALSE(_object["hello"].is<JsonObject&>());
|
EXPECT_FALSE(_object["hello"].is<JsonObject&>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +93,15 @@ TEST_(StoreObject) {
|
|||||||
|
|
||||||
_object["hello"] = obj;
|
_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<JsonObject>());
|
||||||
|
EXPECT_TRUE(_object["hello"].is<const JsonObject&>());
|
||||||
|
EXPECT_TRUE(_object["hello"].is<const JsonObject>());
|
||||||
EXPECT_FALSE(_object["hello"].is<JsonArray&>());
|
EXPECT_FALSE(_object["hello"].is<JsonArray&>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,3 +214,21 @@ TEST(JsonVariant_As_Tests, ArrayAsString) {
|
|||||||
JsonVariant variant = arr;
|
JsonVariant variant = arr;
|
||||||
ASSERT_EQ(String("[4,2]"), variant.as<String>());
|
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