Fix qHash(QFontEngine::FaceId)

There were two problems:

1. qHash() hashed FaceId::uuid, but op== didn't use it for
   determining equality. Thus, x == y => qHash(x) == qHash(y)
   might be broken if fileName and uuid have an orthogonal
   component, if you excuse my vector analogy.

2. To hash fileName and uuid, it concatenated the two,
   causing a temporary QByteArray to be created just for
   hashing its contents. That prevented marking qHash()
   as nothrow.

Fix by using new QtPrivate::QHashCombine and adding
uuid to the list of fields compared in op==.

Change-Id: I49f2379d514d6d3669929e737562cf6de823127e
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
Marc Mutz 2015-06-23 11:37:26 +02:00
parent f6d5c21e3e
commit 5329d739ee

View File

@ -49,6 +49,7 @@
#include "QtCore/qatomic.h"
#include <QtCore/qvarlengtharray.h>
#include <QtCore/QLinkedList>
#include <QtCore/qhashfunctions.h>
#include "private/qtextengine_p.h"
#include "private/qfont_p.h"
@ -328,12 +329,18 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QFontEngine::ShaperFlags)
inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2)
{
return (f1.index == f2.index) && (f1.encoding == f2.encoding) && (f1.filename == f2.filename);
return f1.index == f2.index && f1.encoding == f2.encoding && f1.filename == f2.filename && f1.uuid == f2.uuid;
}
inline uint qHash(const QFontEngine::FaceId &f)
inline uint qHash(const QFontEngine::FaceId &f, uint seed = 0)
Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(f.filename)))
{
return qHash((f.index << 16) + f.encoding) + qHash(f.filename + f.uuid);
QtPrivate::QHashCombine hash;
seed = hash(seed, f.filename);
seed = hash(seed, f.uuid);
seed = hash(seed, f.index);
seed = hash(seed, f.encoding);
return seed;
}