diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 326ae7d8a51..26a479aafbe 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -5,6 +5,7 @@ #ifndef QMAP_H #define QMAP_H +#include #include #include #include @@ -243,8 +244,10 @@ public: } #ifndef Q_QDOC - template friend - QTypeTraits::compare_eq_result_container operator==(const QMap &lhs, const QMap &rhs) +private: + template = true> + friend bool comparesEqual(const QMap &lhs, const QMap &rhs) { if (lhs.d == rhs.d) return true; @@ -253,13 +256,11 @@ public: Q_ASSERT(lhs.d); return rhs.d ? (lhs.d->m == rhs.d->m) : lhs.d->m.empty(); } - - template friend - QTypeTraits::compare_eq_result_container operator!=(const QMap &lhs, const QMap &rhs) - { - return !(lhs == rhs); - } + QT_DECLARE_EQUALITY_OPERATORS_HELPER(QMap, QMap, /* non-constexpr */, noexcept(false), + template = true>) // TODO: add the other comparison operators; std::map has them. +public: #else friend bool operator==(const QMap &lhs, const QMap &rhs); friend bool operator!=(const QMap &lhs, const QMap &rhs); @@ -914,8 +915,10 @@ public: } #ifndef Q_QDOC - template friend - QTypeTraits::compare_eq_result_container operator==(const QMultiMap &lhs, const QMultiMap &rhs) +private: + template = true> + friend bool comparesEqual(const QMultiMap &lhs, const QMultiMap &rhs) { if (lhs.d == rhs.d) return true; @@ -924,13 +927,11 @@ public: Q_ASSERT(lhs.d); return rhs.d ? (lhs.d->m == rhs.d->m) : lhs.d->m.empty(); } - - template friend - QTypeTraits::compare_eq_result_container operator!=(const QMultiMap &lhs, const QMultiMap &rhs) - { - return !(lhs == rhs); - } + QT_DECLARE_EQUALITY_OPERATORS_HELPER(QMultiMap, QMultiMap, /* non-constexpr */, noexcept(false), + template = true>) // TODO: add the other comparison operators; std::multimap has them. +public: #else friend bool operator==(const QMultiMap &lhs, const QMultiMap &rhs); friend bool operator!=(const QMultiMap &lhs, const QMultiMap &rhs); diff --git a/src/corelib/tools/qmap.qdoc b/src/corelib/tools/qmap.qdoc index 0cabf3df38c..1574fa581e4 100644 --- a/src/corelib/tools/qmap.qdoc +++ b/src/corelib/tools/qmap.qdoc @@ -6,6 +6,7 @@ \class QMap \inmodule QtCore \brief The QMap class is a template class that provides an associative array. + \compares equality \ingroup tools \ingroup shared diff --git a/src/corelib/tools/qmultimap.qdoc b/src/corelib/tools/qmultimap.qdoc index 0b05192817d..63f516bee37 100644 --- a/src/corelib/tools/qmultimap.qdoc +++ b/src/corelib/tools/qmultimap.qdoc @@ -6,6 +6,7 @@ \class QMultiMap \inmodule QtCore \brief The QMultiMap class is a template class that provides an associative array with multiple equivalent keys. + \compares equality \ingroup tools \ingroup shared diff --git a/tests/auto/corelib/tools/qmap/CMakeLists.txt b/tests/auto/corelib/tools/qmap/CMakeLists.txt index bddf9267f86..da1fb366456 100644 --- a/tests/auto/corelib/tools/qmap/CMakeLists.txt +++ b/tests/auto/corelib/tools/qmap/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qmap SOURCES tst_qmap.cpp + LIBRARIES + Qt::TestPrivate ) qt_internal_undefine_global_definition(tst_qmap QT_NO_JAVA_STYLE_ITERATORS) diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 6950dcf7056..afed1b53840 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -7,6 +7,8 @@ #include #include +#include + using namespace Qt::StringLiterals; QT_WARNING_DISABLE_DEPRECATED @@ -30,6 +32,7 @@ private slots: void swap(); + void comparisonCompiles(); void operator_eq(); void empty(); @@ -632,6 +635,16 @@ void tst_QMap::swap() sanityCheckTree(m2, __LINE__); } +void tst_QMap::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile>(); +} + void tst_QMap::operator_eq() { { @@ -642,31 +655,37 @@ void tst_QMap::operator_eq() QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); a.insert(1,1); b.insert(1,1); QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); a.insert(0,1); b.insert(0,1); QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); // compare for inequality: a.insert(42,0); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); a.insert(65, -1); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); b.insert(-1, -1); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { @@ -677,19 +696,23 @@ void tst_QMap::operator_eq() QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); a.insert("Hello", "World"); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); b.insert("Hello", "World"); QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); a.insert("Goodbye", "cruel world"); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); b.insert("Goodbye", "cruel world"); @@ -697,12 +720,14 @@ void tst_QMap::operator_eq() a.insert(QString(), QString()); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); // empty keys and null keys match: b.insert(QString(""), QString()); QVERIFY(a == b); QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { @@ -713,6 +738,77 @@ void tst_QMap::operator_eq() b.insert("willy", 1); QVERIFY(a != b); QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); + } + + // multimap + { + QMultiMap a; + QMultiMap b; + + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + a.insert(1, 1); + b.insert(1, 1); + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + a.insert(1, 2); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + b.insert(1, 2); + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + b.insert(2, 1); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + a.insert(2, 2); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + a.insert(2, 1); + b.insert(2, 2); + // The insertion order matters! + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + } + { + QMultiMap a; + QMultiMap b; + + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + a.insert("Hello", 1); + b.insert("Hello", 1); + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + a.insert("Hello", 2); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + b.insert("Hello", 2); + QCOMPARE_EQ(a, b); + QT_TEST_EQUALITY_OPS(a, b, true); + + b.insert("World", 1); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + a.insert("World", 2); + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); + + a.insert("World", 1); + b.insert("World", 2); + // The insertion order matters! + QCOMPARE_NE(a, b); + QT_TEST_EQUALITY_OPS(a, b, false); } }