diff options
author | Andreas Hartmetz <andreas.hartmetz@kdab.com> | 2012-10-14 04:28:51 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-19 18:04:11 +0200 |
commit | bdc115d9698d4f3cf5ce089dbddca75e425d3eeb (patch) | |
tree | 07951c7374ebf7f7c82959872be0d00103e353a0 /src | |
parent | c4ff5c53efc213d9ce4fe0cfe9ab3d6c13cd8716 (diff) |
detach() safely in QVector::erase(), and update callers to not detach.
remove() can use non-detaching iterators internally before calling
erase(), which hasn't been exploited so far, so that the detach() in
erase() never actually detached. When using erase() from outside,
you can't do it legally without calling begin() or end() that detach()
before erase() is called.
Now remove() doesn't detach anymore, and detaching in erase() works.
With new tests that fail after changing only the erase() callers
and pass again after fixing erase().
Change-Id: I47c0a9e362dce8628ec566f5437d951755de96c8
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qvector.h | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 925ad17110..94733f77da 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -200,8 +200,8 @@ public: typedef int size_type; inline void push_back(const T &t) { append(t); } inline void push_front(const T &t) { prepend(t); } - void pop_back() { Q_ASSERT(!isEmpty()); erase(end()-1); } - void pop_front() { Q_ASSERT(!isEmpty()); erase(begin()); } + void pop_back() { Q_ASSERT(!isEmpty()); erase(d->end() - 1); } + void pop_front() { Q_ASSERT(!isEmpty()); erase(d->begin()); } inline bool empty() const { return d->size == 0; } inline T& front() { return first(); } @@ -366,11 +366,11 @@ inline void QVector<T>::insert(int i, int n, const T &t) template <typename T> inline void QVector<T>::remove(int i, int n) { Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range"); - erase(begin() + i, begin() + i + n); } + erase(d->begin() + i, d->begin() + i + n); } template <typename T> inline void QVector<T>::remove(int i) { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::remove", "index out of range"); - erase(begin() + i, begin() + i + 1); } + erase(d->begin() + i, d->begin() + i + 1); } template <typename T> inline void QVector<T>::prepend(const T &t) { insert(begin(), 1, t); } @@ -607,6 +607,8 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend) // FIXME we ara about to delete data maybe it is good time to shrink? if (d->alloc) { detach(); + abegin = d->begin() + itemsUntouched; + aend = abegin + itemsToErase; if (QTypeInfo<T>::isStatic) { iterator moveBegin = abegin + itemsToErase; iterator moveEnd = d->end(); |