mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-18 21:12:25 +02:00
Simplified implementation of comparison operators
This commit is contained in:
@ -28,6 +28,7 @@
|
|||||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
||||||
|
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Operators/VariantOperators.hpp>
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -17,6 +18,7 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||||
|
public VariantShortcuts<ElementProxy<TArray> >,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef ElementProxy<TArray> this_type;
|
typedef ElementProxy<TArray> this_type;
|
||||||
|
|
||||||
@ -77,6 +79,11 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
|||||||
return getUpstreamElement();
|
return getUpstreamElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCE_INLINE int compare(const T& rhs) const {
|
||||||
|
return getUpstreamElement().template compare<T>(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool is() const {
|
FORCE_INLINE bool is() const {
|
||||||
return getUpstreamElement().template is<T>();
|
return getUpstreamElement().template is<T>();
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Operators/VariantOperators.hpp>
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -19,6 +20,7 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
|
|
||||||
template <typename TObject, typename TStringRef>
|
template <typename TObject, typename TStringRef>
|
||||||
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||||
|
public VariantShortcuts<MemberProxy<TObject, TStringRef> >,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef MemberProxy<TObject, TStringRef> this_type;
|
typedef MemberProxy<TObject, TStringRef> this_type;
|
||||||
|
|
||||||
@ -80,6 +82,11 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
|||||||
return getUpstreamMember();
|
return getUpstreamMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCE_INLINE int compare(const T &rhs) const {
|
||||||
|
return getUpstreamMember().template compare<T>(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool is() const {
|
FORCE_INLINE bool is() const {
|
||||||
return getUpstreamMember().template is<TValue>();
|
return getUpstreamMember().template is<TValue>();
|
||||||
|
@ -1,255 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
|
||||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
|
||||||
#include <ArduinoJson/Numbers/Float.hpp>
|
|
||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
class CollectionData;
|
|
||||||
|
|
||||||
template <typename T, typename Enable = void>
|
|
||||||
struct Comparer;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Comparer<T, typename enable_if<IsString<T>::value>::type> {
|
|
||||||
T rhs;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
explicit Comparer(T value) : rhs(value), result(1) {}
|
|
||||||
|
|
||||||
void visitArray(const CollectionData &) {}
|
|
||||||
void visitObject(const CollectionData &) {}
|
|
||||||
void visitFloat(Float) {}
|
|
||||||
void visitString(const char *lhs) {
|
|
||||||
result = -adaptString(rhs).compare(lhs);
|
|
||||||
}
|
|
||||||
void visitRawJson(const char *, size_t) {}
|
|
||||||
void visitNegativeInteger(UInt) {}
|
|
||||||
void visitPositiveInteger(UInt) {}
|
|
||||||
void visitBoolean(bool) {}
|
|
||||||
void visitNull() {
|
|
||||||
result = adaptString(rhs).compare(NULL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if<is_signed<T>::value, int>::type sign(const T &value) {
|
|
||||||
return value < 0 ? -1 : value > 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if<is_unsigned<T>::value, int>::type sign(const T &value) {
|
|
||||||
return value > 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Comparer<T, typename enable_if<is_integral<T>::value ||
|
|
||||||
is_floating_point<T>::value>::type> {
|
|
||||||
T rhs;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
explicit Comparer(T value) : rhs(value), result(1) {}
|
|
||||||
|
|
||||||
void visitArray(const CollectionData &) {}
|
|
||||||
void visitObject(const CollectionData &) {}
|
|
||||||
void visitFloat(Float lhs) {
|
|
||||||
result = sign(lhs - static_cast<Float>(rhs));
|
|
||||||
}
|
|
||||||
void visitString(const char *) {}
|
|
||||||
void visitRawJson(const char *, size_t) {}
|
|
||||||
void visitNegativeInteger(UInt lhs) {
|
|
||||||
result = -sign(static_cast<T>(lhs) + rhs);
|
|
||||||
}
|
|
||||||
void visitPositiveInteger(UInt lhs) {
|
|
||||||
result = static_cast<T>(lhs) < rhs ? -1 : static_cast<T>(lhs) > rhs ? 1 : 0;
|
|
||||||
}
|
|
||||||
void visitBoolean(bool) {}
|
|
||||||
void visitNull() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct Comparer<bool, void> {
|
|
||||||
bool rhs;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
explicit Comparer(bool value) : rhs(value), result(1) {}
|
|
||||||
|
|
||||||
void visitArray(const CollectionData &) {}
|
|
||||||
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 lhs) {
|
|
||||||
result = static_cast<int>(lhs - rhs);
|
|
||||||
}
|
|
||||||
void visitNull() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_NULLPTR
|
|
||||||
template <>
|
|
||||||
struct Comparer<decltype(nullptr), void> {
|
|
||||||
int result;
|
|
||||||
|
|
||||||
explicit Comparer(decltype(nullptr)) : result(1) {}
|
|
||||||
|
|
||||||
void visitArray(const CollectionData &) {}
|
|
||||||
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() {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename TVariant>
|
|
||||||
class VariantComparisons {
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
static int compare(TVariant lhs, const T &rhs) {
|
|
||||||
Comparer<T> comparer(rhs);
|
|
||||||
lhs.accept(comparer);
|
|
||||||
return comparer.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// value == TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator==(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) == 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
|
||||||
const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant == value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator==(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) == 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
|
||||||
TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value != TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator!=(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) != 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
|
||||||
const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant != value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator!=(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) != 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
|
||||||
TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value < TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) > 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<(const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant < value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) < 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<(TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value <= TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<=(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) >= 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<=(const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant <= value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<=(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) <= 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator<=(TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value > TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) < 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>(const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant > value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) > 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>(TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value >= TVariant
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>=(T *lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) <= 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>=(const T &lhs, TVariant rhs) {
|
|
||||||
return compare(rhs, lhs) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TVariant >= value
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>=(TVariant lhs, T *rhs) {
|
|
||||||
return compare(lhs, rhs) >= 0;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
friend bool operator>=(TVariant lhs, const T &rhs) {
|
|
||||||
return compare(lhs, rhs) >= 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
@ -1,17 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Operators/VariantComparisons.hpp>
|
|
||||||
#include <ArduinoJson/Operators/VariantOr.hpp>
|
|
||||||
#include <ArduinoJson/Operators/VariantShortcuts.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
template <typename TImpl>
|
|
||||||
class VariantOperators : public VariantComparisons<TImpl>,
|
|
||||||
public VariantOr<TImpl>,
|
|
||||||
public VariantShortcuts<TImpl> {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
@ -1,37 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantAs.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
template <typename TImpl>
|
|
||||||
class VariantOr {
|
|
||||||
public:
|
|
||||||
// Returns the default value if the VariantRef is undefined of incompatible
|
|
||||||
template <typename T>
|
|
||||||
T operator|(const T &defaultValue) const {
|
|
||||||
if (impl()->template is<T>())
|
|
||||||
return impl()->template as<T>();
|
|
||||||
else
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the default value if the VariantRef is undefined of incompatible
|
|
||||||
// Special case for string: null is treated as undefined
|
|
||||||
const char *operator|(const char *defaultValue) const {
|
|
||||||
const char *value = impl()->template as<const char *>();
|
|
||||||
return value ? value : defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const TImpl *impl() const {
|
|
||||||
return static_cast<const TImpl *>(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
129
src/ArduinoJson/Variant/VariantCompare.hpp
Normal file
129
src/ArduinoJson/Variant/VariantCompare.hpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
|
#include <ArduinoJson/Numbers/Float.hpp>
|
||||||
|
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Strings/IsString.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
class CollectionData;
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct Comparer;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Comparer<T, typename enable_if<IsString<T>::value>::type> {
|
||||||
|
T rhs;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
explicit Comparer(T value) : rhs(value), result(1) {}
|
||||||
|
|
||||||
|
void visitArray(const CollectionData &) {}
|
||||||
|
void visitObject(const CollectionData &) {}
|
||||||
|
void visitFloat(Float) {}
|
||||||
|
void visitString(const char *lhs) {
|
||||||
|
result = -adaptString(rhs).compare(lhs);
|
||||||
|
}
|
||||||
|
void visitRawJson(const char *, size_t) {}
|
||||||
|
void visitNegativeInteger(UInt) {}
|
||||||
|
void visitPositiveInteger(UInt) {}
|
||||||
|
void visitBoolean(bool) {}
|
||||||
|
void visitNull() {
|
||||||
|
result = adaptString(rhs).compare(NULL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
typename enable_if<is_signed<T>::value, int>::type sign2(const T &value) {
|
||||||
|
return value < 0 ? -1 : value > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename enable_if<is_unsigned<T>::value, int>::type sign2(const T &value) {
|
||||||
|
return value > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Comparer<T, typename enable_if<is_integral<T>::value ||
|
||||||
|
is_floating_point<T>::value>::type> {
|
||||||
|
T rhs;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
explicit Comparer(T value) : rhs(value), result(1) {}
|
||||||
|
|
||||||
|
void visitArray(const CollectionData &) {}
|
||||||
|
void visitObject(const CollectionData &) {}
|
||||||
|
void visitFloat(Float lhs) {
|
||||||
|
result = sign2(lhs - static_cast<Float>(rhs));
|
||||||
|
}
|
||||||
|
void visitString(const char *) {}
|
||||||
|
void visitRawJson(const char *, size_t) {}
|
||||||
|
void visitNegativeInteger(UInt lhs) {
|
||||||
|
result = -sign2(static_cast<T>(lhs) + rhs);
|
||||||
|
}
|
||||||
|
void visitPositiveInteger(UInt lhs) {
|
||||||
|
result = static_cast<T>(lhs) < rhs ? -1 : static_cast<T>(lhs) > rhs ? 1 : 0;
|
||||||
|
}
|
||||||
|
void visitBoolean(bool) {}
|
||||||
|
void visitNull() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Comparer<bool, void> {
|
||||||
|
bool rhs;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
explicit Comparer(bool value) : rhs(value), result(1) {}
|
||||||
|
|
||||||
|
void visitArray(const CollectionData &) {}
|
||||||
|
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 lhs) {
|
||||||
|
result = static_cast<int>(lhs - rhs);
|
||||||
|
}
|
||||||
|
void visitNull() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ARDUINOJSON_HAS_NULLPTR
|
||||||
|
template <>
|
||||||
|
struct Comparer<decltype(nullptr), void> {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
explicit Comparer(decltype(nullptr)) : result(1) {}
|
||||||
|
|
||||||
|
void visitArray(const CollectionData &) {}
|
||||||
|
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() {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename TData>
|
||||||
|
template <typename T>
|
||||||
|
int VariantRefBase<TData>::compare(const T &rhs) const {
|
||||||
|
Comparer<T> comparer(rhs);
|
||||||
|
if (_data)
|
||||||
|
_data->accept(comparer);
|
||||||
|
else
|
||||||
|
comparer.visitNull();
|
||||||
|
return comparer.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
157
src/ArduinoJson/Variant/VariantOperators.hpp
Normal file
157
src/ArduinoJson/Variant/VariantOperators.hpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantAs.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TVariant>
|
||||||
|
struct VariantOperators {
|
||||||
|
// Returns the default value if the VariantRef is undefined of incompatible
|
||||||
|
template <typename T>
|
||||||
|
friend T operator|(const TVariant &variant, const T &defaultValue) {
|
||||||
|
if (variant.template is<T>())
|
||||||
|
return variant.template as<T>();
|
||||||
|
else
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the default value if the VariantRef is undefined of incompatible
|
||||||
|
// Special case for string: null is treated as undefined
|
||||||
|
friend const char *operator|(const TVariant &variant,
|
||||||
|
const char *defaultValue) {
|
||||||
|
const char *value = variant.template as<const char *>();
|
||||||
|
return value ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value == TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator==(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) == 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
||||||
|
const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant == value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator==(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) == 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
||||||
|
TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value != TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator!=(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) != 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
||||||
|
const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant != value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator!=(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) != 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
||||||
|
TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value < TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) > 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<(const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant < value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) < 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<(TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value <= TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<=(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) >= 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<=(const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant <= value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<=(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) <= 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator<=(TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value > TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) < 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>(const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant > value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) > 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>(TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value >= TVariant
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>=(T *lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) <= 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>=(const T &lhs, TVariant rhs) {
|
||||||
|
return rhs.compare(lhs) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TVariant >= value
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>=(TVariant lhs, T *rhs) {
|
||||||
|
return lhs.compare(rhs) >= 0;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
friend bool operator>=(TVariant lhs, const T &rhs) {
|
||||||
|
return lhs.compare(rhs) >= 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
#include <ArduinoJson/Operators/VariantOperators.hpp>
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantAs.hpp>
|
#include <ArduinoJson/Variant/VariantAs.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
@ -107,6 +108,9 @@ class VariantRefBase {
|
|||||||
return variantIsInteger<int>(_data);
|
return variantIsInteger<int>(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int compare(const T &) const; // VariantCompare.cpp
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return variantIsNull(_data);
|
return variantIsNull(_data);
|
||||||
}
|
}
|
||||||
@ -141,6 +145,7 @@ class VariantRefBase {
|
|||||||
// - a reference to a ArrayRef or ObjectRef
|
// - a reference to a ArrayRef or ObjectRef
|
||||||
class VariantRef : public VariantRefBase<VariantData>,
|
class VariantRef : public VariantRefBase<VariantData>,
|
||||||
public VariantOperators<VariantRef>,
|
public VariantOperators<VariantRef>,
|
||||||
|
public VariantShortcuts<VariantRef>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef VariantRefBase<VariantData> base_type;
|
typedef VariantRefBase<VariantData> base_type;
|
||||||
friend class VariantConstRef;
|
friend class VariantConstRef;
|
||||||
@ -336,6 +341,7 @@ class VariantRef : public VariantRefBase<VariantData>,
|
|||||||
|
|
||||||
class VariantConstRef : public VariantRefBase<const VariantData>,
|
class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||||
public VariantOperators<VariantConstRef>,
|
public VariantOperators<VariantConstRef>,
|
||||||
|
public VariantShortcuts<VariantConstRef>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef VariantRefBase<const VariantData> base_type;
|
typedef VariantRefBase<const VariantData> base_type;
|
||||||
friend class VariantRef;
|
friend class VariantRef;
|
||||||
|
Reference in New Issue
Block a user