Add qHash() overloads for floating-point types
This implementation is based on GCC's implementation of std::hash<FP>, but only to the extent of checking for zero before hashing the bits. The bit hasher is the Qt one; I didn't even look what GCC uses. The check against 0.0 is mandated by the requirement to have \forall x,y: x == y => qHash(x) == qHash(y) which would be violated for x = 0.0 and y = -0.0 if we only hashed the bits. Implemented out-of-line to avoid potential FP-comparison warnings, as well as to be able to use the file-static hash() functions, which gets inlined unlike qHashBits(), which cannot be. [ChangeLog][QtCore][QHash/QSet] Allowed to use float, double and long double as QHash/QSet keys. Change-Id: I38cec4afb860f17e9f8be7b67544e58b330f8fff Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>bb10
parent
d24cceebf2
commit
c0791ac76e
|
|
@ -737,6 +737,38 @@ void QHashData::checkSanity()
|
|||
Returns the hash value for the \a key, using \a seed to seed the calculation.
|
||||
*/
|
||||
|
||||
/*! \relates QHash
|
||||
\since 5.3
|
||||
|
||||
Returns the hash value for the \a key, using \a seed to seed the calculation.
|
||||
*/
|
||||
uint qHash(float key, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
return key != 0.0f ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
|
||||
}
|
||||
|
||||
/*! \relates QHash
|
||||
\since 5.3
|
||||
|
||||
Returns the hash value for the \a key, using \a seed to seed the calculation.
|
||||
*/
|
||||
uint qHash(double key, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
return key != 0.0 ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
|
||||
}
|
||||
|
||||
#ifndef Q_OS_DARWIN
|
||||
/*! \relates QHash
|
||||
\since 5.3
|
||||
|
||||
Returns the hash value for the \a key, using \a seed to seed the calculation.
|
||||
*/
|
||||
uint qHash(long double key, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
return key != 0.0L ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \fn uint qHash(QChar key, uint seed = 0)
|
||||
\relates QHash
|
||||
\since 5.0
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
|
|||
}
|
||||
}
|
||||
inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
|
||||
Q_CORE_EXPORT uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
Q_CORE_EXPORT uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
#ifndef Q_OS_DARWIN
|
||||
Q_CORE_EXPORT uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
#endif
|
||||
inline uint qHash(QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
|
||||
Q_CORE_EXPORT uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
Q_CORE_EXPORT uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ private slots:
|
|||
void rehash_isnt_quadratic();
|
||||
void dont_need_default_constructor();
|
||||
void qhash();
|
||||
void fp_qhash_of_zero_is_zero();
|
||||
void qmultihash_specific();
|
||||
|
||||
void compare();
|
||||
|
|
@ -1043,6 +1044,20 @@ void tst_QHash::qhash()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_QHash::fp_qhash_of_zero_is_zero()
|
||||
{
|
||||
QCOMPARE(qHash(-0.0f), 0U);
|
||||
QCOMPARE(qHash( 0.0f), 0U);
|
||||
|
||||
QCOMPARE(qHash(-0.0 ), 0U);
|
||||
QCOMPARE(qHash( 0.0 ), 0U);
|
||||
|
||||
#ifndef Q_OS_DARWIN
|
||||
QCOMPARE(qHash(-0.0L), 0U);
|
||||
QCOMPARE(qHash( 0.0L), 0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QHash::qmultihash_specific()
|
||||
{
|
||||
QMultiHash<int, int> hash1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue