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.9 6.8 Change-Id: I6654fa7f5ed80d07369eb6a2b37f1e82cd3aa7f0 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
parent
00155dabf3
commit
ed92f6c22f
@ -332,12 +332,18 @@ public:
|
|||||||
// elements (the one to be removed can be skipped).
|
// elements (the one to be removed can be skipped).
|
||||||
detach();
|
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);
|
auto i = d->m.find(key);
|
||||||
if (i != d->m.end()) {
|
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));
|
T result(std::move(i->second));
|
||||||
d->m.erase(i);
|
d->m.erase(i);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,12 +1044,18 @@ public:
|
|||||||
// elements (the one to be removed can be skipped).
|
// elements (the one to be removed can be skipped).
|
||||||
detach();
|
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);
|
auto i = d->m.find(key);
|
||||||
if (i != d->m.end()) {
|
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));
|
T result(std::move(i->second));
|
||||||
d->m.erase(i);
|
d->m.erase(i);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user