forked from bblanchon/ArduinoJson
Added a return value to visitors
This commit is contained in:
@ -12,12 +12,13 @@ inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
|||||||
return arr ? arr->addElement(pool) : 0;
|
return arr ? arr->addElement(pool) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
inline void arrayAccept(const CollectionData *arr, Visitor &visitor) {
|
inline typename TVisitor::result_type arrayAccept(const CollectionData *arr,
|
||||||
|
TVisitor &visitor) {
|
||||||
if (arr)
|
if (arr)
|
||||||
visitor.visitArray(*arr);
|
return visitor.visitArray(*arr);
|
||||||
else
|
else
|
||||||
visitor.visitNull();
|
return visitor.visitNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||||
|
@ -27,9 +27,9 @@ class ArrayRefBase {
|
|||||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
arrayAccept(_data, visitor);
|
return arrayAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
|
@ -98,8 +98,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
|||||||
return getOrAddUpstreamElement().set(value);
|
return getOrAddUpstreamElement().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
return getUpstreamElement().accept(visitor);
|
return getUpstreamElement().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,40 +65,61 @@ inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ArrayCopier1D {
|
class ArrayCopier1D : public Visitor<size_t> {
|
||||||
public:
|
public:
|
||||||
ArrayCopier1D(T* destination, size_t capacity)
|
ArrayCopier1D(T* destination, size_t capacity)
|
||||||
: _destination(destination), _capacity(capacity), _size(0) {}
|
: _destination(destination), _capacity(capacity) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData& array) {
|
size_t visitArray(const CollectionData& array) {
|
||||||
|
size_t size = 0;
|
||||||
VariantSlot* slot = array.head();
|
VariantSlot* slot = array.head();
|
||||||
|
|
||||||
while (slot != 0 && _size < _capacity) {
|
while (slot != 0 && size < _capacity) {
|
||||||
_destination[_size++] = variantAs<T>(slot->data());
|
_destination[size++] = variantAs<T>(slot->data());
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
void visitObject(const CollectionData&) {}
|
|
||||||
void visitFloat(Float) {}
|
|
||||||
void visitString(const char*) {}
|
|
||||||
void visitRawJson(const char*, size_t) {}
|
|
||||||
void visitNegativeInteger(UInt) {}
|
|
||||||
void visitPositiveInteger(UInt) {}
|
|
||||||
void visitBoolean(bool) {}
|
|
||||||
void visitNull() {}
|
|
||||||
|
|
||||||
size_t result() const {
|
size_t visitObject(const CollectionData&) {
|
||||||
return _size;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitFloat(Float) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitString(const char*) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitRawJson(const char*, size_t) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitNegativeInteger(UInt) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitPositiveInteger(UInt) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitBoolean(bool) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t visitNull() {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* _destination;
|
T* _destination;
|
||||||
size_t _capacity;
|
size_t _capacity;
|
||||||
size_t _size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, size_t N1, size_t N2>
|
template <typename T, size_t N1, size_t N2>
|
||||||
class ArrayCopier2D {
|
class ArrayCopier2D : public Visitor<void> {
|
||||||
public:
|
public:
|
||||||
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
|
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
|
||||||
|
|
||||||
@ -136,8 +157,8 @@ inline typename enable_if<!is_array<T>::value, size_t>::type copyArray(
|
|||||||
template <typename TSource, typename T>
|
template <typename TSource, typename T>
|
||||||
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
|
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
|
||||||
ArrayCopier1D<T> copier(dst, len);
|
ArrayCopier1D<T> copier(dst, len);
|
||||||
src.accept(copier);
|
|
||||||
return copier.result();
|
return src.accept(copier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a JsonArray to a 2D array
|
// Copy a JsonArray to a 2D array
|
||||||
|
@ -15,8 +15,8 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
|
|
||||||
class JsonDocument : public Visitable {
|
class JsonDocument : public Visitable {
|
||||||
public:
|
public:
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
return getVariant().accept(visitor);
|
return getVariant().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class JsonSerializer {
|
class JsonSerializer : public Visitor<size_t> {
|
||||||
public:
|
public:
|
||||||
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
||||||
|
|
||||||
FORCE_INLINE void visitArray(const CollectionData &array) {
|
FORCE_INLINE size_t visitArray(const CollectionData &array) {
|
||||||
write('[');
|
write('[');
|
||||||
|
|
||||||
VariantSlot *slot = array.head();
|
VariantSlot *slot = array.head();
|
||||||
@ -32,9 +32,10 @@ class JsonSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
write(']');
|
write(']');
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitObject(const CollectionData &object) {
|
size_t visitObject(const CollectionData &object) {
|
||||||
write('{');
|
write('{');
|
||||||
|
|
||||||
VariantSlot *slot = object.head();
|
VariantSlot *slot = object.head();
|
||||||
@ -52,41 +53,49 @@ class JsonSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
write('}');
|
write('}');
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitFloat(Float value) {
|
size_t visitFloat(Float value) {
|
||||||
_formatter.writeFloat(value);
|
_formatter.writeFloat(value);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitString(const char *value) {
|
size_t visitString(const char *value) {
|
||||||
_formatter.writeString(value);
|
_formatter.writeString(value);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitRawJson(const char *data, size_t n) {
|
size_t visitRawJson(const char *data, size_t n) {
|
||||||
_formatter.writeRaw(data, n);
|
_formatter.writeRaw(data, n);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt value) {
|
size_t visitNegativeInteger(UInt value) {
|
||||||
_formatter.writeNegativeInteger(value);
|
_formatter.writeNegativeInteger(value);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitPositiveInteger(UInt value) {
|
size_t visitPositiveInteger(UInt value) {
|
||||||
_formatter.writePositiveInteger(value);
|
_formatter.writePositiveInteger(value);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBoolean(bool value) {
|
size_t visitBoolean(bool value) {
|
||||||
_formatter.writeBoolean(value);
|
_formatter.writeBoolean(value);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNull() {
|
size_t visitNull() {
|
||||||
_formatter.writeRaw("null");
|
_formatter.writeRaw("null");
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
size_t bytesWritten() const {
|
size_t bytesWritten() const {
|
||||||
return _formatter.bytesWritten();
|
return _formatter.bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
void write(char c) {
|
void write(char c) {
|
||||||
_formatter.writeRaw(c);
|
_formatter.writeRaw(c);
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
|||||||
public:
|
public:
|
||||||
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData &array) {
|
size_t visitArray(const CollectionData &array) {
|
||||||
VariantSlot *slot = array.head();
|
VariantSlot *slot = array.head();
|
||||||
if (!slot)
|
if (slot) {
|
||||||
return base::write("[]");
|
|
||||||
|
|
||||||
base::write("[\r\n");
|
base::write("[\r\n");
|
||||||
_nesting++;
|
_nesting++;
|
||||||
while (slot != 0) {
|
while (slot != 0) {
|
||||||
@ -35,13 +33,15 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
|||||||
_nesting--;
|
_nesting--;
|
||||||
indent();
|
indent();
|
||||||
base::write("]");
|
base::write("]");
|
||||||
|
} else {
|
||||||
|
base::write("[]");
|
||||||
|
}
|
||||||
|
return this->bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitObject(const CollectionData &object) {
|
size_t visitObject(const CollectionData &object) {
|
||||||
VariantSlot *slot = object.head();
|
VariantSlot *slot = object.head();
|
||||||
if (!slot)
|
if (slot) {
|
||||||
return base::write("{}");
|
|
||||||
|
|
||||||
base::write("{\r\n");
|
base::write("{\r\n");
|
||||||
_nesting++;
|
_nesting++;
|
||||||
while (slot != 0) {
|
while (slot != 0) {
|
||||||
@ -56,6 +56,10 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
|||||||
_nesting--;
|
_nesting--;
|
||||||
indent();
|
indent();
|
||||||
base::write("}");
|
base::write("}");
|
||||||
|
} else {
|
||||||
|
base::write("{}");
|
||||||
|
}
|
||||||
|
return this->bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -12,17 +12,18 @@
|
|||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class TextFormatter {
|
class TextFormatter {
|
||||||
public:
|
public:
|
||||||
explicit TextFormatter(TWriter writer) : _writer(writer), _length(0) {}
|
explicit TextFormatter(TWriter writer) : _writer(writer) {}
|
||||||
|
|
||||||
// Returns the number of bytes sent to the TWriter implementation.
|
// Returns the number of bytes sent to the TWriter implementation.
|
||||||
size_t bytesWritten() const {
|
size_t bytesWritten() const {
|
||||||
return _length;
|
return _writer.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeBoolean(bool value) {
|
void writeBoolean(bool value) {
|
||||||
@ -128,28 +129,28 @@ class TextFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeRaw(const char *s) {
|
void writeRaw(const char *s) {
|
||||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s));
|
_writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRaw(const char *s, size_t n) {
|
void writeRaw(const char *s, size_t n) {
|
||||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), n);
|
_writer.write(reinterpret_cast<const uint8_t *>(s), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRaw(const char *begin, const char *end) {
|
void writeRaw(const char *begin, const char *end) {
|
||||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(begin),
|
_writer.write(reinterpret_cast<const uint8_t *>(begin),
|
||||||
static_cast<size_t>(end - begin));
|
static_cast<size_t>(end - begin));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
void writeRaw(const char (&s)[N]) {
|
void writeRaw(const char (&s)[N]) {
|
||||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
_writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
||||||
}
|
}
|
||||||
void writeRaw(char c) {
|
void writeRaw(char c) {
|
||||||
_length += _writer.write(static_cast<uint8_t>(c));
|
_writer.write(static_cast<uint8_t>(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TWriter _writer;
|
CountingDecorator<TWriter> _writer;
|
||||||
size_t _length;
|
size_t _length;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -8,6 +8,11 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TResult>
|
||||||
|
struct Visitor {
|
||||||
|
typedef TResult result_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct Visitable {
|
struct Visitable {
|
||||||
// template<Visitor>
|
// template<Visitor>
|
||||||
// void accept(Visitor&) const;
|
// void accept(Visitor&) const;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
|
||||||
#include <ArduinoJson/Serialization/measure.hpp>
|
#include <ArduinoJson/Serialization/measure.hpp>
|
||||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
@ -14,19 +15,20 @@
|
|||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class MsgPackSerializer {
|
class MsgPackSerializer : public Visitor<size_t> {
|
||||||
public:
|
public:
|
||||||
MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {}
|
MsgPackSerializer(TWriter writer) : _writer(writer) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) {
|
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
|
||||||
writeByte(0xCA);
|
writeByte(0xCA);
|
||||||
writeInteger(value32);
|
writeInteger(value32);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||||
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
|
typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
|
||||||
float value32 = float(value64);
|
float value32 = float(value64);
|
||||||
if (value32 == value64) {
|
if (value32 == value64) {
|
||||||
writeByte(0xCA);
|
writeByte(0xCA);
|
||||||
@ -35,9 +37,10 @@ class MsgPackSerializer {
|
|||||||
writeByte(0xCB);
|
writeByte(0xCB);
|
||||||
writeInteger(value64);
|
writeInteger(value64);
|
||||||
}
|
}
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitArray(const CollectionData& array) {
|
size_t visitArray(const CollectionData& array) {
|
||||||
size_t n = array.size();
|
size_t n = array.size();
|
||||||
if (n < 0x10) {
|
if (n < 0x10) {
|
||||||
writeByte(uint8_t(0x90 + array.size()));
|
writeByte(uint8_t(0x90 + array.size()));
|
||||||
@ -51,9 +54,10 @@ class MsgPackSerializer {
|
|||||||
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
||||||
slot->data()->accept(*this);
|
slot->data()->accept(*this);
|
||||||
}
|
}
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitObject(const CollectionData& object) {
|
size_t visitObject(const CollectionData& object) {
|
||||||
size_t n = object.size();
|
size_t n = object.size();
|
||||||
if (n < 0x10) {
|
if (n < 0x10) {
|
||||||
writeByte(uint8_t(0x80 + n));
|
writeByte(uint8_t(0x80 + n));
|
||||||
@ -68,9 +72,10 @@ class MsgPackSerializer {
|
|||||||
visitString(slot->key());
|
visitString(slot->key());
|
||||||
slot->data()->accept(*this);
|
slot->data()->accept(*this);
|
||||||
}
|
}
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitString(const char* value) {
|
size_t visitString(const char* value) {
|
||||||
ARDUINOJSON_ASSERT(value != NULL);
|
ARDUINOJSON_ASSERT(value != NULL);
|
||||||
|
|
||||||
size_t n = strlen(value);
|
size_t n = strlen(value);
|
||||||
@ -88,13 +93,15 @@ class MsgPackSerializer {
|
|||||||
writeInteger(uint32_t(n));
|
writeInteger(uint32_t(n));
|
||||||
}
|
}
|
||||||
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitRawJson(const char* data, size_t size) {
|
size_t visitRawJson(const char* data, size_t size) {
|
||||||
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt value) {
|
size_t visitNegativeInteger(UInt value) {
|
||||||
UInt negated = UInt(~value + 1);
|
UInt negated = UInt(~value + 1);
|
||||||
if (value <= 0x20) {
|
if (value <= 0x20) {
|
||||||
writeInteger(int8_t(negated));
|
writeInteger(int8_t(negated));
|
||||||
@ -114,9 +121,10 @@ class MsgPackSerializer {
|
|||||||
writeInteger(int64_t(negated));
|
writeInteger(int64_t(negated));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitPositiveInteger(UInt value) {
|
size_t visitPositiveInteger(UInt value) {
|
||||||
if (value <= 0x7F) {
|
if (value <= 0x7F) {
|
||||||
writeInteger(uint8_t(value));
|
writeInteger(uint8_t(value));
|
||||||
} else if (value <= 0xFF) {
|
} else if (value <= 0xFF) {
|
||||||
@ -141,27 +149,30 @@ class MsgPackSerializer {
|
|||||||
writeInteger(uint64_t(value));
|
writeInteger(uint64_t(value));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBoolean(bool value) {
|
size_t visitBoolean(bool value) {
|
||||||
writeByte(value ? 0xC3 : 0xC2);
|
writeByte(value ? 0xC3 : 0xC2);
|
||||||
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNull() {
|
size_t visitNull() {
|
||||||
writeByte(0xC0);
|
writeByte(0xC0);
|
||||||
}
|
return bytesWritten();
|
||||||
|
|
||||||
size_t bytesWritten() const {
|
|
||||||
return _bytesWritten;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
size_t bytesWritten() const {
|
||||||
|
return _writer.count();
|
||||||
|
}
|
||||||
|
|
||||||
void writeByte(uint8_t c) {
|
void writeByte(uint8_t c) {
|
||||||
_bytesWritten += _writer.write(c);
|
_writer.write(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeBytes(const uint8_t* p, size_t n) {
|
void writeBytes(const uint8_t* p, size_t n) {
|
||||||
_bytesWritten += _writer.write(p, n);
|
_writer.write(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -170,8 +181,7 @@ class MsgPackSerializer {
|
|||||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
TWriter _writer;
|
CountingDecorator<TWriter> _writer;
|
||||||
size_t _bytesWritten;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TSource, typename TDestination>
|
template <typename TSource, typename TDestination>
|
||||||
|
@ -120,8 +120,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
|||||||
return getOrAddUpstreamMember().set(value);
|
return getOrAddUpstreamMember().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor &visitor) const {
|
typename TVisitor::result_type accept(TVisitor &visitor) const {
|
||||||
return getUpstreamMember().accept(visitor);
|
return getUpstreamMember().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void objectAccept(const CollectionData *obj, Visitor &visitor) {
|
typename TVisitor::result_type objectAccept(const CollectionData *obj,
|
||||||
|
TVisitor &visitor) {
|
||||||
if (obj)
|
if (obj)
|
||||||
visitor.visitObject(*obj);
|
return visitor.visitObject(*obj);
|
||||||
else
|
else
|
||||||
visitor.visitNull();
|
return visitor.visitNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||||
|
@ -22,9 +22,9 @@ class ObjectRefBase {
|
|||||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
objectAccept(_data, visitor);
|
return objectAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
|
33
src/ArduinoJson/Serialization/CountingDecorator.hpp
Normal file
33
src/ArduinoJson/Serialization/CountingDecorator.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TWriter>
|
||||||
|
class CountingDecorator {
|
||||||
|
public:
|
||||||
|
explicit CountingDecorator(TWriter& writer) : _writer(writer), _count(0) {}
|
||||||
|
|
||||||
|
void write(uint8_t c) {
|
||||||
|
_count += _writer.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(const uint8_t* s, size_t n) {
|
||||||
|
_count += _writer.write(s, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t count() const {
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TWriter _writer;
|
||||||
|
size_t _count;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource>
|
|||||||
size_t measure(const TSource &source) {
|
size_t measure(const TSource &source) {
|
||||||
DummyWriter dp;
|
DummyWriter dp;
|
||||||
TSerializer<DummyWriter> serializer(dp);
|
TSerializer<DummyWriter> serializer(dp);
|
||||||
source.accept(serializer);
|
return source.accept(serializer);
|
||||||
return serializer.bytesWritten();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource,
|
|||||||
typename TWriter>
|
typename TWriter>
|
||||||
size_t doSerialize(const TSource &source, TWriter writer) {
|
size_t doSerialize(const TSource &source, TWriter writer) {
|
||||||
TSerializer<TWriter> serializer(writer);
|
TSerializer<TWriter> serializer(writer);
|
||||||
source.accept(serializer);
|
return source.accept(serializer);
|
||||||
return serializer.bytesWritten();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource,
|
template <template <typename> class TSerializer, typename TSource,
|
||||||
|
@ -14,20 +14,34 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
|
|
||||||
class CollectionData;
|
class CollectionData;
|
||||||
|
|
||||||
struct ComparerBase {
|
struct ComparerBase : Visitor<CompareResult> {
|
||||||
CompareResult result;
|
CompareResult visitArray(const CollectionData &) {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
ComparerBase() : result(COMPARE_RESULT_DIFFER) {}
|
}
|
||||||
|
CompareResult visitBoolean(bool) {
|
||||||
void visitArray(const CollectionData &) {}
|
return COMPARE_RESULT_DIFFER;
|
||||||
void visitBoolean(bool) {}
|
}
|
||||||
void visitFloat(Float) {}
|
CompareResult visitFloat(Float) {
|
||||||
void visitNegativeInteger(UInt) {}
|
return COMPARE_RESULT_DIFFER;
|
||||||
void visitNull() {}
|
}
|
||||||
void visitObject(const CollectionData &) {}
|
CompareResult visitNegativeInteger(UInt) {
|
||||||
void visitPositiveInteger(UInt) {}
|
return COMPARE_RESULT_DIFFER;
|
||||||
void visitRawJson(const char *, size_t) {}
|
}
|
||||||
void visitString(const char *) {}
|
CompareResult visitNull() {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
|
}
|
||||||
|
CompareResult visitObject(const CollectionData &) {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
|
}
|
||||||
|
CompareResult visitPositiveInteger(UInt) {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
|
}
|
||||||
|
CompareResult visitRawJson(const char *, size_t) {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
|
}
|
||||||
|
CompareResult visitString(const char *) {
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Enable = void>
|
template <typename T, typename Enable = void>
|
||||||
@ -40,19 +54,21 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
|
|||||||
|
|
||||||
explicit Comparer(T value) : rhs(value) {}
|
explicit Comparer(T value) : rhs(value) {}
|
||||||
|
|
||||||
void visitString(const char *lhs) {
|
CompareResult visitString(const char *lhs) {
|
||||||
int i = adaptString(rhs).compare(lhs);
|
int i = adaptString(rhs).compare(lhs);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
result = COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
else if (i > 0)
|
else if (i > 0)
|
||||||
result = COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
else
|
else
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNull() {
|
CompareResult visitNull() {
|
||||||
if (adaptString(rhs).isNull())
|
if (adaptString(rhs).isNull())
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
|
else
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,26 +80,26 @@ struct Comparer<T, typename enable_if<is_integral<T>::value ||
|
|||||||
|
|
||||||
explicit Comparer(T value) : rhs(value) {}
|
explicit Comparer(T value) : rhs(value) {}
|
||||||
|
|
||||||
void visitFloat(Float lhs) {
|
CompareResult visitFloat(Float lhs) {
|
||||||
result = arithmeticCompare(lhs, rhs);
|
return arithmeticCompare(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt lhs) {
|
CompareResult visitNegativeInteger(UInt lhs) {
|
||||||
result = arithmeticCompareNegateLeft(lhs, rhs);
|
return arithmeticCompareNegateLeft(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitPositiveInteger(UInt lhs) {
|
CompareResult visitPositiveInteger(UInt lhs) {
|
||||||
result = arithmeticCompare(lhs, rhs);
|
return arithmeticCompare(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBoolean(bool lhs) {
|
CompareResult visitBoolean(bool lhs) {
|
||||||
visitPositiveInteger(static_cast<UInt>(lhs));
|
return visitPositiveInteger(static_cast<UInt>(lhs));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NullComparer : ComparerBase {
|
struct NullComparer : ComparerBase {
|
||||||
void visitNull() {
|
CompareResult visitNull() {
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,9 +115,11 @@ struct ArrayComparer : ComparerBase {
|
|||||||
|
|
||||||
explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {}
|
explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData &lhs) {
|
CompareResult visitArray(const CollectionData &lhs) {
|
||||||
if (lhs.equalsArray(*_rhs))
|
if (lhs.equalsArray(*_rhs))
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
|
else
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,20 +128,20 @@ struct NegativeIntegerComparer : ComparerBase {
|
|||||||
|
|
||||||
explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {}
|
explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {}
|
||||||
|
|
||||||
void visitFloat(Float lhs) {
|
CompareResult visitFloat(Float lhs) {
|
||||||
result = arithmeticCompareNegateRight(lhs, _rhs);
|
return arithmeticCompareNegateRight(lhs, _rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt lhs) {
|
CompareResult visitNegativeInteger(UInt lhs) {
|
||||||
result = arithmeticCompare(_rhs, lhs);
|
return arithmeticCompare(_rhs, lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitPositiveInteger(UInt) {
|
CompareResult visitPositiveInteger(UInt) {
|
||||||
result = COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBoolean(bool) {
|
CompareResult visitBoolean(bool) {
|
||||||
result = COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,9 +150,11 @@ struct ObjectComparer : ComparerBase {
|
|||||||
|
|
||||||
explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {}
|
explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {}
|
||||||
|
|
||||||
void visitObject(const CollectionData &lhs) {
|
CompareResult visitObject(const CollectionData &lhs) {
|
||||||
if (lhs.equalsObject(*_rhs))
|
if (lhs.equalsObject(*_rhs))
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
|
else
|
||||||
|
return COMPARE_RESULT_DIFFER;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -145,15 +165,15 @@ struct RawComparer : ComparerBase {
|
|||||||
explicit RawComparer(const char *rhsData, size_t rhsSize)
|
explicit RawComparer(const char *rhsData, size_t rhsSize)
|
||||||
: _rhsData(rhsData), _rhsSize(rhsSize) {}
|
: _rhsData(rhsData), _rhsSize(rhsSize) {}
|
||||||
|
|
||||||
void visitRawJson(const char *lhsData, size_t lhsSize) {
|
CompareResult visitRawJson(const char *lhsData, size_t lhsSize) {
|
||||||
size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize;
|
size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize;
|
||||||
int n = memcmp(lhsData, _rhsData, size);
|
int n = memcmp(lhsData, _rhsData, size);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
result = COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
else if (n > 0)
|
else if (n > 0)
|
||||||
result = COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
else
|
else
|
||||||
result = COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,65 +184,62 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
|
|||||||
|
|
||||||
explicit Comparer(T value) : rhs(value) {}
|
explicit Comparer(T value) : rhs(value) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData &lhs) {
|
CompareResult visitArray(const CollectionData &lhs) {
|
||||||
ArrayComparer comparer(lhs);
|
ArrayComparer comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitObject(const CollectionData &lhs) {
|
CompareResult visitObject(const CollectionData &lhs) {
|
||||||
ObjectComparer comparer(lhs);
|
ObjectComparer comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitFloat(Float lhs) {
|
CompareResult visitFloat(Float lhs) {
|
||||||
Comparer<Float> comparer(lhs);
|
Comparer<Float> comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitString(const char *lhs) {
|
CompareResult visitString(const char *lhs) {
|
||||||
Comparer<const char *> comparer(lhs);
|
Comparer<const char *> comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitRawJson(const char *lhsData, size_t lhsSize) {
|
CompareResult visitRawJson(const char *lhsData, size_t lhsSize) {
|
||||||
RawComparer comparer(lhsData, lhsSize);
|
RawComparer comparer(lhsData, lhsSize);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt lhs) {
|
CompareResult visitNegativeInteger(UInt lhs) {
|
||||||
NegativeIntegerComparer comparer(lhs);
|
NegativeIntegerComparer comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitPositiveInteger(UInt lhs) {
|
CompareResult visitPositiveInteger(UInt lhs) {
|
||||||
Comparer<UInt> comparer(lhs);
|
Comparer<UInt> comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBoolean(bool lhs) {
|
CompareResult visitBoolean(bool lhs) {
|
||||||
Comparer<bool> comparer(lhs);
|
Comparer<bool> comparer(lhs);
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNull() {
|
CompareResult visitNull() {
|
||||||
NullComparer comparer;
|
NullComparer comparer;
|
||||||
accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename TComparer>
|
template <typename TComparer>
|
||||||
void accept(TComparer &comparer) {
|
CompareResult accept(TComparer &comparer) {
|
||||||
rhs.accept(comparer);
|
CompareResult reversedResult = rhs.accept(comparer);
|
||||||
switch (comparer.result) {
|
switch (reversedResult) {
|
||||||
case COMPARE_RESULT_GREATER:
|
case COMPARE_RESULT_GREATER:
|
||||||
result = COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
break;
|
|
||||||
case COMPARE_RESULT_LESS:
|
case COMPARE_RESULT_LESS:
|
||||||
result = COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
result = comparer.result;
|
return reversedResult;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -230,8 +247,7 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
|
|||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult compare(const T1 &lhs, const T2 &rhs) {
|
CompareResult compare(const T1 &lhs, const T2 &rhs) {
|
||||||
Comparer<T2> comparer(rhs);
|
Comparer<T2> comparer(rhs);
|
||||||
lhs.accept(comparer);
|
return lhs.accept(comparer);
|
||||||
return comparer.result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int variantCompare(const VariantData *a, const VariantData *b) {
|
inline int variantCompare(const VariantData *a, const VariantData *b) {
|
||||||
|
@ -34,8 +34,8 @@ class VariantData {
|
|||||||
// - no virtual
|
// - no virtual
|
||||||
// - no inheritance
|
// - no inheritance
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor &visitor) const {
|
typename TVisitor::result_type accept(TVisitor &visitor) const {
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case VALUE_IS_FLOAT:
|
case VALUE_IS_FLOAT:
|
||||||
return visitor.visitFloat(_content.asFloat);
|
return visitor.visitFloat(_content.asFloat);
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
inline void variantAccept(const VariantData *var, Visitor &visitor) {
|
inline typename TVisitor::result_type variantAccept(const VariantData *var,
|
||||||
|
TVisitor &visitor) {
|
||||||
if (var != 0)
|
if (var != 0)
|
||||||
var->accept(visitor);
|
return var->accept(visitor);
|
||||||
else
|
else
|
||||||
visitor.visitNull();
|
return visitor.visitNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const CollectionData *variantAsArray(const VariantData *var) {
|
inline const CollectionData *variantAsArray(const VariantData *var) {
|
||||||
|
@ -261,9 +261,9 @@ class VariantRef : public VariantRefBase<VariantData>,
|
|||||||
return variantAs<T>(_data, _pool);
|
return variantAs<T>(_data, _pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor &visitor) const {
|
typename TVisitor::result_type accept(TVisitor &visitor) const {
|
||||||
variantAccept(_data, visitor);
|
return variantAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the type of the variant
|
// Change the type of the variant
|
||||||
@ -347,9 +347,9 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
|||||||
VariantConstRef(const VariantData *data) : base_type(data) {}
|
VariantConstRef(const VariantData *data) : base_type(data) {}
|
||||||
VariantConstRef(VariantRef var) : base_type(var._data) {}
|
VariantConstRef(VariantRef var) : base_type(var._data) {}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor &visitor) const {
|
typename TVisitor::result_type accept(TVisitor &visitor) const {
|
||||||
variantAccept(_data, visitor);
|
return variantAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Reference in New Issue
Block a user