From 5e3f84c71864294af95e7956d93b93aa4af950e0 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 10 Jul 2023 18:27:30 +0200 Subject: [PATCH] Merge all `visitXxx()` into one overloaded `visit()` function --- src/ArduinoJson/Json/JsonSerializer.hpp | 20 ++--- src/ArduinoJson/Json/PrettyJsonSerializer.hpp | 8 +- src/ArduinoJson/MsgPack/MsgPackSerializer.hpp | 35 +++++---- .../Variant/JsonVariantVisitor.hpp | 78 +++---------------- src/ArduinoJson/Variant/VariantCompare.hpp | 52 ++++++++----- src/ArduinoJson/Variant/VariantData.hpp | 34 ++++---- .../Variant/VariantDataVisitor.hpp | 35 +-------- 7 files changed, 97 insertions(+), 165 deletions(-) diff --git a/src/ArduinoJson/Json/JsonSerializer.hpp b/src/ArduinoJson/Json/JsonSerializer.hpp index 81abca1c..c2eeab83 100644 --- a/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/JsonSerializer.hpp @@ -18,7 +18,7 @@ class JsonSerializer : public VariantDataVisitor { 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 { 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 { 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(); } diff --git a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp index 2c5f22c3..1a34fe82 100644 --- a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp +++ b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp @@ -18,7 +18,7 @@ class PrettyJsonSerializer : public JsonSerializer { 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 { 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 { return this->bytesWritten(); } + using base::visit; + private: void indent() { for (uint8_t i = 0; i < nesting_; i++) diff --git a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp index 323ed90c..71997bf5 100644 --- a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp @@ -22,11 +22,13 @@ class MsgPackSerializer : public VariantDataVisitor { MsgPackSerializer(TWriter writer) : writer_(writer) {} template - typename enable_if::type visitFloat(T value32) { + typename enable_if::value && sizeof(T) == 4, + size_t>::type + visit(T value32) { if (canConvertNumber(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 { template ARDUINOJSON_NO_SANITIZE("float-cast-overflow") - typename enable_if::type visitFloat(T value64) { + typename enable_if::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 { 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 { 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 { return bytesWritten(); } - size_t visitRawString(RawString value) { + size_t visit(RawString value) { writeBytes(reinterpret_cast(value.data()), value.size()); return bytesWritten(); } - size_t visitSignedInteger(JsonInteger value) { + size_t visit(JsonInteger value) { if (value > 0) { - visitUnsignedInteger(static_cast(value)); + visit(static_cast(value)); } else if (value >= -0x20) { writeInteger(int8_t(value)); } else if (value >= -0x80) { @@ -139,7 +142,7 @@ class MsgPackSerializer : public VariantDataVisitor { 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 { 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(); } diff --git a/src/ArduinoJson/Variant/JsonVariantVisitor.hpp b/src/ArduinoJson/Variant/JsonVariantVisitor.hpp index 18ae3f41..b9bb73b8 100644 --- a/src/ArduinoJson/Variant/JsonVariantVisitor.hpp +++ b/src/ArduinoJson/Variant/JsonVariantVisitor.hpp @@ -15,39 +15,8 @@ template 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 + 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 + result_type visit(const T& value) { + return visitor_->visit(value); } private: @@ -103,12 +49,12 @@ class VisitorAdapter { template 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 adapter(visitor, resources); + VisitorAdapter adapter(visit, resources); return data->accept(adapter); } diff --git a/src/ArduinoJson/Variant/VariantCompare.hpp b/src/ArduinoJson/Variant/VariantCompare.hpp index 067be7fc..4a5f1f3a 100644 --- a/src/ArduinoJson/Variant/VariantCompare.hpp +++ b/src/ArduinoJson/Variant/VariantCompare.hpp @@ -25,7 +25,7 @@ struct Comparer::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::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 @@ -51,27 +53,31 @@ struct Comparer::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(lhs)); + CompareResult visit(bool lhs) { + return visit(static_cast(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 comparer(lhs); return reverseResult(comparer); } - CompareResult visitString(JsonString lhs) { + CompareResult visit(JsonString lhs) { Comparer 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 comparer(lhs); return reverseResult(comparer); } - CompareResult visitUnsignedInteger(JsonUInt lhs) { + CompareResult visit(JsonUInt lhs) { Comparer comparer(lhs); return reverseResult(comparer); } - CompareResult visitBoolean(bool lhs) { + CompareResult visit(bool lhs) { Comparer comparer(lhs); return reverseResult(comparer); } - CompareResult visitNull(nullptr_t) { + CompareResult visit(nullptr_t) { NullComparer comparer; return reverseResult(comparer); } diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index 8d4f4c15..baa2435b 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -25,50 +25,50 @@ class VariantData { VariantData() : flags_(VALUE_IS_NULL) {} template - 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 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) { diff --git a/src/ArduinoJson/Variant/VariantDataVisitor.hpp b/src/ArduinoJson/Variant/VariantDataVisitor.hpp index b14dd88f..3e5b7fb9 100644 --- a/src/ArduinoJson/Variant/VariantDataVisitor.hpp +++ b/src/ArduinoJson/Variant/VariantDataVisitor.hpp @@ -15,39 +15,8 @@ template 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 + TResult visit(const T&) { return TResult(); } };