SimpleVector as a test case for QArrayData

SimpleVector is meant solely as a test case and reference container
implementation based on QArrayData functionality.

It shall not replace QVector or friends.

Change-Id: I5c66777c720f252c8e073a2884c6d5f1ac836d0e
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
João Abecasis 2011-11-02 11:22:14 +01:00 committed by Qt by Nokia
parent bce08ba220
commit d5d073f874
3 changed files with 289 additions and 0 deletions

View File

@ -1,4 +1,5 @@
TARGET = tst_qarraydata
SOURCES += tst_qarraydata.cpp
HEADERS += simplevector.h
QT = core testlib
CONFIG += testcase parallel_test

View File

@ -0,0 +1,183 @@
/****************************************************************************
**
** 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 test suite 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 QARRAY_TEST_SIMPLE_VECTOR_H
#define QARRAY_TEST_SIMPLE_VECTOR_H
#include <QtCore/qarraydata.h>
#include <algorithm>
template <class T>
struct SimpleVector
{
private:
typedef QArrayData Data;
public:
typedef T value_type;
typedef T *iterator;
typedef const T *const_iterator;
SimpleVector()
: d(const_cast<QArrayData *>(&Data::shared_null))
{
}
SimpleVector(const SimpleVector &vec)
: d(vec.d)
{
d->ref.ref();
}
explicit SimpleVector(Data *ptr)
: d(ptr)
{
}
~SimpleVector()
{
if (!d->ref.deref())
// Not implemented
Q_ASSERT(false);
}
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::shared_null; }
bool isEmpty() const { return this->empty(); }
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
size_t size() const { return d->size; }
size_t capacity() const { return d->alloc; }
const_iterator begin() const { return static_cast<T *>(d->data()); }
const_iterator end() const { return static_cast<T *>(d->data()) + d->size; }
const_iterator constBegin() const { return begin(); }
const_iterator constEnd() const { return end(); }
const T &operator[](size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
const T &at(size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
const T &front() const
{
Q_ASSERT(!isEmpty());
return *begin();
}
const T &back() const
{
Q_ASSERT(!isEmpty());
return *(end() - 1);
}
void swap(SimpleVector &other)
{
qSwap(d, other.d);
}
void clear()
{
SimpleVector tmp(d);
d = const_cast<QArrayData *>(&Data::shared_empty);
}
private:
Data *d;
};
template <class T>
bool operator==(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
if (lhs.isSharedWith(rhs))
return true;
if (lhs.size() != rhs.size())
return false;
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <class T>
bool operator!=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
return !(lhs == rhs);
}
template <class T>
bool operator<(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
template <class T>
bool operator>(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
return rhs < lhs;
}
template <class T>
bool operator<=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
return !(rhs < lhs);
}
template <class T>
bool operator>=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
{
return !(lhs < rhs);
}
namespace std {
template <class T>
void swap(SimpleVector<T> &v1, SimpleVector<T> &v2)
{
v1.swap(v2);
}
}
#endif // include guard

View File

@ -43,6 +43,8 @@
#include <QtTest/QtTest>
#include <QtCore/qarraydata.h>
#include "simplevector.h"
class tst_QArrayData : public QObject
{
Q_OBJECT
@ -51,6 +53,7 @@ private slots:
void referenceCounting();
void sharedNullEmpty();
void staticData();
void simpleVector();
};
void tst_QArrayData::referenceCounting()
@ -148,5 +151,107 @@ void tst_QArrayData::staticData()
QCOMPARE(doubleArray.header.data(), reinterpret_cast<void *>(&doubleArray.data));
}
void tst_QArrayData::simpleVector()
{
QArrayData data0 = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 };
QStaticArrayData<int, 7> data1 = {
Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7),
{ 0, 1, 2, 3, 4, 5, 6 }
};
SimpleVector<int> v1;
SimpleVector<int> v2(v1);
SimpleVector<int> v3(&data0);
SimpleVector<int> v4(&data1.header);
SimpleVector<int> v5(&data0);
SimpleVector<int> v6(&data1.header);
v3 = v1;
v1.swap(v3);
v4.clear();
QVERIFY(v1.isNull());
QVERIFY(v2.isNull());
QVERIFY(v3.isNull());
QVERIFY(!v4.isNull());
QVERIFY(!v5.isNull());
QVERIFY(!v6.isNull());
QVERIFY(v1.isEmpty());
QVERIFY(v2.isEmpty());
QVERIFY(v3.isEmpty());
QVERIFY(v4.isEmpty());
QVERIFY(v5.isEmpty());
QVERIFY(!v6.isEmpty());
QCOMPARE(v1.size(), size_t(0));
QCOMPARE(v2.size(), size_t(0));
QCOMPARE(v3.size(), size_t(0));
QCOMPARE(v4.size(), size_t(0));
QCOMPARE(v5.size(), size_t(0));
QCOMPARE(v6.size(), size_t(7));
QCOMPARE(v1.capacity(), size_t(0));
QCOMPARE(v2.capacity(), size_t(0));
QCOMPARE(v3.capacity(), size_t(0));
QCOMPARE(v4.capacity(), size_t(0));
QCOMPARE(v5.capacity(), size_t(0));
// v6.capacity() is unspecified, for now
QVERIFY(v1.isSharedWith(v2));
QVERIFY(v1.isSharedWith(v3));
QVERIFY(!v1.isSharedWith(v4));
QVERIFY(!v1.isSharedWith(v5));
QVERIFY(!v1.isSharedWith(v6));
QVERIFY(v1.constBegin() == v1.constEnd());
QVERIFY(v4.constBegin() == v4.constEnd());
QVERIFY(v6.constBegin() + v6.size() == v6.constEnd());
QVERIFY(v1 == v2);
QVERIFY(v1 == v3);
QVERIFY(v1 == v4);
QVERIFY(v1 == v5);
QVERIFY(!(v1 == v6));
QVERIFY(v1 != v6);
QVERIFY(v4 != v6);
QVERIFY(v5 != v6);
QVERIFY(!(v1 != v5));
QVERIFY(v1 < v6);
QVERIFY(!(v6 < v1));
QVERIFY(v6 > v1);
QVERIFY(!(v1 > v6));
QVERIFY(v1 <= v6);
QVERIFY(!(v6 <= v1));
QVERIFY(v6 >= v1);
QVERIFY(!(v1 >= v6));
QCOMPARE(v6.front(), 0);
QCOMPARE(v6.back(), 6);
for (size_t i = 0; i < v6.size(); ++i) {
QCOMPARE(v6[i], int(i));
QCOMPARE(v6.at(i), int(i));
QCOMPARE(&v6[i], &v6.at(i));
}
v5 = v6;
QVERIFY(v5.isSharedWith(v6));
QVERIFY(!v1.isSharedWith(v5));
v1.swap(v6);
QVERIFY(v6.isNull());
QVERIFY(v1.isSharedWith(v5));
{
using std::swap;
swap(v1, v6);
QVERIFY(v5.isSharedWith(v6));
QVERIFY(!v1.isSharedWith(v5));
}
}
QTEST_APPLESS_MAIN(tst_QArrayData)
#include "tst_qarraydata.moc"