summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qvarlengtharray
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-23 17:39:52 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-20 09:27:14 +0000
commitdd58ddd5d97f0663d5fafb7e81bff4fc7db13ba7 (patch)
tree4e275f3ded24dde28d6a751efe86784f2e8745a6 /tests/auto/corelib/tools/qvarlengtharray
parent0d23b7f074fde36a164ed2535957114a52a28ad8 (diff)
Add rvalue overload of insert/prepend to QVarLengthArray and QVector
Improves performance and STL compatibility by adding rvalue versions of prepend and insert. [ChangeLog][QtCore][QVarLengthArray] Added rvalue overloads of prepend and insert. [ChangeLog][QtCore][QVector] Added rvalue overloads of prepend and insert. [ChangeLog][QtCore][QVarLengthArray] Can now contain movable but non-copyable types, such as std::unique_ptr. Change-Id: I6c946acc5b67502c91c52ac5dea67cedb1af93a5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/tools/qvarlengtharray')
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp146
1 files changed, 137 insertions, 9 deletions
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index 3971353cbb..229969a943 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -53,6 +53,9 @@ private slots:
void initializeListInt();
void initializeListMovable();
void initializeListComplex();
+ void insertMove();
+ void nonCopyable();
+
private:
template<typename T>
void initializeList();
@@ -287,6 +290,11 @@ struct MyBase
} else {
++errorCount;
}
+ if (!data) {
+ --movedCount;
+ ++liveCount;
+ }
+ data = this;
return *this;
}
@@ -294,36 +302,46 @@ struct MyBase
~MyBase()
{
if (isCopy) {
- if (!copyCount)
+ if (!copyCount || !data)
++errorCount;
else
--copyCount;
}
- if (!liveCount)
- ++errorCount;
- else
- --liveCount;
+ if (data) {
+ if (!liveCount)
+ ++errorCount;
+ else
+ --liveCount;
+ } else
+ --movedCount;
}
- bool hasMoved() const
+ bool wasConstructedAt(const MyBase *that) const
{
- return this != data;
+ return that == data;
}
+ bool hasMoved() const { return !wasConstructedAt(this); }
+
protected:
- MyBase const * const data;
+ MyBase(const MyBase *data, bool isCopy)
+ : data(data), isCopy(isCopy) {}
+
+ const MyBase *data;
bool isCopy;
public:
static int errorCount;
static int liveCount;
static int copyCount;
+ static int movedCount;
};
int MyBase::errorCount = 0;
int MyBase::liveCount = 0;
int MyBase::copyCount = 0;
+int MyBase::movedCount = 0;
struct MyPrimitive
: MyBase
@@ -348,7 +366,39 @@ struct MyPrimitive
struct MyMovable
: MyBase
{
- MyMovable(char input = 'j') : i(input) {}
+ MyMovable(char input = 'j') : MyBase(), i(input) {}
+
+ MyMovable(MyMovable const &other) : MyBase(other), i(other.i) {}
+
+ MyMovable(MyMovable &&other) : MyBase(other.data, other.isCopy), i(other.i)
+ {
+ ++movedCount;
+ other.isCopy = false;
+ other.data = nullptr;
+ }
+
+ MyMovable & operator=(const MyMovable &other)
+ {
+ MyBase::operator=(other);
+ i = other.i;
+ return *this;
+ }
+
+ MyMovable & operator=(MyMovable &&other)
+ {
+ if (isCopy)
+ --copyCount;
+ ++movedCount;
+ if (other.data)
+ --liveCount;
+ isCopy = other.isCopy;
+ data = other.data;
+ other.isCopy = false;
+ other.data = nullptr;
+
+ return *this;
+ }
+
bool operator==(const MyMovable &other) const
{
return i == other.i;
@@ -898,5 +948,83 @@ void tst_QVarLengthArray::initializeList()
#endif
}
+void tst_QVarLengthArray::insertMove()
+{
+ MyBase::errorCount = 0;
+ QCOMPARE(MyBase::liveCount, 0);
+ QCOMPARE(MyBase::copyCount, 0);
+
+ {
+ QVarLengthArray<MyMovable, 4> vec;
+ MyMovable m1;
+ MyMovable m2;
+ MyMovable m3;
+ MyMovable m4;
+ QCOMPARE(MyBase::copyCount, 0);
+ QCOMPARE(MyBase::liveCount, 4);
+
+ vec.append(std::move(m3));
+ QVERIFY(vec.at(0).wasConstructedAt(&m3));
+ QCOMPARE(MyBase::errorCount, 0);
+ QCOMPARE(MyBase::liveCount, 4);
+ QCOMPARE(MyBase::movedCount, 1);
+
+ vec.push_back(std::move(m4));
+ QVERIFY(vec.at(0).wasConstructedAt(&m3));
+ QVERIFY(vec.at(1).wasConstructedAt(&m4));
+ QCOMPARE(MyBase::errorCount, 0);
+ QCOMPARE(MyBase::liveCount, 4);
+ QCOMPARE(MyBase::movedCount, 2);
+
+ vec.prepend(std::move(m1));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m3));
+ QVERIFY(vec.at(2).wasConstructedAt(&m4));
+ QCOMPARE(MyBase::errorCount, 0);
+ QCOMPARE(MyBase::liveCount, 4);
+ QCOMPARE(MyBase::movedCount, 3);
+
+ vec.insert(1, std::move(m2));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m2));
+ QVERIFY(vec.at(2).wasConstructedAt(&m3));
+
+ QCOMPARE(MyBase::copyCount, 0);
+ QCOMPARE(MyBase::liveCount, 4);
+ QCOMPARE(MyBase::errorCount, 0);
+ QCOMPARE(MyBase::movedCount, 4);
+ }
+ QCOMPARE(MyBase::liveCount, 0);
+ QCOMPARE(MyBase::errorCount, 0);
+ QCOMPARE(MyBase::movedCount, 0);
+}
+
+void tst_QVarLengthArray::nonCopyable()
+{
+ QVarLengthArray<std::unique_ptr<int>> vec;
+ std::unique_ptr<int> val1(new int(1));
+ std::unique_ptr<int> val2(new int(2));
+ std::unique_ptr<int> val3(new int(3));
+ std::unique_ptr<int> val4(new int(4));
+ int *const ptr1 = val1.get();
+ int *const ptr2 = val2.get();
+ int *const ptr3 = val3.get();
+ int *const ptr4 = val4.get();
+
+ vec.append(std::move(val3));
+ QVERIFY(ptr3 == vec.at(0).get());
+ vec.append(std::move(val4));
+ QVERIFY(ptr3 == vec.at(0).get());
+ QVERIFY(ptr4 == vec.at(1).get());
+ vec.prepend(std::move(val1));
+ QVERIFY(ptr1 == vec.at(0).get());
+ QVERIFY(ptr3 == vec.at(1).get());
+ QVERIFY(ptr4 == vec.at(2).get());
+ vec.insert(1, std::move(val2));
+ QVERIFY(ptr1 == vec.at(0).get());
+ QVERIFY(ptr2 == vec.at(1).get());
+ QVERIFY(ptr3 == vec.at(2).get());
+}
+
QTEST_APPLESS_MAIN(tst_QVarLengthArray)
#include "tst_qvarlengtharray.moc"