summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2011-07-06 09:21:10 +0200
committerQt by Nokia <qt-info@nokia.com>2011-07-07 12:30:00 +0200
commitee85e9cc10bc6874c892b09fa54b5dbd79854069 (patch)
treeabc628be1f6a35ce12bda3d5f7ca7297dfb4d65c /src
parentfcca106e590ba550c536a6b8de1b011ccc2c0d30 (diff)
Support for compile time generated QStrings
use with QString string(QStringLiteral("foo")) or QString string(qs("foo")). qs(...) can in almost all places replace QLatin1String. the Macro qs requires c++0x support or a compiler where sizeof(wchar_t) == 2. In case these conditions are not met, qs simply falls back to QLatin1String. The commit also cleans up the QStringData structure significantly, now using only 16 bytes for the header on 32 bit systems. The bitflags to store unicode directionality of the string and whether the string would require complex text processing to render are removed. They don't really belong here and the result can be calculated very fast in any case. Added an internal QRefCount class the encapsulates the reference counting semantics required where a negative refcount is never changed. This is required to be able to put the string data into a constant POD object. Change-Id: I5b1395213deca48b2d582a036a0e8a8358d26d14 Reviewed-on: http://codereview.qt.nokia.com/1218 Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qstring.cpp439
-rw-r--r--src/corelib/tools/qstring.h130
2 files changed, 287 insertions, 282 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index afb396ce50..eb5804b254 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -797,10 +797,8 @@ const QString::Null QString::null = { };
\sa split()
*/
-QString::Data QString::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1),
- 0, 0, shared_null.array, 0, 0, 0, 0, 0, {0} };
-QString::Data QString::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
- 0, 0, shared_empty.array, 0, 0, 0, 0, 0, {0} };
+const QConstStringData<1> QString::shared_null = (const QConstStringData<1>) { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
+const QConstStringData<1> QString::shared_empty = (const QConstStringData<1>) { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
int QString::grow(int size)
{
@@ -1044,20 +1042,15 @@ int QString::toWCharArray(wchar_t *array) const
QString::QString(const QChar *unicode, int size)
{
if (!unicode) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size <= 0) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- memcpy(d->array, unicode, size * sizeof(QChar));
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ memcpy(d->data(), unicode, size * sizeof(QChar));
+ d->data()[size] = '\0';
}
}
@@ -1073,24 +1066,19 @@ QString::QString(const QChar *unicode, int size)
QString::QString(const QChar *unicode)
{
if (!unicode) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else {
int size = 0;
while (unicode[size] != 0)
++size;
if (!size) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- memcpy(d->array, unicode, size * sizeof(QChar));
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ memcpy(d->data(), unicode, size * sizeof(QChar));
+ d->data()[size] = '\0';
}
}
}
@@ -1105,18 +1093,14 @@ QString::QString(const QChar *unicode)
QString::QString(int size, QChar ch)
{
if (size <= 0) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
- ushort *i = d->array + size;
- ushort *b = d->array;
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
+ ushort *i = d->data() + size;
+ ushort *b = d->data();
const ushort value = ch.unicode();
while (i != b)
*--i = value;
@@ -1131,13 +1115,10 @@ QString::QString(int size, QChar ch)
*/
QString::QString(int size, Qt::Initialization)
{
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
}
/*! \fn QString::QString(const QLatin1String &str)
@@ -1152,15 +1133,11 @@ QString::QString(int size, Qt::Initialization)
*/
QString::QString(QChar ch)
{
- void *buf = qMalloc(sizeof(Data) + sizeof(QChar));
- Q_CHECK_PTR(buf);
- d = reinterpret_cast<Data *>(buf);
- d->ref = 1;
- d->alloc = d->size = 1;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[0] = ch.unicode();
- d->array[1] = '\0';
+ d = (Data *) qMalloc(sizeof(Data) + 2*sizeof(QChar));
+ Q_CHECK_PTR(d);
+ *d = (Data) { Q_REFCOUNT_INITIALIZER(1), 1, 1, false, { 0 } };
+ d->data()[0] = ch.unicode();
+ d->data()[1] = '\0';
}
/*! \fn QString::QString(const QByteArray &ba)
@@ -1256,21 +1233,23 @@ void QString::resize(int size)
if (size < 0)
size = 0;
- if (size == 0 && !d->capacity) {
- Data *x = &shared_empty;
- x->ref.ref();
+ if (d->offset && d->ref == 1 && size < d->size) {
+ d->size = size;
+ return;
+ }
+
+ if (size == 0 && !d->capacityReserved) {
+ Data *x = const_cast<Data *>(&shared_empty.str);
if (!d->ref.deref())
QString::free(d);
d = x;
} else {
if (d->ref != 1 || size > d->alloc ||
- (!d->capacity && size < d->size && size < d->alloc >> 1))
+ (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
realloc(grow(size));
if (d->alloc >= size) {
d->size = size;
- if (d->data == d->array) {
- d->array[size] = '\0';
- }
+ d->data()[size] = '\0';
}
}
}
@@ -1328,28 +1307,21 @@ void QString::resize(int size)
// ### Qt 5: rename reallocData() to avoid confusion. 197625
void QString::realloc(int alloc)
{
- if (d->ref != 1 || d->data != d->array) {
- Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc * sizeof(QChar)));
+ if (d->ref != 1 || d->offset) {
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
Q_CHECK_PTR(x);
- x->size = qMin(alloc, d->size);
- ::memcpy(x->array, d->data, x->size * sizeof(QChar));
- x->array[x->size] = 0;
- x->ref = 1;
- x->alloc = alloc;
- x->clean = d->clean;
- x->simpletext = d->simpletext;
- x->righttoleft = d->righttoleft;
- x->capacity = d->capacity;
- x->data = x->array;
+ *x = (Data){ Q_REFCOUNT_INITIALIZER(1), qMin(alloc, d->size), alloc, d->capacityReserved, { 0 } };
+ ::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
+ x->data()[x->size] = 0;
if (!d->ref.deref())
QString::free(d);
d = x;
} else {
- Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)));
+ Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + (alloc+1) * sizeof(QChar)));
Q_CHECK_PTR(p);
d = p;
d->alloc = alloc;
- d->data = d->array;
+ d->offset = 0;
}
}
@@ -1363,8 +1335,8 @@ void QString::expand(int i)
int sz = d->size;
resize(qMax(i + 1, sz));
if (d->size - 1 > sz) {
- ushort *n = d->data + d->size - 1;
- ushort *e = d->data + sz;
+ ushort *n = d->data() + d->size - 1;
+ ushort *e = d->data() + sz;
while (n != e)
* --n = ' ';
}
@@ -1482,9 +1454,9 @@ QString &QString::insert(int i, const QLatin1String &str)
int len = qstrlen(str.latin1());
expand(qMax(d->size, i) + len - 1);
- ::memmove(d->data + i + len, d->data + i, (d->size - i - len) * sizeof(QChar));
+ ::memmove(d->data() + i + len, d->data() + i, (d->size - i - len) * sizeof(QChar));
for (int j = 0; j < len; ++j)
- d->data[i + j] = s[j];
+ d->data()[i + j] = s[j];
return *this;
}
@@ -1501,7 +1473,7 @@ QString& QString::insert(int i, const QChar *unicode, int size)
return *this;
const ushort *s = (const ushort *)unicode;
- if (s >= d->data && s < d->data + d->alloc) {
+ if (s >= d->data() && s < d->data() + d->alloc) {
// Part of me - take a copy
ushort *tmp = static_cast<ushort *>(qMalloc(size * sizeof(QChar)));
Q_CHECK_PTR(tmp);
@@ -1513,8 +1485,8 @@ QString& QString::insert(int i, const QChar *unicode, int size)
expand(qMax(d->size, i) + size - 1);
- ::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar));
- memcpy(d->data + i, s, size * sizeof(QChar));
+ ::memmove(d->data() + i + size, d->data() + i, (d->size - i - size) * sizeof(QChar));
+ memcpy(d->data() + i, s, size * sizeof(QChar));
return *this;
}
@@ -1532,8 +1504,8 @@ QString& QString::insert(int i, QChar ch)
if (i < 0)
return *this;
expand(qMax(i, d->size));
- ::memmove(d->data + i + 1, d->data + i, (d->size - i) * sizeof(QChar));
- d->data[i] = ch.unicode();
+ ::memmove(d->data() + i + 1, d->data() + i, (d->size - i) * sizeof(QChar));
+ d->data()[i] = ch.unicode();
return *this;
}
@@ -1557,15 +1529,15 @@ QString& QString::insert(int i, QChar ch)
*/
QString &QString::append(const QString &str)
{
- if (str.d != &shared_null) {
- if (d == &shared_null) {
+ if (str.d != &shared_null.str) {
+ if (d == &shared_null.str) {
operator=(str);
} else {
if (d->ref != 1 || d->size + str.d->size > d->alloc)
realloc(grow(d->size + str.d->size));
- memcpy(d->data + d->size, str.d->data, str.d->size * sizeof(QChar));
+ memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
d->size += str.d->size;
- d->data[d->size] = '\0';
+ d->data()[d->size] = '\0';
}
}
return *this;
@@ -1583,7 +1555,7 @@ QString &QString::append(const QLatin1String &str)
int len = qstrlen((char *)s);
if (d->ref != 1 || d->size + len > d->alloc)
realloc(grow(d->size + len));
- ushort *i = d->data + d->size;
+ ushort *i = d->data() + d->size;
while ((*i++ = *s++))
;
d->size += len;
@@ -1626,8 +1598,8 @@ QString &QString::append(QChar ch)
{
if (d->ref != 1 || d->size + 1 > d->alloc)
realloc(grow(d->size + 1));
- d->data[d->size++] = ch.unicode();
- d->data[d->size] = '\0';
+ d->data()[d->size++] = ch.unicode();
+ d->data()[d->size] = '\0';
return *this;
}
@@ -1707,7 +1679,7 @@ QString &QString::remove(int pos, int len)
resize(pos); // truncate
} else if (len > 0) {
detach();
- memmove(d->data + pos, d->data + pos + len,
+ memmove(d->data() + pos, d->data() + pos + len,
(d->size - pos - len + 1) * sizeof(ushort));
d->size -= len;
}
@@ -1756,14 +1728,14 @@ QString &QString::remove(QChar ch, Qt::CaseSensitivity cs)
ushort c = ch.unicode();
if (cs == Qt::CaseSensitive) {
while (i < d->size)
- if (d->data[i] == ch)
+ if (d->data()[i] == ch)
remove(i, 1);
else
i++;
} else {
c = foldCase(c);
while (i < d->size)
- if (foldCase(d->data[i]) == c)
+ if (foldCase(d->data()[i]) == c)
remove(i, 1);
else
i++;
@@ -1859,10 +1831,10 @@ QString &QString::replace(const QString &before, const QString &after, Qt::CaseS
*/
void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen)
{
- // copy *after in case it lies inside our own d->data area
+ // copy *after in case it lies inside our own d->data() area
// (which we could possibly invalidate via a realloc or corrupt via memcpy operations.)
QChar *afterBuffer = const_cast<QChar *>(after);
- if (after >= reinterpret_cast<QChar *>(d->data) && after < reinterpret_cast<QChar *>(d->data) + d->size) {
+ if (after >= reinterpret_cast<QChar *>(d->data()) && after < reinterpret_cast<QChar *>(d->data()) + d->size) {
afterBuffer = static_cast<QChar *>(qMalloc(alen*sizeof(QChar)));
Q_CHECK_PTR(afterBuffer);
::memcpy(afterBuffer, after, alen*sizeof(QChar));
@@ -1873,30 +1845,30 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
// replace in place
detach();
for (int i = 0; i < nIndices; ++i)
- memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar));
+ memcpy(d->data() + indices[i], afterBuffer, alen * sizeof(QChar));
} else if (alen < blen) {
// replace from front
detach();
uint to = indices[0];
if (alen)
- memcpy(d->data+to, after, alen*sizeof(QChar));
+ memcpy(d->data()+to, after, alen*sizeof(QChar));
to += alen;
uint movestart = indices[0] + blen;
for (int i = 1; i < nIndices; ++i) {
int msize = indices[i] - movestart;
if (msize > 0) {
- memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
+ memmove(d->data() + to, d->data() + movestart, msize * sizeof(QChar));
to += msize;
}
if (alen) {
- memcpy(d->data + to, afterBuffer, alen*sizeof(QChar));
+ memcpy(d->data() + to, afterBuffer, alen*sizeof(QChar));
to += alen;
}
movestart = indices[i] + blen;
}
int msize = d->size - movestart;
if (msize > 0)
- memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
+ memmove(d->data() + to, d->data() + movestart, msize * sizeof(QChar));
resize(d->size - nIndices*(blen-alen));
} else {
// replace from back
@@ -1910,9 +1882,9 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
int movestart = indices[nIndices] + blen;
int insertstart = indices[nIndices] + nIndices*(alen-blen);
int moveto = insertstart + alen;
- memmove(d->data + moveto, d->data + movestart,
+ memmove(d->data() + moveto, d->data() + movestart,
(moveend - movestart)*sizeof(QChar));
- memcpy(d->data + insertstart, afterBuffer, alen*sizeof(QChar));
+ memcpy(d->data() + insertstart, afterBuffer, alen*sizeof(QChar));
moveend = movestart-blen;
}
}
@@ -1994,7 +1966,7 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
return remove(ch, cs);
if (after.d->size == 1)
- return replace(ch, after.d->data[0], cs);
+ return replace(ch, after.d->data()[0], cs);
if (d->size == 0)
return *this;
@@ -2007,13 +1979,13 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
uint pos = 0;
if (cs == Qt::CaseSensitive) {
while (pos < 1023 && index < d->size) {
- if (d->data[index] == cc)
+ if (d->data()[index] == cc)
indices[pos++] = index;
index++;
}
} else {
while (pos < 1023 && index < d->size) {
- if (QChar::toCaseFolded(d->data[index]) == cc)
+ if (QChar::toCaseFolded(d->data()[index]) == cc)
indices[pos++] = index;
index++;
}
@@ -2045,7 +2017,7 @@ QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
ushort b = before.unicode();
if (d->size) {
detach();
- ushort *i = d->data;
+ ushort *i = d->data();
const ushort *e = i + d->size;
if (cs == Qt::CaseSensitive) {
for (; i != e; ++i)
@@ -2170,7 +2142,7 @@ bool QString::operator==(const QString &other) const
if (d->size != other.d->size)
return false;
- return qMemEquals(d->data, other.d->data, d->size);
+ return qMemEquals(d->data(), other.d->data(), d->size);
}
/*!
@@ -2178,7 +2150,7 @@ bool QString::operator==(const QString &other) const
*/
bool QString::operator==(const QLatin1String &other) const
{
- const ushort *uc = d->data;
+ const ushort *uc = d->data();
const ushort *e = uc + d->size;
const uchar *c = (uchar *)other.latin1();
@@ -2240,7 +2212,7 @@ bool QString::operator<(const QString &other) const
*/
bool QString::operator<(const QLatin1String &other) const
{
- const ushort *uc = d->data;
+ const ushort *uc = d->data();
const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
@@ -2342,7 +2314,7 @@ bool QString::operator<(const QLatin1String &other) const
*/
bool QString::operator>(const QLatin1String &other) const
{
- const ushort *uc = d->data;;
+ const ushort *uc = d->data();;
const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
@@ -2687,7 +2659,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
{
const int sl = str.d->size;
if (sl == 1)
- return lastIndexOf(QChar(str.d->data[0]), from, cs);
+ return lastIndexOf(QChar(str.d->data()[0]), from, cs);
const int l = d->size;
if (from < 0)
@@ -2700,7 +2672,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
if (from > delta)
from = delta;
- return lastIndexOfHelper(d->data, from, str.d->data, str.d->size, cs);
+ return lastIndexOfHelper(d->data(), from, str.d->data(), str.d->size, cs);
}
/*!
@@ -2743,7 +2715,7 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity
for (int i = 0; i < sl; ++i)
s[i] = str.latin1()[i];
- return lastIndexOfHelper(d->data, from, s.data(), sl, cs);
+ return lastIndexOfHelper(d->data(), from, s.data(), sl, cs);
}
/*!
@@ -2789,7 +2761,7 @@ int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs
if (from > delta)
from = delta;
- return lastIndexOfHelper(d->data, from, reinterpret_cast<const ushort*>(str.unicode()),
+ return lastIndexOfHelper(d->data(), from, reinterpret_cast<const ushort*>(str.unicode()),
str.size(), cs);
}
@@ -2940,14 +2912,14 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
while (i < pos) {
int copyend = replacements[i].pos;
int size = copyend - copystart;
- memcpy(uc, d->data + copystart, size * sizeof(QChar));
+ memcpy(uc, d->data() + copystart, size * sizeof(QChar));
uc += size;
- memcpy(uc, after.d->data, al * sizeof(QChar));
+ memcpy(uc, after.d->data(), al * sizeof(QChar));
uc += al;
copystart = copyend + replacements[i].length;
i++;
}
- memcpy(uc, d->data + copystart, (d->size - copystart) * sizeof(QChar));
+ memcpy(uc, d->data() + copystart, (d->size - copystart) * sizeof(QChar));
newstring.resize(newlen);
*this = newstring;
caretMode = QRegExp::CaretWontMatch;
@@ -3366,7 +3338,7 @@ QString QString::left(int n) const
{
if (n >= d->size || n < 0)
return *this;
- return QString((const QChar*) d->data, n);
+ return QString((const QChar*) d->data(), n);
}
/*!
@@ -3384,7 +3356,7 @@ QString QString::right(int n) const
{
if (n >= d->size || n < 0)
return *this;
- return QString((const QChar*) d->data + d->size - n, n);
+ return QString((const QChar*) d->data() + d->size - n, n);
}
/*!
@@ -3406,7 +3378,7 @@ QString QString::right(int n) const
QString QString::mid(int position, int n) const
{
- if (d == &shared_null || position >= d->size)
+ if (d == &shared_null.str || position >= d->size)
return QString();
if (n < 0)
n = d->size - position;
@@ -3418,7 +3390,7 @@ QString QString::mid(int position, int n) const
n = d->size - position;
if (position == 0 && n == d->size)
return *this;
- return QString((const QChar*) d->data + position, n);
+ return QString((const QChar*) d->data() + position, n);
}
/*!
@@ -3456,8 +3428,8 @@ bool QString::startsWith(const QChar &c, Qt::CaseSensitivity cs) const
{
return d->size
&& (cs == Qt::CaseSensitive
- ? d->data[0] == c
- : foldCase(d->data[0]) == foldCase(c.unicode()));
+ ? d->data()[0] == c
+ : foldCase(d->data()[0]) == foldCase(c.unicode()));
}
/*!
@@ -3530,8 +3502,8 @@ bool QString::endsWith(const QChar &c, Qt::CaseSensitivity cs) const
{
return d->size
&& (cs == Qt::CaseSensitive
- ? d->data[d->size - 1] == c
- : foldCase(d->data[d->size - 1]) == foldCase(c.unicode()));
+ ? d->data()[d->size - 1] == c
+ : foldCase(d->data()[d->size - 1]) == foldCase(c.unicode()));
}
/*! \fn const char *QString::ascii() const
@@ -3765,22 +3737,17 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
{
Data *d;
if (!str) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size == 0 || (!*str && size < 0)) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
if (size < 0)
size = qstrlen(str);
- d = static_cast<Data *>(qMalloc(sizeof(Data) + size * sizeof(QChar)));
+ d = static_cast<Data *>(qMalloc(sizeof(Data) + (size+1) * sizeof(QChar)));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
- ushort *dst = d->data;
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
+ ushort *dst = d->data();
/* SIMD:
* Unpacking with SSE has been shown to improve performance on recent CPUs
* The same method gives no improvement with NEON.
@@ -3818,11 +3785,9 @@ QString::Data *QString::fromAscii_helper(const char *str, int size)
if (codecForCStrings) {
Data *d;
if (!str) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size == 0 || (!*str && size < 0)) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
if (size < 0)
size = qstrlen(str);
@@ -3995,7 +3960,7 @@ QString& QString::setUnicode(const QChar *unicode, int size)
{
resize(size);
if (unicode && size)
- memcpy(d->data, unicode, size * sizeof(QChar));
+ memcpy(d->data(), unicode, size * sizeof(QChar));
return *this;
}
@@ -4034,7 +3999,7 @@ QString QString::simplified() const
if (d->size == 0)
return *this;
- const QChar * const start = reinterpret_cast<QChar *>(d->data);
+ const QChar * const start = reinterpret_cast<QChar *>(d->data());
const QChar *from = start;
const QChar *fromEnd = start + d->size;
forever {
@@ -4043,8 +4008,7 @@ QString QString::simplified() const
break;
if (++from == fromEnd) {
// All-whitespace string
- shared_empty.ref.ref();
- return QString(&shared_empty, 0);
+ return QString(shared_empty);
}
}
// This loop needs no underflow check, as we already determined that
@@ -4079,7 +4043,7 @@ QString QString::simplified() const
// of already simplified characters - at least one, obviously -
// without a trailing space.
QString result((fromEnd - from) + copyCount, Qt::Uninitialized);
- QChar *to = reinterpret_cast<QChar *>(result.d->data);
+ QChar *to = reinterpret_cast<QChar *>(result.d->data());
::memcpy(to, copyFrom, copyCount * 2);
to += copyCount;
fromEnd--;
@@ -4100,7 +4064,7 @@ QString QString::simplified() const
}
done:
*to++ = ch;
- result.truncate(to - reinterpret_cast<QChar *>(result.d->data));
+ result.truncate(to - reinterpret_cast<QChar *>(result.d->data()));
return result;
}
@@ -4124,7 +4088,7 @@ QString QString::trimmed() const
{
if (d->size == 0)
return *this;
- const QChar *s = (const QChar*)d->data;
+ const QChar *s = (const QChar*)d->data();
if (!s->isSpace() && !s[d->size-1].isSpace())
return *this;
int start = 0;
@@ -4137,8 +4101,7 @@ QString QString::trimmed() const
}
int l = end - start + 1;
if (l <= 0) {
- shared_empty.ref.ref();
- return QString(&shared_empty, 0);
+ return QString(shared_empty);
}
return QString(s + start, l);
}
@@ -4250,8 +4213,8 @@ QString& QString::fill(QChar ch, int size)
{
resize(size < 0 ? d->size : size);
if (d->size) {
- QChar *i = (QChar*)d->data + d->size;
- QChar *b = (QChar*)d->data;
+ QChar *i = (QChar*)d->data() + d->size;
+ QChar *b = (QChar*)d->data();
while (i != b)
*--i = ch;
}
@@ -4597,7 +4560,7 @@ int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
{
if (cs == Qt::CaseSensitive)
return ucstrcmp(constData(), length(), other.constData(), other.length());
- return ucstricmp(d->data, d->data + d->size, other.d->data, other.d->data + other.d->size);
+ return ucstricmp(d->data(), d->data() + d->size, other.d->data(), other.d->data() + other.d->size);
}
/*!
@@ -4828,12 +4791,9 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
const ushort *QString::utf16() const
{
- if (d->data != d->array) {
- QString *that = const_cast<QString*>(this);
- that->realloc(); // ensure '\\0'-termination for ::fromRawData strings
- return that->d->data;
- }
- return d->array;
+ if (d->offset)
+ const_cast<QString*>(this)->realloc(); // ensure '\\0'-termination for ::fromRawData strings
+ return d->data();
}
/*!
@@ -4862,8 +4822,8 @@ QString QString::leftJustified(int width, QChar fill, bool truncate) const
if (padlen > 0) {
result.resize(len+padlen);
if (len)
- memcpy(result.d->data, d->data, sizeof(QChar)*len);
- QChar *uc = (QChar*)result.d->data + len;
+ memcpy(result.d->data(), d->data(), sizeof(QChar)*len);
+ QChar *uc = (QChar*)result.d->data() + len;
while (padlen--)
* uc++ = fill;
} else {
@@ -4900,11 +4860,11 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
int padlen = width - len;
if (padlen > 0) {
result.resize(len+padlen);
- QChar *uc = (QChar*)result.d->data;
+ QChar *uc = (QChar*)result.d->data();
while (padlen--)
* uc++ = fill;
if (len)
- memcpy(uc, d->data, sizeof(QChar)*len);
+ memcpy(uc, d->data(), sizeof(QChar)*len);
} else {
if (truncate)
result = left(width);
@@ -4924,7 +4884,7 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
QString QString::toLower() const
{
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
if (!d->size)
@@ -4939,7 +4899,7 @@ QString QString::toLower() const
}
#endif
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
// this avoids one out of bounds check in the loop
if (QChar(*p).isLowSurrogate())
@@ -4952,17 +4912,17 @@ QString QString::toLower() const
const QUnicodeTables::Properties *prop = qGetProp(c);
if (prop->lowerCaseDiff || prop->lowerCaseSpecial) {
QString s(d->size, Qt::Uninitialized);
- memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
- ushort *pp = s.d->data + (p - d->data);
+ memcpy(s.d->data(), d->data(), (p - d->data())*sizeof(ushort));
+ ushort *pp = s.d->data() + (p - d->data());
while (p < e) {
uint c = *p;
if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
c = QChar::surrogateToUcs4(*(p - 1), c);
prop = qGetProp(c);
if (prop->lowerCaseSpecial) {
- int pos = pp - s.d->data;
+ int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
- pp = s.d->data + pos;
+ pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff;
while (*specialCase)
*pp++ = *specialCase++;
@@ -4971,7 +4931,7 @@ QString QString::toLower() const
}
++p;
}
- s.truncate(pp - s.d->data);
+ s.truncate(pp - s.d->data());
return s;
}
++p;
@@ -4988,11 +4948,11 @@ QString QString::toCaseFolded() const
if (!d->size)
return *this;
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
uint last = 0;
while (p < e) {
@@ -5000,9 +4960,9 @@ QString QString::toCaseFolded() const
if (folded != *p) {
QString s(*this);
s.detach();
- ushort *pp = s.d->data + (p - d->data);
- const ushort *ppe = s.d->data + s.d->size;
- last = pp > s.d->data ? *(pp - 1) : 0;
+ ushort *pp = s.d->data() + (p - d->data());
+ const ushort *ppe = s.d->data() + s.d->size;
+ last = pp > s.d->data() ? *(pp - 1) : 0;
while (pp < ppe) {
*pp = foldCase(*pp, last);
++pp;
@@ -5024,7 +4984,7 @@ QString QString::toCaseFolded() const
QString QString::toUpper() const
{
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
if (!d->size)
@@ -5039,7 +4999,7 @@ QString QString::toUpper() const
}
#endif
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
// this avoids one out of bounds check in the loop
if (QChar(*p).isLowSurrogate())
@@ -5052,17 +5012,17 @@ QString QString::toUpper() const
const QUnicodeTables::Properties *prop = qGetProp(c);
if (prop->upperCaseDiff || prop->upperCaseSpecial) {
QString s(d->size, Qt::Uninitialized);
- memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
- ushort *pp = s.d->data + (p - d->data);
+ memcpy(s.d->data(), d->data(), (p - d->data())*sizeof(ushort));
+ ushort *pp = s.d->data() + (p - d->data());
while (p < e) {
uint c = *p;
if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
c = QChar::surrogateToUcs4(*(p - 1), c);
prop = qGetProp(c);
if (prop->upperCaseSpecial) {
- int pos = pp - s.d->data;
+ int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
- pp = s.d->data + pos;
+ pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->upperCaseDiff;
while (*specialCase)
*pp++ = *specialCase++;
@@ -5071,7 +5031,7 @@ QString QString::toUpper() const
}
++p;
}
- s.truncate(pp - s.d->data);
+ s.truncate(pp - s.d->data());
return s;
}
++p;
@@ -6196,19 +6156,19 @@ QString QString::repeated(int times) const
if (result.d->alloc != resultSize)
return QString(); // not enough memory
- memcpy(result.d->data, d->data, d->size * sizeof(ushort));
+ memcpy(result.d->data(), d->data(), d->size * sizeof(ushort));
int sizeSoFar = d->size;
- ushort *end = result.d->data + sizeSoFar;
+ ushort *end = result.d->data() + sizeSoFar;
const int halfResultSize = resultSize >> 1;
while (sizeSoFar <= halfResultSize) {
- memcpy(end, result.d->data, sizeSoFar * sizeof(ushort));
+ memcpy(end, result.d->data(), sizeSoFar * sizeof(ushort));
end += sizeSoFar;
sizeSoFar <<= 1;
}
- memcpy(end, result.d->data, (resultSize - sizeSoFar) * sizeof(ushort));
- result.d->data[resultSize] = '\0';
+ memcpy(end, result.d->data(), (resultSize - sizeSoFar) * sizeof(ushort));
+ result.d->data()[resultSize] = '\0';
result.d->size = resultSize;
return result;
}
@@ -6902,7 +6862,7 @@ QString QString::multiArg(int numArgs, const QString **args) const
{
QString result;
QMap<int, int> numbersUsed;
- const QChar *uc = (const QChar *) d->data;
+ const QChar *uc = (const QChar *) d->data();
const int len = d->size;
const int end = len - 1;
int lastNumber = -1;
@@ -6951,62 +6911,50 @@ QString QString::multiArg(int numArgs, const QString **args) const
return result;
}
-static bool isStringRightToLeft(const ushort *p, const ushort *end)
-{
- bool righttoleft = false;
- while (p < end) {
- switch(QChar::direction(*p))
- {
- case QChar::DirL:
- goto end;
- case QChar::DirR:
- case QChar::DirAL:
- righttoleft = true;
- goto end;
- default:
- break;
- }
- ++p;
- }
- end:
- return righttoleft;
-}
-/*! \internal
- */
-void QString::updateProperties() const
+/*! \fn bool QString::isSimpleText() const
+
+ \internal
+*/
+bool QString::isSimpleText() const
{
- ushort *p = d->data;
- ushort *end = p + d->size;
- d->simpletext = true;
+ const ushort *p = d->data();
+ const ushort * const end = p + d->size;
while (p < end) {
ushort uc = *p;
// sort out regions of complex text formatting
if (uc > 0x058f && (uc < 0x1100 || uc > 0xfb0f)) {
- d->simpletext = false;
+ return false;
}
p++;
}
- d->righttoleft = isStringRightToLeft(d->data, d->data + d->size);
- d->clean = true;
-}
-
-bool QString::isRightToLeft() const
-{
- return isStringRightToLeft(d->data, d->data + d->size);
+ return true;
}
-/*! \fn bool QString::isSimpleText() const
-
- \internal
-*/
-
/*! \fn bool QString::isRightToLeft() const
Returns true if the string is read right to left.
*/
-
+bool QString::isRightToLeft() const
+{
+ const ushort *p = d->data();
+ const ushort * const end = p + d->size;
+ while (p < end) {
+ switch(QChar::direction(*p))
+ {
+ case QChar::DirL:
+ return false;
+ case QChar::DirR:
+ case QChar::DirAL:
+ return true;
+ default:
+ break;
+ }
+ ++p;
+ }
+ return false;
+}
/*! \fn QChar *QString::data()
@@ -7122,17 +7070,13 @@ bool QString::isRightToLeft() const
QString QString::fromRawData(const QChar *unicode, int size)
{
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
+ *x = (Data){ Q_REFCOUNT_INITIALIZER(1), size, 0, false, { 0 } };
Q_CHECK_PTR(x);
if (unicode) {
- x->data = (ushort *)unicode;
+ x->offset = (const ushort *)unicode - (x->d + sizeof(qptrdiff)/sizeof(ushort));
} else {
- x->data = x->array;
size = 0;
}
- x->ref = 1;
- x->alloc = x->size = size;
- *x->array = '\0';
- x->clean = x->simpletext = x->righttoleft = x->capacity = 0;
return QString(x, 0);
}
@@ -7152,18 +7096,16 @@ QString QString::fromRawData(const QChar *unicode, int size)
*/
QString &QString::setRawData(const QChar *unicode, int size)
{
- if (d->ref != 1 || (d->data == d->array && d->alloc)) {
+ if (d->ref != 1 || d->alloc) {
*this = fromRawData(unicode, size);
} else {
if (unicode) {
- d->data = (ushort *)unicode;
+ d->size = size;
+ d->offset = (const ushort *)unicode - (d->d + sizeof(qptrdiff)/sizeof(ushort));
} else {
- d->data = d->array;
- size = 0;
+ d->offset = 0;
+ d->size = 0;
}
- d->alloc = d->size = size;
- *d->array = '\0';
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
}
return *this;
}
@@ -7212,7 +7154,7 @@ QString &QString::setRawData(const QChar *unicode, int size)
\snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 6
- \sa QString, QLatin1Char
+ \sa QString, QLatin1Char, QStringLiteral
*/
/*! \fn QLatin1String::QLatin1String(const char *str)
@@ -8345,7 +8287,7 @@ QStringRef QString::rightRef(int n) const
QStringRef QString::midRef(int position, int n) const
{
- if (d == &shared_null || position >= d->size)
+ if (d == &shared_null.str || position >= d->size)
return QStringRef();
if (n < 0)
n = d->size - position;
@@ -9071,4 +9013,21 @@ QVector<uint> QStringRef::toUcs4() const
return v;
}
+/*!
+ \macro QStringLiteral(str)
+ \relates QString
+
+ The macro generates the data for a QString out of \a str at compile time if the compiler supports it.
+ Creating a QString from it is free in this case, and the generated string data is stored in
+ the read-only segment of the compiled object file.
+
+ Using QStringLiteral instead of a double quoted ascii literal can significantly speed up creation
+ of QString's from data known at compile time.
+
+ If the compiler is c++0x enabled the string \a str can actually contain unicode data.
+
+ For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to
+ QLatin1String.
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 154012d132..81dff3d309 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -44,7 +44,7 @@
#include <QtCore/qchar.h>
#include <QtCore/qbytearray.h>
-#include <QtCore/qatomic.h>
+#include <QtCore/qrefcount.h>
#include <QtCore/qnamespace.h>
#ifndef QT_NO_STL
@@ -77,9 +77,65 @@ class QLatin1String;
class QStringRef;
template <typename T> class QVector;
+struct QStringData {
+ QtPrivate::RefCount ref;
+ int size;
+ uint alloc : 31;
+ uint capacityReserved : 1;
+ union {
+ qptrdiff offset; // will always work as we add/subtract from a ushort ptr
+ ushort d[sizeof(qptrdiff)/sizeof(ushort)];
+ };
+ inline ushort *data() { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
+ inline const ushort *data() const { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
+};
+
+
+#if defined(Q_COMPILER_UNICODE_STRINGS)
+
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const char16_t data[n];
+ operator const QStringData &() const { return str; }
+};
+#define QStringLiteral(str) (const QConstStringData<sizeof(u"" str)/2>) \
+{ { Q_REFCOUNT_INITIALIZER(-1), sizeof(u"" str)/2 -1, 0, 0, { 0 } }, u"" str }
+
+// wchar_t is 2 bytes
+#elif defined(Q_OS_WIN) || (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) || defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536)
+
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const wchar_t data[n];
+ operator const QStringData &() const { return str; }
+};
+#define QStringLiteral(str) (const QConstStringData<sizeof(L"" str)/2>) \
+{ { Q_REFCOUNT_INITIALIZER(-1), sizeof(L"" str)/2 -1, 0, 0, { 0 } }, L"" str }
+
+// fallback, uses QLatin1String as next best options
+#else
+
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const ushort data[n];
+ operator const QStringData &() const { return str; }
+};
+#define QStringLiteral(str) QLatin1String(str)
+
+#endif
+
+#ifndef QT_NO_KEYWORDS
+#define qs(str) QStringLiteral(str)
+#endif
+
class Q_CORE_EXPORT QString
{
public:
+ typedef QStringData Data;
+
inline QString();
QString(const QChar *unicode, int size); // Qt5: don't cap size < 0
explicit QString(const QChar *unicode); // Qt5: merge with the above
@@ -108,7 +164,7 @@ public:
int capacity() const;
inline void reserve(int size);
- inline void squeeze() { if (d->size < d->alloc || d->ref != 1) realloc(); d->capacity = 0;}
+ inline void squeeze() { if (d->size < d->alloc || d->ref != 1) realloc(); d->capacityReserved = false;}
inline const QChar *unicode() const;
inline QChar *data();
@@ -262,8 +318,8 @@ public:
inline QString &operator+=(QChar c) {
if (d->ref != 1 || d->size + 1 > d->alloc)
realloc(grow(d->size + 1));
- d->data[d->size++] = c.unicode();
- d->data[d->size] = '\0';
+ d->data()[d->size++] = c.unicode();
+ d->data()[d->size] = '\0';
return *this;
}
@@ -491,15 +547,17 @@ public:
// compatibility
struct Null { };
static const Null null;
- inline QString(const Null &): d(&shared_null) { d->ref.ref(); }
+ inline QString(const Null &): d(const_cast<Data *>(&shared_null.str)) {}
inline QString &operator=(const Null &) { *this = QString(); return *this; }
- inline bool isNull() const { return d == &shared_null; }
+ inline bool isNull() const { return d == &shared_null.str; }
- bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; }
+ bool isSimpleText() const;
bool isRightToLeft() const;
QString(int size, Qt::Initialization);
+ template <int n>
+ inline QString(const QConstStringData<n> &dd) : d(const_cast<QStringData *>(&dd.str)) {}
private:
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
@@ -511,22 +569,11 @@ private:
QString &operator=(const QByteArray &a);
#endif
- struct Data {
- QBasicAtomicInt ref;
- int alloc, size;
- ushort *data; // QT5: put that after the bit field to fill alignment gap; don't use sizeof any more then
- ushort clean : 1;
- ushort simpletext : 1;
- ushort righttoleft : 1;
- ushort capacity : 1;
- ushort reserved : 11;
- // ### Qt5: try to ensure that "array" is aligned to 16 bytes on both 32- and 64-bit
- ushort array[1];
- };
- static Data shared_null;
- static Data shared_empty;
+ static const QConstStringData<1> shared_null;
+ static const QConstStringData<1> shared_empty;
Data *d;
- QString(Data *dd, int /*dummy*/) : d(dd) {}
+ inline QString(Data *dd, int /*dummy*/) : d(dd) {}
+
#ifndef QT_NO_TEXTCODEC
static QTextCodec *codecForCStrings;
#endif
@@ -605,23 +652,23 @@ inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLat
inline int QString::length() const
{ return d->size; }
inline const QChar QString::at(int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; }
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
inline const QChar QString::operator[](int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; }
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
inline const QChar QString::operator[](uint i) const
-{ Q_ASSERT(i < uint(size())); return d->data[i]; }
+{ Q_ASSERT(i < uint(size())); return d->data()[i]; }
inline bool QString::isEmpty() const
{ return d->size == 0; }
inline const QChar *QString::unicode() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline const QChar *QString::data() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QChar *QString::data()
-{ detach(); return reinterpret_cast<QChar*>(d->data); }
+{ detach(); return reinterpret_cast<QChar*>(d->data()); }
inline const QChar *QString::constData() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline void QString::detach()
-{ if (d->ref != 1 || d->data != d->array) realloc(); }
+{ if (d->ref != 1 || d->offset) realloc(); }
inline bool QString::isDetached() const
{ return d->ref == 1; }
inline QString &QString::operator=(const QLatin1String &s)
@@ -703,10 +750,10 @@ public:
// all this is not documented: We just say "like QChar" and let it be.
inline operator QChar() const
- { return i < s.d->size ? s.d->data[i] : 0; }
+ { return i < s.d->size ? s.d->data()[i] : 0; }
inline QCharRef &operator=(const QChar &c)
{ if (i >= s.d->size) s.expand(i); else s.detach();
- s.d->data[i] = c.unicode(); return *this; }
+ s.d->data()[i] = c.unicode(); return *this; }
// An operator= for each QChar cast constructors
#ifndef QT_NO_CAST_FROM_ASCII
@@ -773,9 +820,9 @@ inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
-inline QString::QString() : d(&shared_null) { d->ref.ref(); }
+inline QString::QString() : d(const_cast<Data *>(&shared_null.str)) {}
inline QString::~QString() { if (!d->ref.deref()) free(d); }
-inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacity = 1;}
+inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true;}
inline QString &QString::setUtf16(const ushort *autf16, int asize)
{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
inline QCharRef QString::operator[](int i)
@@ -783,17 +830,17 @@ inline QCharRef QString::operator[](int i)
inline QCharRef QString::operator[](uint i)
{ return QCharRef(*this, i); }
inline QString::iterator QString::begin()
-{ detach(); return reinterpret_cast<QChar*>(d->data); }
+{ detach(); return reinterpret_cast<QChar*>(d->data()); }
inline QString::const_iterator QString::begin() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QString::const_iterator QString::constBegin() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QString::iterator QString::end()
-{ detach(); return reinterpret_cast<QChar*>(d->data + d->size); }
+{ detach(); return reinterpret_cast<QChar*>(d->data() + d->size); }
inline QString::const_iterator QString::end() const
-{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
inline QString::const_iterator QString::constEnd() const
-{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
inline QBool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return QBool(indexOf(s, 0, cs) != -1); }
inline QBool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
@@ -1024,7 +1071,7 @@ public:
inline const QChar *unicode() const {
if (!m_string)
- return reinterpret_cast<const QChar *>(QString::shared_null.data);
+ return reinterpret_cast<const QChar *>(QString::shared_null.str.data());
return m_string->unicode() + m_position;
}
inline const QChar *data() const { return unicode(); }
@@ -1154,7 +1201,6 @@ inline QBool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) c
{ return QBool(indexOf(s, 0, cs) != -1); }
-
QT_END_NAMESPACE
QT_END_HEADER