From 53d834721029c19f8ce77f993db9c89761de4864 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 18 Mar 2025 09:18:04 +0100 Subject: [PATCH] Q(Multi)Map: micro-optimize take() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of the RVO-unfriendly¹ auto r = std::move(it->second); erase(it); return r; use map::extract(), if available. The RVO-unfriendly code now only plagues old-fashioned compilers that, in 2025, didn't, yet, manage to implement C++17 _cpp_lib_node_extract. The rest enjoys C++17 guaranteed RVO. Amends 14090760a87f23509b7bb5ad846537c766cb44a5. ¹ theoretically, this code is eligible for NRVO, but embedded in a larger function like this, it won't kick in on most compilers. Reported-by: Allan Sandfeld Jensen Pick-to: 6.8 Change-Id: I6654fa7f5ed80d07369eb6a2b37f1e82cd3aa7f0 Reviewed-by: Giuseppe D'Angelo (cherry picked from commit ed92f6c22fa59de1e536e1631053ae5565dcc0e1) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qmap.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 1fa9b4bc4a3..15f41bfc426 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -332,12 +332,18 @@ public: // elements (the one to be removed can be skipped). detach(); +#ifdef __cpp_lib_node_extract + if (const auto node = d->m.extract(key)) + return std::move(node.mapped()); +#else auto i = d->m.find(key); if (i != d->m.end()) { + // ### breaks RVO on most compilers (but only on old-fashioned ones, so who cares?) T result(std::move(i->second)); d->m.erase(i); return result; } +#endif return T(); } @@ -1038,12 +1044,18 @@ public: // elements (the one to be removed can be skipped). detach(); +#ifdef __cpp_lib_node_extract + if (const auto node = d->m.extract(key)) + return std::move(node.mapped()); +#else auto i = d->m.find(key); if (i != d->m.end()) { + // ### breaks RVO on most compilers (but only on old-fashioned ones, so who cares?) T result(std::move(i->second)); d->m.erase(i); return result; } +#endif return T(); }