From 154fe8d8034f238180418ce32ac18bd6ab6df14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 28 Nov 2024 13:08:25 +0100 Subject: [PATCH] QHash tryEmplace-try_emplace compat Let users use either type Change-Id: Ica22a329df679352ab828aa96102a30fc9eedf79 Reviewed-by: Thiago Macieira --- src/corelib/tools/qhash.h | 36 +++++++++++++------- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 28 +++++++++++++++ 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 7347a73f831..e544b5f870a 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1255,6 +1255,24 @@ public: { QHash::iterator iterator; bool inserted; + + TryEmplaceResult() = default; + // Generated SMFs are fine! + TryEmplaceResult(QHash::iterator it, bool b) + : iterator(it), inserted(b) + { + } + + // Implicit conversion _from_ the return-type of try_emplace: + Q_IMPLICIT TryEmplaceResult(const std::pair &p) + : iterator(p.first.base()), inserted(p.second) + { + } + // Implicit conversion _to_ the return-type of try_emplace: + Q_IMPLICIT operator std::pair() + { + return { key_value_iterator(iterator), inserted }; + } }; iterator erase(const_iterator it) @@ -1387,26 +1405,22 @@ public: template std::pair try_emplace(const Key &key, Args &&...args) { - auto r = tryEmplace_impl(key, std::forward(args)...); - return {key_value_iterator(r.iterator), r.inserted}; + return tryEmplace_impl(key, std::forward(args)...); } template std::pair try_emplace(Key &&key, Args &&...args) { - auto r = tryEmplace_impl(std::move(key), std::forward(args)...); - return {key_value_iterator(r.iterator), r.inserted}; + return tryEmplace_impl(std::move(key), std::forward(args)...); } template key_value_iterator try_emplace(const_iterator /*hint*/, const Key &key, Args &&...args) { - auto r = tryEmplace_impl(key, std::forward(args)...); - return key_value_iterator(r.iterator); + return key_value_iterator(tryEmplace_impl(key, std::forward(args)...).iterator); } template key_value_iterator try_emplace(const_iterator /*hint*/, Key &&key, Args &&...args) { - auto r = tryEmplace_impl(std::move(key), std::forward(args)...); - return key_value_iterator(r.iterator); + return key_value_iterator(tryEmplace_impl(std::move(key), std::forward(args)...).iterator); } private: @@ -1557,14 +1571,12 @@ public: template = true, if_key_constructible_from = true> std::pair try_emplace(K &&key, Args &&...args) { - auto r = tryEmplace_impl(std::forward(key), std::forward(args)...); - return { key_value_iterator(r.iterator), r.inserted }; + return tryEmplace_impl(std::forward(key), std::forward(args)...); } template = true, if_key_constructible_from = true> key_value_iterator try_emplace(const_iterator /*hint*/, K &&key, Args &&...args) { - auto r = tryEmplace_impl(std::forward(key), std::forward(args)...); - return key_value_iterator(r.iterator); + return key_value_iterator(tryEmplace_impl(std::forward(key), std::forward(args)...).iterator); } }; diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index bd8913a39e6..e8bcdb275fe 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -2862,6 +2862,34 @@ void tst_QHash::tryEmplace() QCOMPARE(hash[0], 0); QVERIFY(!inserted2); QCOMPARE(it->second, 0); + + using KVIterator = decltype(hash)::key_value_iterator; + using PairReturn = std::pair; // Return-value of try_emplace + + // Handle conversion _from_ the try_emplace return type. + QHash::TryEmplaceResult t = hash.try_emplace(2, 2); + QCOMPARE(t.inserted, true); + QCOMPARE(t.iterator.value(), 2); + QCOMPARE(hash.size(), 3); + + t = hash.try_emplace(2, -1); + QCOMPARE(t.inserted, false); + QCOMPARE(t.iterator.value(), 2); + QCOMPARE(hash.size(), 3); + + // Handle conversion _to_ the try_emplace return type. + PairReturn p = hash.tryEmplace(1, -1); + QCOMPARE_NE(p.first, hash.keyValueEnd()); + QCOMPARE(hash.size(), 3); + + QVERIFY(!p.second); + QCOMPARE(p.first->second, 1); + + p = hash.try_emplace(cref, -1); + QCOMPARE_NE(p.first, hash.keyValueEnd()); + QCOMPARE(hash.size(), 3); + QVERIFY(!p.second); + QCOMPARE(p.first->second, 0); } { // Make sure any kind of resize is properly handled