Write QList unit tests for movable, complex, etc. types.
authorMitch Curtis <mitch.curtis@nokia.com>
Wed, 23 May 2012 13:56:33 +0000 (15:56 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 24 May 2012 18:20:52 +0000 (20:20 +0200)
Change-Id: I641ada39f7c84cd221ec1e235cdb0c86270d49fc
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
tests/auto/corelib/tools/qlist/tst_qlist.cpp

index c883c1c..a10c301 100644 (file)
 #include <QtTest/QtTest>
 #include <QList>
 
-class tst_QList : public QObject
-{
-    Q_OBJECT
-
-private slots:
-    void init();
-    void cleanup();
+struct Movable {
+    Movable(char input = 'j')
+        : i(input)
+        , state(Constructed)
+    {
+        ++liveCount;
+    }
+    Movable(const Movable &other)
+        : i(other.i)
+        , state(Constructed)
+    {
+        check(other.state, Constructed);
+        ++liveCount;
+    }
 
-    void length() const;
-    void lengthSignature() const;
-    void append() const;
-    void prepend() const;
-    void mid() const;
-    void at() const;
-    void first() const;
-    void last() const;
-    void begin() const;
-    void end() const;
-    void contains() const;
-    void count() const;
-    void empty() const;
-    void endsWith() const;
-    void lastIndexOf() const;
-    void move() const;
-    void removeAll() const;
-    void removeAt() const;
-    void removeOne() const;
-    void replace() const;
-    void startsWith() const;
-    void swap() const;
-    void takeAt() const;
-    void takeFirst() const;
-    void takeLast() const;
-    void toSet() const;
-    void toStdList() const;
-    void toVector() const;
-    void value() const;
-
-    void testSTLIterators() const;
-    void testOperators() const;
+    ~Movable()
+    {
+        check(state, Constructed);
+        i = 0;
+        --liveCount;
+        state = Destructed;
+    }
 
-    void initializeList() const;
+    bool operator ==(const Movable &other) const
+    {
+        check(state, Constructed);
+        check(other.state, Constructed);
+        return i == other.i;
+    }
 
-    void const_shared_null() const;
-    void setSharable1_data() const;
-    void setSharable1() const;
-    void setSharable2_data() const;
-    void setSharable2() const;
+    Movable &operator=(const Movable &other)
+    {
+        check(state, Constructed);
+        check(other.state, Constructed);
+        i = other.i;
+        return *this;
+    }
+    char i;
 
+    static int getLiveCount() { return liveCount; }
 private:
-    int dummyForGuard;
+    static int liveCount;
+
+    enum State { Constructed = 106, Destructed = 110 };
+    State state;
+
+    static void check(const State state1, const State state2)
+    {
+        QCOMPARE(state1, state2);
+    }
 };
 
+int Movable::liveCount = 0;
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Movable);
+
+int qHash(const Movable& movable)
+{
+    return qHash(movable.i);
+}
+
 struct Complex
 {
-    Complex(int val)
+    Complex(int val = 0)
         : value(val)
         , checkSum(this)
     {
@@ -134,86 +146,252 @@ struct Complex
         return value == other.value;
     }
 
-    bool check() const
+    void check() const
     {
-        if (this != checkSum) {
-            ++errorCount;
-            return false;
-        }
-        return true;
+        QVERIFY(this == checkSum);
     }
 
-    struct Guard
-    {
-        Guard() : initialLiveCount(liveCount) {}
-        ~Guard() { if (liveCount != initialLiveCount) ++errorCount; }
-
-    private:
-        Q_DISABLE_COPY(Guard);
-        int initialLiveCount;
-    };
-
-    static void resetErrors() { errorCount = 0; }
-    static int errors() { return errorCount; }
-
+    static int getLiveCount() { return liveCount; }
 private:
-    static int errorCount;
     static int liveCount;
 
     int value;
     void *checkSum;
 };
 
-int Complex::errorCount = 0;
 int Complex::liveCount = 0;
 
-void tst_QList::init()
-{
-    Complex::resetErrors();
-    new (&dummyForGuard) Complex::Guard();
-}
+Q_DECLARE_METATYPE(Complex);
 
-void tst_QList::cleanup()
+// Tests depend on the fact that:
+Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
+Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
+Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
+Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex);
+
+class tst_QList : public QObject
 {
-    QCOMPARE(Complex::errors(), 0);
+    Q_OBJECT
 
-    reinterpret_cast<Complex::Guard *>(&dummyForGuard)->~Guard();
-    QCOMPARE(Complex::errors(), 0);
-}
+private slots:
+    void lengthInt() const;
+    void lengthMovable() const;
+    void lengthComplex() const;
+    void lengthSignature() const;
+    void appendInt() const;
+    void appendMovable() const;
+    void appendComplex() const;
+    void prepend() const;
+    void midInt() const;
+    void midMovable() const;
+    void midComplex() const;
+    void atInt() const;
+    void atMovable() const;
+    void atComplex() const;
+    void firstInt() const;
+    void firstMovable() const;
+    void firstComplex() const;
+    void lastInt() const;
+    void lastMovable() const;
+    void lastComplex() const;
+    void beginInt() const;
+    void beginMovable() const;
+    void beginComplex() const;
+    void endInt() const;
+    void endMovable() const;
+    void endComplex() const;
+    void containsInt() const;
+    void containsMovable() const;
+    void containsComplex() const;
+    void countInt() const;
+    void countMovable() const;
+    void countComplex() const;
+    void emptyInt() const;
+    void emptyMovable() const;
+    void emptyComplex() const;
+    void endsWithInt() const;
+    void endsWithMovable() const;
+    void endsWithComplex() const;
+    void lastIndexOfInt() const;
+    void lastIndexOfMovable() const;
+    void lastIndexOfComplex() const;
+    void moveInt() const;
+    void moveMovable() const;
+    void moveComplex() const;
+    void removeAllInt() const;
+    void removeAllMovable() const;
+    void removeAllComplex() const;
+    void removeAtInt() const;
+    void removeAtMovable() const;
+    void removeAtComplex() const;
+    void removeOneInt() const;
+    void removeOneMovable() const;
+    void removeOneComplex() const;
+    void replaceInt() const;
+    void replaceMovable() const;
+    void replaceComplex() const;
+    void startsWithInt() const;
+    void startsWithMovable() const;
+    void startsWithComplex() const;
+    void swapInt() const;
+    void swapMovable() const;
+    void swapComplex() const;
+    void takeAtInt() const;
+    void takeAtMovable() const;
+    void takeAtComplex() const;
+    void takeFirstInt() const;
+    void takeFirstMovable() const;
+    void takeFirstComplex() const;
+    void takeLastInt() const;
+    void takeLastMovable() const;
+    void takeLastComplex() const;
+    void toSetInt() const;
+    void toSetMovable() const;
+    void toSetComplex() const;
+    void toStdListInt() const;
+    void toStdListMovable() const;
+    void toStdListComplex() const;
+    void toVectorInt() const;
+    void toVectorMovable() const;
+    void toVectorComplex() const;
+    void valueInt() const;
+    void valueMovable() const;
+    void valueComplex() const;
+
+    void testOperatorsInt() const;
+    void testOperatorsMovable() const;
+    void testOperatorsComplex() const;
+    void testSTLIteratorsInt() const;
+    void testSTLIteratorsMovable() const;
+    void testSTLIteratorsComplex() const;
 
