diff --git a/src/corelib/tools/qflatmap_p.h b/src/corelib/tools/qflatmap_p.h index 621eb7adba..d7f8ff48cb 100644 --- a/src/corelib/tools/qflatmap_p.h +++ b/src/corelib/tools/qflatmap_p.h @@ -726,6 +726,30 @@ public: } } + template + std::pair 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)...); + return { fromKeysIterator(c.keys.insert(toKeysIterator(it), key)), true }; + } else { + return {it, false}; + } + } + + template + std::pair 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)...); + return { fromKeysIterator(c.keys.insert(toKeysIterator(it), std::move(key))), true }; + } else { + return {it, false}; + } + } + template = nullptr> void insert(InputIt first, InputIt last) { diff --git a/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp index f8f48d7bfb..af616f0a4c 100644 --- a/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp +++ b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp @@ -26,6 +26,8 @@ ** ****************************************************************************/ +#define QT_USE_QSTRINGBUILDER + #include #include @@ -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; + + 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;