summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qbytearray.cpp21
-rw-r--r--src/corelib/tools/qbytearray.h18
-rw-r--r--src/corelib/tools/qchar.cpp13
-rw-r--r--src/corelib/tools/qfreelist.cpp67
-rw-r--r--src/corelib/tools/qfreelist_p.h294
-rw-r--r--src/corelib/tools/qharfbuzz.cpp2
-rw-r--r--src/corelib/tools/qshareddata.h3
-rw-r--r--src/corelib/tools/qstring.cpp18
-rw-r--r--src/corelib/tools/qstring.h35
-rw-r--r--src/corelib/tools/qstringbuilder.cpp5
-rw-r--r--src/corelib/tools/qstringbuilder.h29
-rw-r--r--src/corelib/tools/tools.pri2
12 files changed, 445 insertions, 62 deletions
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 9f21b72bfd..11ebd8a103 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -904,7 +904,7 @@ QByteArray &QByteArray::operator=(const char *str)
x = const_cast<Data *>(&shared_empty.ba);
} else {
int len = qstrlen(str);
- if (d->ref != 1 || len > d->alloc || (len < d->size && len < d->alloc >> 1))
+ if (d->ref != 1 || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1))
realloc(len);
x = d;
memcpy(x->data(), str, len + 1); // include null terminator
@@ -1432,9 +1432,10 @@ void QByteArray::resize(int size)
x->data()[size] = '\0';
d = x;
} else {
- if (d->ref != 1 || size > d->alloc || (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
+ if (d->ref != 1 || size > int(d->alloc)
+ || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(qAllocMore(size, sizeof(Data)));
- if (d->alloc >= size) {
+ if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
}
@@ -1563,7 +1564,7 @@ QByteArray &QByteArray::prepend(const char *str)
QByteArray &QByteArray::prepend(const char *str, int len)
{
if (str) {
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memmove(d->data()+len, d->data(), d->size);
memcpy(d->data(), str, len);
@@ -1581,7 +1582,7 @@ QByteArray &QByteArray::prepend(const char *str, int len)
QByteArray &QByteArray::prepend(char ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
memmove(d->data()+1, d->data(), d->size);
d->data()[0] = ch;
@@ -1619,7 +1620,7 @@ QByteArray &QByteArray::append(const QByteArray &ba)
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
*this = ba;
} else if (ba.d != &shared_null.ba) {
- if (d->ref != 1 || d->size + ba.d->size > d->alloc)
+ if (d->ref != 1 || d->size + ba.d->size > int(d->alloc))
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
d->size += ba.d->size;
@@ -1653,7 +1654,7 @@ QByteArray& QByteArray::append(const char *str)
{
if (str) {
int len = qstrlen(str);
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memcpy(d->data() + d->size, str, len + 1); // include null terminator
d->size += len;
@@ -1678,7 +1679,7 @@ QByteArray &QByteArray::append(const char *str, int len)
if (len < 0)
len = qstrlen(str);
if (str && len) {
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memcpy(d->data() + d->size, str, len); // include null terminator
d->size += len;
@@ -1695,7 +1696,7 @@ QByteArray &QByteArray::append(const char *str, int len)
QByteArray& QByteArray::append(char ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
d->data()[d->size++] = ch;
d->data()[d->size] = '\0';
@@ -2204,7 +2205,7 @@ QByteArray QByteArray::repeated(int times) const
QByteArray result;
result.reserve(resultSize);
- if (result.d->alloc != resultSize)
+ if (int(result.d->alloc) != resultSize)
return QByteArray(); // not enough memory
memcpy(result.d->data(), d->data(), d->size);
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index dbac302d05..b70dba4d55 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -133,10 +133,10 @@ struct QByteArrayData
inline const char *data() const { return d + sizeof(qptrdiff) + offset; }
};
-template<int n> struct QConstByteArrayData
+template<int N> struct QConstByteArrayData
{
const QByteArrayData ba;
- const char data[n];
+ const char data[N + 1];
};
template<int N> struct QConstByteArrayDataPtr
@@ -146,10 +146,10 @@ template<int N> struct QConstByteArrayDataPtr
#if defined(Q_COMPILER_LAMBDA)
-# define QByteArrayLiteral(str) ([]() { \
- enum { Size = sizeof(str) }; \
+# define QByteArrayLiteral(str) ([]() -> QConstByteArrayDataPtr<sizeof(str) - 1> { \
+ enum { Size = sizeof(str) - 1 }; \
static const QConstByteArrayData<Size> qbytearray_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
return holder; }())
@@ -160,9 +160,9 @@ template<int N> struct QConstByteArrayDataPtr
# define QByteArrayLiteral(str) \
__extension__ ({ \
- enum { Size = sizeof(str) }; \
+ enum { Size = sizeof(str) - 1 }; \
static const QConstByteArrayData<Size> qbytearray_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
holder; })
#endif
@@ -439,10 +439,10 @@ inline int QByteArray::capacity() const
{ return d->alloc; }
inline void QByteArray::reserve(int asize)
-{ if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true; }
+{ if (d->ref != 1 || asize > int(d->alloc)) realloc(asize); d->capacityReserved = true; }
inline void QByteArray::squeeze()
-{ if (d->size < d->alloc) realloc(d->size); d->capacityReserved = false; }
+{ if (d->size < int(d->alloc)) realloc(d->size); d->capacityReserved = false; }
class Q_CORE_EXPORT QByteRef {
QByteArray &a;
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 00261daa95..736bc63b11 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -317,8 +317,6 @@ QT_BEGIN_NAMESPACE
\value Vertical
\value Wide
- \omitvalue Single
-
\sa decomposition()
*/
@@ -382,12 +380,6 @@ QT_BEGIN_NAMESPACE
\value ByteOrderSwapped
\value ParagraphSeparator
\value LineSeparator
-
- \omitvalue null
- \omitvalue replacement
- \omitvalue byteOrderMark
- \omitvalue byteOrderSwapped
- \omitvalue nbsp
*/
/*!
@@ -957,7 +949,7 @@ QString QChar::decomposition(uint ucs4)
/*!
Returns the tag defining the composition of the character. Returns
- QChar::Single if no decomposition exists.
+ QChar::NoDecomposition if no decomposition exists.
*/
QChar::Decomposition QChar::decompositionTag() const
{
@@ -967,7 +959,7 @@ QChar::Decomposition QChar::decompositionTag() const
/*!
\overload
Returns the tag defining the composition of the UCS-4-encoded character
- specified by \a ucs4. Returns QChar::Single if no decomposition exists.
+ specified by \a ucs4. Returns QChar::NoDecomposition if no decomposition exists.
*/
QChar::Decomposition QChar::decompositionTag(uint ucs4)
{
@@ -1232,7 +1224,6 @@ ushort QChar::toCaseFolded(ushort ucs2)
return ucs2 + qGetProp(ucs2)->caseFoldDiff;
}
-
/*!
\fn char QChar::toLatin1() const
diff --git a/src/corelib/tools/qfreelist.cpp b/src/corelib/tools/qfreelist.cpp
new file mode 100644
index 0000000000..bbbdb25e49
--- /dev/null
+++ b/src/corelib/tools/qfreelist.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfreelist_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// default sizes and offsets (no need to define these when customizing)
+enum {
+ Offset0 = 0x00000000,
+ Offset1 = 0x00008000,
+ Offset2 = 0x00080000,
+ Offset3 = 0x00800000,
+
+ Size0 = Offset1 - Offset0,
+ Size1 = Offset2 - Offset1,
+ Size2 = Offset3 - Offset2,
+ Size3 = QFreeListDefaultConstants::MaxIndex - Offset3
+};
+
+const int QFreeListDefaultConstants::Sizes[QFreeListDefaultConstants::BlockCount] = {
+ Size0,
+ Size1,
+ Size2,
+ Size3
+};
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
new file mode 100644
index 0000000000..74ba3b587e
--- /dev/null
+++ b/src/corelib/tools/qfreelist_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFREELIST_P_H
+#define QFREELIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+/*! \internal
+
+ Element in a QFreeList. ConstReferenceType and ReferenceType are used as
+ the return values for QFreeList::at() and QFreeList::operator[](). Contains
+ the real data storage (_t) and the id of the next free element (next).
+
+ Note: the t() functions should be used to access the data, not _t.
+*/
+template <typename T>
+struct QFreeListElement
+{
+ typedef const T &ConstReferenceType;
+ typedef T &ReferenceType;
+
+ T _t;
+ int next;
+
+ inline ConstReferenceType t() const { return _t; }
+ inline ReferenceType t() { return _t; }
+};
+
+/*! \internal
+
+ Element in a QFreeList without a paylout. ConstReferenceType and
+ ReferenceType are void, the t() functions return void and are empty.
+*/
+template <>
+struct QFreeListElement<void>
+{
+ typedef void ConstReferenceType;
+ typedef void ReferenceType;
+
+ int next;
+
+ inline void t() const { }
+ inline void t() { }
+};
+
+/*! \internal
+
+ Defines default constants used by QFreeList:
+
+ - The initial value returned by QFreeList::next() is zero.
+
+ - QFreeList allows for up to 16777216 elements in QFreeList and uses the top
+ 8 bits to store a serial counter for ABA protection.
+
+ - QFreeList will make a maximum of 4 allocations (blocks), with each
+ successive block larger than the previous.
+
+ - Sizes static int[] array to define the size of each block.
+
+ It is possible to define your own constants struct/class and give this to
+ QFreeList to customize/tune the behavior.
+*/
+struct Q_AUTOTEST_EXPORT QFreeListDefaultConstants
+{
+ // used by QFreeList, make sure to define all of when customizing
+ enum {
+ InitialNextValue = 0,
+ IndexMask = 0x00ffffff,
+ SerialMask = ~IndexMask & ~0x80000000,
+ SerialCounter = IndexMask + 1,
+ MaxIndex = IndexMask,
+ BlockCount = 4,
+ };
+
+ static const int Sizes[BlockCount];
+};
+
+/*! \internal
+
+ This is a generic implementation of a lock-free free list. Use next() to
+ get the next free entry in the list, and release(id) when done with the id.
+
+ This version is templated and allows having a payload of type T which can
+ be accessed using the id returned by next(). The payload is allocated and
+ deallocated automatically by the free list, but *NOT* when calling
+ next()/release(). Initialization should be done by code needing it after
+ next() returns. Likewise, cleanup() should happen before calling release().
+ It is possible to have use 'void' as the payload type, in which case the
+ free list only contains indexes to the next free entry.
+
+ The ConstantsType type defaults to QFreeListDefaultConstants above. You can
+ define your custom ConstantsType, see above for details on what needs to be
+ available.
+*/
+template <typename T, typename ConstantsType = QFreeListDefaultConstants>
+class QFreeList
+{
+ typedef T ValueType;
+ typedef QFreeListElement<T> ElementType;
+ typedef typename ElementType::ConstReferenceType ConstReferenceType;
+ typedef typename ElementType::ReferenceType ReferenceType;
+
+ // return which block the index \a x falls in, and modify \a x to be the index into that block
+ static inline int blockfor(int &x)
+ {
+ for (int i = 0; i < ConstantsType::BlockCount; ++i) {
+ int size = ConstantsType::Sizes[i];
+ if (x < size)
+ return i;
+ x -= size;
+ }
+ Q_ASSERT(false);
+ return -1;
+ }
+
+ // allocate a block of the given \a size, initialized starting with the given \a offset
+ static inline ElementType *allocate(int offset, int size)
+ {
+ // qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
+ ElementType *v = new ElementType[size];
+ for (int i = 0; i < size; ++i)
+ v[i].next = offset + i + 1;
+ return v;
+ }
+
+ // take the current serial number from \a o, increment it, and store it in \a n
+ static inline int incrementserial(int o, int n)
+ {
+ return (n & ConstantsType::IndexMask) | ((o + ConstantsType::SerialCounter) & ConstantsType::SerialMask);
+ }
+
+ // the blocks
+ QAtomicPointer<ElementType> _v[ConstantsType::BlockCount];
+ // the next free id
+ QAtomicInt _next;
+
+ // QFreeList is not copyable
+ Q_DISABLE_COPY(QFreeList)
+
+public:
+ inline QFreeList();
+ inline ~QFreeList();
+
+ // returns the payload for the given index \a x
+ inline ConstReferenceType at(int x) const;
+ inline ReferenceType operator[](int x);
+
+ /*
+ Return the next free id. Use this id to access the payload (see above).
+ Call release(id) when done using the id.
+ */
+ inline int next();
+ inline void release(int id);
+};
+
+template <typename T, typename ConstantsType>
+inline QFreeList<T, ConstantsType>::QFreeList()
+ : _next(ConstantsType::InitialNextValue)
+{ }
+
+template <typename T, typename ConstantsType>
+inline QFreeList<T, ConstantsType>::~QFreeList()
+{
+ for (int i = 0; i < ConstantsType::BlockCount; ++i)
+ delete [] static_cast<ElementType *>(_v[i]);
+}
+
+template <typename T, typename ConstantsType>
+inline typename QFreeList<T, ConstantsType>::ConstReferenceType QFreeList<T, ConstantsType>::at(int x) const
+{
+ const int block = blockfor(x);
+ return _v[block][x].t();
+}
+
+template <typename T, typename ConstantsType>
+inline typename QFreeList<T, ConstantsType>::ReferenceType QFreeList<T, ConstantsType>::operator[](int x)
+{
+ const int block = blockfor(x);
+ return _v[block][x].t();
+}
+
+template <typename T, typename ConstantsType>
+inline int QFreeList<T, ConstantsType>::next()
+{
+ int id, newid, at;
+ ElementType *v;
+ do {
+ id = _next; // .loadAqcuire();
+
+ at = id & ConstantsType::IndexMask;
+ const int block = blockfor(at);
+ v = _v[block];
+
+ if (!v) {
+ v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]);
+ if (!_v[block].testAndSetRelease(0, v)) {
+ // race with another thread lost
+ delete [] v;
+ v = _v[block];
+ Q_ASSERT(v != 0);
+ }
+ }
+
+ newid = v[at].next | (id & ~ConstantsType::IndexMask);
+ } while (!_next.testAndSetRelease(id, newid));
+ // qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
+ // id & ConstantsType::IndexMask,
+ // newid & ConstantsType::IndexMask,
+ // (newid & ~ConstantsType::IndexMask) >> 24);
+ return id & ConstantsType::IndexMask;
+}
+
+template <typename T, typename ConstantsType>
+inline void QFreeList<T, ConstantsType>::release(int id)
+{
+ int at = id & ConstantsType::IndexMask;
+ const int block = blockfor(at);
+ ElementType *v = _v[block];
+
+ int x, newid;
+ do {
+ x = _next; // .loadAcquire();
+ v[at].next = x & ConstantsType::IndexMask;
+
+ newid = incrementserial(x, id);
+ } while (!_next.testAndSetRelease(x, newid));
+ // qDebug("QFreeList::release(%d): _next now %d (was %d), serial %d",
+ // id & ConstantsType::IndexMask,
+ // newid & ConstantsType::IndexMask,
+ // x & ConstantsType::IndexMask,
+ // (newid & ~ConstantsType::IndexMask) >> 24);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFREELIST_P_H
diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp
index 68f780d9fd..324cd481ed 100644
--- a/src/corelib/tools/qharfbuzz.cpp
+++ b/src/corelib/tools/qharfbuzz.cpp
@@ -102,7 +102,7 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
return QChar::mirroredChar(ch);
}
-void *HB_Library_Resolve(const char *library, int version, const char *symbol)
+void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
{
#ifdef QT_NO_LIBRARY
return 0;
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 9b404bdf0c..811b186e8b 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -279,6 +279,9 @@ namespace std {
QT_BEGIN_NAMESPACE
#endif
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedDataPointer<T>, Q_MOVABLE_TYPE);
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QExplicitlySharedDataPointer<T>, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 9e238193a3..9ce5eead8c 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -1267,10 +1267,10 @@ void QString::resize(int size)
QString::free(d);
d = x;
} else {
- if (d->ref != 1 || size > d->alloc ||
- (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
+ if (d->ref != 1 || size > int(d->alloc) ||
+ (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(grow(size));
- if (d->alloc >= size) {
+ if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
}
@@ -1560,7 +1560,7 @@ QString &QString::append(const QString &str)
if (d == &shared_null.str) {
operator=(str);
} else {
- if (d->ref != 1 || d->size + str.d->size > d->alloc)
+ if (d->ref != 1 || d->size + str.d->size > int(d->alloc))
realloc(grow(d->size + str.d->size));
memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
d->size += str.d->size;
@@ -1580,7 +1580,7 @@ QString &QString::append(const QLatin1String &str)
const uchar *s = (const uchar *)str.latin1();
if (s) {
int len = qstrlen((char *)s);
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(grow(d->size + len));
ushort *i = d->data() + d->size;
while ((*i++ = *s++))
@@ -1623,7 +1623,7 @@ QString &QString::append(const QLatin1String &str)
*/
QString &QString::append(QChar ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(grow(d->size + 1));
d->data()[d->size++] = ch.unicode();
d->data()[d->size] = '\0';
@@ -3550,8 +3550,8 @@ static QByteArray toLatin1_helper(const QChar *data, int length)
const __m128i questionMark = _mm_set1_epi16('?');
// SSE has no compare instruction for unsigned comparison.
// The variables must be shiffted + 0x8000 to be compared
- const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
- const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000);
+ const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
+ const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
for (int i = 0; i < chunkCount; ++i) {
__m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load
src += 8;
@@ -6152,7 +6152,7 @@ QString QString::repeated(int times) const
QString result;
result.reserve(resultSize);
- if (result.d->alloc != resultSize)
+ if (int(result.d->alloc) != resultSize)
return QString(); // not enough memory
memcpy(result.d->data(), d->data(), d->size * sizeof(ushort));
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index af3e3f3ff9..209994de16 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -97,36 +97,43 @@ template<int N> struct QConstStringDataPtr
};
#if defined(Q_COMPILER_UNICODE_STRINGS)
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const char16_t data[n];
+ const char16_t data[N + 1];
};
-#define QT_QSTRING_UNICODE_MARKER u""
+
+#define QT_UNICODE_LITERAL_II(str) u"" str
#elif defined(Q_OS_WIN) || (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) || defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536)
// wchar_t is 2 bytes
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const wchar_t data[n];
+ const wchar_t data[N + 1];
};
-#define QT_QSTRING_UNICODE_MARKER L""
+
+#if defined(Q_CC_MSVC)
+# define QT_UNICODE_LITERAL_II(str) L##str
+#else
+# define QT_UNICODE_LITERAL_II(str) L"" str
+#endif
#else
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const ushort data[n];
+ const ushort data[N + 1];
};
#endif
-#if defined(QT_QSTRING_UNICODE_MARKER)
+#if defined(QT_UNICODE_LITERAL_II)
+# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
# if defined(Q_COMPILER_LAMBDA)
-# define QStringLiteral(str) ([]() { \
- enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+# define QStringLiteral(str) ([]() -> QConstStringDataPtr<sizeof(QT_UNICODE_LITERAL(str))/2 - 1> { \
+ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QConstStringData<Size> qstring_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
return holder; }())
@@ -137,9 +144,9 @@ template<int n> struct QConstStringData
# define QStringLiteral(str) \
__extension__ ({ \
- enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QConstStringData<Size> qstring_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
holder; })
# endif
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 4c6848498b..7c1bde4ac7 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -108,13 +108,12 @@ QT_BEGIN_NAMESPACE
*/
/*! \internal
- Note: The len contains the ending \0
*/
void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out)
{
#ifndef QT_NO_TEXTCODEC
if (QString::codecForCStrings && len) {
- QString tmp = QString::fromAscii(a, len > 0 ? len - 1 : -1);
+ QString tmp = QString::fromAscii(a, len > 0 ? len : -1);
memcpy(out, reinterpret_cast<const char *>(tmp.constData()), sizeof(QChar) * tmp.size());
out += tmp.length();
return;
@@ -126,7 +125,7 @@ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out
while (*a)
*out++ = QLatin1Char(*a++);
} else {
- for (int i = 0; i < len - 1; ++i)
+ for (int i = 0; i < len; ++i)
*out++ = QLatin1Char(a[i]);
}
}
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 6d998b62aa..30b81c42f4 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -294,7 +294,7 @@ template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
#ifndef QT_NO_CAST_FROM_ASCII
static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
{
- QAbstractConcatenable::convertFromAscii(a, N, out);
+ QAbstractConcatenable::convertFromAscii(a, N - 1, out);
}
#endif
static inline void appendTo(const char a[N], char *&out)
@@ -313,7 +313,7 @@ template <int N> struct QConcatenable<const char[N]> : private QAbstractConcaten
#ifndef QT_NO_CAST_FROM_ASCII
static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
{
- QAbstractConcatenable::convertFromAscii(a, N, out);
+ QAbstractConcatenable::convertFromAscii(a, N - 1, out);
}
#endif
static inline void appendTo(const char a[N], char *&out)
@@ -349,10 +349,9 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
enum { ExactSize = false };
static int size(const QByteArray &ba) { return ba.size(); }
#ifndef QT_NO_CAST_FROM_ASCII
- static inline void appendTo(const QByteArray &ba, QChar *&out)
+ static inline QT_ASCII_CAST_WARN void appendTo(const QByteArray &ba, QChar *&out)
{
- // adding 1 because convertFromAscii expects the size including the null-termination
- QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size() + 1, out);
+ QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size(), out);
}
#endif
static inline void appendTo(const QByteArray &ba, char *&out)
@@ -364,6 +363,26 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
}
};
+template <int N> struct QConcatenable<QConstByteArrayDataPtr<N> > : private QAbstractConcatenable
+{
+ typedef QConstByteArrayDataPtr<N> type;
+ typedef QByteArray ConvertTo;
+ enum { ExactSize = false };
+ static int size(const type &) { return N; }
+#ifndef QT_NO_CAST_FROM_ASCII
+ static inline QT_ASCII_CAST_WARN void appendTo(const type &a, QChar *&out)
+ {
+ QAbstractConcatenable::convertFromAscii(a.ptr->data, N, out);
+ }
+#endif
+ static inline void appendTo(const type &ba, char *&out)
+ {
+ const char *a = ba.ptr->data;
+ while (*a)
+ *out++ = *a++;
+ }
+};
+
namespace QtStringBuilder {
template <typename A, typename B> struct ConvertToTypeHelper
{ typedef A ConvertTo; };
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index f5b38eb1c0..13b597d513 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -13,6 +13,7 @@ HEADERS += \
tools/qdatetime.h \
tools/qdatetime_p.h \
tools/qeasingcurve.h \
+ tools/qfreelist_p.h \
tools/qhash.h \
tools/qline.h \
tools/qlinkedlist.h \
@@ -61,6 +62,7 @@ SOURCES += \
tools/qdatetime.cpp \
tools/qeasingcurve.cpp \
tools/qelapsedtimer.cpp \
+ tools/qfreelist.cpp \
tools/qhash.cpp \
tools/qline.cpp \
tools/qlinkedlist.cpp \