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.8
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>
This commit is contained in:
Marc Mutz 2025-01-02 08:31:21 +01:00 committed by Qt Cherry-pick Bot
parent 12f39bb2ab
commit 3dff1a3f7b
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))
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));