diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qlist.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qlist.h | 35 |
2 files changed, 33 insertions, 6 deletions
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index dbd026e65a..1b6610a724 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE the number of elements in the list. */ -const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, true, { 0 } }; +const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, { 0 } }; static int grow(int size) { @@ -88,7 +88,6 @@ QListData::Data *QListData::detach_grow(int *idx, int num) Q_CHECK_PTR(t); t->ref.initializeOwned(); - t->sharable = true; t->alloc = alloc; // The space reservation algorithm's optimization is biased towards appending: // Something which looks like an append will put the data at the beginning, @@ -130,7 +129,6 @@ QListData::Data *QListData::detach(int alloc) Q_CHECK_PTR(t); t->ref.initializeOwned(); - t->sharable = true; t->alloc = alloc; if (!alloc) { t->begin = 0; diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 798351cd61..bc3350f42b 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -71,7 +71,6 @@ struct Q_CORE_EXPORT QListData { struct Data { QtPrivate::RefCount ref; int alloc, begin, end; - uint sharable : 1; void *array[1]; }; enum { DataHeaderSize = sizeof(Data) - sizeof(void *) }; @@ -114,7 +113,7 @@ class QList public: inline QList() : d(const_cast<QListData::Data *>(&QListData::shared_null)) { } - inline QList(const QList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); } + QList(const QList<T> &l); ~QList(); QList<T> &operator=(const QList<T> &l); #ifdef Q_COMPILER_RVALUE_REFS @@ -142,7 +141,15 @@ public: } inline bool isDetached() const { return !d->ref.isShared(); } - inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QListData::shared_null) d->sharable = sharable; } + inline void setSharable(bool sharable) + { + if (sharable == d->ref.isSharable()) + return; + if (!sharable) + detach(); + if (d != &QListData::shared_null) + d->ref.setSharable(sharable); + } inline bool isSharedWith(const QList<T> &other) const { return d == other.d; } inline bool isEmpty() const { return p.isEmpty(); } @@ -703,6 +710,28 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper() } template <typename T> +Q_OUTOFLINE_TEMPLATE QList<T>::QList(const QList<T> &l) + : d(l.d) +{ + if (!d->ref.ref()) { + p.detach(d->alloc); + + struct Cleanup + { + Cleanup(QListData::Data *d) : d_(d) {} + ~Cleanup() { if (d_) qFree(d_); } + + QListData::Data *d_; + } tryCatch(d); + + node_copy(reinterpret_cast<Node *>(p.begin()), + reinterpret_cast<Node *>(p.end()), + reinterpret_cast<Node *>(l.p.begin())); + tryCatch.d_ = 0; + } +} + +template <typename T> Q_OUTOFLINE_TEMPLATE QList<T>::~QList() { if (!d->ref.deref()) |