+    void initializeList() const;
+
+    void constSharedNullInt() const;
+    void constSharedNullMovable() const;
+    void constSharedNullComplex() const;
+    void setSharableInt_data() const;
+    void setSharableInt() const;
+    void setSharableComplex_data() const;
+    void setSharableComplex() const;
+private:
+    template<typename T> void length() const;
+    template<typename T> void append() const;
+    template<typename T> void mid() const;
+    template<typename T> void at() const;
+    template<typename T> void first() const;
+    template<typename T> void last() const;
+    template<typename T> void begin() const;
+    template<typename T> void end() const;
+    template<typename T> void contains() const;
+    template<typename T> void count() const;
+    template<typename T> void empty() const;
+    template<typename T> void endsWith() const;
+    template<typename T> void lastIndexOf() const;
+    template<typename T> void move() const;
+    template<typename T> void removeAll() const;
+    template<typename T> void removeAt() const;
+    template<typename T> void removeOne() const;
+    template<typename T> void replace() const;
+    template<typename T> void startsWith() const;
+    template<typename T> void swap() const;
+    template<typename T> void takeAt() const;
+    template<typename T> void takeFirst() const;
+    template<typename T> void takeLast() const;
+    template<typename T> void toSet() const;
+    template<typename T> void toStdList() const;
+    template<typename T> void toVector() const;
+    template<typename T> void value() const;
+
+    template<typename T> void testOperators() const;
+    template<typename T> void testSTLIterators() const;
+
+    template<typename T> void constSharedNull() const;
+
+    int dummyForGuard;
+};
+
+template<typename T> struct SimpleValue
+{
+    static T at(int index)
+    {
+        return values[index % maxSize];
+    }
+    static const uint maxSize = 7;
+    static const T values[maxSize];
+};
+
+template<>
+const int SimpleValue<int>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+template<>
+const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+template<>
+const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+
+// Make some macros for the tests to use in order to be slightly more readable...
+#define T_FOO SimpleValue<T>::at(0)
+#define T_BAR SimpleValue<T>::at(1)
+#define T_BAZ SimpleValue<T>::at(2)
+#define T_CAT SimpleValue<T>::at(3)
+#define T_DOG SimpleValue<T>::at(4)
+#define T_BLAH SimpleValue<T>::at(5)
+#define T_WEEE SimpleValue<T>::at(6)
+
+template<typename T>
 void tst_QList::length() const
 {
     /* Empty list. */
     {
-        const QList<int> list;
+        const QList<T> list;
         QCOMPARE(list.length(), 0);
     }
 
     /* One entry. */
     {
-        QList<int> list;
-        list.append(0);
+        QList<T> list;
+        list.append(T_FOO);
         QCOMPARE(list.length(), 1);
     }
 
     /* Two entries. */
     {
-        QList<int> list;
-        list.append(0);
-        list.append(1);
+        QList<T> list;
+        list.append(T_FOO);
+        list.append(T_BAR);
         QCOMPARE(list.length(), 2);
     }
 
     /* Three entries. */
     {
-        QList<int> list;
-        list.append(0);
-        list.append(0);
-        list.append(0);
+        QList<T> list;
+        list.append(T_FOO);
+        list.append(T_BAR);
+        list.append(T_BAZ);
         QCOMPARE(list.length(), 3);
     }
 }
 
