Minh Nguyen / ArduinoJson
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arithmeticCompare.hpp Source File

arithmeticCompare.hpp

00001 // ArduinoJson - arduinojson.org
00002 // Copyright Benoit Blanchon 2014-2021
00003 // MIT License
00004 
00005 #pragma once
00006 
00007 #include <ArduinoJson/Numbers/Integer.hpp>
00008 #include <ArduinoJson/Polyfills/type_traits.hpp>
00009 
00010 namespace ARDUINOJSON_NAMESPACE {
00011 
00012 enum CompareResult {
00013   COMPARE_RESULT_DIFFER = 0,
00014   COMPARE_RESULT_EQUAL = 1,
00015   COMPARE_RESULT_GREATER = 2,
00016   COMPARE_RESULT_LESS = 4,
00017 
00018   COMPARE_RESULT_GREATER_OR_EQUAL = 3,
00019   COMPARE_RESULT_LESS_OR_EQUAL = 5
00020 };
00021 
00022 template <typename T>
00023 CompareResult arithmeticCompare(const T &lhs, const T &rhs) {
00024   if (lhs < rhs)
00025     return COMPARE_RESULT_LESS;
00026   else if (lhs > rhs)
00027     return COMPARE_RESULT_GREATER;
00028   else
00029     return COMPARE_RESULT_EQUAL;
00030 }
00031 
00032 template <typename T1, typename T2>
00033 CompareResult arithmeticCompare(
00034     const T1 &lhs, const T2 &rhs,
00035     typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
00036                            sizeof(T1) < sizeof(T2),
00037                        int  // Using int instead of void to avoid C2572 on
00038                             // Visual Studio 2012, 2013, and 2015
00039                        >::type * = 0) {
00040   return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
00041 }
00042 
00043 template <typename T1, typename T2>
00044 CompareResult arithmeticCompare(
00045     const T1 &lhs, const T2 &rhs,
00046     typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
00047                        sizeof(T2) < sizeof(T1)>::type * = 0) {
00048   return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
00049 }
00050 
00051 template <typename T1, typename T2>
00052 CompareResult arithmeticCompare(
00053     const T1 &lhs, const T2 &rhs,
00054     typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
00055                        is_signed<T1>::value == is_signed<T2>::value &&
00056                        sizeof(T2) == sizeof(T1)>::type * = 0) {
00057   return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
00058 }
00059 
00060 template <typename T1, typename T2>
00061 CompareResult arithmeticCompare(
00062     const T1 &lhs, const T2 &rhs,
00063     typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
00064                        is_unsigned<T1>::value && is_signed<T2>::value &&
00065                        sizeof(T2) == sizeof(T1)>::type * = 0) {
00066   if (rhs < 0)
00067     return COMPARE_RESULT_GREATER;
00068   return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
00069 }
00070 
00071 template <typename T1, typename T2>
00072 CompareResult arithmeticCompare(
00073     const T1 &lhs, const T2 &rhs,
00074     typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
00075                        is_signed<T1>::value && is_unsigned<T2>::value &&
00076                        sizeof(T2) == sizeof(T1)>::type * = 0) {
00077   if (lhs < 0)
00078     return COMPARE_RESULT_LESS;
00079   return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
00080 }
00081 
00082 template <typename T1, typename T2>
00083 CompareResult arithmeticCompare(
00084     const T1 &lhs, const T2 &rhs,
00085     typename enable_if<is_floating_point<T1>::value ||
00086                        is_floating_point<T2>::value>::type * = 0) {
00087   return arithmeticCompare<double>(static_cast<double>(lhs),
00088                                    static_cast<double>(rhs));
00089 }
00090 
00091 template <typename T2>
00092 CompareResult arithmeticCompareNegateLeft(
00093     UInt, const T2 &, typename enable_if<is_unsigned<T2>::value>::type * = 0) {
00094   return COMPARE_RESULT_LESS;
00095 }
00096 
00097 template <typename T2>
00098 CompareResult arithmeticCompareNegateLeft(
00099     UInt lhs, const T2 &rhs,
00100     typename enable_if<is_signed<T2>::value>::type * = 0) {
00101   if (rhs > 0)
00102     return COMPARE_RESULT_LESS;
00103   return arithmeticCompare(-rhs, static_cast<T2>(lhs));
00104 }
00105 
00106 template <typename T1>
00107 CompareResult arithmeticCompareNegateRight(
00108     const T1 &, UInt, typename enable_if<is_unsigned<T1>::value>::type * = 0) {
00109   return COMPARE_RESULT_GREATER;
00110 }
00111 
00112 template <typename T1>
00113 CompareResult arithmeticCompareNegateRight(
00114     const T1 &lhs, UInt rhs,
00115     typename enable_if<is_signed<T1>::value>::type * = 0) {
00116   if (lhs > 0)
00117     return COMPARE_RESULT_GREATER;
00118   return arithmeticCompare(static_cast<T1>(rhs), -lhs);
00119 }
00120 
00121 }  // namespace ARDUINOJSON_NAMESPACE