QDuplicateTracker: accept the number of elements to reserve as a ctor argument

This prevents us from first reserve()ing Prealloc elements, and then
possibly reserve()ing a larger number, which leaves the first bucket
list's memory unused.

Consequently, deprecate reserve().

Change-Id: Ifc0a5a021097f4589557e7b5e45d9d0892797ade
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Marc Mutz 2021-07-12 11:15:44 +02:00
parent fcfc854def
commit a7564e2657
9 changed files with 16 additions and 15 deletions

View File

@ -404,8 +404,7 @@ void ProStringList::removeEmpty()
void ProStringList::removeDuplicates()
{
QDuplicateTracker<ProString> seen;
seen.reserve(size());
QDuplicateTracker<ProString> seen(size());
removeIf([&](const ProString &s) { return seen.hasSeen(s); });
}

View File

@ -416,8 +416,7 @@ void QResourcePrivate::ensureChildren() const
QString path = absoluteFilePath, k;
if (path.startsWith(QLatin1Char(':')))
path = path.mid(1);
QDuplicateTracker<QString> kids;
kids.reserve(related.size());
QDuplicateTracker<QString> kids(related.size());
QString cleaned = cleanPath(path);
for (int i = 0; i < related.size(); ++i) {
QResourceRoot *res = related.at(i);

View File

@ -648,8 +648,7 @@ qsizetype QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QReg
*/
qsizetype QtPrivate::QStringList_removeDuplicates(QStringList *that)
{
QDuplicateTracker<QString> seen;
seen.reserve(that->size());
QDuplicateTracker<QString> seen(that->size());
return that->removeIf([&](const QString &s) { return seen.hasSeen(s); });
}

View File

@ -106,6 +106,14 @@ class QDuplicateTracker {
Q_DISABLE_COPY_MOVE(QDuplicateTracker);
public:
QDuplicateTracker() = default;
explicit QDuplicateTracker(qsizetype n)
#ifdef __cpp_lib_memory_resource
: set{size_t(n), &res}
#else
: set{n}
#endif
{}
Q_DECL_DEPRECATED_X("Pass the capacity to reserve() to the ctor instead.")
void reserve(qsizetype n) { set.reserve(n); }
[[nodiscard]] bool hasSeen(const T &s)
{

View File

@ -810,8 +810,7 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
FcPatternDestroy(pattern);
if (fontSet) {
QDuplicateTracker<QString> duplicates;
duplicates.reserve(fontSet->nfont + 1);
QDuplicateTracker<QString> duplicates(fontSet->nfont + 1);
(void)duplicates.hasSeen(family.toCaseFolded());
for (int i = 0; i < fontSet->nfont; i++) {
FcChar8 *value = nullptr;

View File

@ -1833,7 +1833,7 @@ void Moc::checkProperties(ClassDef *cdef)
// specify get function, for compatibiliy we accept functions
// returning pointers, or const char * for QByteArray.
//
QDuplicateTracker<QByteArray> definedProperties;
QDuplicateTracker<QByteArray> definedProperties(cdef->propertyList.count());
for (int i = 0; i < cdef->propertyList.count(); ++i) {
PropertyDef &p = cdef->propertyList[i];
if (definedProperties.hasSeen(p.name)) {

View File

@ -3101,8 +3101,7 @@ QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
const QModelIndexList indexes = selectionModel()->selectedIndexes();
QList<QTreeWidgetItem*> items;
items.reserve(indexes.count());
QDuplicateTracker<QTreeWidgetItem *> seen;
seen.reserve(indexes.count());
QDuplicateTracker<QTreeWidgetItem *> seen(indexes.count());
for (const auto &index : indexes) {
QTreeWidgetItem *item = d->item(index);
if (item->isHidden() || seen.hasSeen(item))

View File

@ -2625,8 +2625,7 @@ void QStyleSheetStyle::setProperties(QWidget *w)
{
// scan decls for final occurrence of each "qproperty"
QDuplicateTracker<QString> propertySet;
propertySet.reserve(decls.size());
QDuplicateTracker<QString> propertySet(decls.size());
for (int i = decls.count() - 1; i >= 0; --i) {
const QString property = decls.at(i).d->property;
if (!property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive))

View File

@ -168,8 +168,7 @@ size_t qHash(const ConstructionCounted &c, std::size_t seed = 0)
void tst_QDuplicateTracker::appendTo_special()
{
QDuplicateTracker<ConstructionCounted> tracker;
tracker.reserve(3);
QDuplicateTracker<ConstructionCounted> tracker(3);
QVERIFY(!tracker.hasSeen(1));
QVERIFY(!tracker.hasSeen(2));
QVERIFY(!tracker.hasSeen(3));