+void tst_QList::lengthInt() const
+{
+    length<int>();
+}
+
+void tst_QList::lengthMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    length<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::lengthComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    length<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
 void tst_QList::lengthSignature() const
 {
     /* Constness. */
@@ -224,16 +402,17 @@ void tst_QList::lengthSignature() const
     }
 }
 
+template<typename T>
 void tst_QList::append() const
 {
     /* test append(const QList<T> &) function */
-    QString one("one");
-    QString two("two");
-    QString three("three");
-    QString four("four");
-    QList<QString> list1;
-    QList<QString> list2;
-    QList<QString> listTotal;
+    T one(T_FOO);
+    T two(T_BAR);
+    T three(T_BAZ);
+    T four(T_CAT);
+    QList<T> list1;
+    QList<T> list2;
+    QList<T> listTotal;
     list1.append(one);
     list1.append(two);
     list2.append(three);
@@ -246,157 +425,317 @@ void tst_QList::append() const
     QCOMPARE(list1, listTotal);
 }
 
+void tst_QList::appendInt() const
+{
+    append<int>();
+}
+
+void tst_QList::appendMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    append<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::appendComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    append<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
 void tst_QList::prepend() const
 {
-    QList<QString *> list;
-    QString *str1 = new QString;
-    list.prepend(str1);
+    QList<int *> list;
+    int *t1 = new int(0);
+    list.prepend(t1);
     QVERIFY(list.size() == 1);
-    QVERIFY(list.at(0) == str1);
-    QString *str2 = new QString;
-    list.prepend(str2);
+    QVERIFY(list.at(0) == t1);
+    int *t2 = new int(0);
+    list.prepend(t2);
     QVERIFY(list.size() == 2);
-    QVERIFY(list.at(0) == str2);
-    QVERIFY(list.at(1) == str1);
-    QString *str3 = new QString;
-    list.prepend(str3);
+    QVERIFY(list.at(0) == t2);
+    QVERIFY(list.at(1) == t1);
+    int *t3 = new int(0);
+    list.prepend(t3);
     QVERIFY(list.size() == 3);
-    QVERIFY(list.at(0) == str3);
-    QVERIFY(list.at(1) == str2);
-    QVERIFY(list.at(2) == str1);
-    list.removeAll(str2);
-    delete str2;
+    QVERIFY(list.at(0) == t3);
+    QVERIFY(list.at(1) == t2);
+    QVERIFY(list.at(2) == t1);
+    list.removeAll(t2);
+    delete t2;
     QVERIFY(list.size() == 2);
-    QVERIFY(list.at(0) == str3);
-    QVERIFY(list.at(1) == str1);
-    QString *str4 = new QString;
-    list.prepend(str4);
+    QVERIFY(list.at(0) == t3);
+    QVERIFY(list.at(1) == t1);
+    int *t4 = new int(0);
+    list.prepend(t4);
     QVERIFY(list.size() == 3);
-    QVERIFY(list.at(0) == str4);
-    QVERIFY(list.at(1) == str3);
-    QVERIFY(list.at(2) == str1);
+    QVERIFY(list.at(0) == t4);
+    QVERIFY(list.at(1) == t3);
+    QVERIFY(list.at(2) == t1);
     qDeleteAll(list);
     list.clear();
 }
 
+template<typename T>
 void tst_QList::mid() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ << T_CAT << T_DOG << T_BLAH << T_WEEE;
 
     QCOMPARE(list.mid(3, 3),
-             QList<QString>() << "bak" << "buck" << "hello");
+        QList<T>() << T_CAT << T_DOG << T_BLAH);
 
-    QList<int> list1;
+    QList<T> list1;
     QCOMPARE(list1.mid(1, 1).length(), 0);
 }
 
+void tst_QList::midInt() const
+{
+    mid<int>();
+}
+
+void tst_QList::midMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    mid<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::midComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    mid<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::at() const
 {
     // test at() and make sure it functions correctly with some simple list manipulation.
-    QList<QString> list;
+    QList<T> list;
 
     // create a list
-    list << "foo" << "bar" << "baz";
+    list << T_FOO << T_BAR << T_BAZ;
     QVERIFY(list.size() == 3);
-    QCOMPARE(list.at(0), QLatin1String("foo"));
-    QCOMPARE(list.at(1), QLatin1String("bar"));
-    QCOMPARE(list.at(2), QLatin1String("baz"));
+    QCOMPARE(list.at(0), T_FOO);
+    QCOMPARE(list.at(1), T_BAR);
+    QCOMPARE(list.at(2), T_BAZ);
 
     // append an item
-    list << "hello";
+    list << T_CAT;
     QVERIFY(list.size() == 4);
-    QCOMPARE(list.at(0), QLatin1String("foo"));
-    QCOMPARE(list.at(1), QLatin1String("bar"));
-    QCOMPARE(list.at(2), QLatin1String("baz"));
-    QCOMPARE(list.at(3), QLatin1String("hello"));
+    QCOMPARE(list.at(0), T_FOO);
+    QCOMPARE(list.at(1), T_BAR);
+    QCOMPARE(list.at(2), T_BAZ);
+    QCOMPARE(list.at(3), T_CAT);
 
     // remove an item
     list.removeAt(1);
     QVERIFY(list.size() == 3);
-    QCOMPARE(list.at(0), QLatin1String("foo"));
-    QCOMPARE(list.at(1), QLatin1String("baz"));
-    QCOMPARE(list.at(2), QLatin1String("hello"));
+    QCOMPARE(list.at(0), T_FOO);
+    QCOMPARE(list.at(1), T_BAZ);
+    QCOMPARE(list.at(2), T_CAT);
 }
 
