diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 80 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 13 | ||||
-rw-r--r-- | src/corelib/tools/qstringbuilder.cpp | 49 | ||||
-rw-r--r-- | src/corelib/tools/qstringbuilder.h | 38 |
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++; |