summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r--src/corelib/tools/qstring.cpp80
1 files changed, 43 insertions, 37 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index eb5804b2544..fe6cae25d12 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -720,6 +720,18 @@ const QString::Null QString::null = { };
\section1 More Efficient String Construction
+ Many strings are known at compile time. But the trivial
+ constructor QString("Hello"), will convert the string literal
+ to a QString using the codecForCStrings(). To avoid this one
+ can use the QStringLiteral macro to directly create the required
+ data at compile time. Constructing a QString out of the literal
+ does then not cause any overhead at runtime.
+
+ A slightly less efficient way is to use QLatin1String. This class wraps
+ a C string literal, precalculates it length at compile time and can
+ then be used for faster comparison with QStrings and conversion to
+ QStrings than a regular C string literal.
+
Using the QString \c{'+'} operator, it is easy to construct a
complex string from multiple substrings. You will often write code
like this:
@@ -735,9 +747,6 @@ const QString::Null QString::null = { };
where \e{n > 2}, there can be as many as \e{n - 1} calls to the
memory allocator.
- Second, QLatin1String does not store its length internally but
- calls qstrlen() when it needs to know its length.
-
In 4.6, an internal template class \c{QStringBuilder} has been
added along with a few helper functions. This class is marked
internal and does not appear in the documentation, because you
@@ -755,12 +764,6 @@ const QString::Null QString::null = { };
then called \e{once} to get the required space, and the substrings
are copied into it one by one.
- \c{QLatin1Literal} is a second internal class that can replace
- QLatin1String, which can't be changed for compatibility reasons.
- \c{QLatin1Literal} stores its length, thereby saving time when
- \c{QStringBuilder} computes the amount of memory required for the
- final string.
-
Additional efficiency is gained by inlining and reduced reference
counting (the QString created from a \c{QStringBuilder} typically
has a ref count of 1, whereas QString::append() needs an extra
@@ -2076,7 +2079,7 @@ QString &QString::replace(const QLatin1String &before,
const QString &after,
Qt::CaseSensitivity cs)
{
- int blen = qstrlen(before.latin1());
+ int blen = before.size();
QVarLengthArray<ushort> b(blen);
for (int i = 0; i < blen; ++i)
b[i] = (uchar)before.latin1()[i];
@@ -2099,7 +2102,7 @@ QString &QString::replace(const QString &before,
const QLatin1String &after,
Qt::CaseSensitivity cs)
{
- int alen = qstrlen(after.latin1());
+ int alen = after.size();
QVarLengthArray<ushort> a(alen);
for (int i = 0; i < alen; ++i)
a[i] = (uchar)after.latin1()[i];
@@ -2120,7 +2123,7 @@ QString &QString::replace(const QString &before,
*/
QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivity cs)
{
- int alen = qstrlen(after.latin1());
+ int alen = after.size();
QVarLengthArray<ushort> a(alen);
for (int i = 0; i < alen; ++i)
a[i] = (uchar)after.latin1()[i];
@@ -2150,20 +2153,23 @@ bool QString::operator==(const QString &other) const
*/
bool QString::operator==(const QLatin1String &other) const
{
+ if (d->size != other.size())
+ return false;
+
+ if (!other.size())
+ return isEmpty();
+
const ushort *uc = d->data();
const ushort *e = uc + d->size;
const uchar *c = (uchar *)other.latin1();
- if (!c)
- return isEmpty();
-
- while (*c) {
- if (uc == e || *uc != *c)
+ while (uc < e) {
+ if (*uc != *c)
return false;
++uc;
++c;
}
- return (uc == e);
+ return true;
}
/*! \fn bool QString::operator==(const QByteArray &other) const
@@ -2212,20 +2218,20 @@ bool QString::operator<(const QString &other) const
*/
bool QString::operator<(const QLatin1String &other) const
{
- const ushort *uc = d->data();
- const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
-
if (!c || *c == 0)
return false;
- while (*c) {
- if (uc == e || *uc != *c)
+ const ushort *uc = d->data();
+ const ushort *e = uc + qMin(d->size, other.size());
+
+ while (uc < e) {
+ if (*uc != *c)
break;
++uc;
++c;
}
- return (uc == e ? *c : *uc < *c);
+ return (uc == (d->data() + d->size) ? *c : *uc < *c);
}
/*! \fn bool QString::operator<(const QByteArray &other) const
@@ -2314,20 +2320,20 @@ bool QString::operator<(const QLatin1String &other) const
*/
bool QString::operator>(const QLatin1String &other) const
{
- const ushort *uc = d->data();;
- const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
-
if (!c || *c == '\0')
return !isEmpty();
- while (*c) {
- if (uc == e || *uc != *c)
+ const ushort *uc = d->data();;
+ const ushort *e = uc + qMin(d->size, other.size());
+
+ while (uc < e) {
+ if (*uc != *c)
break;
++uc;
++c;
}
- return (uc == e ? false : *uc > *c);
+ return (uc == (d->data() + d->size) ? false : *uc > *c);
}
/*! \fn bool QString::operator>(const QByteArray &other) const
@@ -2696,7 +2702,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
*/
int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
{
- const int sl = qstrlen(str.latin1());
+ const int sl = str.size();
if (sl == 1)
return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
@@ -3832,7 +3838,7 @@ QString QString::fromLocal8Bit(const char *str, int size)
if (!str)
return QString();
if (size == 0 || (!*str && size < 0))
- return QLatin1String("");
+ return QString(shared_empty);
#if !defined(QT_NO_TEXTCODEC)
if (size < 0)
size = qstrlen(str);
@@ -7468,7 +7474,7 @@ QDataStream &operator>>(QDataStream &in, QString &str)
}
}
} else {
- str = QLatin1String("");
+ str = QString(QLatin1String(""));
}
}
return in;
@@ -8440,7 +8446,7 @@ int QStringRef::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- const int sl = qstrlen(str.latin1());
+ const int sl = str.size();
if (sl == 1)
return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
@@ -8793,7 +8799,7 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size,
int from, Qt::CaseSensitivity cs)
{
const char *latin1 = needle.latin1();
- int len = qstrlen(latin1);
+ int len = needle.size();
QVarLengthArray<ushort> s(len);
for (int i = 0; i < len; ++i)
s[i] = latin1[i];
@@ -8834,7 +8840,7 @@ static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
return !needle.latin1();
if (haystackLen == 0)
return !needle.latin1() || *needle.latin1() == 0;
- const int slen = qstrlen(needle.latin1());
+ const int slen = needle.size();
if (slen > haystackLen)
return false;
const ushort *data = reinterpret_cast<const ushort*>(haystack);
@@ -8885,7 +8891,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
return !needle.latin1();
if (haystackLen == 0)
return !needle.latin1() || *needle.latin1() == 0;
- const int slen = qstrlen(needle.latin1());
+ const int slen = needle.size();
int pos = haystackLen - slen;
if (pos < 0)
return false;