+void tst_QList::atInt() const
+{
+    at<int>();
+}
+
+void tst_QList::atMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    at<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::atComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    at<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::first() const
 {
-    QList<QString> list;
-    list << "foo" << "bar";
+    QList<T> list;
+    list << T_FOO << T_BAR;
 
-    QCOMPARE(list.first(), QLatin1String("foo"));
+    QCOMPARE(list.first(), T_FOO);
 
     // remove an item, make sure it still works
     list.pop_front();
     QVERIFY(list.size() == 1);
-    QCOMPARE(list.first(), QLatin1String("bar"));
+    QCOMPARE(list.first(), T_BAR);
+}
+
+void tst_QList::firstInt() const
+{
+    first<int>();
 }
 
+void tst_QList::firstMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    first<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::firstComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    first<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::last() const
 {
-    QList<QString> list;
-    list << "foo" << "bar";
+    QList<T> list;
+    list << T_FOO << T_BAR;
 
-    QCOMPARE(list.last(), QLatin1String("bar"));
+    QCOMPARE(list.last(), T_BAR);
 
     // remove an item, make sure it still works
     list.pop_back();
     QVERIFY(list.size() == 1);
-    QCOMPARE(list.last(), QLatin1String("foo"));
+    QCOMPARE(list.last(), T_FOO);
+}
+
+void tst_QList::lastInt() const
+{
+    last<int>();
+}
+
+void tst_QList::lastMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    last<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::lastComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    last<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
 }
 
+template<typename T>
 void tst_QList::begin() const
 {
-    QList<QString> list;
-    list << "foo" << "bar";
+    QList<T> list;
+    list << T_FOO << T_BAR;
 
-    QCOMPARE(*list.begin(), QLatin1String("foo"));
+    QCOMPARE(*list.begin(), T_FOO);
 
     // remove an item, make sure it still works
     list.pop_front();
     QVERIFY(list.size() == 1);
-    QCOMPARE(*list.begin(), QLatin1String("bar"));
+    QCOMPARE(*list.begin(), T_BAR);
 }
 
+void tst_QList::beginInt() const
+{
+    begin<int>();
+}
+
+void tst_QList::beginMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    begin<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::beginComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    begin<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::end() const
 {
-    QList<QString> list;
-    list << "foo" << "bar";
+    QList<T> list;
+    list << T_FOO << T_BAR;
 
-    QCOMPARE(*--list.end(), QLatin1String("bar"));
+    QCOMPARE(*--list.end(), T_BAR);
 
     // remove an item, make sure it still works
     list.pop_back();
     QVERIFY(list.size() == 1);
-    QCOMPARE(*--list.end(), QLatin1String("foo"));
+    QCOMPARE(*--list.end(), T_FOO);
+}
+
+void tst_QList::endInt() const
+{
+    end<int>();
+}
+
+void tst_QList::endMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    end<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
 }
 
+void tst_QList::endComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    end<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::contains() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
-    QVERIFY(list.contains(QLatin1String("foo")) == true);
-    QVERIFY(list.contains(QLatin1String("pirates")) != true);
+    QVERIFY(list.contains(T_FOO) == true);
+    QVERIFY(list.contains(T_BLAH) != true);
 
     // add it and make sure it matches
-    list.append(QLatin1String("ninjas"));
-    QVERIFY(list.contains(QLatin1String("ninjas")) == true);
+    list.append(T_BLAH);
+    QVERIFY(list.contains(T_BLAH) == true);
+}
+
+void tst_QList::containsInt() const
+{
+    contains<int>();
 }
 
+void tst_QList::containsMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    contains<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::containsComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    contains<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::count() const
 {
-    QList<QString> list;
+    QList<T> list;
 
     // starts empty
     QVERIFY(list.count() == 0);
 
     // goes up
-    list.append(QLatin1String("foo"));
+    list.append(T_FOO);
     QVERIFY(list.count() == 1);
 
     // and up
-    list.append(QLatin1String("bar"));
+    list.append(T_BAR);
     QVERIFY(list.count() == 2);
 
     // and down
@@ -408,15 +747,35 @@ void tst_QList::count() const
     QVERIFY(list.count() == 0);
 }
 
