diff options
author | Marc Mutz <marc.mutz@qt.io> | 2022-11-30 16:22:00 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2022-12-07 07:39:38 +0000 |
commit | 6631444eb12b76608e5d945bc3d53e1678a6a36d (patch) | |
tree | f58632e21181d89bdc2ee9b0d4af7d1a46d15368 /src/corelib/text/qstring.h | |
parent | e7e3e4cf2566ae69df80dba58fb0668c60a88285 (diff) |
QString/QByteArray/QList: de-pessimize op+ [2/2]: overload on rvalue LHS
The + operator is left-associative, so a + b + c is (a + b) + c.
Apply the same trick C++20 applied to std::string's op+ and overload
for rvalue left-hand sides. This means that a + b + c is now
equivalent to
[&] {
auto tmp = a;
tmp += b;
tmp += c;
return tmp;
}()
removing a ton of temporary buffers (not objects, because CoW makes it
impossible for the compiler to track the single conceptual object
passing through the chain) when not using QStringBuilder (which isn't
available for QList).
This is BC, because the operators are all inline free functions or at
least inline members of non-exported classes.
Use multi-\fn to document the new operators. No \since is needed, as
this doesn't change the set of supported operations, just makes some
of them faster.
[ChangeLog][QtCore][QList/QString/QByteArray] Chained additions (a + b
+ c) now produce only one temporary buffer for the whole expression
instead of one per addition. Using += or QStringBuilder is still
faster, though.
Change-Id: I87e837d8803e79dc29c9268f73e6df9fcc0b09a3
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/text/qstring.h')
-rw-r--r-- | src/corelib/text/qstring.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 81a7e492f1..5f54b198fb 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -1490,19 +1490,27 @@ inline bool QByteArray::operator>=(const QString &s) const #if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER) inline QString operator+(const QString &s1, const QString &s2) { QString t(s1); t += s2; return t; } +inline QString operator+(QString &&lhs, const QString &rhs) +{ return std::move(lhs += rhs); } inline QString operator+(const QString &s1, QChar s2) { QString t(s1); t += s2; return t; } +inline QString operator+(QString &&lhs, QChar rhs) +{ return std::move(lhs += rhs); } inline QString operator+(QChar s1, const QString &s2) { QString t(s1); t += s2; return t; } # if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) QT_ASCII_CAST_WARN inline QString operator+(const QString &s1, const char *s2) { QString t(s1); t += QString::fromUtf8(s2); return t; } +QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const char *rhs) +{ QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) } QT_ASCII_CAST_WARN inline QString operator+(const char *s1, const QString &s2) { QString t = QString::fromUtf8(s1); t += s2; return t; } QT_ASCII_CAST_WARN inline QString operator+(const QByteArray &ba, const QString &s) { QString t = QString::fromUtf8(ba); t += s; return t; } QT_ASCII_CAST_WARN inline QString operator+(const QString &s, const QByteArray &ba) { QString t(s); t += QString::fromUtf8(ba); return t; } +QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const QByteArray &rhs) +{ QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) } # endif // QT_NO_CAST_FROM_ASCII #endif // QT_USE_QSTRINGBUILDER |