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
|
#define QARRAY_TEST_SIMPLE_VECTOR_H
|
||||||
|
|
||||||
#include <QtCore/qarraydata.h>
|
#include <QtCore/qarraydata.h>
|
||||||
#include <QtCore/qarraydataops.h>
|
#include <QtCore/qarraydatapointer.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -53,7 +53,6 @@ struct SimpleVector
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef QTypedArrayData<T> Data;
|
typedef QTypedArrayData<T> Data;
|
||||||
typedef QArrayDataOps<T> DataOps;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
@ -61,28 +60,21 @@ public:
|
|||||||
typedef typename Data::const_iterator const_iterator;
|
typedef typename Data::const_iterator const_iterator;
|
||||||
|
|
||||||
SimpleVector()
|
SimpleVector()
|
||||||
: d(Data::sharedNull())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleVector(const SimpleVector &vec)
|
|
||||||
: d(vec.d)
|
|
||||||
{
|
|
||||||
d->ref.ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleVector(size_t n, const T &t)
|
SimpleVector(size_t n, const T &t)
|
||||||
: d(Data::allocate(n))
|
: d(Data::allocate(n))
|
||||||
{
|
{
|
||||||
if (n)
|
if (n)
|
||||||
static_cast<DataOps *>(d)->copyAppend(n, t);
|
d->copyAppend(n, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleVector(const T *begin, const T *end)
|
SimpleVector(const T *begin, const T *end)
|
||||||
: d(Data::allocate(end - begin))
|
: d(Data::allocate(end - begin))
|
||||||
{
|
{
|
||||||
if (end - begin)
|
if (end - begin)
|
||||||
static_cast<DataOps *>(d)->copyAppend(begin, end);
|
d->copyAppend(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit SimpleVector(Data *ptr)
|
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 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 isEmpty() const { return this->empty(); }
|
||||||
|
|
||||||
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
|
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
|
||||||
@ -142,7 +119,7 @@ public:
|
|||||||
&& !d->capacityReserved
|
&& !d->capacityReserved
|
||||||
&& (d->ref != 1 || (d->capacityReserved = 1, false)))) {
|
&& (d->ref != 1 || (d->capacityReserved = 1, false)))) {
|
||||||
SimpleVector detached(Data::allocate(n, true));
|
SimpleVector detached(Data::allocate(n, true));
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(constBegin(), constEnd());
|
detached.d->copyAppend(constBegin(), constEnd());
|
||||||
detached.swap(*this);
|
detached.swap(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,14 +140,14 @@ public:
|
|||||||
SimpleVector detached(Data::allocate(
|
SimpleVector detached(Data::allocate(
|
||||||
qMax(capacity(), size() + (last - first)), d->capacityReserved));
|
qMax(capacity(), size() + (last - first)), d->capacityReserved));
|
||||||
|
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(first, last);
|
detached.d->copyAppend(first, last);
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(begin, begin + d->size);
|
detached.d->copyAppend(begin, begin + d->size);
|
||||||
detached.swap(*this);
|
detached.swap(*this);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<DataOps *>(d)->insert(begin, first, last);
|
d->insert(begin, first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(const_iterator first, const_iterator last)
|
void append(const_iterator first, const_iterator last)
|
||||||
@ -185,15 +162,15 @@ public:
|
|||||||
|
|
||||||
if (d->size) {
|
if (d->size) {
|
||||||
const T *const begin = constBegin();
|
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);
|
detached.swap(*this);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<DataOps *>(d)->copyAppend(first, last);
|
d->copyAppend(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(int position, const_iterator first, const_iterator last)
|
void insert(int position, const_iterator first, const_iterator last)
|
||||||
@ -223,9 +200,9 @@ public:
|
|||||||
qMax(capacity(), size() + (last - first)), d->capacityReserved));
|
qMax(capacity(), size() + (last - first)), d->capacityReserved));
|
||||||
|
|
||||||
if (position)
|
if (position)
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(begin, where);
|
detached.d->copyAppend(begin, where);
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(first, last);
|
detached.d->copyAppend(first, last);
|
||||||
static_cast<DataOps *>(detached.d)->copyAppend(where, end);
|
detached.d->copyAppend(where, end);
|
||||||
detached.swap(*this);
|
detached.swap(*this);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -235,11 +212,11 @@ public:
|
|||||||
if ((first >= where && first < end)
|
if ((first >= where && first < end)
|
||||||
|| (last > where && last <= end)) {
|
|| (last > where && last <= end)) {
|
||||||
SimpleVector tmp(first, last);
|
SimpleVector tmp(first, last);
|
||||||
static_cast<DataOps *>(d)->insert(where, tmp.constBegin(), tmp.constEnd());
|
d->insert(where, tmp.constBegin(), tmp.constEnd());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<DataOps *>(d)->insert(where, first, last);
|
d->insert(where, first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(SimpleVector &other)
|
void swap(SimpleVector &other)
|
||||||
@ -249,12 +226,11 @@ public:
|
|||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
SimpleVector tmp(d);
|
d.clear();
|
||||||
d = Data::sharedEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Data *d;
|
QArrayDataPointer<T> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
Loading…
Reference in New Issue
Block a user