+void tst_QList::countInt() const
+{
+    count<int>();
+}
+
+void tst_QList::countMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    count<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::countComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    count<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::empty() const
 {
-    QList<QString> list;
+    QList<T> list;
 
     // make sure it starts empty
     QVERIFY(list.empty());
 
     // and doesn't stay empty
-    list.append(QLatin1String("foo"));
+    list.append(T_FOO);
     QVERIFY(!list.empty());
 
     // and goes back to being empty
@@ -424,324 +783,687 @@ void tst_QList::empty() const
     QVERIFY(list.empty());
 }
 
+void tst_QList::emptyInt() const
+{
+    empty<int>();
+}
+
+void tst_QList::emptyMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    empty<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::emptyComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    empty<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::endsWith() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // test it returns correctly in both cases
-    QVERIFY(list.endsWith(QLatin1String("baz")));
-    QVERIFY(!list.endsWith(QLatin1String("bar")));
+    QVERIFY(list.endsWith(T_BAZ));
+    QVERIFY(!list.endsWith(T_BAR));
 
     // remove an item and make sure the end item changes
     list.pop_back();
-    QVERIFY(list.endsWith(QLatin1String("bar")));
+    QVERIFY(list.endsWith(T_BAR));
+}
+
+void tst_QList::endsWithInt() const
+{
+    endsWith<int>();
+}
+
+void tst_QList::endsWithMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    endsWith<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
 }
 
+void tst_QList::endsWithComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    endsWith<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::lastIndexOf() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // one instance of the target item
-    QVERIFY(list.lastIndexOf(QLatin1String("baz")) == 2);
+    QVERIFY(list.lastIndexOf(T_BAZ) == 2);
 
     // shouldn't find this
-    QVERIFY(list.lastIndexOf(QLatin1String("shouldntfindme")) == -1);
+    QVERIFY(list.lastIndexOf(T_WEEE) == -1);
 
     // multiple instances
-    list.append("baz");
-    list.append("baz");
-    QVERIFY(list.lastIndexOf(QLatin1String("baz")) == 4);
+    list.append(T_BAZ);
+    list.append(T_BAZ);
+    QVERIFY(list.lastIndexOf(T_BAZ) == 4);
 
     // search from the middle to find the last one
-    QVERIFY(list.lastIndexOf(QLatin1String("baz"), 3) == 3);
+    QVERIFY(list.lastIndexOf(T_BAZ, 3) == 3);
 
-    // try find none
-    QVERIFY(list.lastIndexOf(QLatin1String("baz"), 1) == -1);
+    // try to find none
+    QVERIFY(list.lastIndexOf(T_BAZ, 1) == -1);
+}
+
+void tst_QList::lastIndexOfInt() const
+{
+    lastIndexOf<int>();
 }
 
+void tst_QList::lastIndexOfMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    lastIndexOf<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::lastIndexOfComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    lastIndexOf<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::move() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // move an item
     list.move(0, list.count() - 1);
-    QCOMPARE(list, QList<QString>() << "bar" << "baz" << "foo");
+    QCOMPARE(list, QList<T>() << T_BAR << T_BAZ << T_FOO);
 
     // move it back
     list.move(list.count() - 1, 0);
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz");
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
 
     // move an item in the middle
     list.move(1, 0);
-    QCOMPARE(list, QList<QString>() << "bar" << "foo" << "baz");
+    QCOMPARE(list, QList<T>() << T_BAR << T_FOO << T_BAZ);
+}
+
+void tst_QList::moveInt() const
+{
+    move<int>();
+}
+
+void tst_QList::moveMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    move<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::moveComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    move<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
 }
 
+template<typename T>
 void tst_QList::removeAll() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // remove one instance
-    list.removeAll(QLatin1String("bar"));
-    QCOMPARE(list, QList<QString>() << "foo" << "baz");
+    list.removeAll(T_BAR);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
 
     // many instances
-    list << "foo" << "bar" << "baz";
-    list << "foo" << "bar" << "baz";
-    list << "foo" << "bar" << "baz";
-    list.removeAll(QLatin1String("bar"));
-    QCOMPARE(list, QList<QString>() << "foo" << "baz" << "foo" << "baz" << "foo" << "baz" << "foo" << "baz");
+    list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ;
+    list.removeAll(T_BAR);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
 
     // try remove something that doesn't exist
-    list.removeAll(QLatin1String("you won't remove anything I hope"));
-    QCOMPARE(list, QList<QString>() << "foo" << "baz" << "foo" << "baz" << "foo" << "baz" << "foo" << "baz");
+    list.removeAll(T_WEEE);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
 }
 
+void tst_QList::removeAllInt() const
+{
+    removeAll<int>();
+}
+
+void tst_QList::removeAllMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    removeAll<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::removeAllComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    removeAll<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::removeAt() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // middle
     list.removeAt(1);
-    QCOMPARE(list, QList<QString>() << "foo" << "baz");
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
 
     // start
     list.removeAt(0);
-    QCOMPARE(list, QList<QString>() << "baz");
+    QCOMPARE(list, QList<T>() << T_BAZ);
 
     // final
     list.removeAt(0);
-    QCOMPARE(list, QList<QString>());
+    QCOMPARE(list, QList<T>());
 }
 
