Merge all visitXxx() into one overloaded visit() function

This commit is contained in:
Benoit Blanchon
2023-07-10 18:27:30 +02:00
parent 64922343e6
commit 5e3f84c718
7 changed files with 97 additions and 165 deletions

View File

@ -18,7 +18,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
JsonSerializer(TWriter writer) : formatter_(writer) {}
FORCE_INLINE size_t visitArray(const ArrayData& array) {
FORCE_INLINE size_t visit(const ArrayData& array) {
write('[');
auto it = array.createIterator();
@ -37,7 +37,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitObject(const ObjectData& object) {
size_t visit(const ObjectData& object) {
write('{');
auto it = object.createIterator();
@ -58,42 +58,42 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitFloat(JsonFloat value) {
size_t visit(JsonFloat value) {
formatter_.writeFloat(value);
return bytesWritten();
}
size_t visitString(const char* value) {
size_t visit(const char* value) {
formatter_.writeString(value);
return bytesWritten();
}
size_t visitString(JsonString value) {
size_t visit(JsonString value) {
formatter_.writeString(value.c_str(), value.size());
return bytesWritten();
}
size_t visitRawString(RawString value) {
size_t visit(RawString value) {
formatter_.writeRaw(value.data(), value.size());
return bytesWritten();
}
size_t visitSignedInteger(JsonInteger value) {
size_t visit(JsonInteger value) {
formatter_.writeInteger(value);
return bytesWritten();
}
size_t visitUnsignedInteger(JsonUInt value) {
size_t visit(JsonUInt value) {
formatter_.writeInteger(value);
return bytesWritten();
}
size_t visitBoolean(bool value) {
size_t visit(bool value) {
formatter_.writeBoolean(value);
return bytesWritten();
}
size_t visitNull(nullptr_t) {
size_t visit(nullptr_t) {
formatter_.writeRaw("null");
return bytesWritten();
}

View File

@ -18,7 +18,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
public:
PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
size_t visitArray(const ArrayData& array) {
size_t visit(const ArrayData& array) {
auto it = array.createIterator();
if (!it.done()) {
base::write("[\r\n");
@ -39,14 +39,14 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
return this->bytesWritten();
}
size_t visitObject(const ObjectData& object) {
size_t visit(const ObjectData& object) {
auto it = object.createIterator();
if (!it.done()) {
base::write("{\r\n");
nesting_++;
while (!it.done()) {
indent();
base::visitString(it.key());
base::visit(it.key());
base::write(": ");
it->accept(*this);
@ -62,6 +62,8 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
return this->bytesWritten();
}
using base::visit;
private:
void indent() {
for (uint8_t i = 0; i < nesting_; i++)

View File

@ -22,11 +22,13 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
MsgPackSerializer(TWriter writer) : writer_(writer) {}
template <typename T>
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
typename enable_if<is_floating_point<T>::value && sizeof(T) == 4,
size_t>::type
visit(T value32) {
if (canConvertNumber<JsonInteger>(value32)) {
JsonInteger truncatedValue = JsonInteger(value32);
if (value32 == T(truncatedValue))
return visitSignedInteger(truncatedValue);
return visit(truncatedValue);
}
writeByte(0xCA);
writeInteger(value32);
@ -35,16 +37,17 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
template <typename T>
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
typename enable_if<is_floating_point<T>::value && sizeof(T) == 8,
size_t>::type visit(T value64) {
float value32 = float(value64);
if (value32 == value64)
return visitFloat(value32);
return visit(value32);
writeByte(0xCB);
writeInteger(value64);
return bytesWritten();
}
size_t visitArray(const ArrayData& array) {
size_t visit(const ArrayData& array) {
size_t n = array.size();
if (n < 0x10) {
writeByte(uint8_t(0x90 + n));
@ -61,7 +64,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitObject(const ObjectData& object) {
size_t visit(const ObjectData& object) {
size_t n = object.size();
if (n < 0x10) {
writeByte(uint8_t(0x80 + n));
@ -73,17 +76,17 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
writeInteger(uint32_t(n));
}
for (auto it = object.createIterator(); !it.done(); it.next()) {
visitString(it.key());
visit(it.key());
it->accept(*this);
}
return bytesWritten();
}
size_t visitString(const char* value) {
return visitString(JsonString(value));
size_t visit(const char* value) {
return visit(JsonString(value));
}
size_t visitString(JsonString value) {
size_t visit(JsonString value) {
ARDUINOJSON_ASSERT(value != NULL);
auto n = value.size();
@ -104,14 +107,14 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitRawString(RawString value) {
size_t visit(RawString value) {
writeBytes(reinterpret_cast<const uint8_t*>(value.data()), value.size());
return bytesWritten();
}
size_t visitSignedInteger(JsonInteger value) {
size_t visit(JsonInteger value) {
if (value > 0) {
visitUnsignedInteger(static_cast<JsonUInt>(value));
visit(static_cast<JsonUInt>(value));
} else if (value >= -0x20) {
writeInteger(int8_t(value));
} else if (value >= -0x80) {
@ -139,7 +142,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitUnsignedInteger(JsonUInt value) {
size_t visit(JsonUInt value) {
if (value <= 0x7F) {
writeInteger(uint8_t(value));
} else if (value <= 0xFF) {
@ -167,12 +170,12 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
return bytesWritten();
}
size_t visitBoolean(bool value) {
size_t visit(bool value) {
writeByte(value ? 0xC3 : 0xC2);
return bytesWritten();
}
size_t visitNull(nullptr_t) {
size_t visit(nullptr_t) {
writeByte(0xC0);
return bytesWritten();
}

View File

@ -15,39 +15,8 @@ template <typename TResult>
struct JsonVariantVisitor {
typedef TResult result_type;
TResult visitArray(JsonArrayConst) {
return TResult();
}
TResult visitBoolean(bool) {
return TResult();
}
TResult visitFloat(JsonFloat) {
return TResult();
}
TResult visitSignedInteger(JsonInteger) {
return TResult();
}
TResult visitNull(nullptr_t) {
return TResult();
}
TResult visitObject(JsonObjectConst) {
return TResult();
}
TResult visitUnsignedInteger(JsonUInt) {
return TResult();
}
TResult visitRawString(RawString) {
return TResult();
}
TResult visitString(JsonString) {
template <typename T>
TResult visit(const T&) {
return TResult();
}
};
@ -60,40 +29,17 @@ class VisitorAdapter {
VisitorAdapter(TVisitor& visitor, const ResourceManager* resources)
: visitor_(&visitor), resources_(resources) {}
result_type visitArray(const ArrayData& array) {
return visitor_->visitArray(JsonArrayConst(&array, resources_));
result_type visit(const ArrayData& value) {
return visitor_->visit(JsonArrayConst(&value, resources_));
}
result_type visitObject(const ObjectData& object) {
return visitor_->visitObject(JsonObjectConst(&object, resources_));
result_type visit(const ObjectData& value) {
return visitor_->visit(JsonObjectConst(&value, resources_));
}
result_type visitFloat(JsonFloat value) {
return visitor_->visitFloat(value);
}
result_type visitString(JsonString value) {
return visitor_->visitString(value);
}
result_type visitRawString(RawString value) {
return visitor_->visitRawString(value);
}
result_type visitSignedInteger(JsonInteger value) {
return visitor_->visitSignedInteger(value);
}
result_type visitUnsignedInteger(JsonUInt value) {
return visitor_->visitUnsignedInteger(value);
}
result_type visitBoolean(bool value) {
return visitor_->visitBoolean(value);
}
result_type visitNull(nullptr_t) {
return visitor_->visitNull(nullptr);
template <typename T>
result_type visit(const T& value) {
return visitor_->visit(value);
}
private:
@ -103,12 +49,12 @@ class VisitorAdapter {
template <typename TVisitor>
typename TVisitor::result_type accept(JsonVariantConst variant,
TVisitor& visitor) {
TVisitor& visit) {
auto data = VariantAttorney::getData(variant);
if (!data)
return visitor.visitNull(nullptr);
return visit.visit(nullptr);
auto resources = VariantAttorney::getResourceManager(variant);
VisitorAdapter<TVisitor> adapter(visitor, resources);
VisitorAdapter<TVisitor> adapter(visit, resources);
return data->accept(adapter);
}

View File

@ -25,7 +25,7 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
explicit Comparer(T value) : rhs(value) {}
CompareResult visitString(JsonString lhs) {
CompareResult visit(JsonString lhs) {
int i = stringCompare(adaptString(rhs), adaptString(lhs));
if (i < 0)
return COMPARE_RESULT_GREATER;
@ -35,12 +35,14 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
return COMPARE_RESULT_EQUAL;
}
CompareResult visitNull(nullptr_t) {
CompareResult visit(nullptr_t) {
if (adaptString(rhs).isNull())
return COMPARE_RESULT_EQUAL;
else
return COMPARE_RESULT_DIFFER;
}
using ComparerBase::visit;
};
template <typename T>
@ -51,27 +53,31 @@ struct Comparer<T, typename enable_if<is_integral<T>::value ||
explicit Comparer(T value) : rhs(value) {}
CompareResult visitFloat(JsonFloat lhs) {
CompareResult visit(JsonFloat lhs) {
return arithmeticCompare(lhs, rhs);
}
CompareResult visitSignedInteger(JsonInteger lhs) {
CompareResult visit(JsonInteger lhs) {
return arithmeticCompare(lhs, rhs);
}
CompareResult visitUnsignedInteger(JsonUInt lhs) {
CompareResult visit(JsonUInt lhs) {
return arithmeticCompare(lhs, rhs);
}
CompareResult visitBoolean(bool lhs) {
return visitUnsignedInteger(static_cast<JsonUInt>(lhs));
CompareResult visit(bool lhs) {
return visit(static_cast<JsonUInt>(lhs));
}
using ComparerBase::visit;
};
struct NullComparer : ComparerBase {
CompareResult visitNull(nullptr_t) {
CompareResult visit(nullptr_t) {
return COMPARE_RESULT_EQUAL;
}
using ComparerBase::visit;
};
template <>
@ -84,12 +90,14 @@ struct ArrayComparer : ComparerBase {
explicit ArrayComparer(JsonArrayConst rhs) : rhs_(rhs) {}
CompareResult visitArray(JsonArrayConst lhs) {
CompareResult visit(JsonArrayConst lhs) {
if (rhs_ == lhs)
return COMPARE_RESULT_EQUAL;
else
return COMPARE_RESULT_DIFFER;
}
using ComparerBase::visit;
};
struct ObjectComparer : ComparerBase {
@ -97,12 +105,14 @@ struct ObjectComparer : ComparerBase {
explicit ObjectComparer(JsonObjectConst rhs) : rhs_(rhs) {}
CompareResult visitObject(JsonObjectConst lhs) {
CompareResult visit(JsonObjectConst lhs) {
if (lhs == rhs_)
return COMPARE_RESULT_EQUAL;
else
return COMPARE_RESULT_DIFFER;
}
using ComparerBase::visit;
};
struct RawComparer : ComparerBase {
@ -110,7 +120,7 @@ struct RawComparer : ComparerBase {
explicit RawComparer(RawString rhs) : rhs_(rhs) {}
CompareResult visitRawString(RawString lhs) {
CompareResult visit(RawString lhs) {
size_t size = rhs_.size() < lhs.size() ? rhs_.size() : lhs.size();
int n = memcmp(lhs.data(), rhs_.data(), size);
if (n < 0)
@ -120,6 +130,8 @@ struct RawComparer : ComparerBase {
else
return COMPARE_RESULT_EQUAL;
}
using ComparerBase::visit;
};
struct VariantComparer : ComparerBase {
@ -127,47 +139,47 @@ struct VariantComparer : ComparerBase {
explicit VariantComparer(JsonVariantConst value) : rhs(value) {}
CompareResult visitArray(JsonArrayConst lhs) {
CompareResult visit(JsonArrayConst lhs) {
ArrayComparer comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitObject(JsonObjectConst lhs) {
CompareResult visit(JsonObjectConst lhs) {
ObjectComparer comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitFloat(JsonFloat lhs) {
CompareResult visit(JsonFloat lhs) {
Comparer<JsonFloat> comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitString(JsonString lhs) {
CompareResult visit(JsonString lhs) {
Comparer<JsonString> comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitRawString(RawString value) {
CompareResult visit(RawString value) {
RawComparer comparer(value);
return reverseResult(comparer);
}
CompareResult visitSignedInteger(JsonInteger lhs) {
CompareResult visit(JsonInteger lhs) {
Comparer<JsonInteger> comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitUnsignedInteger(JsonUInt lhs) {
CompareResult visit(JsonUInt lhs) {
Comparer<JsonUInt> comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitBoolean(bool lhs) {
CompareResult visit(bool lhs) {
Comparer<bool> comparer(lhs);
return reverseResult(comparer);
}
CompareResult visitNull(nullptr_t) {
CompareResult visit(nullptr_t) {
NullComparer comparer;
return reverseResult(comparer);
}

View File

@ -25,50 +25,50 @@ class VariantData {
VariantData() : flags_(VALUE_IS_NULL) {}
template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const {
typename TVisitor::result_type accept(TVisitor& visit) const {
switch (type()) {
case VALUE_IS_FLOAT:
return visitor.visitFloat(content_.asFloat);
return visit.visit(content_.asFloat);
case VALUE_IS_ARRAY:
return visitor.visitArray(content_.asArray);
return visit.visit(content_.asArray);
case VALUE_IS_OBJECT:
return visitor.visitObject(content_.asObject);
return visit.visit(content_.asObject);
case VALUE_IS_LINKED_STRING:
return visitor.visitString(JsonString(content_.asLinkedString));
return visit.visit(JsonString(content_.asLinkedString));
case VALUE_IS_OWNED_STRING:
return visitor.visitString(JsonString(content_.asOwnedString->data,
content_.asOwnedString->length,
JsonString::Copied));
return visit.visit(JsonString(content_.asOwnedString->data,
content_.asOwnedString->length,
JsonString::Copied));
case VALUE_IS_RAW_STRING:
return visitor.visitRawString(RawString(
content_.asOwnedString->data, content_.asOwnedString->length));
return visit.visit(RawString(content_.asOwnedString->data,
content_.asOwnedString->length));
case VALUE_IS_SIGNED_INTEGER:
return visitor.visitSignedInteger(content_.asSignedInteger);
return visit.visit(content_.asSignedInteger);
case VALUE_IS_UNSIGNED_INTEGER:
return visitor.visitUnsignedInteger(content_.asUnsignedInteger);
return visit.visit(content_.asUnsignedInteger);
case VALUE_IS_BOOLEAN:
return visitor.visitBoolean(content_.asBoolean != 0);
return visit.visit(content_.asBoolean != 0);
default:
return visitor.visitNull(nullptr);
return visit.visit(nullptr);
}
}
template <typename TVisitor>
static typename TVisitor::result_type accept(const VariantData* var,
TVisitor& visitor) {
TVisitor& visit) {
if (var != 0)
return var->accept(visitor);
return var->accept(visit);
else
return visitor.visitNull(nullptr);
return visit.visit(nullptr);
}
VariantData* addElement(ResourceManager* resources) {

View File

@ -15,39 +15,8 @@ template <typename TResult>
struct VariantDataVisitor {
typedef TResult result_type;
TResult visitArray(const ArrayData&) {
return TResult();
}
TResult visitBoolean(bool) {
return TResult();
}
TResult visitFloat(JsonFloat) {
return TResult();
}
TResult visitSignedInteger(JsonInteger) {
return TResult();
}
TResult visitNull(nullptr_t) {
return TResult();
}
TResult visitObject(const ObjectData&) {
return TResult();
}
TResult visitUnsignedInteger(JsonUInt) {
return TResult();
}
TResult visitRawString(RawString) {
return TResult();
}
TResult visitString(JsonString) {
template <typename T>
TResult visit(const T&) {
return TResult();
}
};