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>
bb10
parent
e7e3e4cf25
commit
6631444eb1
|
|
@ -560,10 +560,16 @@ inline int QByteArray::compare(QByteArrayView a, Qt::CaseSensitivity cs) const n
|
|||
#if !defined(QT_USE_QSTRINGBUILDER)
|
||||
inline QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
|
||||
{ return QByteArray(a1) += a2; }
|
||||
inline QByteArray operator+(QByteArray &&lhs, const QByteArray &rhs)
|
||||
{ return std::move(lhs += rhs); }
|
||||
inline QByteArray operator+(const QByteArray &a1, const char *a2)
|
||||
{ return QByteArray(a1) += a2; }
|
||||
inline QByteArray operator+(QByteArray &&lhs, const char *rhs)
|
||||
{ return std::move(lhs += rhs); }
|
||||
inline QByteArray operator+(const QByteArray &a1, char a2)
|
||||
{ return QByteArray(a1) += a2; }
|
||||
inline QByteArray operator+(QByteArray &&lhs, char rhs)
|
||||
{ return std::move(lhs += rhs); }
|
||||
inline QByteArray operator+(const char *a1, const QByteArray &a2)
|
||||
{ return QByteArray(a1) += a2; }
|
||||
inline QByteArray operator+(char a1, const QByteArray &a2)
|
||||
|
|
|
|||
|
|
@ -6386,6 +6386,7 @@ QString& QString::fill(QChar ch, qsizetype size)
|
|||
|
||||
/*!
|
||||
\fn QString operator+(const QString &s1, const QString &s2)
|
||||
\fn QString operator+(QString &&s1, const QString &s2)
|
||||
\relates QString
|
||||
|
||||
Returns a string which is the result of concatenating \a s1 and \a
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -669,10 +669,14 @@ public:
|
|||
// comfort
|
||||
QList<T> &operator+=(const QList<T> &l) { append(l); return *this; }
|
||||
QList<T> &operator+=(QList<T> &&l) { append(std::move(l)); return *this; }
|
||||
inline QList<T> operator+(const QList<T> &l) const
|
||||
inline QList<T> operator+(const QList<T> &l) const &
|
||||
{ QList n = *this; n += l; return n; }
|
||||
inline QList<T> operator+(QList<T> &&l) const
|
||||
QList<T> operator+(const QList<T> &l) &&
|
||||
{ return std::move(*this += l); }
|
||||
inline QList<T> operator+(QList<T> &&l) const &
|
||||
{ QList n = *this; n += std::move(l); return n; }
|
||||
QList<T> operator+(QList<T> &&l) &&
|
||||
{ return std::move(*this += std::move(l)); }
|
||||
inline QList<T> &operator+=(parameter_type t)
|
||||
{ append(t); return *this; }
|
||||
inline QList<T> &operator<< (parameter_type t)
|
||||
|
|
|
|||
|
|
@ -1316,7 +1316,11 @@
|
|||
\sa append(), operator<<()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> QList<T> QList<T>::operator+(const QList<T> &other) const
|
||||
/*!
|
||||
\fn template <typename T> QList<T> QList<T>::operator+(const QList<T> &other) const &
|
||||
\fn template <typename T> QList<T> QList<T>::operator+(const QList<T> &other) &&
|
||||
\fn template <typename T> QList<T> QList<T>::operator+(QList<T> &&other) const &
|
||||
\fn template <typename T> QList<T> QList<T>::operator+(QList<T> &&other) &&
|
||||
|
||||
Returns a list that contains all the items in this list
|
||||
followed by all the items in the \a other list.
|
||||
|
|
@ -1324,14 +1328,6 @@
|
|||
\sa operator+=()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> QList<T> QList<T>::operator+(QList<T> &&other) const
|
||||
\since 6.0
|
||||
|
||||
\overload
|
||||
|
||||
\sa operator+=()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> QList<T> &QList<T>::operator<<(parameter_type value)
|
||||
|
||||
Appends \a value to the list and returns a reference to this list.
|
||||
|
|
|
|||
Loading…
Reference in New Issue