+void tst_QList::removeAtInt() const
+{
+    removeAt<int>();
+}
+
+void tst_QList::removeAtMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    removeAt<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::removeAtComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    removeAt<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::removeOne() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // middle
-    list.removeOne(QLatin1String("bar"));
-    QCOMPARE(list, QList<QString>() << "foo" << "baz");
+    list.removeOne(T_BAR);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
 
     // start
-    list.removeOne(QLatin1String("foo"));
-    QCOMPARE(list, QList<QString>() << "baz");
+    list.removeOne(T_FOO);
+    QCOMPARE(list, QList<T>() << T_BAZ);
 
     // last
-    list.removeOne(QLatin1String("baz"));
-    QCOMPARE(list, QList<QString>());
+    list.removeOne(T_BAZ);
+    QCOMPARE(list, QList<T>());
 
     // make sure it really only removes one :)
-    list << "foo" << "foo";
-    list.removeOne("foo");
-    QCOMPARE(list, QList<QString>() << "foo");
+    list << T_FOO << T_FOO;
+    list.removeOne(T_FOO);
+    QCOMPARE(list, QList<T>() << T_FOO);
 
     // try remove something that doesn't exist
-    list.removeOne(QLatin1String("you won't remove anything I hope"));
-    QCOMPARE(list, QList<QString>() << "foo");
+    list.removeOne(T_WEEE);
+    QCOMPARE(list, QList<T>() << T_FOO);
+}
+
+void tst_QList::removeOneInt() const
+{
+    removeOne<int>();
 }
 
+void tst_QList::removeOneMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    removeOne<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::removeOneComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    removeOne<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::replace() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // start
-    list.replace(0, "moo");
-    QCOMPARE(list, QList<QString>() << "moo" << "bar" << "baz");
+    list.replace(0, T_CAT);
+    QCOMPARE(list, QList<T>() << T_CAT
+        << T_BAR << T_BAZ);
 
     // middle
-    list.replace(1, "cow");
-    QCOMPARE(list, QList<QString>() << "moo" << "cow" << "baz");
+    list.replace(1, T_DOG);
+    QCOMPARE(list, QList<T>() << T_CAT
+        << T_DOG << T_BAZ);
 
     // end
-    list.replace(2, "milk");
-    QCOMPARE(list, QList<QString>() << "moo" << "cow" << "milk");
+    list.replace(2, T_BLAH);
+    QCOMPARE(list, QList<T>() << T_CAT
+        << T_DOG << T_BLAH);
 }
 
+void tst_QList::replaceInt() const
+{
+    replace<int>();
+}
+
+void tst_QList::replaceMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    replace<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::replaceComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    replace<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::startsWith() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // make sure it starts ok
-    QVERIFY(list.startsWith(QLatin1String("foo")));
+    QVERIFY(list.startsWith(T_FOO));
 
     // remove an item
     list.removeFirst();
-    QVERIFY(list.startsWith(QLatin1String("bar")));
+    QVERIFY(list.startsWith(T_BAR));
+}
+
+void tst_QList::startsWithInt() const
+{
+    startsWith<int>();
+}
+
+void tst_QList::startsWithMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    startsWith<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
 }
 
+void tst_QList::startsWithComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    startsWith<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::swap() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // swap
     list.swap(0, 2);
-    QCOMPARE(list, QList<QString>() << "baz" << "bar" << "foo");
+    QCOMPARE(list, QList<T>() << T_BAZ << T_BAR << T_FOO);
 
     // swap again
     list.swap(1, 2);
-    QCOMPARE(list, QList<QString>() << "baz" << "foo" << "bar");
+    QCOMPARE(list, QList<T>() << T_BAZ << T_FOO << T_BAR);
 
-    QList<QString> list2;
-    list2 << "alpha" << "beta";
+    QList<T> list2;
+    list2 << T_DOG << T_BLAH;
 
     list.swap(list2);
-    QCOMPARE(list,  QList<QString>() << "alpha" << "beta");
-    QCOMPARE(list2, QList<QString>() << "baz" << "foo" << "bar");
+    QCOMPARE(list,  QList<T>() << T_DOG << T_BLAH);
+    QCOMPARE(list2, QList<T>() << T_BAZ << T_FOO << T_BAR);
+}
+
+void tst_QList::swapInt() const
+{
+    swap<int>();
+}
+
+void tst_QList::swapMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    swap<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::swapComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    swap<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
 }
 
+template<typename T>
 void tst_QList::takeAt() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
-    QCOMPARE(list.takeAt(0), QLatin1String("foo"));
+    QCOMPARE(list.takeAt(0), T_FOO);
     QVERIFY(list.size() == 2);
-    QCOMPARE(list.takeAt(1), QLatin1String("baz"));
+    QCOMPARE(list.takeAt(1), T_BAZ);
     QVERIFY(list.size() == 1);
-    QCOMPARE(list.takeAt(0), QLatin1String("bar"));
+    QCOMPARE(list.takeAt(0), T_BAR);
     QVERIFY(list.size() == 0);
 }
 
+void tst_QList::takeAtInt() const
+{
+    takeAt<int>();
+}
+
+void tst_QList::takeAtMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    takeAt<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::takeAtComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    takeAt<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::takeFirst() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
-    QCOMPARE(list.takeFirst(), QLatin1String("foo"));
+    QCOMPARE(list.takeFirst(), T_FOO);
     QVERIFY(list.size() == 2);
