summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2014-07-28 19:50:35 -0700
committerThiago Macieira <thiago.macieira@intel.com>2014-11-02 20:51:57 +0100
commit294c914eb6bb5e0200480400ba31f2049edb9b86 (patch)
tree86fe3198ebc56f63efb2ea136be88e15a708368b
parent939197fd7c8b64256333d096f3b4ebbf066b2481 (diff)
Add rvalue-ref qualified {QString,QByteArray}::{simplified,trimmed}
Of the const overloads that return a QString or a QByteArray, this is one that gains the most benefit. It happens often in constructs like: QByteArray s = x.readLine().trimmed(); After this change, 41 out of 103 calls to trimmed become rvalue in Qt and 272 out of 441 in Qt Creator. For simplified, the numbers are 27 out of 69 in Qt and 10 out of 19 in Qt Creator. Other candidates are left, right, and mid, but there are exactly zero uses of left, right and mid on an xvalue QString or QByteArray in Qt. I'm being lazy and using qstring_compat.cpp to store the QByteArray compat methods. Change-Id: I4e410fc1adc4c761bb07cc3d43b348a65befa9f6 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/corelib/tools/qbytearray.cpp23
-rw-r--r--src/corelib/tools/qbytearray.h17
-rw-r--r--src/corelib/tools/qstring.cpp22
-rw-r--r--src/corelib/tools/qstring.h15
-rw-r--r--src/corelib/tools/qstring_compat.cpp20
-rw-r--r--src/corelib/tools/qstringalgorithms_p.h27
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp12
7 files changed, 121 insertions, 15 deletions
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index f57bcdb424..625b78d001 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -3196,6 +3196,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
*/
/*!
+ \fn QByteArray QByteArray::simplified() const
+
Returns a byte array that has whitespace removed from the start
and the end, and which has each sequence of internal whitespace
replaced with a single space.
@@ -3209,12 +3211,19 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
\sa trimmed()
*/
-QByteArray QByteArray::simplified() const
+QByteArray QByteArray::simplified_helper(const QByteArray &a)
{
- return QStringAlgorithms<const QByteArray>::simplified_helper(*this);
+ return QStringAlgorithms<const QByteArray>::simplified_helper(a);
+}
+
+QByteArray QByteArray::simplified_helper(QByteArray &a)
+{
+ return QStringAlgorithms<QByteArray>::simplified_helper(a);
}
/*!
+ \fn QByteArray QByteArray::trimmed() const
+
Returns a byte array that has whitespace removed from the start
and the end.
@@ -3229,11 +3238,17 @@ QByteArray QByteArray::simplified() const
\sa simplified()
*/
-QByteArray QByteArray::trimmed() const
+QByteArray QByteArray::trimmed_helper(const QByteArray &a)
{
- return QStringAlgorithms<const QByteArray>::trimmed_helper(*this);
+ return QStringAlgorithms<const QByteArray>::trimmed_helper(a);
}
+QByteArray QByteArray::trimmed_helper(QByteArray &a)
+{
+ return QStringAlgorithms<QByteArray>::trimmed_helper(a);
+}
+
+
/*!
Returns a byte array of size \a width that contains this byte
array padded by the \a fill character.
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 46aaeba1b5..6976124bca 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -272,16 +272,24 @@ public:
{ return toUpper_helper(*this); }
QByteArray toUpper() && Q_REQUIRED_RESULT
{ return toUpper_helper(*this); }
+ QByteArray trimmed() const & Q_REQUIRED_RESULT
+ { return trimmed_helper(*this); }
+ QByteArray trimmed() && Q_REQUIRED_RESULT
+ { return trimmed_helper(*this); }
+ QByteArray simplified() const & Q_REQUIRED_RESULT
+ { return simplified_helper(*this); }
+ QByteArray simplified() && Q_REQUIRED_RESULT
+ { return simplified_helper(*this); }
# ifdef Q_REQUIRED_RESULT_pushed
# pragma pop_macro("Q_REQUIRED_RESULT")
# endif
#else
QByteArray toLower() const Q_REQUIRED_RESULT;
QByteArray toUpper() const Q_REQUIRED_RESULT;
-#endif
-
QByteArray trimmed() const Q_REQUIRED_RESULT;
QByteArray simplified() const Q_REQUIRED_RESULT;
+#endif
+
QByteArray leftJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;
QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;
@@ -439,6 +447,11 @@ private:
static QByteArray toLower_helper(QByteArray &a);
static QByteArray toUpper_helper(const QByteArray &a);
static QByteArray toUpper_helper(QByteArray &a);
+ static QByteArray trimmed_helper(const QByteArray &a);
+ static QByteArray trimmed_helper(QByteArray &a);
+ static QByteArray simplified_helper(const QByteArray &a);
+ static QByteArray simplified_helper(QByteArray &a);
+
friend class QByteRef;
friend class QString;
friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes);
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index ae44e4185a..0d13cccbec 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -4682,6 +4682,8 @@ QString& QString::setUnicode(const QChar *unicode, int size)
*/
/*!
+ \fn QString QString::simplified() const
+
Returns a string that has whitespace removed from the start
and the end, and that has each sequence of internal whitespace
replaced with a single space.
@@ -4696,12 +4698,19 @@ QString& QString::setUnicode(const QChar *unicode, int size)
\sa trimmed()
*/
-QString QString::simplified() const
+QString QString::simplified_helper(const QString &str)
+{
+ return QStringAlgorithms<const QString>::simplified_helper(str);
+}
+
+QString QString::simplified_helper(QString &str)
{
- return QStringAlgorithms<const QString>::simplified_helper(*this);
+ return QStringAlgorithms<QString>::simplified_helper(str);
}
/*!
+ \fn QString QString::trimmed() const
+
Returns a string that has whitespace removed from the start and
the end.
@@ -4717,9 +4726,14 @@ QString QString::simplified() const
\sa simplified()
*/
-QString QString::trimmed() const
+QString QString::trimmed_helper(const QString &str)
+{
+ return QStringAlgorithms<const QString>::trimmed_helper(str);
+}
+
+QString QString::trimmed_helper(QString &str)
{
- return QStringAlgorithms<const QString>::trimmed_helper(*this);
+ return QStringAlgorithms<QString>::trimmed_helper(str);
}
/*! \fn const QChar QString::at(int position) const
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index a84179e1e6..718f10860a 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -395,6 +395,14 @@ public:
{ return toCaseFolded_helper(*this); }
QString toCaseFolded() && Q_REQUIRED_RESULT
{ return toCaseFolded_helper(*this); }
+ QString trimmed() const & Q_REQUIRED_RESULT
+ { return trimmed_helper(*this); }
+ QString trimmed() && Q_REQUIRED_RESULT
+ { return trimmed_helper(*this); }
+ QString simplified() const & Q_REQUIRED_RESULT
+ { return simplified_helper(*this); }
+ QString simplified() && Q_REQUIRED_RESULT
+ { return simplified_helper(*this); }
# ifdef Q_REQUIRED_RESULT_pushed
# pragma pop_macro("Q_REQUIRED_RESULT")
# endif
@@ -402,10 +410,9 @@ public:
QString toLower() const Q_REQUIRED_RESULT;
QString toUpper() const Q_REQUIRED_RESULT;
QString toCaseFolded() const Q_REQUIRED_RESULT;
-#endif
-
QString trimmed() const Q_REQUIRED_RESULT;
QString simplified() const Q_REQUIRED_RESULT;
+#endif
QString toHtmlEscaped() const Q_REQUIRED_RESULT;
QString &insert(int i, QChar c);
@@ -780,6 +787,10 @@ private:
static QString toUpper_helper(QString &str);
static QString toCaseFolded_helper(const QString &str);
static QString toCaseFolded_helper(QString &str);
+ static QString trimmed_helper(const QString &str);
+ static QString trimmed_helper(QString &str);
+ static QString simplified_helper(const QString &str);
+ static QString simplified_helper(QString &str);
static Data *fromLatin1_helper(const char *str, int size = -1);
static Data *fromAscii_helper(const char *str, int size = -1);
static QString fromUtf8_helper(const char *str, int size);
diff --git a/src/corelib/tools/qstring_compat.cpp b/src/corelib/tools/qstring_compat.cpp
index bc48e3e5cf..d4f21e483a 100644
--- a/src/corelib/tools/qstring_compat.cpp
+++ b/src/corelib/tools/qstring_compat.cpp
@@ -42,6 +42,16 @@
QT_BEGIN_NAMESPACE
// all these implementations must be the same as the inline versions in qstring.h
+QString QString::trimmed() const
+{
+ return trimmed_helper(*this);
+}
+
+QString QString::simplified() const
+{
+ return simplified_helper(*this);
+}
+
QString QString::toLower() const
{
return toLower_helper(*this);
@@ -83,4 +93,14 @@ QByteArray QByteArray::toUpper() const
return toUpper_helper(*this);
}
+QByteArray QByteArray::trimmed() const
+{
+ return trimmed_helper(*this);
+}
+
+QByteArray QByteArray::simplified() const
+{
+ return simplified_helper(*this);
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/tools/qstringalgorithms_p.h
index 5a68260c59..c3a87b2072 100644
--- a/src/corelib/tools/qstringalgorithms_p.h
+++ b/src/corelib/tools/qstringalgorithms_p.h
@@ -72,6 +72,23 @@ template <typename StringType> struct QStringAlgorithms
// not a problem because there are no space characters (Zs, Zl, Zp) outside the
// Basic Multilingual Plane.
+ static inline StringType trimmed_helper_inplace(NakedStringType &str, const Char *begin, const Char *end)
+ {
+ // in-place trimming:
+ Char *data = const_cast<Char *>(str.cbegin());
+ if (begin != data)
+ memmove(data, begin, (end - begin) * sizeof(Char));
+ str.resize(end - begin);
+ return qMove(str);
+ }
+
+ static inline StringType trimmed_helper_inplace(const NakedStringType &, const Char *, const Char *)
+ {
+ // can't happen
+ Q_UNREACHABLE();
+ return StringType();
+ }
+
static inline void trimmed_helper_positions(const Char *&begin, const Char *&end)
{
// skip white space from start
@@ -94,6 +111,8 @@ template <typename StringType> struct QStringAlgorithms
return str;
if (begin == end)
return StringType();
+ if (!isConst && str.isDetached())
+ return trimmed_helper_inplace(str, begin, end);
return StringType(begin, end - begin);
}
@@ -103,7 +122,9 @@ template <typename StringType> struct QStringAlgorithms
return str;
const Char *src = str.cbegin();
const Char *end = str.cend();
- NakedStringType result(str.size(), Qt::Uninitialized);
+ NakedStringType result = isConst ?
+ StringType(str.size(), Qt::Uninitialized) :
+ qMove(str);
Char *dst = const_cast<Char *>(result.cbegin());
Char *ptr = dst;
@@ -121,12 +142,12 @@ template <typename StringType> struct QStringAlgorithms
--ptr;
int newlen = ptr - dst;
- if (newlen == str.size()) {
+ if (isConst && newlen == str.size()) {
// nothing happened, return the original
return str;
}
result.resize(ptr - dst);
- return qMove(result);
+ return result;
}
};
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 054cb733a1..57473021aa 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -2067,6 +2067,13 @@ void tst_QString::trimmed()
QCOMPARE(a,(QString)" ");
a=" a ";
QCOMPARE(a.trimmed(),(QString)"a");
+
+ a="Text";
+ QCOMPARE(qMove(a).trimmed(),(QString)"Text");
+ a=" ";
+ QCOMPARE(qMove(a).trimmed(),(QString)"");
+ a=" a ";
+ QCOMPARE(qMove(a).trimmed(),(QString)"a");
}
void tst_QString::simplified_data()
@@ -2112,6 +2119,11 @@ void tst_QString::simplified()
} else {
QCOMPARE(result, simple);
}
+
+ // force a detach
+ if (!full.isEmpty())
+ full[0] = full[0];
+ QCOMPARE(qMove(full).simplified(), simple);
}
void tst_QString::insert()