summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/serialization/qbinaryjsonvalue.cpp16
-rw-r--r--src/corelib/serialization/qbinaryjsonvalue_p.h7
-rw-r--r--src/corelib/text/qstring.cpp421
-rw-r--r--src/corelib/text/qstring.h108
-rw-r--r--src/corelib/text/qstringliteral.h44
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring.cpp16
-rw-r--r--tests/auto/other/toolsupport/tst_toolsupport.cpp4
7 files changed, 313 insertions, 303 deletions
diff --git a/src/corelib/serialization/qbinaryjsonvalue.cpp b/src/corelib/serialization/qbinaryjsonvalue.cpp
index 46a1b80104..92a8fd7ec5 100644
--- a/src/corelib/serialization/qbinaryjsonvalue.cpp
+++ b/src/corelib/serialization/qbinaryjsonvalue.cpp
@@ -66,7 +66,7 @@ QBinaryJsonValue::QBinaryJsonValue(QBinaryJsonPrivate::MutableData *data,
case QJsonValue::String: {
QString s = v.toString(parent);
stringData = s.data_ptr();
- stringData->ref();
+ stringData.d->ref();
break;
}
case QJsonValue::Array:
@@ -80,9 +80,10 @@ QBinaryJsonValue::QBinaryJsonValue(QBinaryJsonPrivate::MutableData *data,
}
QBinaryJsonValue::QBinaryJsonValue(QString string)
- : stringData(*reinterpret_cast<QStringData **>(&string)), t(QJsonValue::String)
+ : d(nullptr), t(QJsonValue::String)
{
- stringData->ref();
+ stringData = *(QStringPrivate *)(&string);
+ stringData.d->ref();
}
QBinaryJsonValue::QBinaryJsonValue(const QBinaryJsonArray &a)
@@ -101,8 +102,8 @@ QBinaryJsonValue::QBinaryJsonValue(const QBinaryJsonObject &o)
QBinaryJsonValue::~QBinaryJsonValue()
{
- if (t == QJsonValue::String && stringData && !stringData->deref())
- free(stringData);
+ if (t == QJsonValue::String && !stringData.d->deref())
+ QTypedArrayData<ushort>::deallocate(stringData.d);
if (d && !d->ref.deref())
delete d;
@@ -134,9 +135,8 @@ QString QBinaryJsonValue::toString() const
{
if (t != QJsonValue::String)
return QString();
- stringData->ref(); // the constructor below doesn't add a ref.
- QStringDataPtr holder = { stringData };
- return QString(holder);
+ stringData.d->ref(); // the constructor below doesn't add a ref.
+ return QString(stringData);
}
void QBinaryJsonValue::detach()
diff --git a/src/corelib/serialization/qbinaryjsonvalue_p.h b/src/corelib/serialization/qbinaryjsonvalue_p.h
index 498fc62ecd..f2ca1a8094 100644
--- a/src/corelib/serialization/qbinaryjsonvalue_p.h
+++ b/src/corelib/serialization/qbinaryjsonvalue_p.h
@@ -85,18 +85,17 @@ public:
~QBinaryJsonValue();
QBinaryJsonValue(QBinaryJsonValue &&other) noexcept
- : ui(other.ui),
+ : stringData(other.stringData),
d(other.d),
t(other.t)
{
- other.ui = 0;
other.d = nullptr;
other.t = QJsonValue::Null;
}
QBinaryJsonValue &operator =(QBinaryJsonValue &&other) noexcept
{
- qSwap(ui, other.ui);
+ qSwap(stringData, other.stringData);
qSwap(d, other.d);
qSwap(t, other.t);
return *this;
@@ -122,7 +121,7 @@ private:
quint64 ui;
bool b;
double dbl;
- QStringData *stringData;
+ QStringPrivate stringData;
const QBinaryJsonPrivate::Base *base;
};
QBinaryJsonPrivate::MutableData *d = nullptr; // needed for Objects and Arrays
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 3b6c3fb70f..e1cd018351 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -100,7 +100,7 @@
#define ULLONG_MAX quint64_C(18446744073709551615)
#endif
-#define IS_RAW_DATA(d) ((d)->flags & QArrayData::RawDataType)
+#define IS_RAW_DATA(d) ((d.d)->flags & QArrayData::RawDataType)
QT_BEGIN_NAMESPACE
@@ -2100,8 +2100,10 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
*/
QString::QString(const QChar *unicode, int size)
{
- if (!unicode) {
- d = Data::sharedNull();
+ if (!unicode) {
+ d.d = Data::sharedNull();
+ d.b = Data::sharedNullData();
+ d.size = 0;
} else {
if (size < 0) {
size = 0;
@@ -2109,13 +2111,18 @@ QString::QString(const QChar *unicode, int size)
++size;
}
if (!size) {
- d = Data::allocate(0).first;
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = 0;
} else {
- d = Data::allocate(size + 1).first;
- Q_CHECK_PTR(d);
- d->size = size;
- memcpy(d->data(), unicode, size * sizeof(QChar));
- d->data()[size] = '\0';
+ QPair<Data *, ushort *> pair = Data::allocate(size + 1);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = size;
+ Q_CHECK_PTR(d.d);
+ memcpy(d.b, unicode, size * sizeof(QChar));
+ d.b[size] = '\0';
}
}
}
@@ -2128,15 +2135,20 @@ QString::QString(const QChar *unicode, int size)
*/
QString::QString(int size, QChar ch)
{
- if (size <= 0) {
- d = Data::allocate(0).first;
+ if (size <= 0) {
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = 0;
} else {
- d = Data::allocate(size + 1).first;
- Q_CHECK_PTR(d);
- d->size = size;
- d->data()[size] = '\0';
- ushort *i = d->data() + size;
- ushort *b = d->data();
+ QPair<Data *, ushort *> pair = Data::allocate(size + 1);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = size;
+ Q_CHECK_PTR(d.d);
+ d.b[size] = '\0';
+ ushort *i = d.b + size;
+ ushort *b = d.b;
const ushort value = ch.unicode();
while (i != b)
*--i = value;
@@ -2151,10 +2163,12 @@ QString::QString(int size, QChar ch)
*/
QString::QString(int size, Qt::Initialization)
{
- d = Data::allocate(size + 1).first;
- Q_CHECK_PTR(d);
- d->size = size;
- d->data()[size] = '\0';
+ QPair<Data *, ushort *> pair = Data::allocate(size + 1);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = size;
+ Q_CHECK_PTR(d.d);
+ d.b[size] = '\0';
}
/*! \fn QString::QString(QLatin1String str)
@@ -2169,11 +2183,13 @@ QString::QString(int size, Qt::Initialization)
*/
QString::QString(QChar ch)
{
- d = Data::allocate(2).first;
- Q_CHECK_PTR(d);
- d->size = 1;
- d->data()[0] = ch.unicode();
- d->data()[1] = '\0';
+ QPair<Data *, ushort *> pair = Data::allocate(2);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = 1;
+ Q_CHECK_PTR(d.d);
+ d.b[0] = ch.unicode();
+ d.b[1] = '\0';
}
/*! \fn QString::QString(const QByteArray &ba)
@@ -2195,7 +2211,7 @@ QString::QString(QChar ch)
\internal
*/
-/*! \fn QString::QString(QStringDataPtr)
+/*! \fn QString::QString(QStringPrivate)
\internal
*/
@@ -2265,16 +2281,16 @@ void QString::resize(int size)
if (size < 0)
size = 0;
- if (!d->isShared() && !d->isMutable() && size < d->size) {
- d->size = size;
+ if (!d.d->isShared() && !d.d->isMutable() && size < int(d.size)) {
+ d.size = size;
return;
}
- if (d->needsDetach() || size > capacity())
+ if (d.d->needsDetach() || size > capacity())
reallocData(uint(size) + 1u, true);
- if (d->isMutable()) {
- d->size = size;
- d->data()[size] = '\0';
+ if (d.d->isMutable()) {
+ d.size = size;
+ d.b[size] = '\0';
}
}
@@ -2294,7 +2310,7 @@ void QString::resize(int size, QChar fillChar)
resize(size);
const int difference = length() - oldSize;
if (difference > 0)
- std::fill_n(d->begin() + oldSize, difference, fillChar.unicode());
+ std::fill_n(d.b + oldSize, difference, fillChar.unicode());
}
/*! \fn int QString::capacity() const
@@ -2349,30 +2365,33 @@ void QString::resize(int size, QChar fillChar)
void QString::reallocData(uint alloc, bool grow)
{
- auto allocOptions = d->detachFlags();
+ auto allocOptions = d.d->detachFlags();
if (grow)
allocOptions |= QArrayData::GrowsForward;
- if (d->needsDetach()) {
- Data *x = Data::allocate(alloc, allocOptions).first;
- Q_CHECK_PTR(x);
- x->size = qMin(int(alloc) - 1, d->size);
- ::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
- x->data()[x->size] = 0;
- if (!d->deref())
- Data::deallocate(d);
- d = x;
+ if (d.d->needsDetach()) {
+ QPair<Data *, ushort *> pair = Data::allocate(alloc, allocOptions);
+ Q_CHECK_PTR(pair.first);
+ d.size = qMin(alloc - 1, d.size);
+ ::memcpy(pair.second, d.b, d.size * sizeof(QChar));
+ pair.second[d.size] = 0;
+ if (!d.d->deref())
+ Data::deallocate(d.d);
+ d.d = pair.first;
+ d.b = pair.second;
} else {
- Data *p = Data::reallocateUnaligned(d, d->data(), alloc, allocOptions).first;
- Q_CHECK_PTR(p);
- d = p;
+ QPair<Data *, ushort *> pair =
+ Data::reallocateUnaligned(static_cast<Data *>(d.d), d.b, alloc, allocOptions);
+ Q_CHECK_PTR(pair.first);
+ d.d = pair.first;
+ d.b = pair.second;
}
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void QString::expand(int i)
{
- resize(qMax(i + 1, d->size), QLatin1Char(' '));
+ resize(qMax(i + 1, size()), QLatin1Char(' '));
}
#endif
@@ -2391,9 +2410,9 @@ void QString::expand(int i)
QString &QString::operator=(const QString &other) noexcept
{
- other.d->ref();
- if (!d->deref())
- Data::deallocate(d);
+ other.d.d->ref();
+ if (!d.d->deref())
+ Data::deallocate(d.d);
d = other.d;
return *this;
}
@@ -2415,9 +2434,9 @@ QString &QString::operator=(const QString &other) noexcept
QString &QString::operator=(QLatin1String other)
{
if (isDetached() && other.size() <= capacity()) { // assumes d->alloc == 0 -> !isDetached() (sharedNull)
- d->size = other.size();
- d->data()[other.size()] = 0;
- qt_from_latin1(d->data(), other.latin1(), other.size());
+ d.size = other.size();
+ d.b[other.size()] = 0;
+ qt_from_latin1(d.b, other.latin1(), other.size());
} else {
*this = fromLatin1(other.latin1(), other.size());
}
@@ -2480,10 +2499,9 @@ QString &QString::operator=(QChar ch)
{
if (isDetached() && capacity() >= 1) { // assumes d->alloc == 0 -> !isDetached() (sharedNull)
// re-use existing capacity:
- ushort *dat = d->data();
- dat[0] = ch.unicode();
- dat[1] = 0;
- d->size = 1;
+ d.b[0] = ch.unicode();
+ d.b[1] = 0;
+ d.size = 1;
} else {
operator=(QString(ch));
}
@@ -2569,13 +2587,13 @@ QString &QString::insert(int i, QLatin1String str)
return *this;
int len = str.size();
- if (Q_UNLIKELY(i > d->size))
+ if (Q_UNLIKELY(i > size()))
resize(i + len, QLatin1Char(' '));
else
- resize(d->size + len);
+ resize(size() + len);
- ::memmove(d->data() + i + len, d->data() + i, (d->size - i - len) * sizeof(QChar));
- qt_from_latin1(d->data() + i, s, uint(len));
+ ::memmove(d.b + i + len, d.b + i, (d.size - i - len) * sizeof(QChar));
+ qt_from_latin1(d.b + i, s, uint(len));
return *this;
}
@@ -2592,7 +2610,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->size) {
+ if (s >= d.b && s < d.b + d.size) {
// Part of me - take a copy
ushort *tmp = static_cast<ushort *>(::malloc(size * sizeof(QChar)));
Q_CHECK_PTR(tmp);
@@ -2602,13 +2620,13 @@ QString& QString::insert(int i, const QChar *unicode, int size)
return *this;
}
- if (Q_UNLIKELY(i > d->size))
+ if (Q_UNLIKELY(i > int(d.size)))
resize(i + size, QLatin1Char(' '));
else
- resize(d->size + size);
+ resize(d.size + size);
- ::memmove(d->data() + i + size, d->data() + i, (d->size - i - size) * sizeof(QChar));
- memcpy(d->data() + i, s, size * sizeof(QChar));
+ ::memmove(d.b + i + size, d.b + i, (d.size - i - size) * sizeof(QChar));
+ memcpy(d.b + i, s, size * sizeof(QChar));
return *this;
}
@@ -2622,15 +2640,15 @@ QString& QString::insert(int i, const QChar *unicode, int size)
QString& QString::insert(int i, QChar ch)
{
if (i < 0)
- i += d->size;
+ i += d.size;
if (i < 0)
return *this;
- if (Q_UNLIKELY(i > d->size))
+ if (Q_UNLIKELY(i > size()))
resize(i + 1, QLatin1Char(' '));
else
- resize(d->size + 1);
- ::memmove(d->data() + i + 1, d->data() + i, (d->size - i - 1) * sizeof(QChar));
- d->data()[i] = ch.unicode();
+ resize(d.size + 1);
+ ::memmove(d.b + i + 1, d.b + i, (d.size - i - 1) * sizeof(QChar));
+ d.b[i] = ch.unicode();
return *this;
}
@@ -2654,15 +2672,15 @@ QString& QString::insert(int i, QChar ch)
*/
QString &QString::append(const QString &str)
{
- if (str.d != Data::sharedNull()) {
- if (d == Data::sharedNull()) {
+ if (!str.isNull()) {
+ if (isNull()) {
operator=(str);
} else {
- if (d->needsDetach() || d->size + str.d->size > capacity())
- reallocData(uint(d->size + str.d->size) + 1u, true);
- memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
- d->size += str.d->size;
- d->data()[d->size] = '\0';
+ if (d.d->needsDetach() || size() + str.size() > capacity())
+ reallocData(uint(size() + str.size()) + 1u, true);
+ memcpy(d.b + d.size, str.d.b, str.d.size * sizeof(QChar));
+ d.size += str.d.size;
+ d.b[d.size] = '\0';
}
}
return *this;
@@ -2677,11 +2695,11 @@ QString &QString::append(const QString &str)
QString &QString::append(const QChar *str, int len)
{
if (str && len > 0) {
- if (d->needsDetach() || uint(d->size + len) + 1u > d->allocatedCapacity())
- reallocData(uint(d->size + len) + 1u, true);
- memcpy(d->data() + d->size, str, len * sizeof(QChar));
- d->size += len;
- d->data()[d->size] = '\0';
+ if (d.d->needsDetach() || size() + len > capacity())
+ reallocData(uint(size() + len) + 1u, true);
+ memcpy(d.b + d.size, str, len * sizeof(QChar));
+ d.size += len;
+ d.b[d.size] = '\0';
}
return *this;
}
@@ -2696,12 +2714,12 @@ QString &QString::append(QLatin1String str)
const char *s = str.latin1();
if (s) {
int len = str.size();
- if (d->needsDetach() || d->size + len > capacity())
- reallocData(uint(d->size + len) + 1u, true);
- ushort *i = d->data() + d->size;
+ if (d.d->needsDetach() || size() + len > capacity())
+ reallocData(uint(size() + len) + 1u, true);
+ ushort *i = d.b + d.size;
qt_from_latin1(i, s, uint(len));
i[len] = '\0';
- d->size += len;
+ d.size += len;
}
return *this;
}
@@ -2743,10 +2761,10 @@ QString &QString::append(QLatin1String str)
*/
QString &QString::append(QChar ch)
{
- if (d->needsDetach() || d->size + 1 > capacity())
- reallocData(uint(d->size) + 2u, true);
- d->data()[d->size++] = ch.unicode();
- d->data()[d->size] = '\0';
+ if (d.d->needsDetach() || size() + 1 > capacity())
+ reallocData(uint(d.size) + 2u, true);
+ d.b[d.size++] = ch.unicode();
+ d.b[d.size] = '\0';
return *this;
}
@@ -2839,16 +2857,16 @@ QString &QString::append(QChar ch)
QString &QString::remove(int pos, int len)
{
if (pos < 0) // count from end of string
- pos += d->size;
- if (uint(pos) >= uint(d->size)) {
+ pos += size();
+ if (uint(pos) >= uint(size())) {
// range problems
- } else if (len >= d->size - pos) {
+ } else if (len >= size() - pos) {
resize(pos); // truncate
} else if (len > 0) {
detach();
- memmove(d->data() + pos, d->data() + pos + len,
- (d->size - pos - len + 1) * sizeof(ushort));
- d->size -= len;
+ memmove(d.b + pos, d.b + pos + len,
+ (d.size - pos - len + 1) * sizeof(ushort));
+ d.size -= len;
}
return *this;
}
@@ -2993,10 +3011,10 @@ QString &QString::replace(int pos, int len, const QString &after)
*/
QString &QString::replace(int pos, int len, const QChar *unicode, int size)
{
- if (uint(pos) > uint(d->size))
+ if (uint(pos) > uint(this->size()))
return *this;
- if (len > d->size - pos)
- len = d->size - pos;
+ if (len > this->size() - pos)
+ len = this->size() - pos;
uint index = pos;
replace_helper(&index, 1, len, unicode, size);
@@ -3060,10 +3078,10 @@ bool pointsIntoRange(const QChar *ptr, const ushort *base, int len)
*/
void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen)
{
- // Copy after if it lies inside our own d->data() area (which we could
+ // Copy after if it lies inside our own d.b area (which we could
// possibly invalidate via a realloc or modify by replacement).
QChar *afterBuffer = nullptr;
- if (pointsIntoRange(after, d->data(), d->size)) // Use copy in place of vulnerable original:
+ if (pointsIntoRange(after, d.b, d.size)) // Use copy in place of vulnerable original:
after = afterBuffer = textCopy(after, alen);
QT_TRY {
@@ -3071,36 +3089,36 @@ 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], after, alen * sizeof(QChar));
+ memcpy(d.b + indices[i], after, 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.b+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.b + to, d.b + movestart, msize * sizeof(QChar));
to += msize;
}
if (alen) {
- memcpy(d->data() + to, after, alen * sizeof(QChar));
+ memcpy(d.b + to, after, alen * sizeof(QChar));
to += alen;
}
movestart = indices[i] + blen;
}
- int msize = d->size - movestart;
+ int msize = d.size - movestart;
if (msize > 0)
- memmove(d->data() + to, d->data() + movestart, msize * sizeof(QChar));
- resize(d->size - nIndices*(blen-alen));
+ memmove(d.b + to, d.b + movestart, msize * sizeof(QChar));
+ resize(d.size - nIndices*(blen-alen));
} else {
// replace from back
int adjust = nIndices*(alen-blen);
- int newLen = d->size + adjust;
- int moveend = d->size;
+ int newLen = d.size + adjust;
+ int moveend = d.size;
resize(newLen);
while (nIndices) {
@@ -3108,9 +3126,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.b + moveto, d.b + movestart,
(moveend - movestart)*sizeof(QChar));
- memcpy(d->data() + insertstart, after, alen * sizeof(QChar));
+ memcpy(d.b + insertstart, after, alen * sizeof(QChar));
moveend = movestart-blen;
}
}
@@ -3136,7 +3154,7 @@ QString &QString::replace(const QChar *before, int blen,
const QChar *after, int alen,
Qt::CaseSensitivity cs)
{
- if (d->size == 0) {
+ if (d.size == 0) {
if (blen)
return *this;
} else {
@@ -3171,10 +3189,10 @@ QString &QString::replace(const QChar *before, int blen,
We're about to change data, that before and after might point
into, and we'll need that data for our next batch of indices.
*/
- if (!afterBuffer && pointsIntoRange(after, d->data(), d->size))
+ if (!afterBuffer && pointsIntoRange(after, d.b, d.size))
after = afterBuffer = textCopy(after, alen);
- if (!beforeBuffer && pointsIntoRange(before, d->data(), d->size)) {
+ if (!beforeBuffer && pointsIntoRange(before, d.b, d.size)) {
beforeBuffer = textCopy(before, blen);
matcher = QStringMatcher(beforeBuffer, blen, cs);
}
@@ -3203,13 +3221,13 @@ QString &QString::replace(const QChar *before, int blen,
*/
QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs)
{
- if (after.d->size == 0)
+ if (after.size() == 0)
return remove(ch, cs);
- if (after.d->size == 1)
+ if (after.size() == 1)
return replace(ch, after.front(), cs);
- if (d->size == 0)
+ if (size() == 0)
return *this;
ushort cc = (cs == Qt::CaseSensitive ? ch.unicode() : ch.toCaseFolded().unicode());
@@ -3219,14 +3237,14 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
uint indices[1024];
uint pos = 0;
if (cs == Qt::CaseSensitive) {
- while (pos < 1024 && index < d->size) {
- if (d->data()[index] == cc)
+ while (pos < 1024 && index < size()) {
+ if (d.b[index] == cc)
indices[pos++] = index;
index++;
}
} else {
- while (pos < 1024 && index < d->size) {
- if (QChar::toCaseFolded(d->data()[index]) == cc)
+ while (pos < 1024 && index < size()) {
+ if (QChar::toCaseFolded(d.b[index]) == cc)
indices[pos++] = index;
index++;
}
@@ -3234,12 +3252,12 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
if (!pos) // Nothing to replace
break;
- replace_helper(indices, pos, 1, after.constData(), after.d->size);
+ replace_helper(indices, pos, 1, after.constData(), after.size());
if (Q_LIKELY(index == -1)) // Nothing left to replace
break;
// The call to replace_helper just moved what index points at:
- index += pos*(after.d->size - 1);
+ index += pos*(after.size() - 1);
}
return *this;
}
@@ -3254,13 +3272,13 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
*/
QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
{
- if (d->size) {
+ if (d.size) {
const int idx = indexOf(before, 0, cs);
if (idx != -1) {
detach();
const ushort a = after.unicode();
- ushort *i = d->data();
- const ushort *e = i + d->size;
+ ushort *i = d.b;
+ ushort *const e = i + d.size;
i += idx;
*i = a;
if (cs == Qt::CaseSensitive) {
@@ -3321,7 +3339,7 @@ QString &QString::replace(QLatin1String before, const QString &after, Qt::CaseSe
int blen = before.size();
QVarLengthArray<ushort> b(blen);
qt_from_latin1(b.data(), before.latin1(), blen);
- return replace((const QChar *)b.data(), blen, after.constData(), after.d->size, cs);
+ return replace((const QChar *)b.data(), blen, after.constData(), after.d.size, cs);
}
/*!
@@ -3341,7 +3359,7 @@ QString &QString::replace(const QString &before, QLatin1String after, Qt::CaseSe
int alen = after.size();
QVarLengthArray<ushort> a(alen);
qt_from_latin1(a.data(), after.latin1(), alen);
- return replace(before.constData(), before.d->size, (const QChar *)a.data(), alen, cs);
+ return replace(before.constData(), before.d.size, (const QChar *)a.data(), alen, cs);
}
/*!
@@ -3377,7 +3395,7 @@ QString &QString::replace(QChar c, QLatin1String after, Qt::CaseSensitivity cs)
*/
bool operator==(const QString &s1, const QString &s2) noexcept
{
- if (s1.d->size != s2.d->size)
+ if (s1.d.size != s2.d.size)
return false;
return qt_compare_strings(s1, s2, Qt::CaseSensitive) == 0;
@@ -3390,7 +3408,7 @@ bool operator==(const QString &s1, const QString &s2) noexcept
*/
bool QString::operator==(QLatin1String other) const noexcept
{
- if (d->size != other.size())
+ if (size() != other.size())
return false;
return qt_compare_strings(*this, other, Qt::CaseSensitive) == 0;
@@ -3936,7 +3954,7 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
if (isEmpty() && rx2.indexIn(*this) == -1)
return *this;
- reallocData(uint(d->size) + 1u);
+ reallocData(uint(d.size) + 1u);
int index = 0;
int numCaptures = rx2.captureCount();
@@ -4035,8 +4053,8 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
}
if (!pos)
break;
- replacements[pos].pos = d->size;
- int newlen = d->size + adjust;
+ replacements[pos].pos = d.size;
+ int newlen = d.size + adjust;
// to continue searching at the right position after we did
// the first round of replacements
@@ -4051,14 +4069,14 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
while (i < pos) {
int copyend = replacements[i].pos;
int size = copyend - copystart;
- memcpy(static_cast<void*>(uc), static_cast<const void *>(d->data() + copystart), size * sizeof(QChar));
+ memcpy(static_cast<void*>(uc), static_cast<const void *>(d.b + copystart), size * sizeof(QChar));
uc += size;
- memcpy(static_cast<void *>(uc), static_cast<const void *>(after.d->data()), al * sizeof(QChar));
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(after.d.b), al * sizeof(QChar));
uc += al;
copystart = copyend + replacements[i].length;
i++;
}
- memcpy(static_cast<void *>(uc), static_cast<const void *>(d->data() + copystart), (d->size - copystart) * sizeof(QChar));
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(d.b + copystart), (d.size - copystart) * sizeof(QChar));
newstring.resize(newlen);
*this = newstring;
caretMode = QRegExp::CaretWontMatch;
@@ -4098,7 +4116,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
if (!iterator.hasNext()) // no matches at all
return *this;
- reallocData(uint(d->size) + 1u);
+ reallocData(uint(d.size) + 1u);
int numCaptures = re.captureCount();
@@ -4850,9 +4868,9 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti
*/
QString QString::left(int n) const
{
- if (uint(n) >= uint(d->size))
+ if (uint(n) >= uint(size()))
return *this;
- return QString((const QChar*) d->data(), n);
+ return QString((const QChar*) d.b, n);
}
/*!
@@ -4868,9 +4886,9 @@ QString QString::left(int n) const
*/
QString QString::right(int n) const
{
- if (uint(n) >= uint(d->size))
+ if (uint(n) >= uint(size()))
return *this;
- return QString((const QChar*) d->data() + d->size - n, n);
+ return QString(constData() + size() - n, n);
}
/*!
@@ -4893,18 +4911,19 @@ QString QString::right(int n) const
QString QString::mid(int position, int n) const
{
using namespace QtPrivate;
- switch (QContainerImplHelper::mid(d->size, &position, &n)) {
+ switch (QContainerImplHelper::mid(size(), &position, &n)) {
case QContainerImplHelper::Null:
return QString();
case QContainerImplHelper::Empty:
{
- QStringDataPtr empty = { Data::allocate(0).first };
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ QStringPrivate empty = { pair.first, pair.second, 0 };
return QString(empty);
}
case QContainerImplHelper::Full:
return *this;
case QContainerImplHelper::Subset:
- return QString((const QChar*)d->data() + position, n);
+ return QString(constData() + position, n);
}
Q_UNREACHABLE();
return QString();
@@ -5151,7 +5170,7 @@ QByteArray QString::toLatin1_helper_inplace(QString &s)
// Swap the d pointers.
// Kids, avert your eyes. Don't try this at home.
- QArrayData *ba_d = s.d;
+ QArrayData *ba_d = s.d.d;
// multiply the allocated capacity by sizeof(ushort)
ba_d->alloc *= sizeof(ushort);
@@ -5348,31 +5367,38 @@ QVector<uint> QtPrivate::convertToUcs4(QStringView string)
return qt_convert_to_ucs4(string);
}
-QString::Data *QString::fromLatin1_helper(const char *str, int size)
+QStringPrivate QString::fromLatin1_helper(const char *str, int size)
{
- Data *d;
+ QStringPrivate d;
if (!str) {
- d = Data::sharedNull();
+ d.d = Data::sharedNull();
+ d.b = Data::sharedNullData();
+ d.size = 0;
} else if (size == 0 || (!*str && size < 0)) {
- d = Data::allocate(0).first;
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = 0;
} else {
if (size < 0)
size = qstrlen(str);
- d = Data::allocate(size + 1).first;
- Q_CHECK_PTR(d);
- d->size = size;
- d->data()[size] = '\0';
- ushort *dst = d->data();
+ QPair<Data *, ushort *> pair = Data::allocate(size + 1);
+ d.d = pair.first;
+ d.b = pair.second;
+ d.size = size;
+ Q_CHECK_PTR(d.d);
+ d.b[size] = '\0';
+ ushort *dst = d.b;
qt_from_latin1(dst, str, uint(size));
}
return d;
}
-QString::Data *QString::fromAscii_helper(const char *str, int size)
+QStringPrivate QString::fromAscii_helper(const char *str, int size)
{
QString s = fromUtf8(str, size);
- s.d->ref();
+ s.d.d->ref();
return s.d;
}
@@ -5418,7 +5444,8 @@ QString QString::fromLocal8Bit_helper(const char *str, int size)
if (!str)
return QString();
if (size == 0 || (!*str && size < 0)) {
- QStringDataPtr empty = { Data::allocate(0).first };
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ QStringPrivate empty = { pair.first, pair.second, 0 };
return QString(empty);
}
#if QT_CONFIG(textcodec)
@@ -5588,7 +5615,7 @@ QString& QString::setUnicode(const QChar *unicode, int size)
{
resize(size);
if (unicode && size)
- memcpy(d->data(), unicode, size * sizeof(QChar));
+ memcpy(d.b, unicode, size * sizeof(QChar));
return *this;
}
@@ -5821,7 +5848,7 @@ QString QString::trimmed_helper(QString &str)
void QString::truncate(int pos)
{
- if (pos < d->size)
+ if (pos < size())
resize(pos);
}
@@ -5843,7 +5870,7 @@ void QString::truncate(int pos)
void QString::chop(int n)
{
if (n > 0)
- resize(d->size - n);
+ resize(d.size - n);
}
/*!
@@ -5860,10 +5887,10 @@ void QString::chop(int n)
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();
+ resize(size < 0 ? d.size : size);
+ if (d.size) {
+ QChar *i = (QChar*)d.b + d.size;
+ QChar *b = (QChar*)d.b;
while (i != b)
*--i = ch;
}
@@ -6444,11 +6471,11 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
const ushort *QString::utf16() const
{
- if (!d->isMutable()) {
+ if (!d.d->isMutable()) {
// ensure '\0'-termination for ::fromRawData strings
- const_cast<QString*>(this)->reallocData(uint(d->size) + 1u);
+ const_cast<QString*>(this)->reallocData(uint(d.size) + 1u);
}
- return d->data();
+ return d.b;
}
/*!
@@ -6477,8 +6504,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.b, d.b, sizeof(QChar)*len);
+ QChar *uc = (QChar*)result.d.b + len;
while (padlen--)
* uc++ = fill;
} else {
@@ -6515,11 +6542,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.b;
while (padlen--)
* uc++ = fill;
if (len)
- memcpy(static_cast<void *>(uc), static_cast<const void *>(d->data()), sizeof(QChar)*len);
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(d.b), sizeof(QChar)*len);
} else {
if (truncate)
result = left(width);
@@ -7928,7 +7955,7 @@ QVector<QStringRef> QString::splitRef(const QRegularExpression &re, SplitBehavio
*/
QString QString::repeated(int times) const
{
- if (d->size == 0)
+ if (d.size == 0)
return *this;
if (times <= 1) {
@@ -7937,27 +7964,27 @@ QString QString::repeated(int times) const
return QString();
}
- const int resultSize = times * d->size;
+ const int resultSize = times * d.size;
QString result;
result.reserve(resultSize);
if (result.capacity() != resultSize)
return QString(); // not enough memory
- memcpy(result.d->data(), d->data(), d->size * sizeof(ushort));
+ memcpy(result.d.b, d.b, d.size * sizeof(ushort));
- int sizeSoFar = d->size;
- ushort *end = result.d->data() + sizeSoFar;
+ int sizeSoFar = d.size;
+ ushort *end = result.d.b + sizeSoFar;
const int halfResultSize = resultSize >> 1;
while (sizeSoFar <= halfResultSize) {
- memcpy(end, result.d->data(), sizeSoFar * sizeof(ushort));
+ memcpy(end, result.d.b, sizeSoFar * sizeof(ushort));
end += sizeSoFar;
sizeSoFar <<= 1;
}
- memcpy(end, result.d->data(), (resultSize - sizeSoFar) * sizeof(ushort));
- result.d->data()[resultSize] = '\0';
- result.d->size = resultSize;
+ memcpy(end, result.d.b, (resultSize - sizeSoFar) * sizeof(ushort));
+ result.d.b[resultSize] = '\0';
+ result.d.size = resultSize;
return result;
}
@@ -8957,8 +8984,8 @@ QString QtPrivate::argToQString(QLatin1String pattern, size_t n, const ArgBase *
*/
bool QString::isSimpleText() const
{
- const ushort *p = d->data();
- const ushort * const end = p + d->size;
+ const ushort *p = d.b;
+ const ushort * const end = p + d.size;
while (p < end) {
ushort uc = *p;
// sort out regions of complex text formatting
@@ -9107,17 +9134,21 @@ bool QString::isRightToLeft() const
*/
QString QString::fromRawData(const QChar *unicode, int size)
{
- Data *x;
+ QStringPrivate x;
+ x.size = size;
if (!unicode) {
- x = Data::sharedNull();
+ x.d = Data::sharedNull();
+ x.b = Data::sharedNullData();
} else if (!size) {
- x = Data::allocate(0).first;
+ QPair<Data *, ushort *> pair = Data::allocate(0);
+ x.d = pair.first;
+ x.b = pair.second;
} else {
- x = Data::fromRawData(reinterpret_cast<const ushort *>(unicode), size).ptr;
- Q_CHECK_PTR(x);
+ x.b = const_cast<ushort *>(reinterpret_cast<const ushort *>(unicode));
+ x.d = Data::fromRawData(x.b, size).ptr;
+ Q_CHECK_PTR(x.d);
}
- QStringDataPtr dataPtr = { x };
- return QString(dataPtr);
+ return QString(x);
}
/*!
@@ -9138,11 +9169,11 @@ QString &QString::setRawData(const QChar *unicode, int size)
{
if (!unicode || !size) {
clear();
- } else if (d->isShared() || !IS_RAW_DATA(d)) {
+ } else if (d.d->isShared() || !IS_RAW_DATA(d)) {
*this = fromRawData(unicode, size);
} else {
- d->size = size;
- d->offset = reinterpret_cast<const char *>(unicode) - reinterpret_cast<char *>(d);
+ d.size = size;
+ d.b = const_cast<ushort *>(reinterpret_cast<const ushort *>(unicode));
}
return *this;
}
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index 74528b47c5..c2168af889 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -48,7 +48,7 @@
#include <QtCore/qchar.h>
#include <QtCore/qbytearray.h>
-#include <QtCore/qrefcount.h>
+#include <QtCore/qarraydata.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qstringliteral.h>
#include <QtCore/qstringalgorithms.h>
@@ -246,9 +246,8 @@ qsizetype QStringView::lastIndexOf(QLatin1String s, qsizetype from, Qt::CaseSens
class Q_CORE_EXPORT QString
{
+ typedef QTypedArrayData<ushort> Data;
public:
- typedef QStringData Data;
-
inline QString() noexcept;
explicit QString(const QChar *unicode, int size = -1);
QString(QChar c);
@@ -259,12 +258,13 @@ public:
QString &operator=(QChar c);
QString &operator=(const QString &) noexcept;
QString &operator=(QLatin1String latin1);
- inline QString(QString && other) noexcept : d(other.d) { other.d = Data::sharedNull(); }
+ inline QString(QString &&other) noexcept : d(std::move(other.d))
+ { other.d.d = Data::sharedNull(); other.d.b = Data::sharedNullData(); other.d.size = 0; }
inline QString &operator=(QString &&other) noexcept
{ qSwap(d, other.d); return *this; }
inline void swap(QString &other) noexcept { qSwap(d, other.d); }
- inline int size() const { return d->size; }
- inline int count() const { return d->size; }
+ inline int size() const { return d.size; }
+ inline int count() const { return d.size; }
inline int length() const;
inline bool isEmpty() const;
void resize(int size);
@@ -285,7 +285,7 @@ public:
inline void detach();
inline bool isDetached() const;
- inline bool isSharedWith(const QString &other) const { return d == other.d; }
+ inline bool isSharedWith(const QString &other) const { return d.d == other.d.d; }
void clear();
inline const QChar at(int i) const;
@@ -540,10 +540,10 @@ public:
inline QString &prepend(QLatin1String s) { return insert(0, s); }
inline QString &operator+=(QChar c) {
- if (d->needsDetach() || d->size + 1 > capacity())
- reallocData(uint(d->size) + 2u, true);
- d->data()[d->size++] = c.unicode();
- d->data()[d->size] = '\0';
+ if (d.d->needsDetach() || int(d.size + 1) > capacity())
+ reallocData(uint(d.size) + 2u, true);
+ d.b[d.size++] = c.unicode();
+ d.b[d.size] = '\0';
return *this;
}
@@ -656,8 +656,7 @@ public:
// note - this are all inline so we can benefit from strlen() compile time optimizations
static inline QString fromLatin1(const char *str, int size = -1)
{
- QStringDataPtr dataPtr = { fromLatin1_helper(str, (str && size == -1) ? int(strlen(str)) : size) };
- return QString(dataPtr);
+ return QString(fromLatin1_helper(str, (str && size == -1) ? int(strlen(str)) : size));
}
static inline QString fromUtf8(const char *str, int size = -1)
{
@@ -908,17 +907,17 @@ public:
struct Null { };
QT_DEPRECATED_X("use QString()")
static const Null null;
- inline QString(const Null &): d(Data::sharedNull()) {}
+ inline QString(const Null &) { d.d = Data::sharedNull(); d.b = Data::sharedNullData(); d.size = 0; }
inline QString &operator=(const Null &) { *this = QString(); return *this; }
#endif
- inline bool isNull() const { return d == Data::sharedNull(); }
+ inline bool isNull() const { return d.d == Data::sharedNull(); }
bool isSimpleText() const;
bool isRightToLeft() const;
QString(int size, Qt::Initialization);
- Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
+ explicit QString(QStringPrivate dd) : d(dd) {}
private:
#if defined(QT_NO_CAST_FROM_ASCII)
@@ -930,7 +929,7 @@ private:
QString &operator=(const QByteArray &a);
#endif
- Data *d;
+ QStringPrivate d;
friend inline bool operator==(QChar, const QString &) noexcept;
friend inline bool operator< (QChar, const QString &) noexcept;
@@ -968,8 +967,8 @@ private:
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 QStringPrivate fromLatin1_helper(const char *str, int size = -1);
+ static QStringPrivate fromAscii_helper(const char *str, int size = -1);
static QString fromUtf8_helper(const char *str, int size);
static QString fromLocal8Bit_helper(const char *, int size);
static QByteArray toLatin1_helper(const QString &);
@@ -1005,7 +1004,7 @@ private:
}
public:
- typedef Data * DataPtr;
+ typedef QStringPrivate DataPtr;
inline DataPtr &data_ptr() { return d; }
};
@@ -1021,31 +1020,31 @@ QString QStringView::toString() const
inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size()))
{ }
inline int QString::length() const
-{ return d->size; }
+{ return d.size; }
inline const QChar QString::at(int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
+{ Q_ASSERT(uint(i) < uint(size())); return QChar(d.b[i]); }
inline const QChar QString::operator[](int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
+{ Q_ASSERT(uint(i) < uint(size())); return QChar(d.b[i]); }
inline bool QString::isEmpty() const
-{ return d->size == 0; }
+{ return d.size == 0; }
inline const QChar *QString::unicode() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline const QChar *QString::data() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline QChar *QString::data()
-{ detach(); return reinterpret_cast<QChar*>(d->data()); }
+{ detach(); return reinterpret_cast<QChar*>(d.b); }
inline const QChar *QString::constData() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline void QString::detach()
-{ if (d->needsDetach()) reallocData(uint(d->size) + 1u); }
+{ if (d.d->needsDetach()) reallocData(d.size + 1u); }
inline bool QString::isDetached() const
-{ return !d->isShared(); }
+{ return !d.d->isShared(); }
inline void QString::clear()
{ if (!isNull()) *this = QString(); }
inline QString::QString(const QString &other) noexcept : d(other.d)
-{ Q_ASSERT(&other != this); d->ref(); }
+{ Q_ASSERT(&other != this); d.d->ref(); }
inline int QString::capacity() const
-{ int realCapacity = d->constAllocatedCapacity(); return realCapacity ? realCapacity - 1 : 0; }
+{ int realCapacity = d.d->constAllocatedCapacity(); return realCapacity ? realCapacity - 1 : 0; }
inline QString &QString::setNum(short n, int base)
{ return setNum(qlonglong(n), base); }
inline QString &QString::setNum(ushort n, int base)
@@ -1150,8 +1149,8 @@ public:
inline operator QChar() const
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
- if (Q_LIKELY(i < s.d->size))
- return QChar(s.d->data()[i]);
+ if (Q_LIKELY(i < s.size()))
+ return QChar(s.constData()[i]);
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QCharRef);
#endif
@@ -1160,7 +1159,7 @@ public:
inline QCharRef &operator=(QChar c)
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
- if (Q_UNLIKELY(i >= s.d->size)) {
+ if (Q_UNLIKELY(i >= s.size())) {
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QCharRef);
#endif
@@ -1172,7 +1171,7 @@ public:
#endif
s.detach();
}
- s.d->data()[i] = c.unicode();
+ s.d.b[i] = c.unicode();
return *this;
}
@@ -1254,27 +1253,27 @@ inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
-inline QString::QString() noexcept : d(Data::sharedNull()) {}
-inline QString::~QString() { if (!d->deref()) Data::deallocate(d); }
+inline QString::QString() noexcept { d.d = Data::sharedNull(); d.b = Data::sharedNullData(); d.size = 0; }
+inline QString::~QString() { if (!d.d->deref()) Data::deallocate(d.d); }
inline void QString::reserve(int asize)
{
- if (d->needsDetach() || asize >= capacity())
+ if (d.d->needsDetach() || asize >= capacity())
reallocData(qMax(asize, size()) + 1u);
// we're not shared anymore, for sure
- d->flags |= Data::CapacityReserved;
+ d.d->flags |= Data::CapacityReserved;
}
inline void QString::squeeze()
{
- if ((d->flags & Data::CapacityReserved) == 0)
+ if ((d.d->flags & Data::CapacityReserved) == 0)
return;
- if (d->needsDetach() || d->size < capacity())
- reallocData(uint(d->size) + 1u);
+ if (d.d->needsDetach() || int(d.size) < capacity())
+ reallocData(uint(d.size) + 1u);
// we're not shared anymore, for sure
- d->flags &= ~Data::CapacityReserved;
+ d.d->flags &= ~Data::CapacityReserved;
}
inline QString &QString::setUtf16(const ushort *autf16, int asize)
@@ -1284,21 +1283,21 @@ inline QCharRef QString::operator[](int i)
inline QCharRef QString::front() { return operator[](0); }
inline QCharRef QString::back() { return operator[](size() - 1); }
inline QString::iterator QString::begin()
-{ detach(); return reinterpret_cast<QChar*>(d->data()); }
+{ detach(); return reinterpret_cast<QChar*>(d.b); }
inline QString::const_iterator QString::begin() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline QString::const_iterator QString::cbegin() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline QString::const_iterator QString::constBegin() const
-{ return reinterpret_cast<const QChar*>(d->data()); }
+{ return reinterpret_cast<const QChar*>(d.b); }
inline QString::iterator QString::end()
-{ detach(); return reinterpret_cast<QChar*>(d->data() + d->size); }
+{ detach(); return reinterpret_cast<QChar*>(d.b + d.size); }
inline QString::const_iterator QString::end() const
-{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
+{ return reinterpret_cast<const QChar*>(d.b + d.size); }
inline QString::const_iterator QString::cend() const
-{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
+{ return reinterpret_cast<const QChar*>(d.b + d.size); }
inline QString::const_iterator QString::constEnd() const
-{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
+{ return reinterpret_cast<const QChar*>(d.b + d.size); }
#if QT_STRINGVIEW_LEVEL < 2
inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
@@ -1525,7 +1524,8 @@ inline QString QString::fromStdU32String(const std::u32string &s)
inline std::u32string QString::toStdU32String() const
{
std::u32string u32str(length(), char32_t(0));
- int len = toUcs4_helper(d->data(), length(), reinterpret_cast<uint*>(&u32str[0]));
+ int len = toUcs4_helper(reinterpret_cast<const ushort *>(constData()), length(),
+ reinterpret_cast<uint*>(&u32str[0]));
u32str.resize(len);
return u32str;
}
@@ -1657,7 +1657,7 @@ public:
inline const QChar *unicode() const
{
if (!m_string)
- return reinterpret_cast<const QChar *>(QString::Data::sharedNull()->data());
+ return reinterpret_cast<const QChar *>(QString::Data::sharedNullData());
return m_string->unicode() + m_position;
}
inline const QChar *data() const { return unicode(); }
diff --git a/src/corelib/text/qstringliteral.h b/src/corelib/text/qstringliteral.h
index a0d4ddc30b..a8cf8e2c64 100644
--- a/src/corelib/text/qstringliteral.h
+++ b/src/corelib/text/qstringliteral.h
@@ -49,8 +49,6 @@
QT_BEGIN_NAMESPACE
-typedef QTypedArrayData<ushort> QStringData;
-
// all our supported compilers support Unicode string literals,
// even if their Q_COMPILER_UNICODE_STRING has been revoked due
// to lacking stdlib support. But QStringLiteral only needs the
@@ -65,43 +63,27 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
#define QStringLiteral(str) \
([]() noexcept -> QString { \
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
- static const QStaticStringData<Size> qstring_literal = { \
- Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
- QT_UNICODE_LITERAL(str) }; \
- QStringDataPtr holder = { qstring_literal.data_ptr() }; \
- const QString qstring_literal_temp(holder); \
- return qstring_literal_temp; \
+ static const QArrayData qstring_literal = { \
+ Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, Size, 0, sizeof(QArrayData) \
+ }; \
+ QStringPrivate holder = { \
+ const_cast<QArrayData *>(&qstring_literal), \
+ reinterpret_cast<ushort *>(const_cast<qunicodechar *>(QT_UNICODE_LITERAL(str))), \
+ Size \
+ }; \
+ return QString(holder); \
}()) \
/**/
-#define Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
- { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, size, 0, offset } \
- /**/
-
-#define Q_STATIC_STRING_DATA_HEADER_INITIALIZER(size) \
- Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, sizeof(QStringData)) \
- /**/
-
#if QT_DEPRECATED_SINCE(5, 14)
# define QStringViewLiteral(str) QStringView(QT_UNICODE_LITERAL(str), QtPrivate::Deprecated)
#endif
-template <int N>
-struct QStaticStringData
-{
- QArrayData str;
- qunicodechar data[N + 1];
-
- QStringData *data_ptr() const
- {
- Q_ASSERT(str.isStatic());
- return const_cast<QStringData *>(static_cast<const QStringData*>(&str));
- }
-};
-
-struct QStringDataPtr
+struct QStringPrivate
{
- QStringData *ptr;
+ QArrayData *d;
+ ushort *b;
+ uint size;
};
QT_END_NAMESPACE
diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp
index 01376036b7..ad31f9cefc 100644
--- a/tests/auto/corelib/text/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp
@@ -608,8 +608,7 @@ QString verifyZeroTermination(const QString &str)
QString::DataPtr strDataPtr = const_cast<QString &>(str).data_ptr();
// Skip if isStatic() or fromRawData(), as those offer no guarantees
- if (strDataPtr->isStatic()
- || strDataPtr->offset != QString().data_ptr()->offset)
+ if (strDataPtr.d->isStatic() || !strDataPtr.d->isMutable())
return str;
int strSize = str.size();
@@ -620,7 +619,7 @@ QString verifyZeroTermination(const QString &str)
.arg(strTerminator.unicode(), 4, 16, QChar('0'));
// Skip mutating checks on shared strings
- if (strDataPtr->isShared())
+ if (strDataPtr.d->isShared())
return str;
const QChar *strData = str.constData();
@@ -4070,12 +4069,12 @@ void tst_QString::setRawData()
QVERIFY(cstr == QString(ptr, 1));
// This actually tests the recycling of the shared data object
- QString::DataPtr csd = cstr.data_ptr();
+ void *csd = cstr.data_ptr().d;
cstr.setRawData(ptr2, 1);
QVERIFY(cstr.isDetached());
QVERIFY(cstr.constData() == ptr2);
QVERIFY(cstr == QString(ptr2, 1));
- QVERIFY(cstr.data_ptr() == csd);
+ QVERIFY(cstr.data_ptr().d == csd);
// This tests the discarding of the shared data object
cstr = "foo";
@@ -4083,12 +4082,12 @@ void tst_QString::setRawData()
QVERIFY(cstr.constData() != ptr2);
// Another test of the fallback
- csd = cstr.data_ptr();
+ csd = cstr.data_ptr().d;
cstr.setRawData(ptr2, 1);
QVERIFY(cstr.isDetached());
QVERIFY(cstr.constData() == ptr2);
QVERIFY(cstr == QString(ptr2, 1));
- QVERIFY(cstr.data_ptr() != csd);
+ QVERIFY(cstr.data_ptr().d != csd);
}
void tst_QString::fromStdString()
@@ -6637,8 +6636,7 @@ void tst_QString::literals()
QVERIFY(str.length() == 4);
QVERIFY(str == QLatin1String("abcd"));
- QVERIFY(str.data_ptr()->isStatic());
- QVERIFY(str.data_ptr()->offset == sizeof(QStringData));
+ QVERIFY(str.data_ptr().d->isStatic());
const QChar *s = str.constData();
QString str2 = str;
diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp
index 2440b4a5e9..9591eca16a 100644
--- a/tests/auto/other/toolsupport/tst_toolsupport.cpp
+++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp
@@ -126,9 +126,9 @@ void tst_toolsupport::offsets_data()
#ifdef Q_PROCESSOR_X86
// x86 32-bit has weird alignment rules. Refer to QtPrivate::AlignOf in
// qglobal.h for more details.
- data << 176 << 272;
+ data << 184 << 288;
#else
- data << 180 << 272;
+ data << 188 << 288;
#endif
}
#endif