-    QCOMPARE(list.takeFirst(), QLatin1String("bar"));
+    QCOMPARE(list.takeFirst(), T_BAR);
     QVERIFY(list.size() == 1);
-    QCOMPARE(list.takeFirst(), QLatin1String("baz"));
+    QCOMPARE(list.takeFirst(), T_BAZ);
     QVERIFY(list.size() == 0);
 }
 
+void tst_QList::takeFirstInt() const
+{
+    takeFirst<int>();
+}
+
+void tst_QList::takeFirstMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    takeFirst<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::takeFirstComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    takeFirst<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::takeLast() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
-    QCOMPARE(list.takeLast(), QLatin1String("baz"));
-    QCOMPARE(list.takeLast(), QLatin1String("bar"));
-    QCOMPARE(list.takeLast(), QLatin1String("foo"));
+    QCOMPARE(list.takeLast(), T_BAZ);
+    QCOMPARE(list.takeLast(), T_BAR);
+    QCOMPARE(list.takeLast(), T_FOO);
 }
 
+void tst_QList::takeLastInt() const
+{
+    takeLast<int>();
+}
+
+void tst_QList::takeLastMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    takeLast<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::takeLastComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    takeLast<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::toSet() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // no duplicates
-    QCOMPARE(list.toSet(), QSet<QString>() << "foo" << "bar" << "baz");
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz");
+    QCOMPARE(list.toSet(), QSet<T>() << T_FOO << T_BAR << T_BAZ);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
 
     // duplicates (is this more of a QSet test?)
-    list << "foo" << "bar" << "baz";
-    QCOMPARE(list.toSet(), QSet<QString>() << "foo" << "bar" << "baz");
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz" << "foo" << "bar" << "baz");
+    list << T_FOO << T_BAR << T_BAZ;
+    QCOMPARE(list.toSet(), QSet<T>() << T_FOO << T_BAR << T_BAZ);
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ
+        << T_FOO << T_BAR << T_BAZ);
 }
 
+void tst_QList::toSetInt() const
+{
+    toSet<int>();
+}
+
+void tst_QList::toSetMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    toSet<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::toSetComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    toSet<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::toStdList() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // yuck.
-    std::list<QString> slist;
-    slist.push_back(QLatin1String("foo"));
-    slist.push_back(QLatin1String("bar"));
-    slist.push_back(QLatin1String("baz"));
+    std::list<T> slist;
+    slist.push_back(T_FOO);
+    slist.push_back(T_BAR);
+    slist.push_back(T_BAZ);
 
     QCOMPARE(list.toStdList(), slist);
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz");
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
+}
+
+void tst_QList::toStdListInt() const
+{
+    toStdList<int>();
 }
 
+void tst_QList::toStdListMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    toStdList<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::toStdListComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    toStdList<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::toVector() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
+
+    QCOMPARE(list.toVector(), QVector<T>() << T_FOO << T_BAR << T_BAZ);
+}
+
+void tst_QList::toVectorInt() const
+{
+    toVector<int>();
+}
+
+void tst_QList::toVectorMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    toVector<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
 
-    QCOMPARE(list.toVector(), QVector<QString>() << "foo" << "bar" << "baz");
+void tst_QList::toVectorComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    toVector<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
 }
 
+template<typename T>
 void tst_QList::value() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
     // test real values
-    QCOMPARE(list.value(0), QLatin1String("foo"));
-    QCOMPARE(list.value(2), QLatin1String("baz"));
+    QCOMPARE(list.value(0), T_FOO);
+    QCOMPARE(list.value(2), T_BAZ);
 
     // test empty default
-    QCOMPARE(list.value(3), QString());
-    QCOMPARE(list.value(-1), QString());
+    QCOMPARE(list.value(3), T());
+    QCOMPARE(list.value(-1), T());
 
     // test defaults
-    QLatin1String defaultstr("default");
-    QCOMPARE(list.value(-1, defaultstr), defaultstr);
-    QCOMPARE(list.value(3, defaultstr), defaultstr);
+    T defaultT(T_WEEE);
+    QCOMPARE(list.value(-1, defaultT), defaultT);
+    QCOMPARE(list.value(3, defaultT), defaultT);
+}
+
+void tst_QList::valueInt() const
+{
+    value<int>();
+}
+
+void tst_QList::valueMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    value<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
 }
 
+void tst_QList::valueComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    value<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::testOperators() const
 {
-    QList<QString> list;
-    list << "foo" << "bar" << "baz";
+    QList<T> list;
+    list << T_FOO << T_BAR << T_BAZ;
 
-    QList<QString> listtwo;
-    listtwo << "foo" << "bar" << "baz";
+    QList<T> listtwo;
+    listtwo << T_FOO << T_BAR << T_BAZ;
 
     // test equal
     QVERIFY(list == listtwo);
 
     // not equal
-    listtwo.append("not equal");
+    listtwo.append(T_CAT);
     QVERIFY(list != listtwo);
 
     // +=
     list += listtwo;
     QVERIFY(list.size() == 7);
     QVERIFY(listtwo.size() == 4);
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz" << "foo" << "bar" << "baz" << "not equal");
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ
+        << T_FOO << T_BAR << T_BAZ << T_CAT);
 
     // =
     list = listtwo;
     QCOMPARE(list, listtwo);
