Revert "Optimize QSet::unite"

This reverts commit 92acc94fa98d19929d28feb5d543acf8c50c2290.

The change broke QSet ordering guarantees: The documentation clearly
states that each item from `other` that isn't already in `*this` is
inserted ("STL insertion behavior"). Swapping *this and other breaks
this.

Independent of STL vs. Qt insertion behavior, making the picking of
elements from containers "random" in the sense that the size of the
container is now important, and not merely LHS vs. RHS, is a bad idea.

[ChangeLog][QtCore][QSet] Fixed a regression in unite() that caused
equivalent elements of `*this` to be overwritten by elements of
`other` if `other.size()` was larger than `this->size()`.

Pick-to: 6.9 6.8
Fixes: QTBUG-132500
Change-Id: Ia636b62325139d618b5467a643ff710716324296
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2025-01-02 08:31:21 +01:00
parent 0b7b02cdb4
commit 2d1b302867
2 changed files with 5 additions and 10 deletions

View File

@ -232,13 +232,10 @@ Q_INLINE_TEMPLATE void QSet<T>::reserve(qsizetype asize) { q_hash.reserve(asize)
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
{
if (q_hash.isSharedWith(other.q_hash))
return *this;
QSet<T> tmp = other;
if (size() < other.size())
swap(tmp);
for (const auto &e : std::as_const(tmp))
insert(e);
if (!q_hash.isSharedWith(other.q_hash)) {
for (const T &e : other)
insert(e);
}
return *this;
}

View File

@ -920,7 +920,7 @@ void tst_QSet::setOperationsOnEmptySet()
empty.unite(nonEmpty);
QCOMPARE(empty, nonEmpty);
QVERIFY(!empty.isDetached());
QVERIFY(empty.isDetached());
}
}
@ -1334,11 +1334,9 @@ void tst_QSet::setOperationsPickEquivalentElementsFromLHSContainer_impl()
// (unlike other Qt containers, QSet's insertion behavior is STL-compliant):
//
QVERIFY(lhsCopy.contains(OneL));
QEXPECT_FAIL("", "QTBUG-132500", Continue);
QCOMPARE(lhsCopy.find(OneL)->id, OneL.id);
QVERIFY(lhsCopy.contains(TwoL));
QEXPECT_FAIL("", "QTBUG-132500", Continue);
QCOMPARE(lhsCopy.find(TwoL)->id, TwoL.id);
QVERIFY(lhsCopy.contains(ThreeL));