From 7d16ea40331dc4480af823288e6ed3ca58a677d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 2 Nov 2011 12:10:17 +0100 Subject: [PATCH] Introducing QArrayDataPointer This class provides RAII functionality for handling QArrayData pointers. Together with QArrayDataHeader and QArrayDataOps, this offers common boilerplate code for implementing a container which, itself, defines its own interface. Change-Id: If38eba22fbe8f69038a06fff4acb50af434d229e Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qarraydatapointer.h | 161 ++++++++++++++++++ .../corelib/tools/qarraydata/simplevector.h | 60 ++----- 2 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 src/corelib/tools/qarraydatapointer.h diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h new file mode 100644 index 0000000000..0d072a510e --- /dev/null +++ b/src/corelib/tools/qarraydatapointer.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QARRAYDATAPOINTER_H +#define QARRAYDATAPOINTER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +template +struct QArrayDataPointer +{ +private: + typedef QTypedArrayData Data; + typedef QArrayDataOps DataOps; + +public: + QArrayDataPointer() + : d(Data::sharedNull()) + { + } + + QArrayDataPointer(const QArrayDataPointer &other) + : d((other.d->ref.ref(), other.d)) + { + } + + explicit QArrayDataPointer(QTypedArrayData *ptr) + : d(ptr) + { + } + + QArrayDataPointer &operator=(const QArrayDataPointer &other) + { + QArrayDataPointer tmp(other); + this->swap(tmp); + return *this; + } + + DataOps &operator*() const + { + Q_ASSERT(d); + return *static_cast(d); + } + + DataOps *operator->() const + { + Q_ASSERT(d); + return static_cast(d); + } + + ~QArrayDataPointer() + { + if (!d->ref.deref()) { + (*this)->destroyAll(); + Data::deallocate(d); + } + } + + bool isNull() const + { + return d == Data::sharedNull(); + } + + Data *data() const + { + return d; + } + + void swap(QArrayDataPointer &other) + { + qSwap(d, other.d); + } + + void clear() + { + QArrayDataPointer tmp(d); + d = Data::sharedEmpty(); + } + +private: + Data *d; +}; + +template +inline bool operator==(const QArrayDataPointer &lhs, const QArrayDataPointer &rhs) +{ + return lhs.data() == rhs.data(); +} + +template +inline bool operator!=(const QArrayDataPointer &lhs, const QArrayDataPointer &rhs) +{ + return lhs.data() != rhs.data(); +} + +template +inline void qSwap(QArrayDataPointer &p1, QArrayDataPointer &p2) +{ + p1.swap(p2); +} + +QT_END_NAMESPACE + +namespace std +{ + template + inline void swap( + QT_PREPEND_NAMESPACE(QArrayDataPointer) &p1, + QT_PREPEND_NAMESPACE(QArrayDataPointer) &p2) + { + p1.swap(p2); + } +} + +QT_END_HEADER + +#endif // include guard diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 4aa3ab09c8..38f61189da 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -44,7 +44,7 @@ #define QARRAY_TEST_SIMPLE_VECTOR_H #include -#include +#include #include @@ -53,7 +53,6 @@ struct SimpleVector { private: typedef QTypedArrayData Data; - typedef QArrayDataOps DataOps; public: typedef T value_type; @@ -61,28 +60,21 @@ public: typedef typename Data::const_iterator const_iterator; SimpleVector() - : d(Data::sharedNull()) { } - SimpleVector(const SimpleVector &vec) - : d(vec.d) - { - d->ref.ref(); - } - SimpleVector(size_t n, const T &t) : d(Data::allocate(n)) { if (n) - static_cast(d)->copyAppend(n, t); + d->copyAppend(n, t); } SimpleVector(const T *begin, const T *end) : d(Data::allocate(end - begin)) { if (end - begin) - static_cast(d)->copyAppend(begin, end); + d->copyAppend(begin, end); } explicit SimpleVector(Data *ptr) @@ -90,23 +82,8 @@ public: { } - ~SimpleVector() - { - if (!d->ref.deref()) { - static_cast(d)->destroyAll(); - Data::deallocate(d); - } - } - - SimpleVector &operator=(const SimpleVector &vec) - { - SimpleVector temp(vec); - this->swap(temp); - return *this; - } - bool empty() const { return d->size == 0; } - bool isNull() const { return d == Data::sharedNull(); } + bool isNull() const { return d.isNull(); } bool isEmpty() const { return this->empty(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } @@ -142,7 +119,7 @@ public: && !d->capacityReserved && (d->ref != 1 || (d->capacityReserved = 1, false)))) { SimpleVector detached(Data::allocate(n, true)); - static_cast(detached.d)->copyAppend(constBegin(), constEnd()); + detached.d->copyAppend(constBegin(), constEnd()); detached.swap(*this); } } @@ -163,14 +140,14 @@ public: SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), d->capacityReserved)); - static_cast(detached.d)->copyAppend(first, last); - static_cast(detached.d)->copyAppend(begin, begin + d->size); + detached.d->copyAppend(first, last); + detached.d->copyAppend(begin, begin + d->size); detached.swap(*this); return; } - static_cast(d)->insert(begin, first, last); + d->insert(begin, first, last); } void append(const_iterator first, const_iterator last) @@ -185,15 +162,15 @@ public: if (d->size) { const T *const begin = constBegin(); - static_cast(detached.d)->copyAppend(begin, begin + d->size); + detached.d->copyAppend(begin, begin + d->size); } - static_cast(detached.d)->copyAppend(first, last); + detached.d->copyAppend(first, last); detached.swap(*this); return; } - static_cast(d)->copyAppend(first, last); + d->copyAppend(first, last); } void insert(int position, const_iterator first, const_iterator last) @@ -223,9 +200,9 @@ public: qMax(capacity(), size() + (last - first)), d->capacityReserved)); if (position) - static_cast(detached.d)->copyAppend(begin, where); - static_cast(detached.d)->copyAppend(first, last); - static_cast(detached.d)->copyAppend(where, end); + detached.d->copyAppend(begin, where); + detached.d->copyAppend(first, last); + detached.d->copyAppend(where, end); detached.swap(*this); return; @@ -235,11 +212,11 @@ public: if ((first >= where && first < end) || (last > where && last <= end)) { SimpleVector tmp(first, last); - static_cast(d)->insert(where, tmp.constBegin(), tmp.constEnd()); + d->insert(where, tmp.constBegin(), tmp.constEnd()); return; } - static_cast(d)->insert(where, first, last); + d->insert(where, first, last); } void swap(SimpleVector &other) @@ -249,12 +226,11 @@ public: void clear() { - SimpleVector tmp(d); - d = Data::sharedEmpty(); + d.clear(); } private: - Data *d; + QArrayDataPointer d; }; template