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 <bradley.hughes@nokia.com>
This commit is contained in:
parent
9c04f721a6
commit
7d16ea4033
161
src/corelib/tools/qarraydatapointer.h
Normal file
161
src/corelib/tools/qarraydatapointer.h
Normal file
@ -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 <QtCore/qarraydataops.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(Core)
|
||||
|
||||
template <class T>
|
||||
struct QArrayDataPointer
|
||||
{
|
||||
private:
|
||||
typedef QTypedArrayData<T> Data;
|
||||
typedef QArrayDataOps<T> DataOps;
|
||||
|
||||
public:
|
||||
QArrayDataPointer()
|
||||
: d(Data::sharedNull())
|
||||
{
|
||||
}
|
||||
|
||||
QArrayDataPointer(const QArrayDataPointer &other)
|
||||
: d((other.d->ref.ref(), other.d))
|
||||
{
|
||||
}
|
||||
|
||||
explicit QArrayDataPointer(QTypedArrayData<T> *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<DataOps *>(d);
|
||||
}
|
||||
|
||||
DataOps *operator->() const
|
||||
{
|
||||
Q_ASSERT(d);
|
||||
return static_cast<DataOps *>(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 <class T>
|
||||
inline bool operator==(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
|
||||
{
|
||||
return lhs.data() == rhs.data();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool operator!=(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
|
||||
{
|
||||
return lhs.data() != rhs.data();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void qSwap(QArrayDataPointer<T> &p1, QArrayDataPointer<T> &p2)
|
||||
{
|
||||
p1.swap(p2);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class T>
|
||||
inline void swap(
|
||||
QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p1,
|
||||
QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p2)
|
||||
{
|
||||
p1.swap(p2);
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // include guard
|
@ -44,7 +44,7 @@
|
||||
#define QARRAY_TEST_SIMPLE_VECTOR_H
|
||||
|
||||
#include <QtCore/qarraydata.h>
|
||||
#include <QtCore/qarraydataops.h>
|
||||
#include <QtCore/qarraydatapointer.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -53,7 +53,6 @@ struct SimpleVector
|
||||
{
|
||||
private:
|
||||
typedef QTypedArrayData<T> Data;
|
||||
typedef QArrayDataOps<T> 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<DataOps *>(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<DataOps *>(d)->copyAppend(begin, end);
|
||||
d->copyAppend(begin, end);
|
||||
}
|
||||
|
||||
explicit SimpleVector(Data *ptr)
|
||||
@ -90,23 +82,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
~SimpleVector()
|
||||
{
|
||||
if (!d->ref.deref()) {
|
||||
static_cast<DataOps *>(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<DataOps *>(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<DataOps *>(detached.d)->copyAppend(first, last);
|
||||
static_cast<DataOps *>(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<DataOps *>(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<DataOps *>(detached.d)->copyAppend(begin, begin + d->size);
|
||||
detached.d->copyAppend(begin, begin + d->size);
|
||||
}
|
||||
static_cast<DataOps *>(detached.d)->copyAppend(first, last);
|
||||
detached.d->copyAppend(first, last);
|
||||
detached.swap(*this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<DataOps *>(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<DataOps *>(detached.d)->copyAppend(begin, where);
|
||||
static_cast<DataOps *>(detached.d)->copyAppend(first, last);
|
||||
static_cast<DataOps *>(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<DataOps *>(d)->insert(where, tmp.constBegin(), tmp.constEnd());
|
||||
d->insert(where, tmp.constBegin(), tmp.constEnd());
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<DataOps *>(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<T> d;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
Loading…
Reference in New Issue
Block a user