Q(Multi)Map: micro-optimize take()

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 <allan.jensen@qt.io>
Pick-to: 6.8
Change-Id: I6654fa7f5ed80d07369eb6a2b37f1e82cd3aa7f0
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
(cherry picked from commit ed92f6c22fa59de1e536e1631053ae5565dcc0e1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2025-03-18 09:18:04 +01:00 committed by Qt Cherry-pick Bot
parent 322520ad62
commit 53d8347210

View File

@ -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();
}