QFlatMap: add try_emplace (w/o hint)
QFlatMap, like its public brethren, features the broken Qt-style insert() behavior (what the STL calls insert_or_assign()), which makes its insert() unusable for actual STL-style insert() work, with no replacement except the size-check-and-index-operator trick: const auto oldSize = c.size(); auto &e = c[key]; if (c.size() != oldSize) { // inserted } Even though QFlatMap::insert() appears to return the correct info, it's useless, because the old value has been assigned over by the time insert() returns. Pick-to: 6.3 6.2 Change-Id: If4173c42523a128dfd22ab496dde0089ba73f41c Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
5327bae6f0
commit
f044664c68
@ -726,6 +726,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename...Args>
|
||||
std::pair<iterator, bool> try_emplace(const Key &key, Args&&...args)
|
||||
{
|
||||
auto it = lower_bound(key);
|
||||
if (it == end() || key_compare::operator()(key, it.key())) {
|
||||
c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...);
|
||||
return { fromKeysIterator(c.keys.insert(toKeysIterator(it), key)), true };
|
||||
} else {
|
||||
return {it, false};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename...Args>
|
||||
std::pair<iterator, bool> try_emplace(Key &&key, Args&&...args)
|
||||
{
|
||||
auto it = lower_bound(key);
|
||||
if (it == end() || key_compare::operator()(key, it.key())) {
|
||||
c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...);
|
||||
return { fromKeysIterator(c.keys.insert(toKeysIterator(it), std::move(key))), true };
|
||||
} else {
|
||||
return {it, false};
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIt, is_compatible_iterator<InputIt> = nullptr>
|
||||
void insert(InputIt first, InputIt last)
|
||||
{
|
||||
|
@ -26,6 +26,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#define QT_USE_QSTRINGBUILDER
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <private/qflatmap_p.h>
|
||||
@ -51,6 +53,7 @@ private slots:
|
||||
void iterators();
|
||||
void statefulComparator();
|
||||
void transparency();
|
||||
void try_emplace();
|
||||
void viewIterators();
|
||||
void varLengthArray();
|
||||
};
|
||||
@ -425,6 +428,86 @@ void tst_QFlatMap::transparency()
|
||||
QCOMPARE(m.lower_bound(sv3).value(), "dree");
|
||||
}
|
||||
|
||||
void tst_QFlatMap::try_emplace()
|
||||
{
|
||||
using Map = QFlatMap<QByteArray, QByteArray>;
|
||||
|
||||
const QByteArray foo = QByteArrayLiteral("foo");
|
||||
const qsizetype qqq_1 = 3;
|
||||
const char qqq_2 = 'q';
|
||||
const QByteArray qqq = QByteArray(qqq_1, qqq_2);
|
||||
|
||||
auto sb = [] (const auto &str) { return str % ""; };
|
||||
auto rvalue = [](const auto &x) { return x; };
|
||||
#define lvalue(x) x
|
||||
#define CHECKS() \
|
||||
do { \
|
||||
QVERIFY(!m.try_emplace(rvalue(foo), lvalue(foo)).second); \
|
||||
QCOMPARE(m.value(foo), qqq); \
|
||||
QVERIFY(!m.try_emplace(lvalue(foo), lvalue(foo)).second); \
|
||||
QCOMPARE(m.value(foo), qqq); \
|
||||
QVERIFY(!m.try_emplace(lvalue(foo), sb(foo)).second); \
|
||||
QCOMPARE(m.value(foo), qqq); \
|
||||
QVERIFY(!m.try_emplace(rvalue(foo), sb(foo)).second); \
|
||||
QCOMPARE(m.value(foo), qqq); \
|
||||
} while (0) \
|
||||
/* end */
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(lvalue(foo), lvalue(qqq)).second);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(lvalue(foo), rvalue(qqq)).second);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(lvalue(foo), qqq_1, qqq_2).second);
|
||||
QCOMPARE(m.value(foo), qqq);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(lvalue(foo), sb(qqq)).second);
|
||||
QCOMPARE(m.value(foo), qqq);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(rvalue(foo), lvalue(qqq)).second);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(rvalue(foo), rvalue(qqq)).second);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(rvalue(foo), qqq_1, qqq_2).second);
|
||||
QCOMPARE(m.value(foo), qqq);
|
||||
CHECKS();
|
||||
}
|
||||
|
||||
{
|
||||
Map m;
|
||||
QVERIFY(m.try_emplace(rvalue(foo), sb(qqq)).second);
|
||||
QCOMPARE(m.value(foo), qqq);
|
||||
CHECKS();
|
||||
}
|
||||
#undef CHECKS
|
||||
#undef lvalue
|
||||
}
|
||||
|
||||
void tst_QFlatMap::viewIterators()
|
||||
{
|
||||
using Map = QFlatMap<QByteArray, QByteArray>;
|
||||
|
Loading…
Reference in New Issue
Block a user