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>
This commit is contained in:
Marc Mutz 2014-08-14 11:22:23 +02:00
parent 70e3935c38
commit b8e46fce5c
3 changed files with 65 additions and 0 deletions

View File

@ -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); }

View File

@ -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.
*/

View File

@ -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"