QFlatMap: add insert_or_assign

This does exactly what insert() on Qt associative containers does, but
allows to express the intent of using the STL-incompatible Qt insert()
semantics, in an STL-compatible way, instead of leaving the reader of
the code wondering what semantics are expected.

This is part of a very-long-term goal of fixing Qt associative
container's insert() behavior, in which QFlatMap, being an affected,
but private-API type, is used for proof-of-concept purposes.

Task-number: QTBUG-99651
Pick-to: 6.3 6.2
Change-Id: I69010285438259918aef659d3235180c1b5be696
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Marc Mutz 2022-01-09 10:07:34 +01:00
parent 9f32fc97aa
commit 6891e10f97
3 changed files with 83 additions and 3 deletions

View File

@ -750,6 +750,24 @@ public:
}
}
template <typename M>
std::pair<iterator, bool> insert_or_assign(const Key &key, M &&obj)
{
auto r = try_emplace(key, std::forward<M>(obj));
if (!r.second)
*toValuesIterator(r.first) = std::forward<M>(obj);
return r;
}
template <typename M>
std::pair<iterator, bool> insert_or_assign(Key &&key, M &&obj)
{
auto r = try_emplace(std::move(key), std::forward<M>(obj));
if (!r.second)
*toValuesIterator(r.first) = std::forward<M>(obj);
return r;
}
template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
void insert(InputIt first, InputIt last)
{

View File

@ -224,7 +224,7 @@ static const QPointingDevice *tabletToolInstance(NSEvent *theEvent)
QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(nullptr, timestamp, device, theEvent.isEnteringProximity);
// The windowSystemId starts at 0, but is "unique" while in proximity
if (theEvent.isEnteringProximity)
devicesInProximity->insert(windowSystemId, device);
devicesInProximity->insert_or_assign(windowSystemId, device);
else
devicesInProximity->remove(windowSystemId);
}

View File

@ -53,7 +53,7 @@ private slots:
void iterators();
void statefulComparator();
void transparency();
void try_emplace();
void try_emplace_and_insert_or_assign();
void viewIterators();
void varLengthArray();
};
@ -428,7 +428,7 @@ void tst_QFlatMap::transparency()
QCOMPARE(m.lower_bound(sv3).value(), "dree");
}
void tst_QFlatMap::try_emplace()
void tst_QFlatMap::try_emplace_and_insert_or_assign()
{
using Map = QFlatMap<QByteArray, QByteArray>;
@ -457,12 +457,32 @@ void tst_QFlatMap::try_emplace()
Map m;
QVERIFY(m.try_emplace(lvalue(foo), lvalue(qqq)).second);
CHECKS();
QVERIFY(!m.insert_or_assign(lvalue(foo), lvalue(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(lvalue(foo), lvalue(qqq)).second);
CHECKS();
QVERIFY(!m.try_emplace(lvalue(foo), lvalue(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
{
Map m;
QVERIFY(m.try_emplace(lvalue(foo), rvalue(qqq)).second);
CHECKS();
QVERIFY(!m.insert_or_assign(lvalue(foo), rvalue(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(lvalue(foo), rvalue(qqq)).second);
CHECKS();
QVERIFY(!m.try_emplace(lvalue(foo), rvalue(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
{
@ -477,18 +497,49 @@ void tst_QFlatMap::try_emplace()
QVERIFY(m.try_emplace(lvalue(foo), sb(qqq)).second);
QCOMPARE(m.value(foo), qqq);
CHECKS();
QVERIFY(!m.insert_or_assign(lvalue(foo), sb(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(lvalue(foo), sb(qqq)).second);
QCOMPARE(m.value(foo), qqq);
CHECKS();
QVERIFY(!m.try_emplace(lvalue(foo), sb(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
{
Map m;
QVERIFY(m.try_emplace(rvalue(foo), lvalue(qqq)).second);
CHECKS();
QVERIFY(!m.insert_or_assign(rvalue(foo), lvalue(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(rvalue(foo), lvalue(qqq)).second);
CHECKS();
QVERIFY(!m.try_emplace(rvalue(foo), lvalue(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
{
Map m;
QVERIFY(m.try_emplace(rvalue(foo), rvalue(qqq)).second);
CHECKS();
QVERIFY(!m.insert_or_assign(rvalue(foo), rvalue(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(rvalue(foo), rvalue(qqq)).second);
CHECKS();
QVERIFY(!m.try_emplace(rvalue(foo), rvalue(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
{
@ -503,6 +554,17 @@ void tst_QFlatMap::try_emplace()
QVERIFY(m.try_emplace(rvalue(foo), sb(qqq)).second);
QCOMPARE(m.value(foo), qqq);
CHECKS();
QVERIFY(!m.insert_or_assign(rvalue(foo), sb(foo)).second);
QCOMPARE(m.value(foo), foo);
}
{
Map m;
QVERIFY(m.insert_or_assign(rvalue(foo), sb(qqq)).second);
QCOMPARE(m.value(foo), qqq);
CHECKS();
QVERIFY(!m.try_emplace(rvalue(foo), sb(foo)).second);
QCOMPARE(m.value(foo), qqq);
}
#undef CHECKS
#undef lvalue