From 1cfc43170331aa9488018d50ee9cb1409e4bec97 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 12 Feb 2010 19:44:11 +0100 Subject: Add operator< and qHash for QSharedPointer and fix operator-. This allows using QSharedPointer in QHash and QMap keys. Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer_impl.h | 49 ++++++++++- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 100 +++++++++++++++++++++++ 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8fbfcda..0dcea5f 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -653,6 +653,9 @@ public: T *value; }; +// +// operator== and operator!= +// template bool operator==(const QSharedPointer &ptr1, const QSharedPointer &ptr2) { @@ -674,7 +677,6 @@ bool operator==(const T *ptr1, const QSharedPointer &ptr2) { return ptr1 == ptr2.data(); } - template bool operator!=(const QSharedPointer &ptr1, const X *ptr2) { @@ -697,11 +699,54 @@ bool operator!=(const QSharedPointer &ptr1, const QWeakPointer &ptr2) return ptr2 != ptr1; } +// +// operator- +// template -Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer &ptr1, const QSharedPointer &ptr2) +Q_INLINE_TEMPLATE typename QSharedPointer::difference_type operator-(const QSharedPointer &ptr1, const QSharedPointer &ptr2) { return ptr1.data() - ptr2.data(); } +template +Q_INLINE_TEMPLATE typename QSharedPointer::difference_type operator-(const QSharedPointer &ptr1, X *ptr2) +{ + return ptr1.data() - ptr2; +} +template +Q_INLINE_TEMPLATE typename QSharedPointer::difference_type operator-(T *ptr1, const QSharedPointer &ptr2) +{ + return ptr1 - ptr2.data(); +} + +// +// operator< +// +template +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer &ptr1, const QSharedPointer &ptr2) +{ + return ptr1.data() < ptr2.data(); +} +template +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer &ptr1, X *ptr2) +{ + return ptr1.data() < ptr2; +} +template +Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer &ptr2) +{ + return ptr1 < ptr2.data(); +} + +// +// qHash +// +template inline uint qHash(const T *key); // defined in qhash.h +template +Q_INLINE_TEMPLATE uint qHash(const QSharedPointer &ptr) +{ + return QT_PREPEND_NAMESPACE(qHash)(ptr.data()); +} + template Q_INLINE_TEMPLATE QWeakPointer QSharedPointer::toWeakRef() const diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 7cfa868..07df707 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -42,6 +42,8 @@ #define QT_SHAREDPOINTER_TRACK_POINTERS #include "qsharedpointer.h" #include +#include +#include #include #include @@ -68,6 +70,7 @@ class tst_QSharedPointer: public QObject private slots: void basics_data(); void basics(); + void operators(); void swap(); void forwardDeclaration1(); void forwardDeclaration2(); @@ -94,6 +97,8 @@ private slots: void mixTrackingPointerCode(); void threadStressTest_data(); void threadStressTest(); + void map(); + void hash(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -271,6 +276,35 @@ void tst_QSharedPointer::basics() // aData is deleted here } +void tst_QSharedPointer::operators() +{ + QSharedPointer p1; + QSharedPointer p2(new char); + qptrdiff diff = p2.data() - p1.data(); + Q_ASSERT(p1.data() < p2.data()); + Q_ASSERT(diff > 0); + + // operator- + QCOMPARE(p2 - p1.data(), diff); + QCOMPARE(p2.data() - p1, diff); + QCOMPARE(p2 - p1, diff); + QCOMPARE(p1 - p2, -diff); + QCOMPARE(p1 - p1, qptrdiff(0)); + QCOMPARE(p2 - p2, qptrdiff(0)); + + // operator< + QVERIFY(p1 < p2.data()); + QVERIFY(p1.data() < p2); + QVERIFY(p1 < p2); + QVERIFY(!(p2 < p1)); + QVERIFY(!(p2 < p2)); + QVERIFY(!(p1 < p1)); + + // qHash + QCOMPARE(qHash(p1), qHash(p1.data())); + QCOMPARE(qHash(p2), qHash(p2.data())); +} + void tst_QSharedPointer::swap() { QSharedPointer p1, p2(new int(42)), control = p2; @@ -1544,6 +1578,72 @@ void tst_QSharedPointer::threadStressTest() } } +template +void hashAndMapTest() +{ + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Value; + + Container c; + QVERIFY(c.isEmpty()); + + Key k0; + c.insert(k0, Value(0)); + QVERIFY(!c.isEmpty()); + + typename Container::iterator it; + it = c.find(k0); + QVERIFY(it != c.end()); + it = c.find(Key()); + QVERIFY(it != c.end()); + it = c.find(Key(0)); + QVERIFY(it != c.end()); + + Key k1(new typename Key::value_type(42)); + it = c.find(k1); + QVERIFY(it == c.end()); + + c.insert(k1, Value(42)); + it = c.find(k1); + QVERIFY(it != c.end()); + QVERIFY(it != c.find(Key())); + + if (Ordered) { + Q_ASSERT(k0 < k1); + + it = c.begin(); + QCOMPARE(it.key(), k0); + QCOMPARE(it.value(), Value(0)); + + ++it; + QCOMPARE(it.key(), k1); + QCOMPARE(it.value(), Value(42)); + + ++it; + QVERIFY(it == c.end()); + } + + c.insertMulti(k1, Value(47)); + it = c.find(k1); + QVERIFY(it != c.end()); + QCOMPARE(it.key(), k1); + ++it; + QVERIFY(it != c.end()); + QCOMPARE(it.key(), k1); + ++it; + QVERIFY(it == c.end()); +} + +void tst_QSharedPointer::map() +{ + hashAndMapTest, int>, true>(); +} + +void tst_QSharedPointer::hash() +{ + hashAndMapTest, int>, false>(); +} + void tst_QSharedPointer::validConstructs() { { -- cgit v0.12