Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
VariantCompare.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <ArduinoJson/Configuration.hpp> 00008 #include <ArduinoJson/Misc/Visitable.hpp> 00009 #include <ArduinoJson/Numbers/arithmeticCompare.hpp> 00010 #include <ArduinoJson/Polyfills/type_traits.hpp> 00011 #include <ArduinoJson/Strings/IsString.hpp> 00012 00013 namespace ARDUINOJSON_NAMESPACE { 00014 00015 class CollectionData; 00016 00017 struct ComparerBase : Visitor<CompareResult> { 00018 CompareResult visitArray(const CollectionData &) { 00019 return COMPARE_RESULT_DIFFER; 00020 } 00021 CompareResult visitBoolean(bool) { 00022 return COMPARE_RESULT_DIFFER; 00023 } 00024 CompareResult visitFloat(Float) { 00025 return COMPARE_RESULT_DIFFER; 00026 } 00027 CompareResult visitNegativeInteger(UInt) { 00028 return COMPARE_RESULT_DIFFER; 00029 } 00030 CompareResult visitNull() { 00031 return COMPARE_RESULT_DIFFER; 00032 } 00033 CompareResult visitObject(const CollectionData &) { 00034 return COMPARE_RESULT_DIFFER; 00035 } 00036 CompareResult visitPositiveInteger(UInt) { 00037 return COMPARE_RESULT_DIFFER; 00038 } 00039 CompareResult visitRawJson(const char *, size_t) { 00040 return COMPARE_RESULT_DIFFER; 00041 } 00042 CompareResult visitString(const char *) { 00043 return COMPARE_RESULT_DIFFER; 00044 } 00045 }; 00046 00047 template <typename T, typename Enable = void> 00048 struct Comparer; 00049 00050 template <typename T> 00051 struct Comparer<T, typename enable_if<IsString<T>::value>::type> 00052 : ComparerBase { 00053 T rhs; 00054 00055 explicit Comparer(T value) : rhs(value) {} 00056 00057 CompareResult visitString(const char *lhs) { 00058 int i = adaptString(rhs).compare(lhs); 00059 if (i < 0) 00060 return COMPARE_RESULT_GREATER; 00061 else if (i > 0) 00062 return COMPARE_RESULT_LESS; 00063 else 00064 return COMPARE_RESULT_EQUAL; 00065 } 00066 00067 CompareResult visitNull() { 00068 if (adaptString(rhs).isNull()) 00069 return COMPARE_RESULT_EQUAL; 00070 else 00071 return COMPARE_RESULT_DIFFER; 00072 } 00073 }; 00074 00075 template <typename T> 00076 struct Comparer<T, typename enable_if<is_integral<T>::value || 00077 is_floating_point<T>::value>::type> 00078 : ComparerBase { 00079 T rhs; 00080 00081 explicit Comparer(T value) : rhs(value) {} 00082 00083 CompareResult visitFloat(Float lhs) { 00084 return arithmeticCompare(lhs, rhs); 00085 } 00086 00087 CompareResult visitNegativeInteger(UInt lhs) { 00088 return arithmeticCompareNegateLeft(lhs, rhs); 00089 } 00090 00091 CompareResult visitPositiveInteger(UInt lhs) { 00092 return arithmeticCompare(lhs, rhs); 00093 } 00094 00095 CompareResult visitBoolean(bool lhs) { 00096 return visitPositiveInteger(static_cast<UInt>(lhs)); 00097 } 00098 }; 00099 00100 struct NullComparer : ComparerBase { 00101 CompareResult visitNull() { 00102 return COMPARE_RESULT_EQUAL; 00103 } 00104 }; 00105 00106 #if ARDUINOJSON_HAS_NULLPTR 00107 template <> 00108 struct Comparer<decltype(nullptr), void> : NullComparer { 00109 explicit Comparer(decltype(nullptr)) : NullComparer() {} 00110 }; 00111 #endif 00112 00113 struct ArrayComparer : ComparerBase { 00114 const CollectionData *_rhs; 00115 00116 explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {} 00117 00118 CompareResult visitArray(const CollectionData &lhs) { 00119 if (lhs.equalsArray(*_rhs)) 00120 return COMPARE_RESULT_EQUAL; 00121 else 00122 return COMPARE_RESULT_DIFFER; 00123 } 00124 }; 00125 00126 struct NegativeIntegerComparer : ComparerBase { 00127 UInt _rhs; 00128 00129 explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {} 00130 00131 CompareResult visitFloat(Float lhs) { 00132 return arithmeticCompareNegateRight(lhs, _rhs); 00133 } 00134 00135 CompareResult visitNegativeInteger(UInt lhs) { 00136 return arithmeticCompare(_rhs, lhs); 00137 } 00138 00139 CompareResult visitPositiveInteger(UInt) { 00140 return COMPARE_RESULT_GREATER; 00141 } 00142 00143 CompareResult visitBoolean(bool) { 00144 return COMPARE_RESULT_GREATER; 00145 } 00146 }; 00147 00148 struct ObjectComparer : ComparerBase { 00149 const CollectionData *_rhs; 00150 00151 explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {} 00152 00153 CompareResult visitObject(const CollectionData &lhs) { 00154 if (lhs.equalsObject(*_rhs)) 00155 return COMPARE_RESULT_EQUAL; 00156 else 00157 return COMPARE_RESULT_DIFFER; 00158 } 00159 }; 00160 00161 struct RawComparer : ComparerBase { 00162 const char *_rhsData; 00163 size_t _rhsSize; 00164 00165 explicit RawComparer(const char *rhsData, size_t rhsSize) 00166 : _rhsData(rhsData), _rhsSize(rhsSize) {} 00167 00168 CompareResult visitRawJson(const char *lhsData, size_t lhsSize) { 00169 size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize; 00170 int n = memcmp(lhsData, _rhsData, size); 00171 if (n < 0) 00172 return COMPARE_RESULT_LESS; 00173 else if (n > 0) 00174 return COMPARE_RESULT_GREATER; 00175 else 00176 return COMPARE_RESULT_EQUAL; 00177 } 00178 }; 00179 00180 template <typename T> 00181 struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type> 00182 : ComparerBase { 00183 T rhs; 00184 00185 explicit Comparer(T value) : rhs(value) {} 00186 00187 CompareResult visitArray(const CollectionData &lhs) { 00188 ArrayComparer comparer(lhs); 00189 return accept(comparer); 00190 } 00191 00192 CompareResult visitObject(const CollectionData &lhs) { 00193 ObjectComparer comparer(lhs); 00194 return accept(comparer); 00195 } 00196 00197 CompareResult visitFloat(Float lhs) { 00198 Comparer<Float> comparer(lhs); 00199 return accept(comparer); 00200 } 00201 00202 CompareResult visitString(const char *lhs) { 00203 Comparer<const char *> comparer(lhs); 00204 return accept(comparer); 00205 } 00206 00207 CompareResult visitRawJson(const char *lhsData, size_t lhsSize) { 00208 RawComparer comparer(lhsData, lhsSize); 00209 return accept(comparer); 00210 } 00211 00212 CompareResult visitNegativeInteger(UInt lhs) { 00213 NegativeIntegerComparer comparer(lhs); 00214 return accept(comparer); 00215 } 00216 00217 CompareResult visitPositiveInteger(UInt lhs) { 00218 Comparer<UInt> comparer(lhs); 00219 return accept(comparer); 00220 } 00221 00222 CompareResult visitBoolean(bool lhs) { 00223 Comparer<bool> comparer(lhs); 00224 return accept(comparer); 00225 } 00226 00227 CompareResult visitNull() { 00228 NullComparer comparer; 00229 return accept(comparer); 00230 } 00231 00232 private: 00233 template <typename TComparer> 00234 CompareResult accept(TComparer &comparer) { 00235 CompareResult reversedResult = rhs.accept(comparer); 00236 switch (reversedResult) { 00237 case COMPARE_RESULT_GREATER: 00238 return COMPARE_RESULT_LESS; 00239 case COMPARE_RESULT_LESS: 00240 return COMPARE_RESULT_GREATER; 00241 default: 00242 return reversedResult; 00243 } 00244 } 00245 }; 00246 00247 template <typename T1, typename T2> 00248 CompareResult compare(const T1 &lhs, const T2 &rhs) { 00249 Comparer<T2> comparer(rhs); 00250 return lhs.accept(comparer); 00251 } 00252 00253 inline int variantCompare(const VariantData *a, const VariantData *b) { 00254 return compare(VariantConstRef(a), VariantConstRef(b)); 00255 } 00256 00257 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:37 by
1.7.2