Revert "Optimize QSet::unite"

This reverts commit 92acc94fa9.

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()`.

Fixes: QTBUG-132500
Change-Id: Ia636b62325139d618b5467a643ff710716324296
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 2d1b3028673493cb144060cbec49b1b95f4188d2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3dff1a3f7b22bc623b3c326630bfd94d2bd35d08)
bb10
Marc Mutz 2025-01-02 08:31:21 +01:00 committed by Qt Cherry-pick Bot
parent 88d9371d2c
commit 0e17856f63
2 changed files with 5 additions and 10 deletions

View File

@ -229,13 +229,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

@ -898,7 +898,7 @@ void tst_QSet::setOperationsOnEmptySet()
empty.unite(nonEmpty);
QCOMPARE(empty, nonEmpty);
QVERIFY(!empty.isDetached());
QVERIFY(empty.isDetached());
}
}
@ -1312,11 +1312,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));