summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlist.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qlist.h')
-rw-r--r--src/corelib/tools/qlist.h74
1 files changed, 47 insertions, 27 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 3d55b3002d..0d5b109f2f 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -46,15 +46,13 @@
#include <QtCore/qiterator.h>
#include <QtCore/qrefcount.h>
-#ifndef QT_NO_STL
#include <iterator>
#include <list>
-#endif
#ifdef Q_COMPILER_INITIALIZER_LISTS
-#include <iterator>
#include <initializer_list>
#endif
+#include <stdlib.h>
#include <new>
#include <limits.h>
#include <string.h>
@@ -71,7 +69,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 +111,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
@@ -132,17 +129,25 @@ public:
inline int size() const { return p.size(); }
- inline void detach() { if (d->ref != 1) detach_helper(); }
+ inline void detach() { if (d->ref.isShared()) detach_helper(); }
inline void detachShared()
{
// The "this->" qualification is needed for GCCE.
- if (d->ref != 1 && this->d != &QListData::shared_null)
+ if (d->ref.isShared() && this->d != &QListData::shared_null)
detach_helper();
}
- inline bool isDetached() const { return d->ref == 1; }
- inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QListData::shared_null) d->sharable = sharable; }
+ inline bool isDetached() const { return !d->ref.isShared(); }
+ 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(); }
@@ -325,12 +330,10 @@ public:
static QList<T> fromVector(const QVector<T> &vector);
static QList<T> fromSet(const QSet<T> &set);
-#ifndef QT_NO_STL
static inline QList<T> fromStdList(const std::list<T> &list)
{ QList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
inline std::list<T> toStdList() const
{ std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
-#endif
private:
Node *detach_helper_grow(int i, int n);
@@ -421,13 +424,8 @@ template <typename T>
Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
{
if (d != l.d) {
- QListData::Data *o = l.d;
- o->ref.ref();
- if (!d->ref.deref())
- dealloc(d);
- d = o;
- if (!d->sharable)
- detach_helper();
+ QList<T> tmp(l);
+ tmp.swap(*this);
}
return *this;
}
@@ -480,7 +478,7 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
{
if (d->alloc < alloc) {
- if (d->ref != 1)
+ if (d->ref.isShared())
detach_helper(alloc);
else
p.realloc(alloc);
@@ -490,7 +488,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
template <typename T>
Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
{
- if (d->ref != 1) {
+ if (d->ref.isShared()) {
Node *n = detach_helper_grow(INT_MAX, 1);
QT_TRY {
node_construct(n, t);
@@ -524,7 +522,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
template <typename T>
inline void QList<T>::prepend(const T &t)
{
- if (d->ref != 1) {
+ if (d->ref.isShared()) {
Node *n = detach_helper_grow(0, 1);
QT_TRY {
node_construct(n, t);
@@ -558,7 +556,7 @@ inline void QList<T>::prepend(const T &t)
template <typename T>
inline void QList<T>::insert(int i, const T &t)
{
- if (d->ref != 1) {
+ if (d->ref.isShared()) {
Node *n = detach_helper_grow(i, 1);
QT_TRY {
node_construct(n, t);
@@ -665,7 +663,7 @@ Q_OUTOFLINE_TEMPLATE typename QList<T>::Node *QList<T>::detach_helper_grow(int i
node_copy(reinterpret_cast<Node *>(p.begin()),
reinterpret_cast<Node *>(p.begin() + i), n);
} QT_CATCH(...) {
- qFree(d);
+ free(d);
d = x;
QT_RETHROW;
}
@@ -675,7 +673,7 @@ Q_OUTOFLINE_TEMPLATE typename QList<T>::Node *QList<T>::detach_helper_grow(int i
} QT_CATCH(...) {
node_destruct(reinterpret_cast<Node *>(p.begin()),
reinterpret_cast<Node *>(p.begin() + i));
- qFree(d);
+ free(d);
d = x;
QT_RETHROW;
}
@@ -694,7 +692,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper(int alloc)
QT_TRY {
node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n);
} QT_CATCH(...) {
- qFree(d);
+ free(d);
d = x;
QT_RETHROW;
}
@@ -710,6 +708,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_) free(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())
@@ -739,7 +759,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::dealloc(QListData::Data *data)
{
node_destruct(reinterpret_cast<Node *>(data->array + data->begin),
reinterpret_cast<Node *>(data->array + data->end));
- qFree(data);
+ free(data);
}
@@ -804,7 +824,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l)
if (isEmpty()) {
*this = l;
} else {
- Node *n = (d->ref != 1)
+ Node *n = (d->ref.isShared())
? detach_helper_grow(INT_MAX, l.size())
: reinterpret_cast<Node *>(p.append(l.p));
QT_TRY {