-    QCOMPARE(list, QList<QString>() << "foo" << "bar" << "baz" << "not equal");
+    QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT);
 
     // []
-    QCOMPARE(list[0], QLatin1String("foo"));
-    QCOMPARE(list[list.size() - 1], QLatin1String("not equal"));
+    QCOMPARE(list[0], T_FOO);
+    QCOMPARE(list[list.size() - 1], T_CAT);
+}
+
+void tst_QList::testOperatorsInt() const
+{
+    testOperators<int>();
 }
 
+void tst_QList::testOperatorsMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    testOperators<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::testOperatorsComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    testOperators<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
+template<typename T>
 void tst_QList::testSTLIterators() const
 {
-    QList<QString> list;
+    QList<T> list;
 
     // create a list
-    list << "foo" << "bar" << "baz";
-    QList<QString>::iterator it = list.begin();
-    QCOMPARE(*it, QLatin1String("foo")); it++;
-    QCOMPARE(*it, QLatin1String("bar")); it++;
-    QCOMPARE(*it, QLatin1String("baz")); it++;
+    list << T_FOO << T_BAR << T_BAZ;
+    typename QList<T>::iterator it = list.begin();
+    QCOMPARE(*it, T_FOO); it++;
+    QCOMPARE(*it, T_BAR); it++;
+    QCOMPARE(*it, T_BAZ); it++;
     QCOMPARE(it, list.end()); it--;
 
     // walk backwards
-    QCOMPARE(*it, QLatin1String("baz")); it--;
-    QCOMPARE(*it, QLatin1String("bar")); it--;
-    QCOMPARE(*it, QLatin1String("foo"));
+    QCOMPARE(*it, T_BAZ); it--;
+    QCOMPARE(*it, T_BAR); it--;
+    QCOMPARE(*it, T_FOO);
 
     // test erase
     it = list.erase(it);
     QVERIFY(list.size() == 2);
-    QCOMPARE(*it, QLatin1String("bar"));
+    QCOMPARE(*it, T_BAR);
 
     // test multiple erase
     it = list.erase(it, it + 2);
@@ -749,15 +1471,34 @@ void tst_QList::testSTLIterators() const
     QCOMPARE(it, list.end());
 
     // insert again
-    it = list.insert(it, QLatin1String("foo"));
+    it = list.insert(it, T_FOO);
     QVERIFY(list.size() == 1);
-    QCOMPARE(*it, QLatin1String("foo"));
+    QCOMPARE(*it, T_FOO);
 
     // insert again
-    it = list.insert(it, QLatin1String("bar"));
+    it = list.insert(it, T_BAR);
     QVERIFY(list.size() == 2);
-    QCOMPARE(*it++, QLatin1String("bar"));
-    QCOMPARE(*it, QLatin1String("foo"));
+    QCOMPARE(*it++, T_BAR);
+    QCOMPARE(*it, T_FOO);
+}
+
+void tst_QList::testSTLIteratorsInt() const
+{
+    testSTLIterators<int>();
+}
+
+void tst_QList::testSTLIteratorsMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    testSTLIterators<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::testSTLIteratorsComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    testSTLIterators<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
 }
 
 void tst_QList::initializeList() const
@@ -774,17 +1515,37 @@ void tst_QList::initializeList() const
 #endif
 }
 
-void tst_QList::const_shared_null() const
+template<typename T>
+void tst_QList::constSharedNull() const
 {
-    QList<int> list1;
+    QList<T> list1;
     list1.setSharable(false);
     QVERIFY(list1.isDetached());
 
-    QList<int> list2;
+    QList<T> list2;
     list2.setSharable(true);
     QVERIFY(!list2.isDetached());
 }
 
+void tst_QList::constSharedNullInt() const
+{
+    constSharedNull<int>();
+}
+
+void tst_QList::constSharedNullMovable() const
+{
+    const int liveCount = Movable::getLiveCount();
+    constSharedNull<Movable>();
+    QCOMPARE(liveCount, Movable::getLiveCount());
+}
+
+void tst_QList::constSharedNullComplex() const
+{
+    const int liveCount = Complex::getLiveCount();
+    constSharedNull<Complex>();
+    QCOMPARE(liveCount, Complex::getLiveCount());
+}
+
 Q_DECLARE_METATYPE(QList<int>);
 Q_DECLARE_METATYPE(QList<Complex>);
 
@@ -842,22 +1603,22 @@ void runSetSharableTest()
     QCOMPARE(list.size(), size);
 }
 
-void tst_QList::setSharable1_data() const
+void tst_QList::setSharableInt_data() const
 {
     generateSetSharableData<int>();
 }
 
-void tst_QList::setSharable2_data() const
+void tst_QList::setSharableComplex_data() const
 {
     generateSetSharableData<Complex>();
 }
 
-void tst_QList::setSharable1() const
+void tst_QList::setSharableInt() const
 {
     runSetSharableTest<int>();
 }
 
-void tst_QList::setSharable2() const
+void tst_QList::setSharableComplex() const
 {
     runSetSharableTest<Complex>();
 }