diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/tools/qlist.cpp | 18 | ||||
-rw-r--r-- | src/corelib/tools/qlist.h | 28 |
2 files changed, 42 insertions, 4 deletions
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index ac0dc46..a468c77 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -154,6 +154,19 @@ QListData::Data *QListData::detach(int alloc) } /*! + * Detaches the QListData by allocating new memory for a list which will be bigger + * than the copied one and is expected to grow further. + * 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::detach_grow(int alloc) +{ + return detach(grow(alloc)); +} + +/*! * 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. @@ -596,6 +609,11 @@ void **QListData::erase(void **xi) \internal */ +/*! \fn void QList::detach_grow(int alloc) + + \internal +*/ + /*! \fn void QList::detachShared() \internal diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 8c75c98..1edac03 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -73,6 +73,7 @@ struct Q_CORE_EXPORT QListData { enum { DataHeaderSize = sizeof(Data) - sizeof(void *) }; Data *detach(int alloc); + Data *detach_grow(int alloc); Data *detach(); // remove in 5.0 Data *detach2(); // remove in 5.0 Data *detach3(); // remove in 5.0 @@ -121,6 +122,7 @@ public: inline int size() const { return p.size(); } inline void detach() { if (d->ref != 1) detach_helper(); } + inline void detach_grow(int by) { if (d->ref != 1) detach_helper_grow(d->end - d->begin + by); } inline void detachShared() { @@ -333,6 +335,7 @@ public: #endif private: + void detach_helper_grow(int alloc); void detach_helper(int alloc); void detach_helper(); void free(QListData::Data *d); @@ -480,7 +483,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc) template <typename T> Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) { - detach(); + detach_grow(1); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { Node *n = reinterpret_cast<Node *>(p.append()); QT_TRY { @@ -504,7 +507,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) template <typename T> inline void QList<T>::prepend(const T &t) { - detach(); + detach_grow(1); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { Node *n = reinterpret_cast<Node *>(p.prepend()); QT_TRY { @@ -528,7 +531,7 @@ inline void QList<T>::prepend(const T &t) template <typename T> inline void QList<T>::insert(int i, const T &t) { - detach(); + detach_grow(1); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { Node *n = reinterpret_cast<Node *>(p.insert(i)); QT_TRY { @@ -622,6 +625,23 @@ Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i, const T& defaultValue) const } template <typename T> +Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper_grow(int alloc) +{ + Node *n = reinterpret_cast<Node *>(p.begin()); + QListData::Data *x = p.detach_grow(alloc); + QT_TRY { + node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n); + } QT_CATCH(...) { + qFree(d); + d = x; + QT_RETHROW; + } + + if (!x->ref.deref()) + free(x); +} + +template <typename T> Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper(int alloc) { Node *n = reinterpret_cast<Node *>(p.begin()); @@ -730,7 +750,7 @@ Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList< template <typename T> Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l) { - detach(); + detach_grow(l.size()); Node *n = reinterpret_cast<Node *>(p.append2(l.p)); QT_TRY{ node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin())); |