summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2011-07-04 12:21:06 +0200
committerQt by Nokia <qt-info@nokia.com>2011-07-07 12:30:00 +0200
commitf4c07fe72168778cd6ea5a6c07fb6add91b2e3d0 (patch)
tree866cf043306325db0de2ee7dcf690fae32990bb1 /src/corelib
parentee85e9cc10bc6874c892b09fa54b5dbd79854069 (diff)
Unify QLatin1String and QLatin1Literal
Unify the two classes and get rid of one TODO item for Qt 5. Using strlen in the constructor of QLatin1String works, as the compiler can do the calculation at compile time. Change-Id: I59d98c71a34b86d4211fa0d8cfd40b7d612c5a78 Reviewed-on: http://codereview.qt.nokia.com/1219 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qstring.cpp80
-rw-r--r--src/corelib/tools/qstring.h13
-rw-r--r--src/corelib/tools/qstringbuilder.cpp49
-rw-r--r--src/corelib/tools/qstringbuilder.h38
4 files changed, 57 insertions, 123 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index eb5804b254..fe6cae25d1 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;
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 81dff3d309..e0473e411a 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -610,11 +610,11 @@ public:
class Q_CORE_EXPORT QLatin1String
{
public:
- inline explicit QLatin1String(const char *s) : chars(s) {}
- inline QLatin1String &operator=(const QLatin1String &other)
- { chars = other.chars; return *this; }
+ inline explicit QLatin1String(const char *s) : m_size(s ? strlen(s) : 0), m_data(s) {}
- inline const char *latin1() const { return chars; }
+ inline const char *latin1() const { return m_data; }
+ inline int size() const { return m_size; }
+ inline const char *data() const { return m_data; }
inline bool operator==(const QString &s) const
{ return s == *this; }
@@ -642,9 +642,12 @@ public:
inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const
{ return QString::fromAscii(s) <= *this; }
private:
- const char *chars;
+ int m_size;
+ const char *m_data;
};
+// Qt 4.x compatibility
+typedef QLatin1String QLatin1Literal;
inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLatin1.latin1()))
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 1cc7e5d2c3..4c6848498b 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -45,47 +45,6 @@
QT_BEGIN_NAMESPACE
/*!
- \class QLatin1Literal
- \internal
- \reentrant
- \since 4.6
-
- \brief The QLatin1Literal class provides a thin wrapper around string
- literals used in source code.
-
- \ingroup tools
- \ingroup shared
- \ingroup string-processing
-
-
- Unlike \c QLatin1String, a \c QLatin1Literal can retrieve its size
- without iterating over the literal.
-
- The main use of \c QLatin1Literal is in conjunction with \c QStringBuilder
- to reduce the number of reallocations needed to build up a string from
- smaller chunks.
-
- \sa QStringBuilder, QLatin1String, QString, QStringRef
-*/
-
-/*! \fn int QLatin1Literal::size() const
-
- Returns the number of characters in the literal \e{excluding} the trailing
- NULL char.
-*/
-
-/*! \fn QLatin1Literal::QLatin1Literal(const char str)
-
- Constructs a new literal from the string \a str.
-*/
-
-/*! \fn const char *QLatin1Literal::data() const
-
- Returns a pointer to the first character of the string literal.
- The string literal is terminated by a NUL character.
-*/
-
-/*!
\class QStringBuilder
\internal
\reentrant
@@ -110,7 +69,7 @@ QT_BEGIN_NAMESPACE
The QStringBuilder class is not to be used explicitly in user
code. Instances of the class are created as return values of the
operator%() function, acting on objects of type QString,
- QLatin1String, QLatin1Literal, QStringRef, QChar, QCharRef,
+ QLatin1String, QStringRef, QChar, QCharRef,
QLatin1Char, and \c char.
Concatenating strings with operator%() generally yields better
@@ -118,7 +77,7 @@ QT_BEGIN_NAMESPACE
if there are three or more of them, and performs equally well in other
cases.
- \sa QLatin1Literal, QString
+ \sa QLatin1String, QString
*/
/*! \fn QStringBuilder::QStringBuilder(const A &a, const B &b)
@@ -132,7 +91,7 @@ QT_BEGIN_NAMESPACE
takes a QString parameter.
This function is usable with arguments of type \c QString,
- \c QLatin1String, \c QLatin1Literal, \c QStringRef,
+ \c QLatin1String, \c QStringRef,
\c QChar, \c QCharRef, \c QLatin1Char, and \c char.
*/
@@ -145,7 +104,7 @@ QT_BEGIN_NAMESPACE
/*!
\fn operator QStringBuilder::QString() const
- Converts the \c QLatin1Literal into a \c QString object.
+ Converts the \c QLatin1String into a \c QString object.
*/
/*! \internal
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 594ab2f183..c86a51f8e3 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -59,22 +59,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Core)
-// ### Qt 5: merge with QLatin1String
-class QLatin1Literal
-{
-public:
- int size() const { return m_size; }
- const char *data() const { return m_data; }
-
- template <int N>
- QLatin1Literal(const char (&str)[N])
- : m_size(N - 1), m_data(str) {}
-
-private:
- const int m_size;
- const char * const m_data;
-};
-
struct Q_CORE_EXPORT QAbstractConcatenable
{
protected:
@@ -234,31 +218,13 @@ template <> struct QConcatenable<QLatin1String>
typedef QLatin1String type;
typedef QString ConvertTo;
enum { ExactSize = true };
- static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
+ static int size(const QLatin1String &a) { return a.size(); }
static inline void appendTo(const QLatin1String &a, QChar *&out)
{
- for (const char *s = a.latin1(); *s; )
- *out++ = QLatin1Char(*s++);
- }
- static inline void appendTo(const QLatin1String &a, char *&out)
- {
- for (const char *s = a.latin1(); *s; )
- *out++ = *s++;
- }
-};
-
-template <> struct QConcatenable<QLatin1Literal>
-{
- typedef QLatin1Literal type;
- typedef QString ConvertTo;
- enum { ExactSize = true };
- static int size(const QLatin1Literal &a) { return a.size(); }
- static inline void appendTo(const QLatin1Literal &a, QChar *&out)
- {
for (const char *s = a.data(); *s; )
*out++ = QLatin1Char(*s++);
}
- static inline void appendTo(const QLatin1Literal &a, char *&out)
+ static inline void appendTo(const QLatin1String &a, char *&out)
{
for (const char *s = a.data(); *s; )
*out++ = *s++;