Added comparisons between JsonVariants

This commit is contained in:
Benoit Blanchon
2020-07-02 15:28:34 +02:00
parent 0e794a28a1
commit 7e58347fbe
19 changed files with 808 additions and 666 deletions

View File

@@ -0,0 +1,121 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2020
// MIT License
#pragma once
#include <ArduinoJson/Numbers/Integer.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
namespace ARDUINOJSON_NAMESPACE {
enum CompareResult {
COMPARE_RESULT_DIFFER = 0,
COMPARE_RESULT_EQUAL = 1,
COMPARE_RESULT_GREATER = 2,
COMPARE_RESULT_LESS = 4,
COMPARE_RESULT_GREATER_OR_EQUAL = 3,
COMPARE_RESULT_LESS_OR_EQUAL = 5
};
template <typename T>
CompareResult arithmeticCompare(const T &lhs, const T &rhs) {
if (lhs < rhs)
return COMPARE_RESULT_LESS;
else if (lhs > rhs)
return COMPARE_RESULT_GREATER;
else
return COMPARE_RESULT_EQUAL;
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
sizeof(T1) < sizeof(T2),
int // Using int instead of void to avoid C2572 on
// Visual Studio 2012, 2013, and 2015
>::type * = 0) {
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
sizeof(T2) < sizeof(T1)>::type * = 0) {
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
is_signed<T1>::value == is_signed<T2>::value &&
sizeof(T2) == sizeof(T1)>::type * = 0) {
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
is_unsigned<T1>::value && is_signed<T2>::value &&
sizeof(T2) == sizeof(T1)>::type * = 0) {
if (rhs < 0)
return COMPARE_RESULT_GREATER;
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
is_signed<T1>::value && is_unsigned<T2>::value &&
sizeof(T2) == sizeof(T1)>::type * = 0) {
if (lhs < 0)
return COMPARE_RESULT_LESS;
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
}
template <typename T1, typename T2>
CompareResult arithmeticCompare(
const T1 &lhs, const T2 &rhs,
typename enable_if<is_floating_point<T1>::value ||
is_floating_point<T2>::value>::type * = 0) {
return arithmeticCompare<double>(static_cast<double>(lhs),
static_cast<double>(rhs));
}
template <typename T2>
CompareResult arithmeticCompareNegateLeft(
UInt, const T2 &, typename enable_if<is_unsigned<T2>::value>::type * = 0) {
return COMPARE_RESULT_LESS;
}
template <typename T2>
CompareResult arithmeticCompareNegateLeft(
UInt lhs, const T2 &rhs,
typename enable_if<is_signed<T2>::value>::type * = 0) {
if (rhs > 0)
return COMPARE_RESULT_LESS;
return arithmeticCompare(-rhs, static_cast<T2>(lhs));
}
template <typename T1>
CompareResult arithmeticCompareNegateRight(
const T1 &, UInt, typename enable_if<is_unsigned<T1>::value>::type * = 0) {
return COMPARE_RESULT_GREATER;
}
template <typename T1>
CompareResult arithmeticCompareNegateRight(
const T1 &lhs, UInt rhs,
typename enable_if<is_signed<T1>::value>::type * = 0) {
if (lhs > 0)
return COMPARE_RESULT_GREATER;
return arithmeticCompare(static_cast<T1>(rhs), -lhs);
}
} // namespace ARDUINOJSON_NAMESPACE