forked from bblanchon/ArduinoJson
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
|
Reference in New Issue
Block a user