summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2025-11-28 13:20:37 +0100
committerMarc Mutz <marc.mutz@qt.io>2025-12-05 10:57:33 +0000
commitda20f36276ea40b6e99e9d86fb7ebf7384198ddc (patch)
tree9214f25548328b85701056086111f90a3064be77
parent6ccf37253d89dbc36cc2e518cb9a7cc169d49b6b (diff)
QFlatMap: restore NRVO in do_take()
The usual problem, the usual solution... At the time of construction of the return object it is known which of the two variables to construct, so NRVO would be permissible, but most compilers don't enable it because the structure isn't T result; // first (non-trivial) variable declared // must be a function's top-level scope ~~~ return result; // only one // or else all return statements are token-by-token the same The usual fix is to wrap the tail part of the function (= the one that constructs a T and returns it, as opposed to the part that returns temporaries) in an IILE expression: the lambda then _has_ said structure, so is NRVO'ed and the call to the lambda is RVO'ed in the caller. Invert the polarity of the if statement in order to keep the meat of the function's git history intact. Amends deddafe0a6a32aa438cc36c7dcfae8c323274487. Pick-to: 6.10 6.8 Change-Id: I3f22665daca320be283e4088cf1062f115cd49e4 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/corelib/tools/qflatmap_p.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/corelib/tools/qflatmap_p.h b/src/corelib/tools/qflatmap_p.h
index 554d7ea0df8..bdb0e24dde8 100644
--- a/src/corelib/tools/qflatmap_p.h
+++ b/src/corelib/tools/qflatmap_p.h
@@ -903,12 +903,13 @@ private:
T do_take(iterator it)
{
- if (it != end()) {
+ if (it == end())
+ return {};
+ return [&] {
T result = std::move(it.value());
erase(it);
return result;
- }
- return {};
+ }();
}
template <class InputIt, is_compatible_iterator<InputIt> = nullptr>