SimpleVector as a test case for QArrayData
authorJoão Abecasis <joao.abecasis@nokia.com>
Wed, 2 Nov 2011 10:22:14 +0000 (11:22 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 7 Dec 2011 01:01:42 +0000 (02:01 +0100)
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>
tests/auto/corelib/tools/qarraydata/qarraydata.pro
tests/auto/corelib/tools/qarraydata/simplevector.h [new file with mode: 0644]
tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp

index d384408..8e36811 100644 (file)
@@ -1,4 +1,5 @@
 TARGET = tst_qarraydata
 SOURCES  += tst_qarraydata.cpp
+HEADERS  += simplevector.h
 QT = core testlib
 CONFIG += testcase parallel_test
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h
new file mode 100644 (file)
index 0000000..ad08ad5
--- /dev/null
@@ -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
index 31006c6..1265876 100644 (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"