diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2015-04-08 19:44:48 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2015-05-05 13:59:31 +0000 |
commit | 87155a8d651c94872207cf2a1b85a92d5c509073 (patch) | |
tree | 7bcc73a2d0236220bdd3d5cda2d25d7415d0eed9 | |
parent | 85d9403a129100c00ef096baa01c3c024d0f705a (diff) |
Add qHash(QRegExp) and qHash(QRegularExpression)
QReg*Exp*s can be compared for equality,
so qHash should be overloaded, too.
There was a (poor) private implementation of qHash(QRegExpEngineKey)
already, which has now been replaced with a better one (the old one
didn't take into account all the fields that make up equality,
producing unnecessary collisions).
[ChangeLog][QtCore][QRegExp] Added qHash(QRegExp).
[ChangeLog][QtCore][QRegularExpression] Added qHash(QRegularExpression).
Change-Id: I1d22fbcc0508018a3f94b4c24571b13ba6e07df2
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-rw-r--r-- | src/corelib/tools/qregexp.cpp | 30 | ||||
-rw-r--r-- | src/corelib/tools/qregexp.h | 5 | ||||
-rw-r--r-- | src/corelib/tools/qregularexpression.cpp | 16 | ||||
-rw-r--r-- | src/corelib/tools/qregularexpression.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qregexp/tst_qregexp.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp | 5 |
6 files changed, 58 insertions, 5 deletions
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index cd8c393d51..5aa9d54843 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -38,6 +38,7 @@ #include "qcache.h" #include "qdatastream.h" #include "qdebug.h" +#include "qhashfunctions.h" #include "qlist.h" #include "qmap.h" #include "qmutex.h" @@ -882,6 +883,15 @@ static bool operator==(const QRegExpEngineKey &key1, const QRegExpEngineKey &key && key1.cs == key2.cs; } +static uint qHash(const QRegExpEngineKey &key, uint seed = 0) Q_DECL_NOTHROW +{ + QtPrivate::QHashCombine hash; + seed = hash(seed, key.pattern); + seed = hash(seed, key.patternSyntax); + seed = hash(seed, key.cs); + return seed; +} + class QRegExpEngine; //Q_DECLARE_TYPEINFO(QVector<int>, Q_MOVABLE_TYPE); @@ -3807,11 +3817,6 @@ struct QRegExpPrivate }; #if !defined(QT_NO_REGEXP_OPTIM) -uint qHash(const QRegExpEngineKey &key, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(key.pattern, seed); -} - typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache; Q_GLOBAL_STATIC(EngineCache, globalEngineCache) static QBasicMutex globalEngineCacheMutex; @@ -4033,6 +4038,21 @@ bool QRegExp::operator==(const QRegExp &rx) const } /*! + \since 5.6 + \relates QRegExp + + Returns the hash value for \a key, using + \a seed to seed the calculation. +*/ +uint qHash(const QRegExp &key, uint seed) Q_DECL_NOTHROW +{ + QtPrivate::QHashCombine hash; + seed = hash(seed, key.priv->engineKey); + seed = hash(seed, key.priv->minimal); + return seed; +} + +/*! \fn bool QRegExp::operator!=(const QRegExp &rx) const Returns \c true if this regular expression is not equal to \a rx; diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h index b08a8bd282..f384e6c51f 100644 --- a/src/corelib/tools/qregexp.h +++ b/src/corelib/tools/qregexp.h @@ -45,6 +45,9 @@ QT_BEGIN_NAMESPACE struct QRegExpPrivate; class QStringList; +class QRegExp; + +Q_CORE_EXPORT uint qHash(const QRegExp &key, uint seed = 0) Q_DECL_NOTHROW; class Q_CORE_EXPORT QRegExp { @@ -104,6 +107,8 @@ public: static QString escape(const QString &str); + friend Q_CORE_EXPORT uint qHash(const QRegExp &key, uint seed) Q_DECL_NOTHROW; + private: QRegExpPrivate *priv; }; diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 9950b90720..18dd2d12c2 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -38,6 +38,7 @@ #ifndef QT_NO_REGULAREXPRESSION #include <QtCore/qcoreapplication.h> +#include <QtCore/qhashfunctions.h> #include <QtCore/qmutex.h> #include <QtCore/qvector.h> #include <QtCore/qstringlist.h> @@ -1838,6 +1839,21 @@ bool QRegularExpression::operator==(const QRegularExpression &re) const */ /*! + \since 5.6 + \relates QRegularExpression + + Returns the hash value for \a key, using + \a seed to seed the calculation. +*/ +uint qHash(const QRegularExpression &key, uint seed) Q_DECL_NOTHROW +{ + QtPrivate::QHashCombine hash; + seed = hash(seed, key.d->pattern); + seed = hash(seed, key.d->patternOptions); + return seed; +} + +/*! Escapes all characters of \a str so that they no longer have any special meaning when used as a regular expression pattern string, and returns the escaped string. For instance: diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h index d2abfc7701..2bca6a211b 100644 --- a/src/corelib/tools/qregularexpression.h +++ b/src/corelib/tools/qregularexpression.h @@ -49,6 +49,9 @@ QT_BEGIN_NAMESPACE class QRegularExpressionMatch; class QRegularExpressionMatchIterator; struct QRegularExpressionPrivate; +class QRegularExpression; + +Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed = 0) Q_DECL_NOTHROW; class Q_CORE_EXPORT QRegularExpression { @@ -139,6 +142,7 @@ private: friend class QRegularExpressionMatch; friend struct QRegularExpressionMatchPrivate; friend class QRegularExpressionMatchIterator; + friend Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed) Q_DECL_NOTHROW; QRegularExpression(QRegularExpressionPrivate &dd); QExplicitlySharedDataPointer<QRegularExpressionPrivate> d; diff --git a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp b/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp index fefdec7496..b9a3fc13c5 100644 --- a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp +++ b/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp @@ -1224,6 +1224,9 @@ void tst_QRegExp::operator_eq() for (int j = 0; j < I * J * K * ELL; ++j) { QCOMPARE(rxtable[i] == rxtable[j], i / ELL == j / ELL); QCOMPARE(rxtable[i] != rxtable[j], i / ELL != j / ELL); + // this just happens to have no hash collisions. If at some point + // we get collisions, restrict the test to only equal elements: + QCOMPARE(qHash(rxtable[i]) == qHash(rxtable[j]), i / ELL == j / ELL); } } } diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index 99f6a31267..6b7614b7b9 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -1424,6 +1424,7 @@ static void verifyEquality(const QRegularExpression &re1, const QRegularExpressi { QVERIFY(re1 == re2); QVERIFY(re2 == re1); + QCOMPARE(qHash(re1), qHash(re2)); QVERIFY(!(re1 != re2)); QVERIFY(!(re2 != re1)); @@ -1431,22 +1432,26 @@ static void verifyEquality(const QRegularExpression &re1, const QRegularExpressi QVERIFY(re1 == re3); QVERIFY(re3 == re1); + QCOMPARE(qHash(re1), qHash(re3)); QVERIFY(!(re1 != re3)); QVERIFY(!(re3 != re1)); QVERIFY(re2 == re3); QVERIFY(re3 == re2); + QCOMPARE(qHash(re2), qHash(re3)); QVERIFY(!(re2 != re3)); QVERIFY(!(re3 != re2)); re3 = re2; QVERIFY(re1 == re3); QVERIFY(re3 == re1); + QCOMPARE(qHash(re1), qHash(re3)); QVERIFY(!(re1 != re3)); QVERIFY(!(re3 != re1)); QVERIFY(re2 == re3); QVERIFY(re3 == re2); + QCOMPARE(qHash(re2), qHash(re3)); QVERIFY(!(re2 != re3)); QVERIFY(!(re3 != re2)); } |