diff --git a/src/ArduinoJson/Variant/JsonVariantVisitor.hpp b/src/ArduinoJson/Variant/JsonVariantVisitor.hpp new file mode 100644 index 00000000..bf7b38fc --- /dev/null +++ b/src/ArduinoJson/Variant/JsonVariantVisitor.hpp @@ -0,0 +1,115 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2023, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include +#include +#include + +ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE + +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() { + return TResult(); + } + + TResult visitObject(JsonObjectConst) { + return TResult(); + } + + TResult visitUnsignedInteger(JsonUInt) { + return TResult(); + } + + TResult visitRawString(const char*, size_t) { + return TResult(); + } + + TResult visitString(const char*, size_t) { + return TResult(); + } +}; + +template +class VisitorAdapter { + public: + using result_type = typename TVisitor::result_type; + + VisitorAdapter(TVisitor& visitor, const ResourceManager* resources) + : visitor_(&visitor), resources_(resources) {} + + result_type visitArray(const ArrayData& array) { + return visitor_->visitArray(JsonArrayConst(&array, resources_)); + } + + result_type visitObject(const ObjectData& object) { + return visitor_->visitObject(JsonObjectConst(&object, resources_)); + } + + result_type visitFloat(JsonFloat value) { + return visitor_->visitFloat(value); + } + + result_type visitString(const char* s, size_t n) { + return visitor_->visitString(s, n); + } + + result_type visitRawString(const char* p, size_t n) { + return visitor_->visitRawString(p, n); + } + + 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() { + return visitor_->visitNull(); + } + + private: + TVisitor* visitor_; + const ResourceManager* resources_; +}; + +template +typename TVisitor::result_type accept(JsonVariantConst variant, + TVisitor& visitor) { + auto data = VariantAttorney::getData(variant); + if (!data) + return visitor.visitNull(); + auto resources = VariantAttorney::getResourceManager(variant); + VisitorAdapter adapter(visitor, resources); + return data->accept(adapter); +} + +ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantCompare.hpp b/src/ArduinoJson/Variant/VariantCompare.hpp index f12a9e0f..456b7748 100644 --- a/src/ArduinoJson/Variant/VariantCompare.hpp +++ b/src/ArduinoJson/Variant/VariantCompare.hpp @@ -8,11 +8,11 @@ #include #include #include -#include +#include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -struct ComparerBase : VariantDataVisitor {}; +struct ComparerBase : JsonVariantVisitor {}; template struct Comparer; @@ -79,12 +79,12 @@ struct Comparer : NullComparer { }; struct ArrayComparer : ComparerBase { - const ArrayData* rhs_; + JsonArrayConst rhs_; - explicit ArrayComparer(const ArrayData& rhs) : rhs_(&rhs) {} + explicit ArrayComparer(JsonArrayConst rhs) : rhs_(rhs) {} - CompareResult visitArray(const ArrayData& lhs) { - if (JsonArrayConst(&lhs, nullptr) == JsonArrayConst(rhs_, nullptr)) + CompareResult visitArray(JsonArrayConst lhs) { + if (rhs_ == lhs) return COMPARE_RESULT_EQUAL; else return COMPARE_RESULT_DIFFER; @@ -92,12 +92,12 @@ struct ArrayComparer : ComparerBase { }; struct ObjectComparer : ComparerBase { - const ObjectData* rhs_; + JsonObjectConst rhs_; - explicit ObjectComparer(const ObjectData& rhs) : rhs_(&rhs) {} + explicit ObjectComparer(JsonObjectConst rhs) : rhs_(rhs) {} - CompareResult visitObject(const ObjectData& lhs) { - if (JsonObjectConst(&lhs, nullptr) == JsonObjectConst(rhs_, nullptr)) + CompareResult visitObject(JsonObjectConst lhs) { + if (lhs == rhs_) return COMPARE_RESULT_EQUAL; else return COMPARE_RESULT_DIFFER; @@ -124,59 +124,59 @@ struct RawComparer : ComparerBase { }; struct VariantComparer : ComparerBase { - const VariantData* rhs; + JsonVariantConst rhs; - explicit VariantComparer(const VariantData* value) : rhs(value) {} + explicit VariantComparer(JsonVariantConst value) : rhs(value) {} - CompareResult visitArray(const ArrayData& lhs) { + CompareResult visitArray(JsonArrayConst lhs) { ArrayComparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } - CompareResult visitObject(const ObjectData& lhs) { + CompareResult visitObject(JsonObjectConst lhs) { ObjectComparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitFloat(JsonFloat lhs) { Comparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitString(const char* lhs, size_t) { Comparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitRawString(const char* lhsData, size_t lhsSize) { RawComparer comparer(lhsData, lhsSize); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitSignedInteger(JsonInteger lhs) { Comparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitUnsignedInteger(JsonUInt lhs) { Comparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitBoolean(bool lhs) { Comparer comparer(lhs); - return accept(comparer); + return reverseResult(comparer); } CompareResult visitNull() { NullComparer comparer; - return accept(comparer); + return reverseResult(comparer); } private: template - CompareResult accept(TComparer& comparer) { - CompareResult reversedResult = VariantData::accept(rhs, comparer); + CompareResult reverseResult(TComparer& comparer) { + CompareResult reversedResult = accept(rhs, comparer); switch (reversedResult) { case COMPARE_RESULT_GREATER: return COMPARE_RESULT_LESS; @@ -193,18 +193,13 @@ struct Comparer::value>::type> : VariantComparer { explicit Comparer(const T& value) - : VariantComparer(VariantAttorney::getData(value)) {} + : VariantComparer(static_cast(value)) {} }; template CompareResult compare(ArduinoJson::JsonVariantConst lhs, const T& rhs) { Comparer comparer(rhs); - return VariantData::accept(VariantAttorney::getData(lhs), comparer); -} - -inline CompareResult compare(const VariantData* lhs, const VariantData* rhs) { - VariantComparer comparer(rhs); - return VariantData::accept(lhs, comparer); + return accept(lhs, comparer); } ARDUINOJSON_END_PRIVATE_NAMESPACE