Added a return value to visitors

This commit is contained in:
Benoit Blanchon
2020-08-29 18:40:27 +02:00
parent f448e805e9
commit 5ab53f42b2
20 changed files with 298 additions and 198 deletions

View File

@ -12,12 +12,13 @@ inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
return arr ? arr->addElement(pool) : 0;
}
template <typename Visitor>
inline void arrayAccept(const CollectionData *arr, Visitor &visitor) {
template <typename TVisitor>
inline typename TVisitor::result_type arrayAccept(const CollectionData *arr,
TVisitor &visitor) {
if (arr)
visitor.visitArray(*arr);
return visitor.visitArray(*arr);
else
visitor.visitNull();
return visitor.visitNull();
}
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {

View File

@ -27,9 +27,9 @@ class ArrayRefBase {
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
}
template <typename Visitor>
FORCE_INLINE void accept(Visitor& visitor) const {
arrayAccept(_data, visitor);
template <typename TVisitor>
FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
return arrayAccept(_data, visitor);
}
FORCE_INLINE bool isNull() const {

View File

@ -98,8 +98,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return getOrAddUpstreamElement().set(value);
}
template <typename Visitor>
void accept(Visitor& visitor) const {
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const {
return getUpstreamElement().accept(visitor);
}

View File

@ -65,40 +65,61 @@ inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
}
template <typename T>
class ArrayCopier1D {
class ArrayCopier1D : public Visitor<size_t> {
public:
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();
while (slot != 0 && _size < _capacity) {
_destination[_size++] = variantAs<T>(slot->data());
while (slot != 0 && size < _capacity) {
_destination[size++] = variantAs<T>(slot->data());
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 {
return _size;
size_t visitObject(const CollectionData&) {
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:
T* _destination;
size_t _capacity;
size_t _size;
};
template <typename T, size_t N1, size_t N2>
class ArrayCopier2D {
class ArrayCopier2D : public Visitor<void> {
public:
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>
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
ArrayCopier1D<T> copier(dst, len);
src.accept(copier);
return copier.result();
return src.accept(copier);
}
// Copy a JsonArray to a 2D array

View File

@ -15,8 +15,8 @@ namespace ARDUINOJSON_NAMESPACE {
class JsonDocument : public Visitable {
public:
template <typename Visitor>
void accept(Visitor& visitor) const {
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const {
return getVariant().accept(visitor);
}

View File

@ -12,11 +12,11 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TWriter>
class JsonSerializer {
class JsonSerializer : public Visitor<size_t> {
public:
JsonSerializer(TWriter writer) : _formatter(writer) {}
FORCE_INLINE void visitArray(const CollectionData &array) {
FORCE_INLINE size_t visitArray(const CollectionData &array) {
write('[');
VariantSlot *slot = array.head();
@ -32,9 +32,10 @@ class JsonSerializer {
}
write(']');
return bytesWritten();
}
void visitObject(const CollectionData &object) {
size_t visitObject(const CollectionData &object) {
write('{');
VariantSlot *slot = object.head();
@ -52,41 +53,49 @@ class JsonSerializer {
}
write('}');
return bytesWritten();
}
void visitFloat(Float value) {
size_t visitFloat(Float value) {
_formatter.writeFloat(value);
return bytesWritten();
}
void visitString(const char *value) {
size_t visitString(const char *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);
return bytesWritten();
}
void visitNegativeInteger(UInt value) {
size_t visitNegativeInteger(UInt value) {
_formatter.writeNegativeInteger(value);
return bytesWritten();
}
void visitPositiveInteger(UInt value) {
size_t visitPositiveInteger(UInt value) {
_formatter.writePositiveInteger(value);
return bytesWritten();
}
void visitBoolean(bool value) {
size_t visitBoolean(bool value) {
_formatter.writeBoolean(value);
return bytesWritten();
}
void visitNull() {
size_t visitNull() {
_formatter.writeRaw("null");
return bytesWritten();
}
protected:
size_t bytesWritten() const {
return _formatter.bytesWritten();
}
protected:
void write(char c) {
_formatter.writeRaw(c);
}

View File

@ -18,44 +18,48 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
public:
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
void visitArray(const CollectionData &array) {
size_t visitArray(const CollectionData &array) {
VariantSlot *slot = array.head();
if (!slot)
return base::write("[]");
if (slot) {
base::write("[\r\n");
_nesting++;
while (slot != 0) {
indent();
slot->data()->accept(*this);
base::write("[\r\n");
_nesting++;
while (slot != 0) {
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
}
_nesting--;
indent();
slot->data()->accept(*this);
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
base::write("]");
} else {
base::write("[]");
}
_nesting--;
indent();
base::write("]");
return this->bytesWritten();
}
void visitObject(const CollectionData &object) {
size_t visitObject(const CollectionData &object) {
VariantSlot *slot = object.head();
if (!slot)
return base::write("{}");
if (slot) {
base::write("{\r\n");
_nesting++;
while (slot != 0) {
indent();
base::visitString(slot->key());
base::write(": ");
slot->data()->accept(*this);
base::write("{\r\n");
_nesting++;
while (slot != 0) {
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
}
_nesting--;
indent();
base::visitString(slot->key());
base::write(": ");
slot->data()->accept(*this);
slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n");
base::write("}");
} else {
base::write("{}");
}
_nesting--;
indent();
base::write("}");
return this->bytesWritten();
}
private:

View File

@ -12,17 +12,18 @@
#include <ArduinoJson/Numbers/Integer.hpp>
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Polyfills/attributes.hpp>
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <typename TWriter>
class TextFormatter {
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.
size_t bytesWritten() const {
return _length;
return _writer.count();
}
void writeBoolean(bool value) {
@ -128,28 +129,28 @@ class TextFormatter {
}
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) {
_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) {
_length += _writer.write(reinterpret_cast<const uint8_t *>(begin),
static_cast<size_t>(end - begin));
_writer.write(reinterpret_cast<const uint8_t *>(begin),
static_cast<size_t>(end - begin));
}
template <size_t 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) {
_length += _writer.write(static_cast<uint8_t>(c));
_writer.write(static_cast<uint8_t>(c));
}
protected:
TWriter _writer;
CountingDecorator<TWriter> _writer;
size_t _length;
private:

View File

@ -8,6 +8,11 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TResult>
struct Visitor {
typedef TResult result_type;
};
struct Visitable {
// template<Visitor>
// void accept(Visitor&) const;

View File

@ -7,6 +7,7 @@
#include <ArduinoJson/MsgPack/endianess.hpp>
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
#include <ArduinoJson/Serialization/measure.hpp>
#include <ArduinoJson/Serialization/serialize.hpp>
#include <ArduinoJson/Variant/VariantData.hpp>
@ -14,19 +15,20 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TWriter>
class MsgPackSerializer {
class MsgPackSerializer : public Visitor<size_t> {
public:
MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {}
MsgPackSerializer(TWriter writer) : _writer(writer) {}
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);
writeInteger(value32);
return bytesWritten();
}
template <typename T>
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);
if (value32 == value64) {
writeByte(0xCA);
@ -35,9 +37,10 @@ class MsgPackSerializer {
writeByte(0xCB);
writeInteger(value64);
}
return bytesWritten();
}
void visitArray(const CollectionData& array) {
size_t visitArray(const CollectionData& array) {
size_t n = array.size();
if (n < 0x10) {
writeByte(uint8_t(0x90 + array.size()));
@ -51,9 +54,10 @@ class MsgPackSerializer {
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
slot->data()->accept(*this);
}
return bytesWritten();
}
void visitObject(const CollectionData& object) {
size_t visitObject(const CollectionData& object) {
size_t n = object.size();
if (n < 0x10) {
writeByte(uint8_t(0x80 + n));
@ -68,9 +72,10 @@ class MsgPackSerializer {
visitString(slot->key());
slot->data()->accept(*this);
}
return bytesWritten();
}
void visitString(const char* value) {
size_t visitString(const char* value) {
ARDUINOJSON_ASSERT(value != NULL);
size_t n = strlen(value);
@ -88,13 +93,15 @@ class MsgPackSerializer {
writeInteger(uint32_t(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);
return bytesWritten();
}
void visitNegativeInteger(UInt value) {
size_t visitNegativeInteger(UInt value) {
UInt negated = UInt(~value + 1);
if (value <= 0x20) {
writeInteger(int8_t(negated));
@ -114,9 +121,10 @@ class MsgPackSerializer {
writeInteger(int64_t(negated));
}
#endif
return bytesWritten();
}
void visitPositiveInteger(UInt value) {
size_t visitPositiveInteger(UInt value) {
if (value <= 0x7F) {
writeInteger(uint8_t(value));
} else if (value <= 0xFF) {
@ -141,27 +149,30 @@ class MsgPackSerializer {
writeInteger(uint64_t(value));
}
#endif
return bytesWritten();
}
void visitBoolean(bool value) {
size_t visitBoolean(bool value) {
writeByte(value ? 0xC3 : 0xC2);
return bytesWritten();
}
void visitNull() {
size_t visitNull() {
writeByte(0xC0);
}
size_t bytesWritten() const {
return _bytesWritten;
return bytesWritten();
}
private:
size_t bytesWritten() const {
return _writer.count();
}
void writeByte(uint8_t c) {
_bytesWritten += _writer.write(c);
_writer.write(c);
}
void writeBytes(const uint8_t* p, size_t n) {
_bytesWritten += _writer.write(p, n);
_writer.write(p, n);
}
template <typename T>
@ -170,8 +181,7 @@ class MsgPackSerializer {
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
}
TWriter _writer;
size_t _bytesWritten;
CountingDecorator<TWriter> _writer;
};
template <typename TSource, typename TDestination>

View File

@ -120,8 +120,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return getOrAddUpstreamMember().set(value);
}
template <typename Visitor>
void accept(Visitor &visitor) const {
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor &visitor) const {
return getUpstreamMember().accept(visitor);
}

View File

@ -8,12 +8,13 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename Visitor>
void objectAccept(const CollectionData *obj, Visitor &visitor) {
template <typename TVisitor>
typename TVisitor::result_type objectAccept(const CollectionData *obj,
TVisitor &visitor) {
if (obj)
visitor.visitObject(*obj);
return visitor.visitObject(*obj);
else
visitor.visitNull();
return visitor.visitNull();
}
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {

View File

@ -22,9 +22,9 @@ class ObjectRefBase {
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
}
template <typename Visitor>
FORCE_INLINE void accept(Visitor& visitor) const {
objectAccept(_data, visitor);
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const {
return objectAccept(_data, visitor);
}
FORCE_INLINE bool isNull() const {

View 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

View File

@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource>
size_t measure(const TSource &source) {
DummyWriter dp;
TSerializer<DummyWriter> serializer(dp);
source.accept(serializer);
return serializer.bytesWritten();
return source.accept(serializer);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource,
typename TWriter>
size_t doSerialize(const TSource &source, TWriter writer) {
TSerializer<TWriter> serializer(writer);
source.accept(serializer);
return serializer.bytesWritten();
return source.accept(serializer);
}
template <template <typename> class TSerializer, typename TSource,

View File

@ -14,20 +14,34 @@ namespace ARDUINOJSON_NAMESPACE {
class CollectionData;
struct ComparerBase {
CompareResult result;
ComparerBase() : result(COMPARE_RESULT_DIFFER) {}
void visitArray(const CollectionData &) {}
void visitBoolean(bool) {}
void visitFloat(Float) {}
void visitNegativeInteger(UInt) {}
void visitNull() {}
void visitObject(const CollectionData &) {}
void visitPositiveInteger(UInt) {}
void visitRawJson(const char *, size_t) {}
void visitString(const char *) {}
struct ComparerBase : Visitor<CompareResult> {
CompareResult visitArray(const CollectionData &) {
return COMPARE_RESULT_DIFFER;
}
CompareResult visitBoolean(bool) {
return COMPARE_RESULT_DIFFER;
}
CompareResult visitFloat(Float) {
return COMPARE_RESULT_DIFFER;
}
CompareResult visitNegativeInteger(UInt) {
return COMPARE_RESULT_DIFFER;
}
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>
@ -40,19 +54,21 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
explicit Comparer(T value) : rhs(value) {}
void visitString(const char *lhs) {
CompareResult visitString(const char *lhs) {
int i = adaptString(rhs).compare(lhs);
if (i < 0)
result = COMPARE_RESULT_GREATER;
return COMPARE_RESULT_GREATER;
else if (i > 0)
result = COMPARE_RESULT_LESS;
return COMPARE_RESULT_LESS;
else
result = COMPARE_RESULT_EQUAL;
return COMPARE_RESULT_EQUAL;
}
void visitNull() {
CompareResult visitNull() {
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) {}
void visitFloat(Float lhs) {
result = arithmeticCompare(lhs, rhs);
CompareResult visitFloat(Float lhs) {
return arithmeticCompare(lhs, rhs);
}
void visitNegativeInteger(UInt lhs) {
result = arithmeticCompareNegateLeft(lhs, rhs);
CompareResult visitNegativeInteger(UInt lhs) {
return arithmeticCompareNegateLeft(lhs, rhs);
}
void visitPositiveInteger(UInt lhs) {
result = arithmeticCompare(lhs, rhs);
CompareResult visitPositiveInteger(UInt lhs) {
return arithmeticCompare(lhs, rhs);
}
void visitBoolean(bool lhs) {
visitPositiveInteger(static_cast<UInt>(lhs));
CompareResult visitBoolean(bool lhs) {
return visitPositiveInteger(static_cast<UInt>(lhs));
}
};
struct NullComparer : ComparerBase {
void visitNull() {
result = COMPARE_RESULT_EQUAL;
CompareResult visitNull() {
return COMPARE_RESULT_EQUAL;
}
};
@ -99,9 +115,11 @@ struct ArrayComparer : ComparerBase {
explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {}
void visitArray(const CollectionData &lhs) {
CompareResult visitArray(const CollectionData &lhs) {
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) {}
void visitFloat(Float lhs) {
result = arithmeticCompareNegateRight(lhs, _rhs);
CompareResult visitFloat(Float lhs) {
return arithmeticCompareNegateRight(lhs, _rhs);
}
void visitNegativeInteger(UInt lhs) {
result = arithmeticCompare(_rhs, lhs);
CompareResult visitNegativeInteger(UInt lhs) {
return arithmeticCompare(_rhs, lhs);
}
void visitPositiveInteger(UInt) {
result = COMPARE_RESULT_GREATER;
CompareResult visitPositiveInteger(UInt) {
return COMPARE_RESULT_GREATER;
}
void visitBoolean(bool) {
result = COMPARE_RESULT_GREATER;
CompareResult visitBoolean(bool) {
return COMPARE_RESULT_GREATER;
}
};
@ -132,9 +150,11 @@ struct ObjectComparer : ComparerBase {
explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {}
void visitObject(const CollectionData &lhs) {
CompareResult visitObject(const CollectionData &lhs) {
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)
: _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;
int n = memcmp(lhsData, _rhsData, size);
if (n < 0)
result = COMPARE_RESULT_LESS;
return COMPARE_RESULT_LESS;
else if (n > 0)
result = COMPARE_RESULT_GREATER;
return COMPARE_RESULT_GREATER;
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) {}
void visitArray(const CollectionData &lhs) {
CompareResult visitArray(const CollectionData &lhs) {
ArrayComparer comparer(lhs);
accept(comparer);
return accept(comparer);
}
void visitObject(const CollectionData &lhs) {
CompareResult visitObject(const CollectionData &lhs) {
ObjectComparer comparer(lhs);
accept(comparer);
return accept(comparer);
}
void visitFloat(Float lhs) {
CompareResult visitFloat(Float 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);
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);
accept(comparer);
return accept(comparer);
}
void visitNegativeInteger(UInt lhs) {
CompareResult visitNegativeInteger(UInt lhs) {
NegativeIntegerComparer comparer(lhs);
accept(comparer);
return accept(comparer);
}
void visitPositiveInteger(UInt lhs) {
CompareResult visitPositiveInteger(UInt lhs) {
Comparer<UInt> comparer(lhs);
accept(comparer);
return accept(comparer);
}
void visitBoolean(bool lhs) {
CompareResult visitBoolean(bool lhs) {
Comparer<bool> comparer(lhs);
accept(comparer);
return accept(comparer);
}
void visitNull() {
CompareResult visitNull() {
NullComparer comparer;
accept(comparer);
return accept(comparer);
}
private:
template <typename TComparer>
void accept(TComparer &comparer) {
rhs.accept(comparer);
switch (comparer.result) {
CompareResult accept(TComparer &comparer) {
CompareResult reversedResult = rhs.accept(comparer);
switch (reversedResult) {
case COMPARE_RESULT_GREATER:
result = COMPARE_RESULT_LESS;
break;
return COMPARE_RESULT_LESS;
case COMPARE_RESULT_LESS:
result = COMPARE_RESULT_GREATER;
break;
return COMPARE_RESULT_GREATER;
default:
result = comparer.result;
break;
return reversedResult;
}
}
};
@ -230,8 +247,7 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
template <typename T1, typename T2>
CompareResult compare(const T1 &lhs, const T2 &rhs) {
Comparer<T2> comparer(rhs);
lhs.accept(comparer);
return comparer.result;
return lhs.accept(comparer);
}
inline int variantCompare(const VariantData *a, const VariantData *b) {

View File

@ -34,8 +34,8 @@ class VariantData {
// - no virtual
// - no inheritance
template <typename Visitor>
void accept(Visitor &visitor) const {
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor &visitor) const {
switch (type()) {
case VALUE_IS_FLOAT:
return visitor.visitFloat(_content.asFloat);

View File

@ -9,12 +9,13 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename Visitor>
inline void variantAccept(const VariantData *var, Visitor &visitor) {
template <typename TVisitor>
inline typename TVisitor::result_type variantAccept(const VariantData *var,
TVisitor &visitor) {
if (var != 0)
var->accept(visitor);
return var->accept(visitor);
else
visitor.visitNull();
return visitor.visitNull();
}
inline const CollectionData *variantAsArray(const VariantData *var) {

View File

@ -261,9 +261,9 @@ class VariantRef : public VariantRefBase<VariantData>,
return variantAs<T>(_data, _pool);
}
template <typename Visitor>
void accept(Visitor &visitor) const {
variantAccept(_data, visitor);
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor &visitor) const {
return variantAccept(_data, visitor);
}
// Change the type of the variant
@ -347,9 +347,9 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
VariantConstRef(const VariantData *data) : base_type(data) {}
VariantConstRef(VariantRef var) : base_type(var._data) {}
template <typename Visitor>
void accept(Visitor &visitor) const {
variantAccept(_data, visitor);
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor &visitor) const {
return variantAccept(_data, visitor);
}
template <typename T>