summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2014-08-14 11:22:23 +0200
committerMarc Mutz <marc.mutz@kdab.com>2015-01-18 19:36:06 +0100
commitb8e46fce5c70c399c615e1b846076f379db173c5 (patch)
treed91cca50e2039845328e25c2ddf8188ea122d0f7
parent70e3935c38c077e35629a6651479a8a9f9e9f528 (diff)
Add qHash() overload for QSet
...using qHashRangeCommutative(). Also add a test. [ChangeLog][QtCore][QSet] Can now be used as the key in QSet, QHash. Change-Id: Ie7c81d257a3b324fc03d394fa7c9fcf0c6fb062a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qset.h9
-rw-r--r--src/corelib/tools/qset.qdoc11
-rw-r--r--tests/auto/corelib/tools/qset/tst_qset.cpp45
3 files changed, 65 insertions, 0 deletions
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 662afbf84a..baa412a550 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -237,6 +237,15 @@ private:
}
};
+template <typename T>
+uint qHash(const QSet<T> &key, uint seed = 0)
+Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRangeCommutative(key.begin(), key.end(), seed)))
+{
+ return qHashRangeCommutative(key.begin(), key.end(), seed);
+}
+
+// inline function implementations
+
template <class T>
Q_INLINE_TEMPLATE void QSet<T>::reserve(int asize) { q_hash.reserve(asize); }
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index ab7d72611e..73599a2a72 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -968,3 +968,14 @@
\sa{Serializing Qt Data Types}{Format of the QDataStream operators}
*/
+
+/*!
+ \fn uint qHash(const QSet<T> &key, uint seed = 0)
+ \relates QHash
+ \since 5.5
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+
+ The hash value is independent of the order of elements in \a key, that is, sets
+ that contain the same elements hash to the same value.
+*/
diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp
index b86ee24ac7..b8e23d3fae 100644
--- a/tests/auto/corelib/tools/qset/tst_qset.cpp
+++ b/tests/auto/corelib/tools/qset/tst_qset.cpp
@@ -72,6 +72,7 @@ private slots:
void javaMutableIterator();
void makeSureTheComfortFunctionsCompile();
void initializerList();
+ void qhash();
};
struct IdentityTracker {
@@ -968,6 +969,50 @@ void tst_QSet::initializerList()
#endif
}
+QT_BEGIN_NAMESPACE
+extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
+QT_END_NAMESPACE
+
+void tst_QSet::qhash()
+{
+ //
+ // check that sets containing the same elements hash to the same value
+ //
+ {
+ QSet<int> s1;
+ s1.reserve(4);
+ s1 << 400 << 300 << 200 << 100;
+
+ // also change the seed:
+ qt_qhash_seed = qt_qhash_seed + 0x9e3779b9;
+
+ QSet<int> s2;
+ s2.reserve(100); // provoke different bucket counts
+ s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too
+
+ QVERIFY(s1.capacity() != s2.capacity());
+ QCOMPARE(s1, s2);
+ QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different
+ QCOMPARE(qHash(s1), qHash(s2));
+ }
+
+ //
+ // check that sets of sets work:
+ //
+ {
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } };
+#else
+ QSet<QSet<int> > intSetSet;
+ QSet<int> intSet01, intSet12;
+ intSet01 << 0 << 1;
+ intSet12 << 1 << 2;
+ intSetSet << intSet01 << intSet12 << (intSet01|intSet12);
+#endif
+ QCOMPARE(intSetSet.size(), 3);
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QSet)
#include "tst_qset.moc"