diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 57fdae322e0..48e8aed5f5b 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -51,6 +51,8 @@ Q_DECL_UNUSED static constexpr quint64 MaximumPreallocatedElementCount = \brief The QCborValue class encapsulates a value in CBOR. + \compares strong + This class can be used to hold one of the many types available in CBOR. CBOR is the Concise Binary Object Representation, a very compact form of binary data encoding that is a superset of JSON. It was created by the IETF @@ -1239,9 +1241,9 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv } /*! - \fn bool QCborValue::operator==(const QCborValue &other) const + \fn bool QCborValue::operator==(const QCborValue &lhs, const QCborValue &rhs) - Compares this value and \a other, and returns true if they hold the same + Compares \a lhs and \a rhs, and returns true if they hold the same contents, false otherwise. If each QCborValue contains an array or map, the comparison is recursive to elements contained in them. @@ -1252,9 +1254,9 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv */ /*! - \fn bool QCborValue::operator!=(const QCborValue &other) const + \fn bool QCborValue::operator!=(const QCborValue &lhs, const QCborValue &rhs) - Compares this value and \a other, and returns true if contents differ, + Compares \a lhs and \a rhs, and returns true if contents differ, false otherwise. If each QCborValue contains an array or map, the comparison is recursive to elements contained in them. @@ -1263,12 +1265,17 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv \sa compare(), QCborValue::operator==(), QCborMap::operator==(), operator==(), operator<() */ +bool comparesEqual(const QCborValue &lhs, + const QCborValue &rhs) noexcept +{ + return lhs.compare(rhs) == 0; +} /*! - \fn bool QCborValue::operator<(const QCborValue &other) const + \fn bool QCborValue::operator<(const QCborValue &lhs, const QCborValue &rhs) - Compares this value and \a other, and returns true if this value should be - sorted before \a other, false otherwise. If each QCborValue contains an + Compares \a lhs and \a rhs, and returns true if \a lhs should be + sorted before \a rhs, false otherwise. If each QCborValue contains an array or map, the comparison is recursive to elements contained in them. For more information on CBOR sorting order, see QCborValue::compare(). @@ -1277,6 +1284,47 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv operator==(), operator!=() */ +/*! + \fn bool QCborValue::operator<=(const QCborValue &lhs, const QCborValue &rhs) + + Compares \a lhs and \a rhs, and returns true if \a lhs should be + sorted before \a rhs or is being equal to \a rhs, false otherwise. + If each QCborValue contains an array or map, the comparison is recursive + to elements contained in them. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator<(), QCborMap::operator==(), + operator==(), operator!=() +*/ + +/*! + \fn bool QCborValue::operator>(const QCborValue &lhs, const QCborValue &rhs) + + Compares \a lhs and \a rhs, and returns true if \a lhs should be + sorted after \a rhs, false otherwise. If each QCborValue contains an + array or map, the comparison is recursive to elements contained in them. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator>=(), QCborMap::operator==(), + operator==(), operator!=() +*/ + +/*! + \fn bool QCborValue::operator>=(const QCborValue &lhs, const QCborValue &rhs) + + Compares \a lhs and \a rhs, and returns true if \a lhs should be + sorted after \a rhs or is being equal to \a rhs, false otherwise. + If each QCborValue contains an array or map, the comparison is recursive + to elements contained in them. + + For more information on CBOR sorting order, see QCborValue::compare(). + + \sa compare(), QCborValue::operator>(), QCborMap::operator==(), + operator==(), operator!=() +*/ + /*! Compares this value and \a other, and returns an integer that indicates whether this value should be sorted prior to (if the result is negative) or diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index aeac764780e..03861bf527e 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -5,8 +5,9 @@ #define QCBORVALUE_H #include -#include #include +#include +#include #if QT_CONFIG(regularexpression) # include #endif @@ -22,10 +23,6 @@ # undef False #endif -#if 0 && __has_include() -# include -#endif - QT_BEGIN_NAMESPACE class QCborArray; @@ -222,15 +219,7 @@ public: QCborValueRef operator[](const QString & key); int compare(const QCborValue &other) const; -#if 0 && __has_include() - std::strong_ordering operator<=>(const QCborValue &other) const - { - int c = compare(other); - if (c > 0) return std::partial_ordering::greater; - if (c == 0) return std::partial_ordering::equivalent; - return std::partial_ordering::less; - } -#else +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const QCborValue &other) const noexcept { return compare(other) == 0; } bool operator!=(const QCborValue &other) const noexcept @@ -260,6 +249,16 @@ public: QString toDiagnosticNotation(DiagnosticNotationOptions opts = Compact) const; private: + friend Q_CORE_EXPORT bool comparesEqual(const QCborValue &lhs, + const QCborValue &rhs) noexcept; + friend Qt::strong_ordering compareThreeWay(const QCborValue &lhs, + const QCborValue &rhs) noexcept + { + int c = lhs.compare(rhs); + return Qt::compareThreeWay(c, 0); + } + + Q_DECLARE_STRONGLY_ORDERED(QCborValue) friend class QCborValueRef; friend class QCborContainerPrivate; friend class QJsonPrivate::Value; diff --git a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt index 2c2344ca5df..4b723964899 100644 --- a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt +++ b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt @@ -19,4 +19,5 @@ qt_internal_add_test(tst_qcborvalue ../../../../../src/3rdparty/tinycbor/tests/parser LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index a686ca0f2e9..7a49f015382 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -26,6 +27,7 @@ private slots: void tagged(); void extendedTypes_data(); void extendedTypes(); + void compareCompiles() { QTestPrivate::testAllComparisonOperatorsCompile(); } void copyCompare_data() { basics_data(); } void copyCompare(); @@ -477,6 +479,7 @@ QT_WARNING_DISABLE_GCC("-Wself-move") // self-moving v = std::move(v); QCOMPARE(v, other); // make sure it's still valid + QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal); QT_WARNING_POP // moving @@ -488,24 +491,15 @@ QT_WARNING_POP other = v; v = other; - QCOMPARE(v.compare(other), 0); - QCOMPARE(v, other); - QVERIFY(!(v != other)); - QVERIFY(!(v < other)); -#if 0 && __has_include() - QVERIFY(v <= other); - QVERIFY(v >= other); - QVERIFY(!(v > other)); -#endif + QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal); if (v.isUndefined()) other = nullptr; else other = {}; QVERIFY(v.type() != other.type()); - QVERIFY(!(v == other)); - QVERIFY(v != other); + QT_TEST_EQUALITY_OPS(v, other, false); // they're different types, so they can't compare equal QVERIFY(v.compare(other) != 0); @@ -1815,64 +1809,59 @@ void tst_QCborValue::sorting() QCborValue vdouble1(1.5), vdouble2(qInf()); QCborValue vndouble1(-1.5), vndouble2(-qInf()); -#define CHECK_ORDER(v1, v2) \ - QVERIFY(v1 < v2); \ - QVERIFY(!(v2 < v2)) - // intra-type comparisons - CHECK_ORDER(vfalse, vtrue); - CHECK_ORDER(vsimple1, vsimple32); - CHECK_ORDER(vsimple32, vsimple255); - CHECK_ORDER(vint1, vint2); - CHECK_ORDER(vdouble1, vdouble2); - CHECK_ORDER(vndouble1, vndouble2); + QT_TEST_ALL_COMPARISON_OPS(vfalse, vtrue, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vsimple1, vsimple32, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vsimple32, vsimple255, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vint1, vint2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vdouble1, vdouble2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vndouble1, vndouble2, Qt::strong_ordering::less); // note: shorter length sorts first - CHECK_ORDER(vba1, vba2); - CHECK_ORDER(vba2, vba3); - CHECK_ORDER(vs1, vs2); - CHECK_ORDER(vs2, vs3); - CHECK_ORDER(va1, va2); - CHECK_ORDER(va2, va3); - CHECK_ORDER(vm1, vm2); - CHECK_ORDER(vm2, vm3); - CHECK_ORDER(vdt1, vdt2); - CHECK_ORDER(vtagged1, vtagged2); - CHECK_ORDER(vtagged2, vtagged3); - CHECK_ORDER(vtagged3, vtagged4); - CHECK_ORDER(vtagged4, vtagged5); - CHECK_ORDER(vurl1, vurl2); - CHECK_ORDER(vuuid1, vuuid2); + QT_TEST_ALL_COMPARISON_OPS(vba1, vba2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vba2, vba3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vs1, vs2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vs2, vs3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(va1, va2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(va2, va3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vm1, vm2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vm2, vm3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vdt1, vdt2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged1, vtagged2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged2, vtagged3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged3, vtagged4, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged4, vtagged5, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vurl1, vurl2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vuuid1, vuuid2, Qt::strong_ordering::less); // surprise 1: CBOR sorts integrals by absolute value - CHECK_ORDER(vneg1, vneg2); + QT_TEST_ALL_COMPARISON_OPS(vneg1, vneg2, Qt::strong_ordering::less); // surprise 2: CBOR sorts negatives after positives (sign+magnitude) - CHECK_ORDER(vint2, vneg1); + QT_TEST_ALL_COMPARISON_OPS(vint2, vneg1, Qt::strong_ordering::less); QVERIFY(vint2.toInteger() > vneg1.toInteger()); - CHECK_ORDER(vdouble2, vndouble1); + QT_TEST_ALL_COMPARISON_OPS(vdouble2, vndouble1, Qt::strong_ordering::less); QVERIFY(vdouble2.toDouble() > vndouble1.toDouble()); // inter-type comparisons - CHECK_ORDER(vneg2, vba1); - CHECK_ORDER(vba3, vs1); - CHECK_ORDER(vs3, va1); - CHECK_ORDER(va2, vm1); - CHECK_ORDER(vm2, vdt1); - CHECK_ORDER(vdt2, vtagged1); - CHECK_ORDER(vtagged2, vurl1); - CHECK_ORDER(vurl1, vuuid1); - CHECK_ORDER(vuuid2, vtagged3); - CHECK_ORDER(vtagged4, vsimple1); - CHECK_ORDER(vsimple1, vfalse); - CHECK_ORDER(vtrue, vnull); - CHECK_ORDER(vnull, vundef); - CHECK_ORDER(vundef, vsimple32); - CHECK_ORDER(vsimple255, vdouble1); + QT_TEST_ALL_COMPARISON_OPS(vneg2, vba1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vba3, vs1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vs3, va1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(va2, vm1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vm2, vdt1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vdt2, vtagged1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged2, vurl1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vurl1, vuuid1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vuuid2, vtagged3, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtagged4, vsimple1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vsimple1, vfalse, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vtrue, vnull, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vnull, vundef, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vundef, vsimple32, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(vsimple255, vdouble1, Qt::strong_ordering::less); // which shows all doubles sorted after integrals - CHECK_ORDER(vint2, vdouble1); + QT_TEST_ALL_COMPARISON_OPS(vint2, vdouble1, Qt::strong_ordering::less); QVERIFY(vint2.toInteger() > vdouble1.toDouble()); -#undef CHECK_ORDER } static void addCommonCborData()