summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qlist.cpp4
-rw-r--r--src/corelib/tools/qlist.h35
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())