QHttpHeaders: de-pessimize Private::replaceOrAppend()

All callers of replaceOrAppend() (present and future) pass an rvalue
`value`, so take advantage of C++17 guaranteed copy elision, take
`value` by value and move it into place.

Even for implicitly-shared classes, a move (pointer swap) is cheaper
than a copy (atomic ref-count upping/downing; ca. 100x slower than a
normal int).

Amends d8f6425fef1050525480afec662a417a7645c22e.

Pick-to: 6.8
Change-Id: Ia52a2ec2c079f515f92b0890e42669d4ba435c20
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 8761fa5b8bec2f9b80550523e824f4e3141aca49)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2025-03-11 10:28:06 +01:00 committed by Qt Cherry-pick Bot
parent 5482f0d0a9
commit 619af4198e

View File

@ -791,7 +791,7 @@ public:
// we can define common methods which 'detach()' the private itself. // we can define common methods which 'detach()' the private itself.
using Self = QExplicitlySharedDataPointer<QHttpHeadersPrivate>; using Self = QExplicitlySharedDataPointer<QHttpHeadersPrivate>;
static void removeAll(Self &d, const HeaderName &name); static void removeAll(Self &d, const HeaderName &name);
static void replaceOrAppend(Self &d, const HeaderName &name, const QByteArray &value); static void replaceOrAppend(Self &d, const HeaderName &name, QByteArray value);
void combinedValue(const HeaderName &name, QByteArray &result) const; void combinedValue(const HeaderName &name, QByteArray &result) const;
void values(const HeaderName &name, QList<QByteArray> &result) const; void values(const HeaderName &name, QList<QByteArray> &result) const;
@ -855,20 +855,20 @@ QByteArrayView QHttpHeadersPrivate::value(const HeaderName &name, QByteArrayView
return defaultValue; return defaultValue;
} }
void QHttpHeadersPrivate::replaceOrAppend(Self &d, const HeaderName &name, const QByteArray &value) void QHttpHeadersPrivate::replaceOrAppend(Self &d, const HeaderName &name, QByteArray value)
{ {
d.detach(); d.detach();
auto it = std::find_if(d->headers.begin(), d->headers.end(), headerNameMatches(name)); auto it = std::find_if(d->headers.begin(), d->headers.end(), headerNameMatches(name));
if (it != d->headers.end()) { if (it != d->headers.end()) {
// Found something to replace => replace, and then rearrange any remaining // Found something to replace => replace, and then rearrange any remaining
// matches to the end and erase them // matches to the end and erase them
it->value = value; it->value = std::move(value);
d->headers.erase( d->headers.erase(
std::remove_if(it + 1, d->headers.end(), headerNameMatches(name)), std::remove_if(it + 1, d->headers.end(), headerNameMatches(name)),
d->headers.end()); d->headers.end());
} else { } else {
// Found nothing to replace => append // Found nothing to replace => append
d->headers.append(Header{name, value}); d->headers.append(Header{name, std::move(value)});
} }
} }