summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-02-18 18:44:31 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-02-18 18:44:31 (GMT)
commit03f7e1f5315f076fcb7234b3d29d120d6779595c (patch)
tree565b5d07e6d84fd0e9d6ff9c299998b01235456f /src/corelib/tools
parentc18beac8163634b48bbf1e7280923e96f5ef0a51 (diff)
parent26c367b9b9e220056af3a47eced366d6d187a890 (diff)
downloadQt-03f7e1f5315f076fcb7234b3d29d120d6779595c.zip
Qt-03f7e1f5315f076fcb7234b3d29d120d6779595c.tar.gz
Qt-03f7e1f5315f076fcb7234b3d29d120d6779595c.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/berlin-staging-1 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/berlin-staging-1: (22 commits) optimize qstring::simplified() Revert optimizations to QString::append unbreak QList::append() and co. again Implement bookmark manager widget. optimization: use QList::reserve() and QVector::reserve() amend "purge msvc.net and msvc2002 makespecs" Added QPlainTextEditor::anchorAt(const QPoint &pos) Fix memmory leak. Fix spacing. Prevent renaming the bookmarks menu root item, it's just a placeholder. Fix broken set last shown pagen when the last page was about:blank. Move launch with external app in base class. Make sure the bookmarks menu updates on add/ remove as well. Fix broken Drag&Drop, reset and clear the model if we set new bookmarks. avoid double reallocations in appending operations avoid double reallocation in string-growing replace() case optimize qHash() some more optimize QList::mid() optimization: use QList::reserve() in QSet::toList() add QList::reserve() ...
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qhash.cpp12
-rw-r--r--src/corelib/tools/qlist.cpp39
-rw-r--r--src/corelib/tools/qlist.h41
-rw-r--r--src/corelib/tools/qset.h1
-rw-r--r--src/corelib/tools/qstring.cpp121
-rw-r--r--src/corelib/tools/qstring.h3
-rw-r--r--src/corelib/tools/qvector.h4
7 files changed, 182 insertions, 39 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 285f4c9..85a8b63 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -64,13 +64,11 @@ QT_BEGIN_NAMESPACE
static uint hash(const uchar *p, int n)
{
uint h = 0;
- uint g;
while (n--) {
h = (h << 4) + *p++;
- g = h & 0xf0000000;
- h ^= g >> 23;
- h &= ~g;
+ h ^= (h & 0xf0000000) >> 23;
+ h &= 0x0fffffff;
}
return h;
}
@@ -78,13 +76,11 @@ static uint hash(const uchar *p, int n)
static uint hash(const QChar *p, int n)
{
uint h = 0;
- uint g;
while (n--) {
h = (h << 4) + (*p++).unicode();
- g = h & 0xf0000000;
- h ^= g >> 23;
- h &= ~g;
+ h ^= (h & 0xf0000000) >> 23;
+ h &= 0x0fffffff;
}
return h;
}
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index ce62016..ac0dc46 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -125,22 +125,23 @@ QListData::Data *QListData::detach2()
}
/*!
- * Detaches the QListData by reallocating new memory.
+ * Detaches the QListData by allocating new memory for a list which possibly
+ * has a different size than the copied one.
* Returns the old (shared) data, it is up to the caller to deref() and free()
* For the new data node_copy needs to be called.
*
* \internal
*/
-QListData::Data *QListData::detach3()
+QListData::Data *QListData::detach(int alloc)
{
Data *x = d;
- Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *)));
+ Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *)));
Q_CHECK_PTR(t);
t->ref = 1;
t->sharable = true;
- t->alloc = x->alloc;
- if (!t->alloc) {
+ t->alloc = alloc;
+ if (!alloc) {
t->begin = 0;
t->end = 0;
} else {
@@ -152,6 +153,21 @@ QListData::Data *QListData::detach3()
return x;
}
+/*!
+ * Detaches the QListData by reallocating new memory.
+ * Returns the old (shared) data, it is up to the caller to deref() and free()
+ * For the new data node_copy needs to be called.
+ *
+ * \internal
+ */
+#if QT_VERSION >= 0x050000
+# error "Remove QListData::detach3(), it is only required for binary compatibility for 4.5.x to 4.6.x"
+#endif
+QListData::Data *QListData::detach3()
+{
+ return detach(d->alloc);
+}
+
void QListData::realloc(int alloc)
{
Q_ASSERT(d->ref == 1);
@@ -647,6 +663,19 @@ void **QListData::erase(void **xi)
Same as at().
*/
+/*! \fn QList::reserve(int alloc)
+
+ Reserve space for \a alloc elements.
+
+ If \a alloc is smaller than the current size of the list, nothing will happen.
+
+ Use this function to avoid repetetive reallocation of QList's internal
+ data if you can predict how many elements will be appended.
+ Note that the reservation applies only to the internal pointer array.
+
+ \since 4.7
+*/
+
/*! \fn void QList::append(const T &value)
Inserts \a value at the end of the list.
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 1d08c41..8c75c98 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -72,9 +72,10 @@ struct Q_CORE_EXPORT QListData {
};
enum { DataHeaderSize = sizeof(Data) - sizeof(void *) };
+ Data *detach(int alloc);
Data *detach(); // remove in 5.0
Data *detach2(); // remove in 5.0
- Data *detach3();
+ Data *detach3(); // remove in 5.0
void realloc(int alloc);
static Data shared_null;
Data *d;
@@ -140,6 +141,7 @@ public:
const T &operator[](int i) const;
T &operator[](int i);
+ void reserve(int size);
void append(const T &t);
void append(const QList<T> &t);
void prepend(const T &t);
@@ -331,6 +333,7 @@ public:
#endif
private:
+ void detach_helper(int alloc);
void detach_helper();
void free(QListData::Data *d);
@@ -464,6 +467,17 @@ inline T QList<T>::takeLast()
{ T t = last(); removeLast(); return t; }
template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
+{
+ if (d->alloc < alloc) {
+ if (d->ref != 1)
+ detach_helper(alloc);
+ else
+ p.realloc(alloc);
+ }
+}
+
+template <typename T>
Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
{
detach();
@@ -575,11 +589,20 @@ Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
- QList<T> cpy;
if (pos + alength > size())
alength = size() - pos;
- for (int i = pos; i < pos + alength; ++i)
- cpy += at(i);
+ QList<T> cpy;
+ cpy.reserve(alength);
+ cpy.d->end = alength;
+ QT_TRY {
+ cpy.node_copy(reinterpret_cast<Node *>(cpy.p.begin()),
+ reinterpret_cast<Node *>(cpy.p.end()),
+ reinterpret_cast<Node *>(p.begin() + pos));
+ } QT_CATCH(...) {
+ // restore the old end
+ cpy.d->end = 0;
+ QT_RETHROW;
+ }
return cpy;
}
@@ -599,10 +622,10 @@ Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i, const T& defaultValue) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
+Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper(int alloc)
{
Node *n = reinterpret_cast<Node *>(p.begin());
- QListData::Data *x = p.detach3();
+ QListData::Data *x = p.detach(alloc);
QT_TRY {
node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n);
} QT_CATCH(...) {
@@ -616,6 +639,12 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
}
template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
+{
+ detach_helper(d->alloc);
+}
+
+template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
{
if (d && !d->ref.deref())
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 6525880..9acbed4 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -292,6 +292,7 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QSet<T>::toList() const
{
QList<T> result;
+ result.reserve(size());
typename QSet<T>::const_iterator i = constBegin();
while (i != constEnd()) {
result.append(*i);
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index dec59b7..ac1bee7 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -989,6 +989,40 @@ QString::QString(const QChar *unicode, int size)
}
}
+/*!
+ \since 4.7
+
+ Constructs a string initialized with the characters of the QChar array
+ \a unicode, which must be terminated with a 0.
+
+ QString makes a deep copy of the string data. The unicode data is copied as
+ is and the Byte Order Mark is preserved if present.
+*/
+QString::QString(const QChar *unicode)
+{
+ if (!unicode) {
+ d = &shared_null;
+ d->ref.ref();
+ } else {
+ int size = 0;
+ while (unicode[size] != 0)
+ ++size;
+ if (!size) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ Q_CHECK_PTR(d);
+ d->ref = 1;
+ d->alloc = d->size = size;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ memcpy(d->array, unicode, size * sizeof(QChar));
+ d->array[size] = '\0';
+ }
+ }
+}
+
/*!
Constructs a string of the given \a size with every character set
@@ -1766,13 +1800,14 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
}
QT_TRY {
- detach();
if (blen == alen) {
// replace in place
+ detach();
for (int i = 0; i < nIndices; ++i)
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));
@@ -3867,7 +3902,7 @@ QString QString::fromUtf8(const char *str, int size)
host byte order is assumed.
This function is comparatively slow.
- Use QString(const ushort *, int) if possible.
+ Use QString(const ushort *, int) or QString(const ushort *) if possible.
QString makes a deep copy of the Unicode data.
@@ -3960,24 +3995,74 @@ QString QString::simplified() const
{
if (d->size == 0)
return *this;
- QString result(d->size, Qt::Uninitialized);
- const QChar *from = (const QChar*) d->data;
- const QChar *fromend = (const QChar*) from+d->size;
- int outc=0;
- QChar *to = (QChar*) result.d->data;
- for (;;) {
- while (from!=fromend && from->isSpace())
- from++;
- while (from!=fromend && !from->isSpace())
- to[outc++] = *from++;
- if (from!=fromend)
- to[outc++] = QLatin1Char(' ');
- else
+
+ const QChar * const start = reinterpret_cast<QChar *>(d->data);
+ const QChar *from = start;
+ const QChar *fromEnd = start + d->size;
+ forever {
+ QChar ch = *from;
+ if (!ch.isSpace())
break;
+ if (++from == fromEnd) {
+ // All-whitespace string
+ shared_empty.ref.ref();
+ return QString(&shared_empty, 0);
+ }
+ }
+ // This loop needs no underflow check, as we already determined that
+ // the string contains non-whitespace. If the string has exactly one
+ // non-whitespace, it will be checked twice - we can live with that.
+ while (fromEnd[-1].isSpace())
+ fromEnd--;
+ // The rest of the function depends on the fact that we already know
+ // that the last character in the source is no whitespace.
+ const QChar *copyFrom = from;
+ int copyCount;
+ forever {
+ if (++from == fromEnd) {
+ // Only leading and/or trailing whitespace, if any at all
+ return mid(copyFrom - start, from - copyFrom);
+ }
+ QChar ch = *from;
+ if (!ch.isSpace())
+ continue;
+ if (ch != QLatin1Char(' ')) {
+ copyCount = from - copyFrom;
+ break;
+ }
+ ch = *++from;
+ if (ch.isSpace()) {
+ copyCount = from - copyFrom - 1;
+ break;
+ }
+ }
+ // 'from' now points at the non-trailing whitespace which made the
+ // string not simplified in the first place. 'copyCount' is the number
+ // 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);
+ ::memcpy(to, copyFrom, copyCount * 2);
+ to += copyCount;
+ fromEnd--;
+ QChar ch;
+ forever {
+ *to++ = QLatin1Char(' ');
+ do {
+ ch = *++from;
+ } while (ch.isSpace());
+ if (from == fromEnd)
+ break;
+ do {
+ *to++ = ch;
+ ch = *++from;
+ if (from == fromEnd)
+ goto done;
+ } while (!ch.isSpace());
}
- if (outc > 0 && to[outc-1] == QLatin1Char(' '))
- outc--;
- result.truncate(outc);
+ done:
+ *to++ = ch;
+ result.truncate(to - reinterpret_cast<QChar *>(result.d->data));
return result;
}
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 702a21a..8de3c7d 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -91,7 +91,8 @@ class Q_CORE_EXPORT QString
{
public:
inline QString();
- QString(const QChar *unicode, int size);
+ QString(const QChar *unicode, int size); // Qt5: don't cap size < 0
+ explicit QString(const QChar *unicode); // Qt5: merge with the above
QString(QChar c);
QString(int size, QChar c);
inline QString(const QLatin1String &latin1);
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 61b22fd..2fc4d6c 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -728,9 +728,10 @@ Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
length = size() - pos;
if (pos == 0 && length == size())
return *this;
- QVector<T> copy;
if (pos + length > size())
length = size() - pos;
+ QVector<T> copy;
+ copy.reserve(length);
for (int i = pos; i < pos + length; ++i)
copy += at(i);
return copy;
@@ -740,6 +741,7 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
{
QList<T> result;
+ result.reserve(size());
for (int i = 0; i < size(); ++i)
result.append(at(i));
return result;