summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp117
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8.pro2
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8data.cpp163
-rw-r--r--tests/auto/corelib/global/global.pro3
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp111
-rw-r--r--tests/auto/corelib/global/qtendian/qtendian.pro4
-rw-r--r--tests/auto/corelib/global/qtendian/tst_qtendian.cpp146
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp24
-rw-r--r--tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp114
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp24
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp39
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp225
-rw-r--r--tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp154
-rw-r--r--tests/auto/corelib/kernel/qobject/oldnormalizeobject.h69
-rw-r--r--tests/auto/corelib/kernel/qobject/test/test.pro4
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp118
-rw-r--r--tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.binbin0 -> 53 bytes
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp137
-rw-r--r--tests/auto/corelib/tools/qarraydata/qarraydata.pro5
-rw-r--r--tests/auto/corelib/tools/qarraydata/simplevector.h341
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp1464
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp172
-rw-r--r--tests/auto/corelib/tools/qlist/tst_qlist.cpp172
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp2
-rw-r--r--tests/auto/corelib/tools/qmap/tst_qmap.cpp166
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp20
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp220
-rw-r--r--tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp96
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp94
-rw-r--r--tests/auto/corelib/tools/tools.pro1
30 files changed, 3608 insertions, 599 deletions
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
index dd6774e101..025bb349d6 100644
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
@@ -206,88 +206,8 @@ void tst_Utf8::invalidUtf8_data()
{
QTest::addColumn<QByteArray>("utf8");
- QTest::newRow("1char") << QByteArray("\x80");
- QTest::newRow("2chars-1") << QByteArray("\xC2\xC0");
- QTest::newRow("2chars-2") << QByteArray("\xC3\xDF");
- QTest::newRow("2chars-3") << QByteArray("\xC7\xF0");
- QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0");
- QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0");
- QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0");
- QTest::newRow("4chars-2") << QByteArray("\xF0\x90\xC0\x80");
- QTest::newRow("4chars-3") << QByteArray("\xF0\xC0\x80\x80");
-
- // Surrogate pairs must now be present either
- // U+D800: 1101 10 0000 00 0000
- // encoding: xxxz:1101 xz10:0000 xz00:0000
- QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80");
- // U+DC00: 1101 11 0000 00 0000
- // encoding: xxxz:1101 xz11:0000 xz00:0000
- QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80");
-
- // not even in pair:
- QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80");
-
- // Characters outside the Unicode range:
- // 0x110000: 00 0100 01 0000 00 0000 00 0000
- // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000
- QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80");
- // 0x200000: 00 1000 00 0000 00 0000 00 0000
- // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000
- QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80");
- // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000
- // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80");
- // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111
- // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF");
-
- // As seen above, 0xFE and 0xFF never appear:
- QTest::newRow("fe") << QByteArray("\xFE");
- QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF");
- QTest::newRow("ff") << QByteArray("\xFF");
- QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF");
-
- // some combinations in UTF-8 are invalid even though they have the proper bits set
- // these are known as overlong sequences
-
- // "A": U+0041: 01 00 0001
- // overlong 2: xxz0:0001 xz00:0001
- QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81");
- // overlong 3: xxxz:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81");
- // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81");
-
- // NBSP: U+00A0: 10 00 0000
- // proper encoding: xxz0:0010 xz00:0000
- // overlong 3: xxxz:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-3") << QByteArray("\xC0\x82\x80");
- // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80");
-
- // U+0800: 10 0000 00 0000
- // proper encoding: xxxz:0000 xz10:0000 xz00:0000
- // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80");
-
- // U+010000: 00 0100 00 0000 00 0000
- // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000
- QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000
- QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80");
+ extern void loadInvalidUtf8Rows();
+ loadInvalidUtf8Rows();
}
void tst_Utf8::invalidUtf8()
@@ -313,37 +233,8 @@ void tst_Utf8::nonCharacters_data()
QTest::addColumn<QByteArray>("utf8");
QTest::addColumn<QString>("utf16");
- // Unicode has a couple of "non-characters" that one can use internally,
- // but are not allowed to be used for text interchange.
- //
- // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
- // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
- // U+FDEF (inclusive)
-
- // U+FDD0 through U+FDEF
- for (int i = 0; i < 16; ++i) {
- char utf8[] = { char(0357), char(0267), char(0220 + i), 0 };
- QString utf16 = QChar(0xfdd0 + i);
- QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16;
- }
-
- // the last two in Planes 1 through 16
- for (uint plane = 1; plane <= 16; ++plane) {
- for (uint lower = 0xfffe; lower < 0x10000; ++lower) {
- uint ucs4 = (plane << 16) | lower;
- char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)),
- char(0x80 | (uchar(ucs4 >> 12) & 0x3f)),
- char(0x80 | (uchar(ucs4 >> 6) & 0x3f)),
- char(0x80 | (uchar(ucs4) & 0x3f)),
- 0 };
- ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 };
-
- QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16);
- }
- }
-
- QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe));
- QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff));
+ extern void loadNonCharactersRows();
+ loadNonCharactersRows();
}
void tst_Utf8::nonCharacters()
diff --git a/tests/auto/corelib/codecs/utf8/utf8.pro b/tests/auto/corelib/codecs/utf8/utf8.pro
index 2d200e82a4..1df6ac7e50 100644
--- a/tests/auto/corelib/codecs/utf8/utf8.pro
+++ b/tests/auto/corelib/codecs/utf8/utf8.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
TARGET = tst_utf8
QT = core testlib
-SOURCES += tst_utf8.cpp
+SOURCES += tst_utf8.cpp utf8data.cpp
CONFIG += parallel_test
diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp
new file mode 100644
index 0000000000..2c0bae3e5d
--- /dev/null
+++ b/tests/auto/corelib/codecs/utf8/utf8data.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** 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$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+void loadInvalidUtf8Rows()
+{
+ QTest::newRow("1char") << QByteArray("\x80");
+ QTest::newRow("2chars-1") << QByteArray("\xC2\xC0");
+ QTest::newRow("2chars-2") << QByteArray("\xC3\xDF");
+ QTest::newRow("2chars-3") << QByteArray("\xC7\xF0");
+ QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0");
+ QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0");
+ QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0");
+ QTest::newRow("4chars-2") << QByteArray("\xF0\x90\xC0\x80");
+ QTest::newRow("4chars-3") << QByteArray("\xF0\xC0\x80\x80");
+
+ // Surrogate pairs must now be present either
+ // U+D800: 1101 10 0000 00 0000
+ // encoding: xxxz:1101 xz10:0000 xz00:0000
+ QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80");
+ // U+DC00: 1101 11 0000 00 0000
+ // encoding: xxxz:1101 xz11:0000 xz00:0000
+ QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80");
+
+ // not even in pair:
+ QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80");
+
+ // Characters outside the Unicode range:
+ // 0x110000: 00 0100 01 0000 00 0000 00 0000
+ // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000
+ QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80");
+ // 0x200000: 00 1000 00 0000 00 0000 00 0000
+ // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000
+ QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80");
+ // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000
+ // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80");
+ // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111
+ // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF");
+
+ // As seen above, 0xFE and 0xFF never appear:
+ QTest::newRow("fe") << QByteArray("\xFE");
+ QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF");
+ QTest::newRow("ff") << QByteArray("\xFF");
+ QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF");
+
+ // some combinations in UTF-8 are invalid even though they have the proper bits set
+ // these are known as overlong sequences
+
+ // "A": U+0041: 01 00 0001
+ // overlong 2: xxz0:0001 xz00:0001
+ QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81");
+ // overlong 3: xxxz:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81");
+ // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81");
+
+ // NBSP: U+00A0: 10 00 0000
+ // proper encoding: xxz0:0010 xz00:0000
+ // overlong 3: xxxz:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-3") << QByteArray("\xC0\x82\x80");
+ // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80");
+
+ // U+0800: 10 0000 00 0000
+ // proper encoding: xxxz:0000 xz10:0000 xz00:0000
+ // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80");
+
+ // U+010000: 00 0100 00 0000 00 0000
+ // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000
+ QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000
+ QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80");
+
+}
+
+void loadNonCharactersRows()
+{
+ // Unicode has a couple of "non-characters" that one can use internally,
+ // but are not allowed to be used for text interchange.
+ //
+ // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
+ // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
+ // U+FDEF (inclusive)
+
+ // U+FDD0 through U+FDEF
+ for (int i = 0; i < 16; ++i) {
+ char utf8[] = { char(0357), char(0267), char(0220 + i), 0 };
+ QString utf16 = QChar(0xfdd0 + i);
+ QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16;
+ }
+
+ // the last two in Planes 1 through 16
+ for (uint plane = 1; plane <= 16; ++plane) {
+ for (uint lower = 0xfffe; lower < 0x10000; ++lower) {
+ uint ucs4 = (plane << 16) | lower;
+ char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)),
+ char(0x80 | (uchar(ucs4 >> 12) & 0x3f)),
+ char(0x80 | (uchar(ucs4 >> 6) & 0x3f)),
+ char(0x80 | (uchar(ucs4) & 0x3f)),
+ 0 };
+ ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 };
+
+ QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16);
+ }
+ }
+
+ QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe));
+ QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff));
+}
diff --git a/tests/auto/corelib/global/global.pro b/tests/auto/corelib/global/global.pro
index d4293a896c..5489b8330d 100644
--- a/tests/auto/corelib/global/global.pro
+++ b/tests/auto/corelib/global/global.pro
@@ -6,4 +6,5 @@ SUBDIRS=\
qglobal \
qnumeric \
qrand \
- qlogging
+ qlogging \
+ qtendian
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index b3d76bef8a..529bafaa7a 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -56,6 +56,7 @@ private slots:
void qstaticassert();
void qConstructorFunction();
void isEnum();
+ void qAlignOf();
};
void tst_QGlobal::qIsNull()
@@ -415,5 +416,115 @@ void tst_QGlobal::isEnum()
#undef IS_ENUM_FALSE
}
+struct Empty {};
+template <class T> struct AlignmentInStruct { T dummy; };
+
+typedef int (*fun) ();
+typedef int (Empty::*memFun) ();
+
+#define TEST_AlignOf(type, alignment) \
+ do { \
+ TEST_AlignOf_impl(type, alignment); \
+ \
+ TEST_AlignOf_impl(type &, alignment); \
+ TEST_AlignOf_RValueRef(type &&, alignment); \
+ \
+ TEST_AlignOf_impl(type [5], alignment); \
+ TEST_AlignOf_impl(type (&) [5], alignment); \
+ \
+ TEST_AlignOf_impl(AlignmentInStruct<type>, alignment); \
+ \
+ /* Some internal sanity validation, just for fun */ \
+ TEST_AlignOf_impl(AlignmentInStruct<type [5]>, alignment); \
+ TEST_AlignOf_impl(AlignmentInStruct<type &>, Q_ALIGNOF(void *)); \
+ TEST_AlignOf_impl(AlignmentInStruct<type (&) [5]>, \
+ Q_ALIGNOF(void *)); \
+ TEST_AlignOf_RValueRef(AlignmentInStruct<type &&>, \
+ Q_ALIGNOF(void *)); \
+ } while (false) \
+ /**/
+
+#ifdef Q_COMPILER_RVALUE_REFS
+#define TEST_AlignOf_RValueRef(type, alignment) \
+ TEST_AlignOf_impl(type, alignment)
+#else
+#define TEST_AlignOf_RValueRef(type, alignment) do {} while (false)
+#endif
+
+#define TEST_AlignOf_impl(type, alignment) \
+ do { \
+ QCOMPARE(Q_ALIGNOF(type), size_t(alignment)); \
+ /* Compare to native operator for compilers that support it,
+ otherwise... erm... check consistency! :-) */ \
+ QCOMPARE(QT_EMULATED_ALIGNOF(type), Q_ALIGNOF(type)); \
+ } while (false)
+ /**/
+
+void tst_QGlobal::qAlignOf()
+{
+ // Built-in types, except 64-bit integers and double
+ TEST_AlignOf(char, 1);
+ TEST_AlignOf(signed char, 1);
+ TEST_AlignOf(unsigned char, 1);
+ TEST_AlignOf(qint8, 1);
+ TEST_AlignOf(quint8, 1);
+ TEST_AlignOf(qint16, 2);
+ TEST_AlignOf(quint16, 2);
+ TEST_AlignOf(qint32, 4);
+ TEST_AlignOf(quint32, 4);
+ TEST_AlignOf(void *, sizeof(void *));
+
+ // Depends on platform and compiler, disabling test for now
+ // TEST_AlignOf(long double, 16);
+
+ // Empty struct
+ TEST_AlignOf(Empty, 1);
+
+ // Function pointers
+ TEST_AlignOf(fun, Q_ALIGNOF(void *));
+ TEST_AlignOf(memFun, Q_ALIGNOF(void *));
+
+
+ // 64-bit integers and double
+ TEST_AlignOf_impl(qint64, 8);
+ TEST_AlignOf_impl(quint64, 8);
+ TEST_AlignOf_impl(double, 8);
+
+ TEST_AlignOf_impl(qint64 &, 8);
+ TEST_AlignOf_impl(quint64 &, 8);
+ TEST_AlignOf_impl(double &, 8);
+
+ TEST_AlignOf_RValueRef(qint64 &&, 8);
+ TEST_AlignOf_RValueRef(quint64 &&, 8);
+ TEST_AlignOf_RValueRef(double &&, 8);
+
+ // 32-bit x86 ABI idiosyncrasies
+#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN)
+ TEST_AlignOf_impl(AlignmentInStruct<qint64>, 4);
+#else
+ TEST_AlignOf_impl(AlignmentInStruct<qint64>, 8);
+#endif
+
+ TEST_AlignOf_impl(AlignmentInStruct<quint64>, Q_ALIGNOF(AlignmentInStruct<qint64>));
+ TEST_AlignOf_impl(AlignmentInStruct<double>, Q_ALIGNOF(AlignmentInStruct<qint64>));
+
+ // 32-bit x86 ABI, Clang disagrees with gcc
+#if !defined(Q_PROCESSOR_X86_32) || !defined(Q_CC_CLANG)
+ TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(qint64));
+#else
+ TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(AlignmentInStruct<qint64>));
+#endif
+
+ TEST_AlignOf_impl(qint64 (&) [5], Q_ALIGNOF(qint64 [5]));
+ TEST_AlignOf_impl(quint64 [5], Q_ALIGNOF(quint64 [5]));
+ TEST_AlignOf_impl(quint64 (&) [5], Q_ALIGNOF(quint64 [5]));
+ TEST_AlignOf_impl(double [5], Q_ALIGNOF(double [5]));
+ TEST_AlignOf_impl(double (&) [5], Q_ALIGNOF(double [5]));
+}
+
+#undef TEST_AlignOf
+#undef TEST_AlignOf_RValueRef
+#undef TEST_AlignOf_impl
+
QTEST_MAIN(tst_QGlobal)
#include "tst_qglobal.moc"
diff --git a/tests/auto/corelib/global/qtendian/qtendian.pro b/tests/auto/corelib/global/qtendian/qtendian.pro
new file mode 100644
index 0000000000..caad0fc764
--- /dev/null
+++ b/tests/auto/corelib/global/qtendian/qtendian.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase parallel_test
+TARGET = tst_qtendian
+QT = core testlib
+SOURCES = tst_qtendian.cpp
diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
new file mode 100644
index 0000000000..002060b0ef
--- /dev/null
+++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** 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$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtCore/qendian.h>
+
+
+class tst_QtEndian: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void fromBigEndian();
+ void fromLittleEndian();
+
+ void toBigEndian();
+ void toLittleEndian();
+};
+
+struct TestData
+{
+ quint64 data64;
+ quint32 data32;
+ quint16 data16;
+ quint8 data8;
+
+ quint8 reserved;
+};
+
+union RawTestData
+{
+ uchar rawData[sizeof(TestData)];
+ TestData data;
+};
+
+static const TestData inNativeEndian = { 0x0123456789abcdef, 0x00c0ffee, 0xcafe, 0xcf, '\0' };
+static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" };
+static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" };
+
+#define EXPAND_ENDIAN_TEST(endian) \
+ do { \
+ /* Unsigned tests */ \
+ ENDIAN_TEST(endian, quint, 64); \
+ ENDIAN_TEST(endian, quint, 32); \
+ ENDIAN_TEST(endian, quint, 16); \
+ ENDIAN_TEST(endian, quint, 8); \
+ \
+ /* Signed tests */ \
+ ENDIAN_TEST(endian, qint, 64); \
+ ENDIAN_TEST(endian, qint, 32); \
+ ENDIAN_TEST(endian, qint, 16); \
+ ENDIAN_TEST(endian, qint, 8); \
+ } while (false) \
+ /**/
+
+#define ENDIAN_TEST(endian, type, size) \
+ do { \
+ QCOMPARE(qFrom ## endian ## Endian( \
+ (type ## size)(in ## endian ## Endian.data.data ## size)), \
+ (type ## size)(inNativeEndian.data ## size)); \
+ QCOMPARE(qFrom ## endian ## Endian<type ## size>( \
+ in ## endian ## Endian.rawData + offsetof(TestData, data ## size)), \
+ (type ## size)(inNativeEndian.data ## size)); \
+ } while (false) \
+ /**/
+
+void tst_QtEndian::fromBigEndian()
+{
+ EXPAND_ENDIAN_TEST(Big);
+}
+
+void tst_QtEndian::fromLittleEndian()
+{
+ EXPAND_ENDIAN_TEST(Little);
+}
+
+#undef ENDIAN_TEST
+
+
+#define ENDIAN_TEST(endian, type, size) \
+ do { \
+ QCOMPARE(qTo ## endian ## Endian( \
+ (type ## size)(inNativeEndian.data ## size)), \
+ (type ## size)(in ## endian ## Endian.data.data ## size)); \
+ \
+ RawTestData test; \
+ qTo ## endian ## Endian( \
+ (type ## size)(inNativeEndian.data ## size), \
+ test.rawData + offsetof(TestData, data ## size)); \
+ QCOMPARE(test.data.data ## size, in ## endian ## Endian.data.data ## size ); \
+ } while (false) \
+ /**/
+
+void tst_QtEndian::toBigEndian()
+{
+ EXPAND_ENDIAN_TEST(Big);
+}
+
+void tst_QtEndian::toLittleEndian()
+{
+ EXPAND_ENDIAN_TEST(Little);
+}
+
+#undef ENDIAN_TEST
+
+QTEST_MAIN(tst_QtEndian)
+#include "tst_qtendian.moc"
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index a74d817b8a..a1b7dbca0f 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -262,9 +262,16 @@ void tst_QUrl::hashInPath()
QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt"));
QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt"));
QCOMPARE(withHashInPath.toString(), QString("hi%23mum.txt"));
+ QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt"));
QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded());
QVERIFY(withHashInPath == fromHashInPath);
+
+ const QUrl localWithHash = QUrl::fromLocalFile("/hi#mum.txt");
+ QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt"));
+ QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt"));
+ QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt"));
+ QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt"));
}
void tst_QUrl::unc()
@@ -352,6 +359,7 @@ void tst_QUrl::setUrl()
QCOMPARE(url.port(), -1);
QCOMPARE(url.toString(), QString::fromLatin1("file:///"));
QCOMPARE(url.toDisplayString(), QString::fromLatin1("file:///"));
+ QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("/"));
}
{
@@ -367,6 +375,7 @@ void tst_QUrl::setUrl()
QCOMPARE(url.port(), 80);
QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80"));
QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80"));
+ QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80"));
QUrl url2("//www1.foo.bar");
QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar"));
@@ -451,15 +460,7 @@ void tst_QUrl::setUrl()
QUrl url = u1;
QVERIFY(url.isValid());
QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
- QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
- }
-
- {
- QString u1 = "file:/home/dfaure/my#myref";
- QUrl url = u1;
- QVERIFY(url.isValid());
-
- QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
+ QCOMPARE(url.toString(QUrl::PreferLocalFile), QString::fromLatin1("file:///home/dfaure/my#myref"));
QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
}
@@ -1001,6 +1002,7 @@ void tst_QUrl::toLocalFile()
QUrl url(theUrl);
QCOMPARE(url.toLocalFile(), theFile);
+ QCOMPARE(url.isLocalFile(), !theFile.isEmpty());
}
void tst_QUrl::fromLocalFile_data()
@@ -2419,8 +2421,8 @@ void tst_QUrl::nameprep_testsuite_data()
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
-extern void qt_nameprep(QString *source, int from);
-extern bool qt_check_std3rules(const QChar *, int);
+Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from);
+Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int);
QT_END_NAMESPACE
#endif
diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
index 1651d00738..55997a3ca0 100644
--- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
+++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
@@ -114,6 +114,7 @@ public slots:
void voidSlotNoParameterNames(bool, int);
signals:
void voidSignal();
+ void voidSignalVoid(void);
void voidSignalInt(int voidSignalIntArg);
void voidSignalQReal(qreal voidSignalQRealArg);
void voidSignalQString(const QString &voidSignalQStringArg);
@@ -196,7 +197,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignal")
<< QByteArray("voidSignal()")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>())
<< (QList<QByteArray>())
<< (QList<QByteArray>())
@@ -205,7 +206,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokable")
<< QByteArray("voidInvokable()")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>())
<< (QList<QByteArray>())
<< (QList<QByteArray>())
@@ -214,7 +215,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlot")
<< QByteArray("voidSlot()")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>())
<< (QList<QByteArray>())
<< (QList<QByteArray>())
@@ -223,16 +224,25 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject()")
<< QByteArray("MethodTestObject()")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>())
<< (QList<QByteArray>())
<< (QList<QByteArray>())
<< QMetaMethod::Public
<< QMetaMethod::Constructor;
+ QTest::newRow("voidSignalVoid")
+ << QByteArray("voidSignalVoid()")
+ << int(QMetaType::Void) << QByteArray("void")
+ << QList<int>()
+ << QList<QByteArray>()
+ << QList<QByteArray>()
+ << QMetaMethod::Protected
+ << QMetaMethod::Signal;
+
QTest::newRow("voidSignalInt")
<< QByteArray("voidSignalInt(int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("voidSignalIntArg"))
@@ -241,7 +251,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableInt")
<< QByteArray("voidInvokableInt(int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("voidInvokableIntArg"))
@@ -250,7 +260,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotInt")
<< QByteArray("voidSlotInt(int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("voidSlotIntArg"))
@@ -259,7 +269,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(int)")
<< QByteArray("MethodTestObject(int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("constructorIntArg"))
@@ -268,7 +278,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignalQReal")
<< QByteArray("voidSignalQReal(qreal)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<qreal>())
<< (QList<QByteArray>() << QByteArray("qreal"))
<< (QList<QByteArray>() << QByteArray("voidSignalQRealArg"))
@@ -277,7 +287,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableQReal")
<< QByteArray("voidInvokableQReal(qreal)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<qreal>())
<< (QList<QByteArray>() << QByteArray("qreal"))
<< (QList<QByteArray>() << QByteArray("voidInvokableQRealArg"))
@@ -286,7 +296,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotQReal")
<< QByteArray("voidSlotQReal(qreal)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<qreal>())
<< (QList<QByteArray>() << QByteArray("qreal"))
<< (QList<QByteArray>() << QByteArray("voidSlotQRealArg"))
@@ -295,7 +305,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(qreal)")
<< QByteArray("MethodTestObject(qreal)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << qMetaTypeId<qreal>())
<< (QList<QByteArray>() << QByteArray("qreal"))
<< (QList<QByteArray>() << QByteArray("constructorQRealArg"))
@@ -304,7 +314,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignalQString")
<< QByteArray("voidSignalQString(QString)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::QString))
<< (QList<QByteArray>() << QByteArray("QString"))
<< (QList<QByteArray>() << QByteArray("voidSignalQStringArg"))
@@ -313,7 +323,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableQString")
<< QByteArray("voidInvokableQString(QString)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::QString))
<< (QList<QByteArray>() << QByteArray("QString"))
<< (QList<QByteArray>() << QByteArray("voidInvokableQStringArg"))
@@ -322,7 +332,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotQString")
<< QByteArray("voidSlotQString(QString)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::QString))
<< (QList<QByteArray>() << QByteArray("QString"))
<< (QList<QByteArray>() << QByteArray("voidSlotQStringArg"))
@@ -331,7 +341,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(QString)")
<< QByteArray("MethodTestObject(QString)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << int(QMetaType::QString))
<< (QList<QByteArray>() << QByteArray("QString"))
<< (QList<QByteArray>() << QByteArray("constructorQStringArg"))
@@ -340,7 +350,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignalCustomType")
<< QByteArray("voidSignalCustomType(CustomType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<CustomType>())
<< (QList<QByteArray>() << QByteArray("CustomType"))
<< (QList<QByteArray>() << QByteArray("voidSignalCustomTypeArg"))
@@ -349,7 +359,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableCustomType")
<< QByteArray("voidInvokableCustomType(CustomType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<CustomType>())
<< (QList<QByteArray>() << QByteArray("CustomType"))
<< (QList<QByteArray>() << QByteArray("voidInvokableCustomTypeArg"))
@@ -358,7 +368,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotCustomType")
<< QByteArray("voidSlotCustomType(CustomType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << qMetaTypeId<CustomType>())
<< (QList<QByteArray>() << QByteArray("CustomType"))
<< (QList<QByteArray>() << QByteArray("voidSlotCustomTypeArg"))
@@ -367,7 +377,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(CustomType)")
<< QByteArray("MethodTestObject(CustomType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << qMetaTypeId<CustomType>())
<< (QList<QByteArray>() << QByteArray("CustomType"))
<< (QList<QByteArray>() << QByteArray("constructorCustomTypeArg"))
@@ -376,7 +386,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignalCustomUnregisteredType")
<< QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
@@ -385,7 +395,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableCustomUnregisteredType")
<< QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
@@ -394,7 +404,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotCustomUnregisteredType")
<< QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << 0)
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
@@ -403,7 +413,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(CustomUnregisteredType)")
<< QByteArray("MethodTestObject(CustomUnregisteredType)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << 0)
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
@@ -536,7 +546,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
<< QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< parameterTypes << parameterTypeNames << parameterNames
<< QMetaMethod::Public
<< QMetaMethod::Constructor;
@@ -544,7 +554,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSignalNoParameterNames")
<< QByteArray("voidSignalNoParameterNames(bool,int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
@@ -553,7 +563,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableNoParameterNames")
<< QByteArray("voidInvokableNoParameterNames(bool,int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
@@ -562,7 +572,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotNoParameterNames")
<< QByteArray("voidSlotNoParameterNames(bool,int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::Void) << QByteArray("void")
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
@@ -571,7 +581,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(bool,int)")
<< QByteArray("MethodTestObject(bool,int)")
- << int(QMetaType::Void) << QByteArray("")
+ << int(QMetaType::UnknownType) << QByteArray("")
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
@@ -603,15 +613,51 @@ void tst_QMetaMethod::method()
QCOMPARE(method.methodType(), methodType);
QCOMPARE(method.access(), access);
- QCOMPARE(method.signature(), signature.constData());
+ QVERIFY(!method.methodSignature().isEmpty());
+ if (method.methodSignature() != signature) {
+ // QMetaMethod should always produce a semantically equivalent signature
+ int signatureIndex = (methodType == QMetaMethod::Constructor)
+ ? mo->indexOfConstructor(method.methodSignature())
+ : mo->indexOfMethod(method.methodSignature());
+ QCOMPARE(signatureIndex, index);
+ }
- QCOMPARE(method.tag(), "");
+ QByteArray computedName = signature.left(signature.indexOf('('));
+ QCOMPARE(method.name(), computedName);
- QCOMPARE(method.typeName(), returnTypeName.constData());
- QCOMPARE(QMetaType::type(method.typeName()), returnType);
+ QCOMPARE(method.tag(), "");
+ QCOMPARE(method.returnType(), returnType);
+ QVERIFY(method.typeName() != 0);
+ if (QByteArray(method.typeName()) != returnTypeName) {
+ // QMetaMethod should always produce a semantically equivalent typename
+ QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName));
+ }
- QCOMPARE(method.parameterTypes(), parameterTypeNames);
+ if (method.parameterTypes() != parameterTypeNames) {
+ // QMetaMethod should always produce semantically equivalent typenames
+ QList<QByteArray> actualTypeNames = method.parameterTypes();
+ QCOMPARE(actualTypeNames.size(), parameterTypeNames.size());
+ for (int i = 0; i < parameterTypeNames.size(); ++i) {
+ QCOMPARE(QMetaType::type(actualTypeNames.at(i)),
+ QMetaType::type(parameterTypeNames.at(i)));
+ }
+ }
QCOMPARE(method.parameterNames(), parameterNames);
+
+ QCOMPARE(method.parameterCount(), parameterTypes.size());
+ for (int i = 0; i < parameterTypes.size(); ++i)
+ QCOMPARE(method.parameterType(i), parameterTypes.at(i));
+
+ {
+ QVector<int> actualParameterTypes(parameterTypes.size());
+ method.getParameterTypes(actualParameterTypes.data());
+ for (int i = 0; i < parameterTypes.size(); ++i)
+ QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i));
+ }
+
+ // Bogus indexes
+ QCOMPARE(method.parameterType(-1), 0);
+ QCOMPARE(method.parameterType(parameterTypes.size()), 0);
}
void tst_QMetaMethod::invalidMethod()
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index 09fd0a7adb..5cf28b5141 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -816,9 +816,22 @@ void tst_QMetaObject::normalizedSignature_data()
QTest::newRow("function") << "void foo()" << "void foo()";
QTest::newRow("spaces") << " void foo( ) " << "void foo()";
+ QTest::newRow("void") << "void foo(void)" << "void foo()";
+ QTest::newRow("void spaces") << "void foo( void )" << "void foo()";
+ QTest::newRow("void*") << "void foo(void*)" << "void foo(void*)";
+ QTest::newRow("void* spaces") << "void foo( void * )" << "void foo(void*)";
+ QTest::newRow("function ptr") << "void foo(void(*)(void))" << "void foo(void(*)())";
+ QTest::newRow("function ptr spaces") << "void foo( void ( * ) ( void ))" << "void foo(void(*)())";
+ QTest::newRow("function ptr void*") << "void foo(void(*)(void*))" << "void foo(void(*)(void*))";
+ QTest::newRow("function ptr void* spaces") << "void foo( void ( * ) ( void * ))" << "void foo(void(*)(void*))";
QTest::newRow("template args") << " void foo( QMap<a, a>, QList<b>) "
<< "void foo(QMap<a,a>,QList<b>)";
+ QTest::newRow("void template args") << " void foo( Foo<void>, Bar<void> ) "
+ << "void foo(Foo<void>,Bar<void>)";
+ QTest::newRow("void* template args") << " void foo( Foo<void*>, Bar<void *> ) "
+ << "void foo(Foo<void*>,Bar<void*>)";
QTest::newRow("rettype") << "QList<int, int> foo()" << "QList<int,int>foo()";
+ QTest::newRow("rettype void template") << "Foo<void> foo()" << "Foo<void>foo()";
QTest::newRow("const rettype") << "const QString *foo()" << "const QString*foo()";
QTest::newRow("const ref") << "const QString &foo()" << "const QString&foo()";
QTest::newRow("reference") << "QString &foo()" << "QString&foo()";
@@ -877,6 +890,7 @@ void tst_QMetaObject::normalizedType_data()
QTest::newRow("struct") << "const struct foo*" << "const foo*";
QTest::newRow("struct2") << "struct foo const*" << "const foo*";
QTest::newRow("enum") << "enum foo" << "foo";
+ QTest::newRow("void") << "void" << "void";
}
void tst_QMetaObject::normalizedType()
@@ -978,25 +992,25 @@ void tst_QMetaObject::propertyNotify()
QVERIFY(prop.isValid());
QVERIFY(prop.hasNotifySignal());
QMetaMethod signal = prop.notifySignal();
- QCOMPARE(signal.signature(), "value6Changed()");
+ QCOMPARE(signal.methodSignature(), QByteArray("value6Changed()"));
prop = mo->property(mo->indexOfProperty("value7"));
QVERIFY(prop.isValid());
QVERIFY(prop.hasNotifySignal());
signal = prop.notifySignal();
- QCOMPARE(signal.signature(), "value7Changed(QString)");
+ QCOMPARE(signal.methodSignature(), QByteArray("value7Changed(QString)"));
prop = mo->property(mo->indexOfProperty("value8"));
QVERIFY(prop.isValid());
QVERIFY(!prop.hasNotifySignal());
signal = prop.notifySignal();
- QCOMPARE(signal.signature(), (const char *)0);
+ QCOMPARE(signal.methodSignature(), QByteArray());
prop = mo->property(mo->indexOfProperty("value"));
QVERIFY(prop.isValid());
QVERIFY(!prop.hasNotifySignal());
signal = prop.notifySignal();
- QCOMPARE(signal.signature(), (const char *)0);
+ QCOMPARE(signal.methodSignature(), QByteArray());
}
void tst_QMetaObject::propertyConstant()
@@ -1114,7 +1128,7 @@ void tst_QMetaObject::indexOfMethod()
QFETCH(bool, isSignal);
int idx = object->metaObject()->indexOfMethod(name);
QVERIFY(idx >= 0);
- QCOMPARE(object->metaObject()->method(idx).signature(), name.constData());
+ QCOMPARE(object->metaObject()->method(idx).methodSignature(), name);
QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx);
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
}
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 97b14a374e..0649d1e1d8 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -217,6 +217,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(nullMethod.signature(), QByteArray());
QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
QVERIFY(nullMethod.returnType().isEmpty());
+ QVERIFY(nullMethod.parameterTypes().isEmpty());
QVERIFY(nullMethod.parameterNames().isEmpty());
QVERIFY(nullMethod.tag().isEmpty());
QVERIFY(nullMethod.access() == QMetaMethod::Public);
@@ -228,7 +229,8 @@ void tst_QMetaObjectBuilder::method()
QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)");
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(method1.methodType() == QMetaMethod::Method);
- QVERIFY(method1.returnType().isEmpty());
+ QCOMPARE(method1.returnType(), QByteArray("void"));
+ QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QVERIFY(method1.parameterNames().isEmpty());
QVERIFY(method1.tag().isEmpty());
QVERIFY(method1.access() == QMetaMethod::Public);
@@ -242,6 +244,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Method);
QCOMPARE(method2.returnType(), QByteArray("int"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(method2.parameterNames().isEmpty());
QVERIFY(method2.tag().isEmpty());
QVERIFY(method2.access() == QMetaMethod::Public);
@@ -267,6 +270,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(method1.methodType() == QMetaMethod::Method);
QCOMPARE(method1.returnType(), QByteArray("int"));
+ QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
QCOMPARE(method1.tag(), QByteArray("tag"));
QVERIFY(method1.access() == QMetaMethod::Private);
@@ -276,6 +280,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Method);
QCOMPARE(method2.returnType(), QByteArray("int"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(method2.parameterNames().isEmpty());
QVERIFY(method2.tag().isEmpty());
QVERIFY(method2.access() == QMetaMethod::Public);
@@ -296,6 +301,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(method1.methodType() == QMetaMethod::Method);
QCOMPARE(method1.returnType(), QByteArray("int"));
+ QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
QCOMPARE(method1.tag(), QByteArray("tag"));
QVERIFY(method1.access() == QMetaMethod::Private);
@@ -305,6 +311,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Method);
QCOMPARE(method2.returnType(), QByteArray("QString"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
QVERIFY(method2.access() == QMetaMethod::Protected);
@@ -320,6 +327,7 @@ void tst_QMetaObjectBuilder::method()
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Method);
QCOMPARE(method2.returnType(), QByteArray("QString"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
QVERIFY(method2.access() == QMetaMethod::Protected);
@@ -346,7 +354,8 @@ void tst_QMetaObjectBuilder::slot()
QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)");
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(method1.methodType() == QMetaMethod::Slot);
- QVERIFY(method1.returnType().isEmpty());
+ QCOMPARE(method1.returnType(), QByteArray("void"));
+ QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QVERIFY(method1.parameterNames().isEmpty());
QVERIFY(method1.tag().isEmpty());
QVERIFY(method1.access() == QMetaMethod::Public);
@@ -358,7 +367,8 @@ void tst_QMetaObjectBuilder::slot()
QMetaMethodBuilder method2 = builder.addSlot("bar(QString)");
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Slot);
- QVERIFY(method2.returnType().isEmpty());
+ QCOMPARE(method2.returnType(), QByteArray("void"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(method2.parameterNames().isEmpty());
QVERIFY(method2.tag().isEmpty());
QVERIFY(method2.access() == QMetaMethod::Public);
@@ -383,7 +393,8 @@ void tst_QMetaObjectBuilder::signal()
QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(method1.methodType() == QMetaMethod::Signal);
- QVERIFY(method1.returnType().isEmpty());
+ QCOMPARE(method1.returnType(), QByteArray("void"));
+ QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QVERIFY(method1.parameterNames().isEmpty());
QVERIFY(method1.tag().isEmpty());
QVERIFY(method1.access() == QMetaMethod::Protected);
@@ -395,7 +406,8 @@ void tst_QMetaObjectBuilder::signal()
QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
QVERIFY(method2.methodType() == QMetaMethod::Signal);
- QVERIFY(method2.returnType().isEmpty());
+ QCOMPARE(method2.returnType(), QByteArray("void"));
+ QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(method2.parameterNames().isEmpty());
QVERIFY(method2.tag().isEmpty());
QVERIFY(method2.access() == QMetaMethod::Protected);
@@ -421,6 +433,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
QVERIFY(ctor1.returnType().isEmpty());
+ QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QVERIFY(ctor1.parameterNames().isEmpty());
QVERIFY(ctor1.tag().isEmpty());
QVERIFY(ctor1.access() == QMetaMethod::Public);
@@ -433,6 +446,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
QVERIFY(ctor2.returnType().isEmpty());
+ QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(ctor2.parameterNames().isEmpty());
QVERIFY(ctor2.tag().isEmpty());
QVERIFY(ctor2.access() == QMetaMethod::Public);
@@ -458,6 +472,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
QCOMPARE(ctor1.returnType(), QByteArray("int"));
+ QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
QCOMPARE(ctor1.tag(), QByteArray("tag"));
QVERIFY(ctor1.access() == QMetaMethod::Private);
@@ -466,6 +481,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
QVERIFY(ctor2.returnType().isEmpty());
+ QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
QVERIFY(ctor2.parameterNames().isEmpty());
QVERIFY(ctor2.tag().isEmpty());
QVERIFY(ctor2.access() == QMetaMethod::Public);
@@ -484,6 +500,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
QCOMPARE(ctor1.returnType(), QByteArray("int"));
+ QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
QCOMPARE(ctor1.tag(), QByteArray("tag"));
QVERIFY(ctor1.access() == QMetaMethod::Private);
@@ -492,6 +509,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
+ QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
QVERIFY(ctor2.access() == QMetaMethod::Protected);
@@ -506,6 +524,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
+ QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
QVERIFY(ctor2.access() == QMetaMethod::Protected);
@@ -525,6 +544,7 @@ void tst_QMetaObjectBuilder::constructor()
QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
QCOMPARE(prototypeConstructor.returnType(), QByteArray());
+ QVERIFY(prototypeConstructor.parameterTypes().isEmpty());
QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
QCOMPARE(prototypeConstructor.index(), 1);
@@ -1161,12 +1181,15 @@ bool tst_QMetaObjectBuilder::checkForSideEffects
static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
{
- if (QByteArray(method1.signature()) != QByteArray(method2.signature()))
+ if (method1.methodSignature() != method2.methodSignature())
return false;
if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
return false;
+ if (method1.parameterTypes() != method2.parameterTypes())
+ return false;
+
if (method1.parameterNames() != method2.parameterNames())
return false;
@@ -1466,7 +1489,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
default: {
QMetaMethod ctor = _o->metaObject()->constructor(_id);
- qFatal("You forgot to add a case for CreateInstance %s", ctor.signature());
+ qFatal("You forgot to add a case for CreateInstance %s", ctor.methodSignature().constData());
}
}
} else if (_c == QMetaObject::InvokeMetaMethod) {
@@ -1478,7 +1501,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_a[2])); break;
default: {
QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id);
- qFatal("You forgot to add a case for InvokeMetaMethod %s", method.signature());
+ qFatal("You forgot to add a case for InvokeMetaMethod %s", method.methodSignature().constData());
}
}
} else if (_c == QMetaObject::IndexOfMethod) {
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index d93e00eed8..9f4944b44b 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -97,16 +97,36 @@ private slots:
void isEnum();
void registerStreamBuiltin();
void automaticTemplateRegistration();
+ void saveAndLoadBuiltin_data();
+ void saveAndLoadBuiltin();
+ void saveAndLoadCustom();
};
struct Foo { int i; };
+
+class CustomQObject : public QObject
+{
+ Q_OBJECT
+public:
+ CustomQObject(QObject *parent = 0)
+ : QObject(parent)
+ {
+ }
+};
+
+class CustomNonQObject {};
+
void tst_QMetaType::defined()
{
QCOMPARE(int(QMetaTypeId2<QString>::Defined), 1);
QCOMPARE(int(QMetaTypeId2<Foo>::Defined), 0);
QCOMPARE(int(QMetaTypeId2<void*>::Defined), 1);
QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0);
+ QVERIFY(QMetaTypeId2<CustomQObject*>::Defined);
+ QVERIFY(!QMetaTypeId2<CustomQObject>::Defined);
+ QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined);
+ QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined);
}
struct Bar
@@ -312,6 +332,7 @@ void tst_QMetaType::typeName_data()
QTest::addColumn<QString>("aTypeName");
QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA)
+ QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast<const char*>(0);
QTest::newRow("Whity<double>") << static_cast<QMetaType::Type>(::qMetaTypeId<Whity<double> >()) << QString::fromLatin1("Whity<double>");
QTest::newRow("Whity<int>") << static_cast<QMetaType::Type>(::qMetaTypeId<Whity<int> >()) << QString::fromLatin1("Whity<int>");
@@ -510,6 +531,46 @@ template<> struct TestValueFactory<QMetaType::QRegExp> {
#endif
}
};
+template<> struct TestValueFactory<QMetaType::QRegularExpression> {
+ static QRegularExpression *create()
+ {
+#ifndef QT_NO_REGEXP
+ return new QRegularExpression("abc.*def");
+#else
+ return 0;
+#endif
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonValue> {
+ static QJsonValue *create() { return new QJsonValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QJsonObject> {
+ static QJsonObject *create() {
+ QJsonObject *o = new QJsonObject();
+ o->insert("a", 123.);
+ o->insert("b", true);
+ o->insert("c", QJsonValue::Null);
+ o->insert("d", QLatin1String("ciao"));
+ return o;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonArray> {
+ static QJsonArray *create() {
+ QJsonArray *a = new QJsonArray();
+ a->append(123.);
+ a->append(true);
+ a->append(QJsonValue::Null);
+ a->append(QLatin1String("ciao"));
+ return a;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonDocument> {
+ static QJsonDocument *create() {
+ return new QJsonDocument(
+ QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
+ );
+ }
+};
template<> struct TestValueFactory<QMetaType::QVariant> {
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
};
@@ -630,6 +691,8 @@ void tst_QMetaType::sizeOf_data()
{
QTest::addColumn<QMetaType::Type>("type");
QTest::addColumn<size_t>("size");
+
+ QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << size_t(0);
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
QTest::newRow(#RealType) << QMetaType::MetaTypeName << size_t(QTypeInfo<RealType>::sizeOf);
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
@@ -805,41 +868,15 @@ void tst_QMetaType::construct_data()
create_data();
}
-#ifndef Q_ALIGNOF
-template<uint N>
-struct RoundToNextHighestPowerOfTwo
-{
-private:
- enum { V1 = N-1 };
- enum { V2 = V1 | (V1 >> 1) };
- enum { V3 = V2 | (V2 >> 2) };
- enum { V4 = V3 | (V3 >> 4) };
- enum { V5 = V4 | (V4 >> 8) };
- enum { V6 = V5 | (V5 >> 16) };
-public:
- enum { Value = V6 + 1 };
-};
-#endif
-
-template<class T>
-struct TypeAlignment
-{
-#ifdef Q_ALIGNOF
- enum { Value = Q_ALIGNOF(T) };
-#else
- enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value };
-#endif
-};
-
template<int ID>
static void testConstructHelper()
{
typedef typename MetaEnumToType<ID>::Type Type;
QMetaType info(ID);
int size = info.sizeOf();
- void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
+ void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type));
void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
- void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
+ void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type));
void *actual2 = info.construct(storage2, /*copy=*/0);
QCOMPARE(actual1, storage1);
QCOMPARE(actual2, storage2);
@@ -908,9 +945,9 @@ static void testConstructCopyHelper()
QMetaType info(ID);
int size = QMetaType::sizeOf(ID);
QCOMPARE(info.sizeOf(), size);
- void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
+ void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type));
void *actual1 = QMetaType::construct(ID, storage1, expected);
- void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
+ void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type));
void *actual2 = info.construct(storage2, expected);
QCOMPARE(actual1, storage1);
QCOMPARE(actual2, storage2);
@@ -1052,6 +1089,7 @@ void tst_QMetaType::isRegistered_data()
QTest::newRow("-1") << -1 << false;
QTest::newRow("-42") << -42 << false;
QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
+ QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false;
}
void tst_QMetaType::isRegistered()
@@ -1291,6 +1329,133 @@ void tst_QMetaType::automaticTemplateRegistration()
}
}
+template <typename T>
+struct StreamingTraits
+{
+ enum { isStreamable = 1 }; // Streamable by default
+};
+
+// Non-streamable types
+
+#define DECLARE_NONSTREAMABLE(Type) \
+ template<> struct StreamingTraits<Type> { enum { isStreamable = 0 }; };
+
+DECLARE_NONSTREAMABLE(void)
+DECLARE_NONSTREAMABLE(void*)
+DECLARE_NONSTREAMABLE(QModelIndex)
+DECLARE_NONSTREAMABLE(QJsonValue)
+DECLARE_NONSTREAMABLE(QJsonObject)
+DECLARE_NONSTREAMABLE(QJsonArray)
+DECLARE_NONSTREAMABLE(QJsonDocument)
+DECLARE_NONSTREAMABLE(QObject*)
+DECLARE_NONSTREAMABLE(QWidget*)
+
+#define DECLARE_GUI_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
+ DECLARE_NONSTREAMABLE(RealType)
+QT_FOR_EACH_STATIC_GUI_CLASS(DECLARE_GUI_CLASS_NONSTREAMABLE)
+#undef DECLARE_GUI_CLASS_NONSTREAMABLE
+
+#define DECLARE_WIDGETS_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
+ DECLARE_NONSTREAMABLE(RealType)
+QT_FOR_EACH_STATIC_WIDGETS_CLASS(DECLARE_WIDGETS_CLASS_NONSTREAMABLE)
+#undef DECLARE_WIDGETS_CLASS_NONSTREAMABLE
+
+#undef DECLARE_NONSTREAMABLE
+
+void tst_QMetaType::saveAndLoadBuiltin_data()
+{
+ QTest::addColumn<int>("type");
+ QTest::addColumn<bool>("isStreamable");
+
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::isStreamable);
+ QT_FOR_EACH_STATIC_TYPE(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+}
+
+void tst_QMetaType::saveAndLoadBuiltin()
+{
+ QFETCH(int, type);
+ QFETCH(bool, isStreamable);
+
+ void *value = QMetaType::create(type);
+
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::ReadWrite);
+ QCOMPARE(QMetaType::save(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable) {
+ QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+ }
+
+ stream.device()->seek(0);
+ stream.resetStatus();
+ QCOMPARE(QMetaType::load(stream, type, value), isStreamable);
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ if (isStreamable) {
+ QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+ }
+
+ QMetaType::destroy(type, value);
+}
+
+struct CustomStreamableType
+{
+ int a;
+};
+Q_DECLARE_METATYPE(CustomStreamableType)
+
+QDataStream &operator<<(QDataStream &out, const CustomStreamableType &t)
+{
+ out << t.a; return out;
+}
+
+QDataStream &operator>>(QDataStream &in, CustomStreamableType &t)
+{
+ int a;
+ in >> a;
+ if (in.status() == QDataStream::Ok)
+ t.a = a;
+ return in;
+}
+
+void tst_QMetaType::saveAndLoadCustom()
+{
+ CustomStreamableType t;
+ t.a = 123;
+
+ int id = ::qMetaTypeId<CustomStreamableType>();
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::ReadWrite);
+ QVERIFY(!QMetaType::save(stream, id, &t));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+ QVERIFY(!QMetaType::load(stream, id, &t));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ qRegisterMetaTypeStreamOperators<CustomStreamableType>("CustomStreamableType");
+ QVERIFY(QMetaType::save(stream, id, &t));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ CustomStreamableType t2;
+ t2.a = -1;
+ QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+ QCOMPARE(t2.a, -1);
+
+ stream.device()->seek(0);
+ stream.resetStatus();
+ QVERIFY(QMetaType::load(stream, id, &t2));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+ QCOMPARE(t2.a, t.a);
+
+ QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+}
+
// Compile-time test, it should be possible to register function pointer types
class Undefined;
diff --git a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp b/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp
deleted file mode 100644
index 2d180b88ea..0000000000
--- a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** 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$
-**
-****************************************************************************/
-
-/****************************************************************************
-** Meta object code from reading C++ file 'oldnormalizeobject.h'
-**
-** Created: Wed Nov 18 11:43:05 2009
-** by: The Qt Meta Object Compiler version 62 (Qt 4.6.0)
-**
-*****************************************************************************/
-
-// Yhis file was generated from moc version 4.6 to test binary compatibility
-// It should *not* be generated by the current moc
-
-#include "oldnormalizeobject.h"
-
-QT_BEGIN_MOC_NAMESPACE
-static const uint qt_meta_data_OldNormalizeObject[] = {
-
- // content:
- 4, // revision
- 0, // classname
- 0, 0, // classinfo
- 6, 14, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 3, // signalCount
-
- // signals: signature, parameters, type, tag, flags
- 24, 20, 19, 19, 0x05,
- 57, 20, 19, 19, 0x05,
- 100, 20, 19, 19, 0x05,
-
- // slots: signature, parameters, type, tag, flags
- 149, 20, 19, 19, 0x0a,
- 180, 20, 19, 19, 0x0a,
- 221, 20, 19, 19, 0x0a,
-
- 0 // eod
-};
-
-static const char qt_meta_stringdata_OldNormalizeObject[] = {
- "OldNormalizeObject\0\0ref\0"
- "typeRefSignal(Template<Class&>&)\0"
- "constTypeRefSignal(Template<const Class&>)\0"
- "typeConstRefSignal(Template<const Class&>const&)\0"
- "typeRefSlot(Template<Class&>&)\0"
- "constTypeRefSlot(Template<const Class&>)\0"
- "typeConstRefSlot(Template<const Class&>const&)\0"
-};
-
-const QMetaObject OldNormalizeObject::staticMetaObject = {
- { &QObject::staticMetaObject, qt_meta_stringdata_OldNormalizeObject,
- qt_meta_data_OldNormalizeObject, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &OldNormalizeObject::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *OldNormalizeObject::metaObject() const
-{
- return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *OldNormalizeObject::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_OldNormalizeObject))
- return static_cast<void*>(const_cast< OldNormalizeObject*>(this));
- return QObject::qt_metacast(_clname);
-}
-
-int OldNormalizeObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- switch (_id) {
- case 0: typeRefSignal((*reinterpret_cast< Template<Class&>(*)>(_a[1]))); break;
- case 1: constTypeRefSignal((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break;
- case 2: typeConstRefSignal((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break;
- case 3: typeRefSlot((*reinterpret_cast< Template<Class&>(*)>(_a[1]))); break;
- case 4: constTypeRefSlot((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break;
- case 5: typeConstRefSlot((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break;
- default: ;
- }
- _id -= 6;
- }
- return _id;
-}
-
-// SIGNAL 0
-void OldNormalizeObject::typeRefSignal(Template<Class&> & _t1)
-{
- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
- QMetaObject::activate(this, &staticMetaObject, 0, _a);
-}
-
-// SIGNAL 1
-void OldNormalizeObject::constTypeRefSignal(const Template<const Class&> & _t1)
-{
- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
- QMetaObject::activate(this, &staticMetaObject, 1, _a);
-}
-
-// SIGNAL 2
-void OldNormalizeObject::typeConstRefSignal(Template<Class const&> const & _t1)
-{
- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
- QMetaObject::activate(this, &staticMetaObject, 2, _a);
-}
-QT_END_MOC_NAMESPACE
diff --git a/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h b/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h
deleted file mode 100644
index f73027707a..0000000000
--- a/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtTest 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 OLDNORMALIZEOBJECT_H
-#define OLDNORMALIZEOBJECT_H
-
-#include <QObject>
-
-struct Struct;
-class Class;
-template <typename T> class Template;
-
-// An object with old moc output that incorrectly normalizes 'T<C> const &' in the function
-// signatures
-class OldNormalizeObject : public QObject
-{
- /* tmake ignore Q_OBJECT */
- Q_OBJECT
-
-signals:
- void typeRefSignal(Template<Class &> &ref);
- void constTypeRefSignal(const Template<const Class &> &ref);
- void typeConstRefSignal(Template<Class const &> const &ref);
-
-public slots:
- void typeRefSlot(Template<Class &> &) {}
- void constTypeRefSlot(const Template<const Class &> &) {}
- void typeConstRefSlot(Template<Class const &> const &) {}
-};
-
-#endif // OLDNORMALIZEOBJECT_H
diff --git a/tests/auto/corelib/kernel/qobject/test/test.pro b/tests/auto/corelib/kernel/qobject/test/test.pro
index c08f910f8f..824223db15 100644
--- a/tests/auto/corelib/kernel/qobject/test/test.pro
+++ b/tests/auto/corelib/kernel/qobject/test/test.pro
@@ -3,9 +3,5 @@ TARGET = ../tst_qobject
QT = core-private network testlib
SOURCES = ../tst_qobject.cpp
-# this is here for a reason, moc_oldnormalizedobject.cpp is not auto-generated, it was generated by
-# moc from Qt 4.6, and should *not* be generated by the current moc
-SOURCES += ../moc_oldnormalizeobject.cpp
-
load(testcase) # for target.path and installTestHelperApp()
installTestHelperApp("../signalbug/signalbug",signalbug,signalbug)
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index a6ad1d53bc..90d20843e3 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -45,6 +45,7 @@
#include <qpointer.h>
#include <qtimer.h>
#include <qregexp.h>
+#include <qregularexpression.h>
#include <qmetaobject.h>
#include <qvariant.h>
#include <QTcpServer>
@@ -164,6 +165,7 @@ signals:
void signal3();
void signal4();
QT_MOC_COMPAT void signal5();
+ void signal6(void);
public slots:
void aPublicSlot() { aPublicSlotCalled++; }
@@ -656,6 +658,26 @@ void tst_QObject::findChildren()
l = qFindChildren<QObject*>(&o, QRegExp("harry"));
QCOMPARE(l.size(), 0);
+ l = o.findChildren<QObject*>(QRegularExpression("o.*"));
+ QCOMPARE(l.size(), 5);
+ QVERIFY(l.contains(&o1));
+ QVERIFY(l.contains(&o2));
+ QVERIFY(l.contains(&o11));
+ QVERIFY(l.contains(&o12));
+ QVERIFY(l.contains(&o111));
+ l = o.findChildren<QObject*>(QRegularExpression("t.*"));
+ QCOMPARE(l.size(), 2);
+ QVERIFY(l.contains(&t1));
+ QVERIFY(l.contains(&t121));
+ tl = o.findChildren<QTimer*>(QRegularExpression(".*"));
+ QCOMPARE(tl.size(), 3);
+ QVERIFY(tl.contains(&t1));
+ QVERIFY(tl.contains(&t121));
+ tl = o.findChildren<QTimer*>(QRegularExpression("o.*"));
+ QCOMPARE(tl.size(), 0);
+ l = o.findChildren<QObject*>(QRegularExpression("harry"));
+ QCOMPARE(l.size(), 0);
+
// empty and null string check
op = qFindChild<QObject*>(&o);
QCOMPARE(op, &o1);
@@ -803,6 +825,8 @@ void tst_QObject::connectDisconnectNotify_data()
QTest::newRow("combo2") << SIGNAL( signal2(void) ) << SLOT( slot2( ) );
QTest::newRow("combo3") << SIGNAL( signal3( ) ) << SLOT( slot3(void) );
QTest::newRow("combo4") << SIGNAL( signal4( void ) )<< SLOT( slot4( void ) );
+ QTest::newRow("combo5") << SIGNAL( signal6( void ) ) << SLOT( slot4() );
+ QTest::newRow("combo6") << SIGNAL( signal6() ) << SLOT( slot4() );
}
void tst_QObject::connectDisconnectNotify()
@@ -1793,56 +1817,56 @@ void tst_QObject::metamethod()
QMetaMethod m;
m = mobj->method(mobj->indexOfMethod("invoke1()"));
- QVERIFY(QByteArray(m.signature()) == "invoke1()");
+ QVERIFY(m.methodSignature() == "invoke1()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Public);
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("sinvoke1()"));
- QVERIFY(QByteArray(m.signature()) == "sinvoke1()");
+ QVERIFY(m.methodSignature() == "sinvoke1()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Public);
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("invoke2()"));
- QVERIFY(QByteArray(m.signature()) == "invoke2()");
+ QVERIFY(m.methodSignature() == "invoke2()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Protected);
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("sinvoke2()"));
- QVERIFY(QByteArray(m.signature()) == "sinvoke2()");
+ QVERIFY(m.methodSignature() == "sinvoke2()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Protected);
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("invoke3()"));
- QVERIFY(QByteArray(m.signature()) == "invoke3()");
+ QVERIFY(m.methodSignature() == "invoke3()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Private);
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("sinvoke3()"));
- QVERIFY(QByteArray(m.signature()) == "sinvoke3()");
+ QVERIFY(m.methodSignature() == "sinvoke3()");
QVERIFY(m.methodType() == QMetaMethod::Method);
QVERIFY(m.access() == QMetaMethod::Private);
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("signal5()"));
- QVERIFY(QByteArray(m.signature()) == "signal5()");
+ QVERIFY(m.methodSignature() == "signal5()");
QVERIFY(m.methodType() == QMetaMethod::Signal);
QVERIFY(m.access() == QMetaMethod::Protected);
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("aPublicSlot()"));
- QVERIFY(QByteArray(m.signature()) == "aPublicSlot()");
+ QVERIFY(m.methodSignature() == "aPublicSlot()");
QVERIFY(m.methodType() == QMetaMethod::Slot);
QVERIFY(m.access() == QMetaMethod::Public);
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
@@ -2291,8 +2315,6 @@ public slots:
void constTemplateSlot3(const Template< const int >) {}
};
-#include "oldnormalizeobject.h"
-
void tst_QObject::normalize()
{
NormalizeObject object;
@@ -2603,82 +2625,6 @@ void tst_QObject::normalize()
SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
SLOT(typeConstRefSlot(Template<Class const &> const &))));
- // same test again, this time with an object compiled with old moc output... we know that
- // it is not possible to connect everything, whic is the purpose for this test
- OldNormalizeObject oldobject;
-
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(const Template<const Class &> &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(const Template<Class const &> &))));
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
-
- // these fail in older Qt versions, but pass now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(const Template<const Class &> &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(const Template<Class const &> &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
-
- // these also fail in older Qt versions, but pass now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(const Template<const Class &> &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(const Template<Class const &> &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
- SLOT(constTypeRefSlot(Template<Class const &> const &))));
-
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(const Template<const Class &> &))));
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(const Template<Class const &> &))));
- // this fails in older versions, but passes now due to proper normalizing
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
- QVERIFY(oldobject.connect(&oldobject,
- SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
- SLOT(typeConstRefSlot(Template<Class const &> const &))));
-
QVERIFY(object.connect(&object,
SIGNAL(typePointerConstRefSignal(Class*const&)),
SLOT(typePointerConstRefSlot(Class*const&))));
diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin
new file mode 100644
index 0000000000..eaa50f7310
--- /dev/null
+++ b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin
Binary files differ
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 655c714322..1e382dde3a 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -58,6 +58,7 @@
#include <qmatrix4x4.h>
#include <qpen.h>
#include <qpolygon.h>
+#include <qpalette.h>
#include <qtransform.h>
#include <qvector2d.h>
#include <qvector3d.h>
@@ -192,6 +193,7 @@ private slots:
void toLocale();
void toRegExp();
+ void toRegularExpression();
void matrix();
@@ -274,6 +276,8 @@ private slots:
void forwardDeclare();
void debugStream_data();
void debugStream();
+ void debugStreamType_data();
+ void debugStreamType();
void loadQt4Stream_data();
void loadQt4Stream();
@@ -283,6 +287,9 @@ private slots:
void loadQt5Stream();
void saveQt5Stream_data();
void saveQt5Stream();
+
+ void guiVariantAtExit();
+ void widgetsVariantAtExit();
private:
void dataStream_data(QDataStream::Version version);
void loadQVariantFromDataStream(QDataStream::Version version);
@@ -1319,6 +1326,21 @@ void tst_QVariant::toRegExp()
rx = variant.toRegExp();
}
+void tst_QVariant::toRegularExpression()
+{
+ QVariant variant;
+ QRegularExpression re = variant.toRegularExpression();
+ QCOMPARE(re, QRegularExpression());
+
+ variant = QRegularExpression("abc.*def");
+ re = variant.toRegularExpression();
+ QCOMPARE(re, QRegularExpression("abc.*def"));
+
+ variant = QVariant::fromValue(QRegularExpression("[ab]\\w+"));
+ re = variant.value<QRegularExpression>();
+ QCOMPARE(re, QRegularExpression("[ab]\\w+"));
+}
+
void tst_QVariant::matrix()
{
QVariant variant;
@@ -1519,6 +1541,8 @@ void tst_QVariant::writeToReadFromDataStream_data()
QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << true;
QTest::newRow( "regexp" ) << QVariant(QRegExp("foo", Qt::CaseInsensitive)) << false;
QTest::newRow( "regexp_empty" ) << QVariant(QRegExp()) << false;
+ QTest::newRow( "regularexpression" ) << QVariant(QRegularExpression("abc.*def")) << false;
+ QTest::newRow( "regularexpression_empty" ) << QVariant(QRegularExpression()) << false;
// types known to QMetaType, but not part of QVariant::Type
QTest::newRow("QMetaType::Long invalid") << QVariant(QMetaType::Long, (void *) 0) << false;
@@ -1625,8 +1649,8 @@ void tst_QVariant::writeToReadFromOldDataStream()
void tst_QVariant::checkDataStream()
{
- QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 46");
- const QByteArray settingsHex("0000002effffffffff");
+ QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 49");
+ const QByteArray settingsHex("00000031ffffffffff");
const QByteArray settings = QByteArray::fromHex(settingsHex);
QDataStream in(settings);
QVariant v;
@@ -1944,6 +1968,7 @@ void tst_QVariant::typeName_data()
QTest::newRow("48") << int(QVariant::Vector3D) << QByteArray("QVector3D");
QTest::newRow("49") << int(QVariant::Vector4D) << QByteArray("QVector4D");
QTest::newRow("50") << int(QVariant::Quaternion) << QByteArray("QQuaternion");
+ QTest::newRow("51") << int(QVariant::RegularExpression) << QByteArray("QRegularExpression");
}
void tst_QVariant::typeName()
@@ -2547,9 +2572,24 @@ public:
};
Q_DECLARE_METATYPE(CustomQObjectDerived*)
+class CustomQObjectDerivedNoMetaType : public CustomQObject {
+ Q_OBJECT
+public:
+ CustomQObjectDerivedNoMetaType(QObject *parent = 0) : CustomQObject(parent) {}
+};
+
void tst_QVariant::qvariant_cast_QObject_derived()
{
{
+ CustomQObjectDerivedNoMetaType *object = new CustomQObjectDerivedNoMetaType(this);
+ QVariant data = QVariant::fromValue(object);
+ QVERIFY(data.userType() == qMetaTypeId<CustomQObjectDerivedNoMetaType*>());
+ QCOMPARE(data.value<QObject *>(), object);
+ QCOMPARE(data.value<CustomQObjectDerivedNoMetaType *>(), object);
+ QCOMPARE(data.value<CustomQObject *>(), object);
+ QVERIFY(data.value<CustomQWidget*>() == 0);
+ }
+ {
CustomQObjectDerived *object = new CustomQObjectDerived(this);
QVariant data = QVariant::fromValue(object);
@@ -2787,7 +2827,7 @@ Q_DECLARE_METATYPE( MyClass )
void tst_QVariant::loadUnknownUserType()
{
qRegisterMetaType<MyClass>("MyClass");
- char data[] = {0, 0, 1, 0, 0, 0, 0, 0, 8, 77, 121, 67, 108, 97, 115, 115, 0};
+ char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0};
QByteArray ba(data, sizeof(data));
QDataStream ds(&ba, QIODevice::ReadOnly);
@@ -3548,6 +3588,10 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version)
stream >> typeName >> loadedVariant;
const int id = QMetaType::type(typeName.toLatin1());
+ if (id == QMetaType::Void) {
+ // Void type is not supported by QVariant
+ return;
+ }
QVariant constructedVariant(static_cast<QVariant::Type>(id));
QCOMPARE(constructedVariant.userType(), id);
@@ -3567,6 +3611,10 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
dataFileStream >> typeName;
QByteArray data = file.readAll();
const int id = QMetaType::type(typeName.toLatin1());
+ if (id == QMetaType::Void) {
+ // Void type is not supported by QVariant
+ return;
+ }
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
@@ -3588,8 +3636,8 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
class MessageHandler {
public:
- MessageHandler(const int typeId)
- : oldMsgHandler(qInstallMsgHandler(handler))
+ MessageHandler(const int typeId, QtMsgHandler msgHandler = handler)
+ : oldMsgHandler(qInstallMsgHandler(msgHandler))
{
currentId = typeId;
}
@@ -3603,13 +3651,24 @@ public:
{
return ok;
}
-private:
+protected:
static void handler(QtMsgType, const char *txt)
{
QString msg = QString::fromLatin1(txt);
// Format itself is not important, but basic data as a type name should be included in the output
- ok = msg.startsWith("QVariant(") + QMetaType::typeName(currentId);
- QVERIFY2(ok, (QString::fromLatin1("Message is not valid: '") + msg + '\'').toLatin1().constData());
+ ok = msg.startsWith("QVariant(");
+ QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData());
+ ok &= (currentId == QMetaType::UnknownType
+ ? msg.contains("Invalid")
+ : msg.contains(QMetaType::typeName(currentId)));
+ QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData());
+ if (currentId == QMetaType::Char || currentId == QMetaType::QChar) {
+ // Chars insert '\0' into the qdebug stream, it is not possible to find a real string length
+ return;
+ }
+ ok &= msg.endsWith(") ");
+ QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData());
+
}
QtMsgHandler oldMsgHandler;
@@ -3627,11 +3686,14 @@ void tst_QVariant::debugStream_data()
const char *tagName = QMetaType::typeName(id);
if (!tagName)
continue;
- QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
+ if (id != QMetaType::Void) {
+ QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
+ }
}
QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
QTest::newRow("MyClass") << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>();
+ QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType);
}
void tst_QVariant::debugStream()
@@ -3644,5 +3706,62 @@ void tst_QVariant::debugStream()
QVERIFY(msgHandler.testPassed());
}
+struct MessageHandlerType : public MessageHandler
+{
+ MessageHandlerType(const int typeId)
+ : MessageHandler(typeId, handler)
+ {}
+ static void handler(QtMsgType, const char *txt)
+ {
+ QString msg = QString::fromLatin1(txt);
+ // Format itself is not important, but basic data as a type name should be included in the output
+ ok = msg.startsWith("QVariant::");
+ QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData());
+ ok &= (currentId == QMetaType::UnknownType
+ ? msg.contains("Invalid")
+ : msg.contains(QMetaType::typeName(currentId)));
+ QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData());
+ }
+};
+
+void tst_QVariant::debugStreamType_data()
+{
+ debugStream_data();
+}
+
+void tst_QVariant::debugStreamType()
+{
+ QFETCH(QVariant, variant);
+ QFETCH(int, typeId);
+
+ MessageHandlerType msgHandler(typeId);
+ qDebug() << QVariant::Type(typeId);
+ QVERIFY(msgHandler.testPassed());
+}
+
+void tst_QVariant::guiVariantAtExit()
+{
+ // crash test, it should not crash at QGuiApplication exit
+ static QVariant cursor = QCursor();
+ static QVariant point = QPoint();
+ static QVariant image = QImage();
+ static QVariant pallete = QPalette();
+ Q_UNUSED(cursor);
+ Q_UNUSED(point);
+ Q_UNUSED(image);
+ Q_UNUSED(pallete);
+ QVERIFY(true);
+}
+
+void tst_QVariant::widgetsVariantAtExit()
+{
+ // crash test, it should not crash at QGuiApplication exit
+ static QVariant icon= QIcon();
+ static QVariant sizePolicy = QSizePolicy();
+ Q_UNUSED(icon);
+ Q_UNUSED(sizePolicy);
+ QVERIFY(true);
+}
+
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"
diff --git a/tests/auto/corelib/tools/qarraydata/qarraydata.pro b/tests/auto/corelib/tools/qarraydata/qarraydata.pro
new file mode 100644
index 0000000000..8e368117fa
--- /dev/null
+++ b/tests/auto/corelib/tools/qarraydata/qarraydata.pro
@@ -0,0 +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
index 0000000000..fe8108bff2
--- /dev/null
+++ b/tests/auto/corelib/tools/qarraydata/simplevector.h
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** 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 <QtCore/qarraydatapointer.h>
+
+#include <algorithm>
+
+template <class T>
+struct SimpleVector
+{
+private:
+ typedef QTypedArrayData<T> Data;
+
+public:
+ typedef T value_type;
+ typedef typename Data::iterator iterator;
+ typedef typename Data::const_iterator const_iterator;
+
+ SimpleVector()
+ {
+ }
+
+ SimpleVector(size_t n, const T &t)
+ : d(Data::allocate(n))
+ {
+ if (n)
+ d->copyAppend(n, t);
+ }
+
+ SimpleVector(const T *begin, const T *end)
+ : d(Data::allocate(end - begin))
+ {
+ if (end - begin)
+ d->copyAppend(begin, end);
+ }
+
+ SimpleVector(QArrayDataPointerRef<T> ptr)
+ : d(ptr)
+ {
+ }
+
+ explicit SimpleVector(Data *ptr)
+ : d(ptr)
+ {
+ }
+
+ bool empty() const { return d->size == 0; }
+ bool isNull() const { return d.isNull(); }
+ bool isEmpty() const { return this->empty(); }
+
+ bool isStatic() const { return d->ref.isStatic(); }
+ bool isShared() const { return d->ref.isShared(); }
+ bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
+ bool isSharable() const { return d->ref.isSharable(); }
+
+ void setSharable(bool sharable) { d.setSharable(sharable); }
+
+ size_t size() const { return d->size; }
+ size_t capacity() const { return d->alloc; }
+
+ iterator begin() { detach(); return d->begin(); }
+ iterator end() { detach(); return d->end(); }
+
+ const_iterator begin() const { return d->begin(); }
+ const_iterator end() const { return d->end(); }
+
+ const_iterator constBegin() const { return begin(); }
+ const_iterator constEnd() const { return end(); }
+
+ T &operator[](size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
+ T &at(size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
+
+ 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]; }
+
+ T &front()
+ {
+ Q_ASSERT(!isEmpty());
+ detach();
+ return *begin();
+ }
+
+ T &back()
+ {
+ Q_ASSERT(!isEmpty());
+ detach();
+ return *(end() - 1);
+ }
+
+ const T &front() const
+ {
+ Q_ASSERT(!isEmpty());
+ return *begin();
+ }
+
+ const T &back() const
+ {
+ Q_ASSERT(!isEmpty());
+ return *(end() - 1);
+ }
+
+ void reserve(size_t n)
+ {
+ if (n == 0)
+ return;
+
+ if (n <= capacity()) {
+ if (d->capacityReserved)
+ return;
+ if (!d->ref.isShared()) {
+ d->capacityReserved = 1;
+ return;
+ }
+ }
+
+ SimpleVector detached(Data::allocate(qMax(n, size()),
+ d->detachFlags() | Data::CapacityReserved));
+ if (size())
+ detached.d->copyAppend(constBegin(), constEnd());
+ detached.swap(*this);
+ }
+
+ void prepend(const_iterator first, const_iterator last)
+ {
+ if (!d->size) {
+ append(first, last);
+ return;
+ }
+
+ if (first == last)
+ return;
+
+ T *const begin = d->begin();
+ if (d->ref.isShared()
+ || capacity() - size() < size_t(last - first)) {
+ SimpleVector detached(Data::allocate(
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags() | Data::Grow));
+
+ detached.d->copyAppend(first, last);
+ detached.d->copyAppend(begin, begin + d->size);
+ detached.swap(*this);
+
+ return;
+ }
+
+ d->insert(begin, first, last);
+ }
+
+ void append(const_iterator first, const_iterator last)
+ {
+ if (first == last)
+ return;
+
+ if (d->ref.isShared()
+ || capacity() - size() < size_t(last - first)) {
+ SimpleVector detached(Data::allocate(
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags() | Data::Grow));
+
+ if (d->size) {
+ const T *const begin = constBegin();
+ detached.d->copyAppend(begin, begin + d->size);
+ }
+ detached.d->copyAppend(first, last);
+ detached.swap(*this);
+
+ return;
+ }
+
+ d->copyAppend(first, last);
+ }
+
+ void insert(int position, const_iterator first, const_iterator last)
+ {
+ if (position < 0)
+ position += d->size + 1;
+
+ if (position <= 0) {
+ prepend(first, last);
+ return;
+ }
+
+ if (size_t(position) >= size()) {
+ append(first, last);
+ return;
+ }
+
+ if (first == last)
+ return;
+
+ T *const begin = d->begin();
+ T *const where = begin + position;
+ const T *const end = begin + d->size;
+ if (d->ref.isShared()
+ || capacity() - size() < size_t(last - first)) {
+ SimpleVector detached(Data::allocate(
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags() | Data::Grow));
+
+ if (position)
+ detached.d->copyAppend(begin, where);
+ detached.d->copyAppend(first, last);
+ detached.d->copyAppend(where, end);
+ detached.swap(*this);
+
+ return;
+ }
+
+ if ((first >= where && first < end)
+ || (last > where && last <= end)) {
+ // Copy overlapping data first and only then shuffle it into place
+ T *start = d->begin() + position;
+ T *middle = d->end();
+
+ d->copyAppend(first, last);
+ std::rotate(start, middle, d->end());
+
+ return;
+ }
+
+ d->insert(where, first, last);
+ }
+
+ void swap(SimpleVector &other)
+ {
+ qSwap(d, other.d);
+ }
+
+ void clear()
+ {
+ d.clear();
+ }
+
+ void detach()
+ {
+ d.detach();
+ }
+
+ static SimpleVector fromRawData(const T *data, size_t size,
+ QArrayData::AllocationOptions options = Data::Default)
+ {
+ return SimpleVector(Data::fromRawData(data, size, options));
+ }
+
+private:
+ QArrayDataPointer<T> 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
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
new file mode 100644
index 0000000000..9bfbac0017
--- /dev/null
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -0,0 +1,1464 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** 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$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtCore/QString>
+#include <QtCore/qarraydata.h>
+
+#include "simplevector.h"
+
+struct SharedNullVerifier
+{
+ SharedNullVerifier()
+ {
+ Q_ASSERT(QArrayData::shared_null.ref.isStatic());
+ Q_ASSERT(QArrayData::shared_null.ref.isShared());
+ Q_ASSERT(QArrayData::shared_null.ref.isSharable());
+ }
+};
+
+// This is meant to verify/ensure that shared_null is not being dynamically
+// initialized and stays away from the order-of-static-initialization fiasco.
+//
+// Of course, if this was to fail, qmake and the build should have crashed and
+// burned before we ever got to this point :-)
+SharedNullVerifier globalInit;
+
+class tst_QArrayData : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void referenceCounting();
+ void sharedNullEmpty();
+ void staticData();
+ void simpleVector();
+ void simpleVectorReserve_data();
+ void simpleVectorReserve();
+ void allocate_data();
+ void allocate();
+ void alignment_data();
+ void alignment();
+ void typedData();
+ void gccBug43247();
+ void arrayOps();
+ void setSharable_data();
+ void setSharable();
+ void fromRawData();
+ void literals();
+ void variadicLiterals();
+ void rValueReferences();
+ void grow();
+};
+
+template <class T> const T &const_(const T &t) { return t; }
+
+void tst_QArrayData::referenceCounting()
+{
+ {
+ // Reference counting initialized to 1 (owned)
+ QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 };
+
+ QCOMPARE(array.ref.atomic.load(), 1);
+
+ QVERIFY(!array.ref.isStatic());
+ QVERIFY(array.ref.isSharable());
+
+ QVERIFY(array.ref.ref());
+ QCOMPARE(array.ref.atomic.load(), 2);
+
+ QVERIFY(array.ref.deref());
+ QCOMPARE(array.ref.atomic.load(), 1);
+
+ QVERIFY(array.ref.ref());
+ QCOMPARE(array.ref.atomic.load(), 2);
+
+ QVERIFY(array.ref.deref());
+ QCOMPARE(array.ref.atomic.load(), 1);
+
+ QVERIFY(!array.ref.deref());
+ QCOMPARE(array.ref.atomic.load(), 0);
+
+ // Now would be a good time to free/release allocated data
+ }
+
+ {
+ // Reference counting initialized to 0 (non-sharable)
+ QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
+
+ QCOMPARE(array.ref.atomic.load(), 0);
+
+ QVERIFY(!array.ref.isStatic());
+ QVERIFY(!array.ref.isSharable());
+
+ QVERIFY(!array.ref.ref());
+ // Reference counting fails, data should be copied
+ QCOMPARE(array.ref.atomic.load(), 0);
+
+ QVERIFY(!array.ref.deref());
+ QCOMPARE(array.ref.atomic.load(), 0);
+
+ // Free/release data
+ }
+
+ {
+ // Reference counting initialized to -1 (static read-only data)
+ QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
+
+ QCOMPARE(array.ref.atomic.load(), -1);
+
+ QVERIFY(array.ref.isStatic());
+ QVERIFY(array.ref.isSharable());
+
+ QVERIFY(array.ref.ref());
+ QCOMPARE(array.ref.atomic.load(), -1);
+
+ QVERIFY(array.ref.deref());
+ QCOMPARE(array.ref.atomic.load(), -1);
+ }
+}
+
+void tst_QArrayData::sharedNullEmpty()
+{
+ QArrayData *null = const_cast<QArrayData *>(&QArrayData::shared_null);
+ QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0);
+
+ QVERIFY(null->ref.isStatic());
+ QVERIFY(null->ref.isSharable());
+ QVERIFY(null->ref.isShared());
+
+ QVERIFY(empty->ref.isStatic());
+ QVERIFY(empty->ref.isSharable());
+ QVERIFY(empty->ref.isShared());
+
+ QCOMPARE(null->ref.atomic.load(), -1);
+ QCOMPARE(empty->ref.atomic.load(), -1);
+
+ QVERIFY(null->ref.ref());
+ QVERIFY(empty->ref.ref());
+
+ QCOMPARE(null->ref.atomic.load(), -1);
+ QCOMPARE(empty->ref.atomic.load(), -1);
+
+ QVERIFY(null->ref.deref());
+ QVERIFY(empty->ref.deref());
+
+ QCOMPARE(null->ref.atomic.load(), -1);
+ QCOMPARE(empty->ref.atomic.load(), -1);
+
+ QVERIFY(null != empty);
+
+ QCOMPARE(null->size, 0);
+ QCOMPARE(null->alloc, 0u);
+ QCOMPARE(null->capacityReserved, 0u);
+
+ QCOMPARE(empty->size, 0);
+ QCOMPARE(empty->alloc, 0u);
+ QCOMPARE(empty->capacityReserved, 0u);
+}
+
+void tst_QArrayData::staticData()
+{
+ QStaticArrayData<char, 10> charArray = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(char, 10),
+ { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
+ };
+ QStaticArrayData<int, 10> intArray = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
+ };
+ QStaticArrayData<double, 10> doubleArray = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(double, 10),
+ { 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f }
+ };
+
+ QCOMPARE(charArray.header.size, 10);
+ QCOMPARE(intArray.header.size, 10);
+ QCOMPARE(doubleArray.header.size, 10);
+
+ QCOMPARE(charArray.header.data(), reinterpret_cast<void *>(&charArray.data));
+ QCOMPARE(intArray.header.data(), reinterpret_cast<void *>(&intArray.data));
+ QCOMPARE(doubleArray.header.data(), reinterpret_cast<void *>(&doubleArray.data));
+}
+
+void tst_QArrayData::simpleVector()
+{
+ QArrayData data0 = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
+ QStaticArrayData<int, 7> data1 = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7),
+ { 0, 1, 2, 3, 4, 5, 6 }
+ };
+
+ int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+ SimpleVector<int> v1;
+ SimpleVector<int> v2(v1);
+ SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0));
+ SimpleVector<int> v4(static_cast<QTypedArrayData<int> *>(&data1.header));
+ SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0));
+ SimpleVector<int> v6(static_cast<QTypedArrayData<int> *>(&data1.header));
+ SimpleVector<int> v7(10, 5);
+ SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array));
+
+ 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(!v7.isNull());
+ QVERIFY(!v8.isNull());
+
+ QVERIFY(v1.isEmpty());
+ QVERIFY(v2.isEmpty());
+ QVERIFY(v3.isEmpty());
+ QVERIFY(v4.isEmpty());
+ QVERIFY(v5.isEmpty());
+ QVERIFY(!v6.isEmpty());
+ QVERIFY(!v7.isEmpty());
+ QVERIFY(!v8.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(v7.size(), size_t(10));
+ QCOMPARE(v8.size(), size_t(10));
+
+ 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(v7.capacity() >= size_t(10));
+ QVERIFY(v8.capacity() >= size_t(10));
+
+ QVERIFY(v1.isStatic());
+ QVERIFY(v2.isStatic());
+ QVERIFY(v3.isStatic());
+ QVERIFY(v4.isStatic());
+ QVERIFY(v5.isStatic());
+ QVERIFY(v6.isStatic());
+ QVERIFY(!v7.isStatic());
+ QVERIFY(!v8.isStatic());
+
+ QVERIFY(v1.isShared());
+ QVERIFY(v2.isShared());
+ QVERIFY(v3.isShared());
+ QVERIFY(v4.isShared());
+ QVERIFY(v5.isShared());
+ QVERIFY(v6.isShared());
+ QVERIFY(!v7.isShared());
+ QVERIFY((SimpleVector<int>(v7), v7.isShared()));
+ QVERIFY(!v7.isShared());
+ QVERIFY(!v8.isShared());
+
+ QVERIFY(v1.isSharable());
+ QVERIFY(v2.isSharable());
+ QVERIFY(v3.isSharable());
+ QVERIFY(v4.isSharable());
+ QVERIFY(v5.isSharable());
+ QVERIFY(v6.isSharable());
+ QVERIFY(v7.isSharable());
+ QVERIFY(v8.isSharable());
+
+ QVERIFY(v1.isSharedWith(v2));
+ QVERIFY(v1.isSharedWith(v3));
+ QVERIFY(v1.isSharedWith(v4));
+ QVERIFY(!v1.isSharedWith(v5));
+ QVERIFY(!v1.isSharedWith(v6));
+
+ QCOMPARE((void *)v1.constBegin(), (void *)v1.constEnd());
+ QCOMPARE((void *)v4.constBegin(), (void *)v4.constEnd());
+ QCOMPARE((void *)(v6.constBegin() + v6.size()), (void *)v6.constEnd());
+ QCOMPARE((void *)(v7.constBegin() + v7.size()), (void *)v7.constEnd());
+ QCOMPARE((void *)(v8.constBegin() + v8.size()), (void *)v8.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));
+
+ {
+ SimpleVector<int> temp(v6);
+
+ QCOMPARE(const_(v6).front(), 0);
+ QCOMPARE(const_(v6).back(), 6);
+
+ QVERIFY(temp.isShared());
+ QVERIFY(temp.isSharedWith(v6));
+
+ QCOMPARE(temp.front(), 0);
+ QCOMPARE(temp.back(), 6);
+
+ // Detached
+ QVERIFY(!temp.isShared());
+ const int *const tempBegin = temp.begin();
+
+ for (size_t i = 0; i < v6.size(); ++i) {
+ QCOMPARE(const_(v6)[i], int(i));
+ QCOMPARE(const_(v6).at(i), int(i));
+ QCOMPARE(&const_(v6)[i], &const_(v6).at(i));
+
+ QCOMPARE(const_(v8)[i], const_(v6)[i]);
+
+ QCOMPARE(temp[i], int(i));
+ QCOMPARE(temp.at(i), int(i));
+ QCOMPARE(&temp[i], &temp.at(i));
+ }
+
+ // A single detach should do
+ QCOMPARE(temp.begin(), tempBegin);
+ }
+
+ {
+ int count = 0;
+ Q_FOREACH (int value, v7) {
+ QCOMPARE(value, 5);
+ ++count;
+ }
+
+ QCOMPARE(count, 10);
+ }
+
+ {
+ int count = 0;
+ Q_FOREACH (int value, v8) {
+ QCOMPARE(value, count);
+ ++count;
+ }
+
+ QCOMPARE(count, 10);
+ }
+
+ 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));
+ }
+
+ v1.prepend(array, array + sizeof(array)/sizeof(array[0]));
+ QCOMPARE(v1.size(), size_t(10));
+ QVERIFY(v1 == v8);
+
+ v6 = v1;
+ QVERIFY(v1.isSharedWith(v6));
+
+ v1.prepend(array, array + sizeof(array)/sizeof(array[0]));
+ QVERIFY(!v1.isSharedWith(v6));
+ QCOMPARE(v1.size(), size_t(20));
+ QCOMPARE(v6.size(), size_t(10));
+
+ for (int i = 0; i < 20; ++i)
+ QCOMPARE(v1[i], v6[i % 10]);
+
+ v1.clear();
+
+ v1.append(array, array + sizeof(array)/sizeof(array[0]));
+ QCOMPARE(v1.size(), size_t(10));
+ QVERIFY(v1 == v8);
+
+ v6 = v1;
+ QVERIFY(v1.isSharedWith(v6));
+
+ v1.append(array, array + sizeof(array)/sizeof(array[0]));
+ QVERIFY(!v1.isSharedWith(v6));
+ QCOMPARE(v1.size(), size_t(20));
+ QCOMPARE(v6.size(), size_t(10));
+
+ for (int i = 0; i < 20; ++i)
+ QCOMPARE(v1[i], v6[i % 10]);
+
+ v1.insert(0, v6.constBegin(), v6.constEnd());
+ QCOMPARE(v1.size(), size_t(30));
+
+ v6 = v1;
+ QVERIFY(v1.isSharedWith(v6));
+
+ v1.insert(10, v6.constBegin(), v6.constEnd());
+ QVERIFY(!v1.isSharedWith(v6));
+ QCOMPARE(v1.size(), size_t(60));
+ QCOMPARE(v6.size(), size_t(30));
+
+ for (int i = 0; i < 30; ++i)
+ QCOMPARE(v6[i], v8[i % 10]);
+
+ v1.insert(v1.size(), v6.constBegin(), v6.constEnd());
+ QCOMPARE(v1.size(), size_t(90));
+
+ v1.insert(-1, v8.constBegin(), v8.constEnd());
+ QCOMPARE(v1.size(), size_t(100));
+
+ v1.insert(-11, v8.constBegin(), v8.constEnd());
+ QCOMPARE(v1.size(), size_t(110));
+
+ v1.insert(-200, v8.constBegin(), v8.constEnd());
+ QCOMPARE(v1.size(), size_t(120));
+
+ for (int i = 0; i < 120; ++i)
+ QCOMPARE(v1[i], v8[i % 10]);
+
+ {
+ v7.setSharable(true);
+ QVERIFY(v7.isSharable());
+
+ SimpleVector<int> copy1(v7);
+ QVERIFY(copy1.isSharedWith(v7));
+
+ v7.setSharable(false);
+ QVERIFY(!v7.isSharable());
+
+ QVERIFY(!copy1.isSharedWith(v7));
+ QCOMPARE(v7.size(), copy1.size());
+ for (size_t i = 0; i < copy1.size(); ++i)
+ QCOMPARE(v7[i], copy1[i]);
+
+ SimpleVector<int> clone(v7);
+ QVERIFY(!clone.isSharedWith(v7));
+ QCOMPARE(clone.size(), copy1.size());
+ for (size_t i = 0; i < copy1.size(); ++i)
+ QCOMPARE(clone[i], copy1[i]);
+
+ v7.setSharable(true);
+ QVERIFY(v7.isSharable());
+
+ SimpleVector<int> copy2(v7);
+ QVERIFY(copy2.isSharedWith(v7));
+ }
+
+ {
+ SimpleVector<int> null;
+ SimpleVector<int> empty(0, 5);
+
+ QVERIFY(null.isSharable());
+ QVERIFY(empty.isSharable());
+
+ null.setSharable(true);
+ empty.setSharable(true);
+
+ QVERIFY(null.isSharable());
+ QVERIFY(empty.isSharable());
+
+ QVERIFY(null.isEmpty());
+ QVERIFY(empty.isEmpty());
+
+ null.setSharable(false);
+ empty.setSharable(false);
+
+ QVERIFY(!null.isSharable());
+ QVERIFY(!empty.isSharable());
+
+ QVERIFY(null.isEmpty());
+ QVERIFY(empty.isEmpty());
+
+ null.setSharable(true);
+ empty.setSharable(true);
+
+ QVERIFY(null.isSharable());
+ QVERIFY(empty.isSharable());
+
+ QVERIFY(null.isEmpty());
+ QVERIFY(empty.isEmpty());
+ }
+}
+
+Q_DECLARE_METATYPE(SimpleVector<int>)
+
+void tst_QArrayData::simpleVectorReserve_data()
+{
+ QTest::addColumn<SimpleVector<int> >("vector");
+ QTest::addColumn<size_t>("capacity");
+ QTest::addColumn<size_t>("size");
+
+ QTest::newRow("null") << SimpleVector<int>() << size_t(0) << size_t(0);
+ QTest::newRow("empty") << SimpleVector<int>(0, 42) << size_t(0) << size_t(0);
+ QTest::newRow("non-empty") << SimpleVector<int>(5, 42) << size_t(5) << size_t(5);
+
+ static const QStaticArrayData<int, 15> array = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 15),
+ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } };
+ QArrayDataPointerRef<int> p = {
+ static_cast<QTypedArrayData<int> *>(
+ const_cast<QArrayData *>(&array.header)) };
+
+ QTest::newRow("static") << SimpleVector<int>(p) << size_t(0) << size_t(15);
+ QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array.data, 15) << size_t(0) << size_t(15);
+}
+
+void tst_QArrayData::simpleVectorReserve()
+{
+ QFETCH(SimpleVector<int>, vector);
+ QFETCH(size_t, capacity);
+ QFETCH(size_t, size);
+
+ QVERIFY(!capacity || capacity >= size);
+
+ QCOMPARE(vector.capacity(), capacity);
+ QCOMPARE(vector.size(), size);
+
+ const SimpleVector<int> copy(vector);
+
+ vector.reserve(0);
+ QCOMPARE(vector.capacity(), capacity);
+ QCOMPARE(vector.size(), size);
+
+ vector.reserve(10);
+
+ // zero-capacity (immutable) resets with detach
+ if (!capacity)
+ capacity = size;
+
+ QCOMPARE(vector.capacity(), qMax(size_t(10), capacity));
+ QCOMPARE(vector.size(), size);
+
+ vector.reserve(20);
+ QCOMPARE(vector.capacity(), size_t(20));
+ QCOMPARE(vector.size(), size);
+
+ vector.reserve(30);
+ QCOMPARE(vector.capacity(), size_t(30));
+ QCOMPARE(vector.size(), size);
+
+ QVERIFY(vector == copy);
+}
+
+struct Deallocator
+{
+ Deallocator(size_t objectSize, size_t alignment)
+ : objectSize(objectSize)
+ , alignment(alignment)
+ {
+ }
+
+ ~Deallocator()
+ {
+ Q_FOREACH (QArrayData *data, headers)
+ QArrayData::deallocate(data, objectSize, alignment);
+ }
+
+ size_t objectSize;
+ size_t alignment;
+ QVector<QArrayData *> headers;
+};
+
+Q_DECLARE_METATYPE(const QArrayData *)
+Q_DECLARE_METATYPE(QArrayData::AllocationOptions)
+
+void tst_QArrayData::allocate_data()
+{
+ QTest::addColumn<size_t>("objectSize");
+ QTest::addColumn<size_t>("alignment");
+ QTest::addColumn<QArrayData::AllocationOptions>("allocateOptions");
+ QTest::addColumn<bool>("isCapacityReserved");
+ QTest::addColumn<bool>("isSharable");
+ QTest::addColumn<const QArrayData *>("commonEmpty");
+
+ struct {
+ char const *typeName;
+ size_t objectSize;
+ size_t alignment;
+ } types[] = {
+ { "char", sizeof(char), Q_ALIGNOF(char) },
+ { "short", sizeof(short), Q_ALIGNOF(short) },
+ { "void *", sizeof(void *), Q_ALIGNOF(void *) }
+ };
+
+ QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0);
+ QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable);
+
+ QVERIFY(shared_empty);
+ QVERIFY(unsharable_empty);
+
+ struct {
+ char const *description;
+ QArrayData::AllocationOptions allocateOptions;
+ bool isCapacityReserved;
+ bool isSharable;
+ const QArrayData *commonEmpty;
+ } options[] = {
+ { "Default", QArrayData::Default, false, true, shared_empty },
+ { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty },
+ { "Reserved | Unsharable",
+ QArrayData::CapacityReserved | QArrayData::Unsharable, true, false,
+ unsharable_empty },
+ { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty },
+ { "Grow", QArrayData::Grow, false, true, shared_empty }
+ };
+
+ for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
+ for (size_t j = 0; j < sizeof(options)/sizeof(options[0]); ++j)
+ QTest::newRow(qPrintable(
+ QLatin1String(types[i].typeName)
+ + QLatin1String(": ")
+ + QLatin1String(options[j].description)))
+ << types[i].objectSize << types[i].alignment
+ << options[j].allocateOptions << options[j].isCapacityReserved
+ << options[j].isSharable << options[j].commonEmpty;
+}
+
+void tst_QArrayData::allocate()
+{
+ QFETCH(size_t, objectSize);
+ QFETCH(size_t, alignment);
+ QFETCH(QArrayData::AllocationOptions, allocateOptions);
+ QFETCH(bool, isCapacityReserved);
+ QFETCH(bool, isSharable);
+ QFETCH(const QArrayData *, commonEmpty);
+
+ // Minimum alignment that can be requested is that of QArrayData.
+ // Typically, this alignment is sizeof(void *) and ensured by malloc.
+ size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
+
+ // Shared Empty
+ QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0,
+ QArrayData::AllocationOptions(allocateOptions)), commonEmpty);
+
+ Deallocator keeper(objectSize, minAlignment);
+ keeper.headers.reserve(1024);
+
+ for (int capacity = 1; capacity <= 1024; capacity <<= 1) {
+ QArrayData *data = QArrayData::allocate(objectSize, minAlignment,
+ capacity, QArrayData::AllocationOptions(allocateOptions));
+ keeper.headers.append(data);
+
+ QCOMPARE(data->size, 0);
+ if (allocateOptions & QArrayData::Grow)
+ QVERIFY(data->alloc > uint(capacity));
+ else
+ QCOMPARE(data->alloc, uint(capacity));
+ QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
+ QCOMPARE(data->ref.isSharable(), isSharable);
+
+ // Check that the allocated array can be used. Best tested with a
+ // memory checker, such as valgrind, running.
+ ::memset(data->data(), 'A', objectSize * capacity);
+ }
+}
+
+class Unaligned
+{
+ char dummy[8];
+};
+
+void tst_QArrayData::alignment_data()
+{
+ QTest::addColumn<size_t>("alignment");
+
+ for (int i = 1; i < 10; ++i) {
+ size_t alignment = 1u << i;
+ QTest::newRow(qPrintable(QString::number(alignment))) << alignment;
+ }
+}
+
+void tst_QArrayData::alignment()
+{
+ QFETCH(size_t, alignment);
+
+ // Minimum alignment that can be requested is that of QArrayData.
+ // Typically, this alignment is sizeof(void *) and ensured by malloc.
+ size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
+
+ Deallocator keeper(sizeof(Unaligned), minAlignment);
+ keeper.headers.reserve(100);
+
+ for (int i = 0; i < 100; ++i) {
+ QArrayData *data = QArrayData::allocate(sizeof(Unaligned),
+ minAlignment, 8, QArrayData::Default);
+ keeper.headers.append(data);
+
+ QVERIFY(data);
+ QCOMPARE(data->size, 0);
+ QVERIFY(data->alloc >= uint(8));
+
+ // These conditions should hold as long as header and array are
+ // allocated together
+ QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData)));
+ QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData)
+ + minAlignment - Q_ALIGNOF(QArrayData)));
+
+ // Data is aligned
+ QCOMPARE(quintptr(data->data()) % alignment, quintptr(0u));
+
+ // Check that the allocated array can be used. Best tested with a
+ // memory checker, such as valgrind, running.
+ ::memset(data->data(), 'A', sizeof(Unaligned) * 8);
+ }
+}
+
+void tst_QArrayData::typedData()
+{
+ QStaticArrayData<int, 10> data = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
+ };
+ QCOMPARE(data.header.size, 10);
+
+ {
+ QTypedArrayData<int> *array =
+ static_cast<QTypedArrayData<int> *>(&data.header);
+ QCOMPARE(array->data(), data.data);
+
+ int j = 0;
+ for (QTypedArrayData<int>::iterator iter = array->begin();
+ iter != array->end(); ++iter, ++j)
+ QCOMPARE(iter, data.data + j);
+ QCOMPARE(j, 10);
+ }
+
+ {
+ const QTypedArrayData<int> *array =
+ static_cast<const QTypedArrayData<int> *>(&data.header);
+
+ QCOMPARE(array->data(), data.data);
+
+ int j = 0;
+ for (QTypedArrayData<int>::const_iterator iter = array->begin();
+ iter != array->end(); ++iter, ++j)
+ QCOMPARE(iter, data.data + j);
+ QCOMPARE(j, 10);
+ }
+
+ {
+ QTypedArrayData<int> *null = QTypedArrayData<int>::sharedNull();
+ QTypedArrayData<int> *empty = QTypedArrayData<int>::allocate(0);
+
+ QVERIFY(null != empty);
+
+ QCOMPARE(null->size, 0);
+ QCOMPARE(empty->size, 0);
+
+ QCOMPARE(null->begin(), null->end());
+ QCOMPARE(empty->begin(), empty->end());
+ }
+
+
+ {
+ Deallocator keeper(sizeof(char),
+ Q_ALIGNOF(QTypedArrayData<char>::AlignmentDummy));
+ QArrayData *array = QTypedArrayData<char>::allocate(10);
+ keeper.headers.append(array);
+
+ QVERIFY(array);
+ QCOMPARE(array->size, 0);
+ QCOMPARE(array->alloc, 10u);
+
+ // Check that the allocated array can be used. Best tested with a
+ // memory checker, such as valgrind, running.
+ ::memset(array->data(), 0, 10 * sizeof(char));
+
+ keeper.headers.clear();
+ QTypedArrayData<short>::deallocate(array);
+
+ QVERIFY(true);
+ }
+
+ {
+ Deallocator keeper(sizeof(short),
+ Q_ALIGNOF(QTypedArrayData<short>::AlignmentDummy));
+ QArrayData *array = QTypedArrayData<short>::allocate(10);
+ keeper.headers.append(array);
+
+ QVERIFY(array);
+ QCOMPARE(array->size, 0);
+ QCOMPARE(array->alloc, 10u);
+
+ // Check that the allocated array can be used. Best tested with a
+ // memory checker, such as valgrind, running.
+ ::memset(array->data(), 0, 10 * sizeof(short));
+
+ keeper.headers.clear();
+ QTypedArrayData<short>::deallocate(array);
+
+ QVERIFY(true);
+ }
+
+ {
+ Deallocator keeper(sizeof(double),
+ Q_ALIGNOF(QTypedArrayData<double>::AlignmentDummy));
+ QArrayData *array = QTypedArrayData<double>::allocate(10);
+ keeper.headers.append(array);
+
+ QVERIFY(array);
+ QCOMPARE(array->size, 0);
+ QCOMPARE(array->alloc, 10u);
+
+ // Check that the allocated array can be used. Best tested with a
+ // memory checker, such as valgrind, running.
+ ::memset(array->data(), 0, 10 * sizeof(double));
+
+ keeper.headers.clear();
+ QTypedArrayData<double>::deallocate(array);
+
+ QVERIFY(true);
+ }
+}
+
+void tst_QArrayData::gccBug43247()
+{
+ // This test tries to verify QArrayData is not affected by GCC optimizer
+ // bug #43247.
+ // Reported on GCC 4.4.3, Linux, affects QVector
+
+ QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (3)");
+ QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (4)");
+ QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (5)");
+ QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (6)");
+ QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (7)");
+
+ SimpleVector<int> array(10, 0);
+ // QVector<int> vector(10, 0);
+
+ for (int i = 0; i < 10; ++i) {
+ if (i >= 3 && i < 8)
+ qDebug("GCC Optimization bug #43247 not triggered (%i)", i);
+
+ // When access to data is implemented through an array of size 1, this
+ // line lets the compiler assume i == 0, and the conditional above is
+ // skipped.
+ QVERIFY(array.at(i) == 0);
+ // QVERIFY(vector.at(i) == 0);
+ }
+}
+
+struct CountedObject
+{
+ CountedObject()
+ : id(liveCount++)
+ {
+ }
+
+ CountedObject(const CountedObject &other)
+ : id(other.id)
+ {
+ ++liveCount;
+ }
+
+ ~CountedObject()
+ {
+ --liveCount;
+ }
+
+ CountedObject &operator=(const CountedObject &other)
+ {
+ id = other.id;
+ return *this;
+ }
+
+ struct LeakChecker
+ {
+ LeakChecker()
+ : previousLiveCount(liveCount)
+ {
+ }
+
+ ~LeakChecker()
+ {
+ QCOMPARE(liveCount, previousLiveCount);
+ }
+
+ private:
+ const size_t previousLiveCount;
+ };
+
+ size_t id; // not unique
+ static size_t liveCount;
+};
+
+size_t CountedObject::liveCount = 0;
+
+void tst_QArrayData::arrayOps()
+{
+ CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
+
+ const int intArray[5] = { 80, 101, 100, 114, 111 };
+ const QString stringArray[5] = {
+ QLatin1String("just"),
+ QLatin1String("for"),
+ QLatin1String("testing"),
+ QLatin1String("a"),
+ QLatin1String("vector")
+ };
+ const CountedObject objArray[5];
+
+ QVERIFY(!QTypeInfo<int>::isComplex && !QTypeInfo<int>::isStatic);
+ QVERIFY(QTypeInfo<QString>::isComplex && !QTypeInfo<QString>::isStatic);
+ QVERIFY(QTypeInfo<CountedObject>::isComplex && QTypeInfo<CountedObject>::isStatic);
+
+ QCOMPARE(CountedObject::liveCount, size_t(5));
+ for (size_t i = 0; i < 5; ++i)
+ QCOMPARE(objArray[i].id, i);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // copyAppend (I)
+ SimpleVector<int> vi(intArray, intArray + 5);
+ SimpleVector<QString> vs(stringArray, stringArray + 5);
+ SimpleVector<CountedObject> vo(objArray, objArray + 5);
+
+ QCOMPARE(CountedObject::liveCount, size_t(10));
+ for (int i = 0; i < 5; ++i) {
+ QCOMPARE(vi[i], intArray[i]);
+ QVERIFY(vs[i].isSharedWith(stringArray[i]));
+ QCOMPARE(vo[i].id, objArray[i].id);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // destroyAll
+ vi.clear();
+ vs.clear();
+ vo.clear();
+
+ QCOMPARE(CountedObject::liveCount, size_t(5));
+
+ ////////////////////////////////////////////////////////////////////////////
+ // copyAppend (II)
+ int referenceInt = 7;
+ QString referenceString = QLatin1String("reference");
+ CountedObject referenceObject;
+
+ vi = SimpleVector<int>(5, referenceInt);
+ vs = SimpleVector<QString>(5, referenceString);
+ vo = SimpleVector<CountedObject>(5, referenceObject);
+
+ QCOMPARE(vi.size(), size_t(5));
+ QCOMPARE(vs.size(), size_t(5));
+ QCOMPARE(vo.size(), size_t(5));
+
+ QCOMPARE(CountedObject::liveCount, size_t(11));
+ for (int i = 0; i < 5; ++i) {
+ QCOMPARE(vi[i], referenceInt);
+ QVERIFY(vs[i].isSharedWith(referenceString));
+ QCOMPARE(vo[i].id, referenceObject.id);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // insert
+ vi.reserve(30);
+ vs.reserve(30);
+ vo.reserve(30);
+
+ QCOMPARE(vi.size(), size_t(5));
+ QCOMPARE(vs.size(), size_t(5));
+ QCOMPARE(vo.size(), size_t(5));
+
+ QVERIFY(vi.capacity() >= 30);
+ QVERIFY(vs.capacity() >= 30);
+ QVERIFY(vo.capacity() >= 30);
+
+ // Displace as many elements as array is extended by
+ vi.insert(0, intArray, intArray + 5);
+ vs.insert(0, stringArray, stringArray + 5);
+ vo.insert(0, objArray, objArray + 5);
+
+ QCOMPARE(vi.size(), size_t(10));
+ QCOMPARE(vs.size(), size_t(10));
+ QCOMPARE(vo.size(), size_t(10));
+
+ // Displace more elements than array is extended by
+ vi.insert(0, intArray, intArray + 5);
+ vs.insert(0, stringArray, stringArray + 5);
+ vo.insert(0, objArray, objArray + 5);
+
+ QCOMPARE(vi.size(), size_t(15));
+ QCOMPARE(vs.size(), size_t(15));
+ QCOMPARE(vo.size(), size_t(15));
+
+ // Displace less elements than array is extended by
+ vi.insert(5, vi.constBegin(), vi.constEnd());
+ vs.insert(5, vs.constBegin(), vs.constEnd());
+ vo.insert(5, vo.constBegin(), vo.constEnd());
+
+ QCOMPARE(vi.size(), size_t(30));
+ QCOMPARE(vs.size(), size_t(30));
+ QCOMPARE(vo.size(), size_t(30));
+
+ QCOMPARE(CountedObject::liveCount, size_t(36));
+ for (int i = 0; i < 15; ++i) {
+ QCOMPARE(vi[i], intArray[i % 5]);
+ QVERIFY(vs[i].isSharedWith(stringArray[i % 5]));
+ QCOMPARE(vo[i].id, objArray[i % 5].id);
+ }
+
+ for (int i = 15; i < 20; ++i) {
+ QCOMPARE(vi[i], referenceInt);
+ QVERIFY(vs[i].isSharedWith(referenceString));
+ QCOMPARE(vo[i].id, referenceObject.id);
+ }
+
+ for (int i = 20; i < 25; ++i) {
+ QCOMPARE(vi[i], intArray[i % 5]);
+ QVERIFY(vs[i].isSharedWith(stringArray[i % 5]));
+ QCOMPARE(vo[i].id, objArray[i % 5].id);
+ }
+
+ for (int i = 25; i < 30; ++i) {
+ QCOMPARE(vi[i], referenceInt);
+ QVERIFY(vs[i].isSharedWith(referenceString));
+ QCOMPARE(vo[i].id, referenceObject.id);
+ }
+}
+
+Q_DECLARE_METATYPE(QArrayDataPointer<int>)
+
+static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array,
+ int fillValue, size_t size)
+{
+ const int *iter = array->begin();
+ const int *const end = array->end();
+
+ for (size_t i = 0; i < size; ++i, ++iter)
+ if (*iter != fillValue)
+ return false;
+
+ if (iter != end)
+ return false;
+
+ return true;
+}
+
+void tst_QArrayData::setSharable_data()
+{
+ QTest::addColumn<QArrayDataPointer<int> >("array");
+ QTest::addColumn<size_t>("size");
+ QTest::addColumn<size_t>("capacity");
+ QTest::addColumn<bool>("isCapacityReserved");
+ QTest::addColumn<int>("fillValue");
+
+ QArrayDataPointer<int> null;
+ QArrayDataPointer<int> empty; empty.clear();
+
+ static QStaticArrayData<int, 10> staticArrayData = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
+ { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
+ };
+
+ QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5,
+ QArrayData::CapacityReserved));
+ QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(10,
+ QArrayData::Default));
+ QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15,
+ QArrayData::CapacityReserved));
+ QArrayDataPointer<int> staticArray(
+ static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
+ QArrayDataPointer<int> rawData(
+ QTypedArrayData<int>::fromRawData(staticArrayData.data, 10));
+
+ nonEmpty->copyAppend(5, 1);
+ nonEmptyReserved->copyAppend(7, 2);
+
+ QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0;
+ QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0;
+ // unsharable-empty implicitly tested in shared-empty
+ QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0;
+ QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(10) << false << 1;
+ QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2;
+ QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3;
+ QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3;
+}
+
+void tst_QArrayData::setSharable()
+{
+ QFETCH(QArrayDataPointer<int>, array);
+ QFETCH(size_t, size);
+ QFETCH(size_t, capacity);
+ QFETCH(bool, isCapacityReserved);
+ QFETCH(int, fillValue);
+
+ QVERIFY(array->ref.isShared()); // QTest has a copy
+ QVERIFY(array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ // shared-null becomes shared-empty, may otherwise detach
+ array.setSharable(true);
+
+ QVERIFY(array->ref.isSharable());
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(array->ref.isShared());
+ QVERIFY(array->ref.isSharable());
+ QCOMPARE(copy.data(), array.data());
+ }
+
+ // Unshare, must detach
+ array.setSharable(false);
+
+ // Immutability (alloc == 0) is lost on detach
+ if (capacity == 0 && size != 0)
+ capacity = size;
+
+ QVERIFY(!array->ref.isShared());
+ QVERIFY(!array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(!array->ref.isShared());
+ QVERIFY(!array->ref.isSharable());
+
+ // Null/empty is always shared
+ QCOMPARE(copy->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(copy->ref.isSharable());
+
+ QCOMPARE(size_t(copy->size), size);
+ QCOMPARE(size_t(copy->alloc), capacity);
+ QCOMPARE(bool(copy->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(copy, fillValue, size));
+ }
+
+ // Make sharable, again
+ array.setSharable(true);
+
+ QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(array->ref.isShared());
+ QCOMPARE(copy.data(), array.data());
+ }
+
+ QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(array->ref.isSharable());
+}
+
+void tst_QArrayData::fromRawData()
+{
+ static const int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ {
+ // Default: Immutable, sharable
+ SimpleVector<int> raw = SimpleVector<int>::fromRawData(array,
+ sizeof(array)/sizeof(array[0]), QArrayData::Default);
+
+ QCOMPARE(raw.size(), size_t(11));
+ QCOMPARE(raw.constBegin(), array);
+ QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0])));
+
+ QVERIFY(!raw.isShared());
+ QVERIFY(SimpleVector<int>(raw).isSharedWith(raw));
+ QVERIFY(!raw.isShared());
+
+ // Detach
+ QCOMPARE(raw.back(), 11);
+ QVERIFY(raw.constBegin() != array);
+ }
+
+ {
+ // Immutable, unsharable
+ SimpleVector<int> raw = SimpleVector<int>::fromRawData(array,
+ sizeof(array)/sizeof(array[0]), QArrayData::Unsharable);
+
+ QCOMPARE(raw.size(), size_t(11));
+ QCOMPARE(raw.constBegin(), array);
+ QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0])));
+
+ SimpleVector<int> copy(raw);
+ QVERIFY(!copy.isSharedWith(raw));
+ QVERIFY(!raw.isShared());
+
+ QCOMPARE(copy.size(), size_t(11));
+
+ for (size_t i = 0; i < 11; ++i)
+ QCOMPARE(const_(copy)[i], const_(raw)[i]);
+
+ QCOMPARE(raw.size(), size_t(11));
+ QCOMPARE(raw.constBegin(), array);
+ QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0])));
+
+ // Detach
+ QCOMPARE(raw.back(), 11);
+ QVERIFY(raw.constBegin() != array);
+ }
+}
+
+void tst_QArrayData::literals()
+{
+ {
+ QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ");
+ QCOMPARE(d->size, 10 + 1);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d->data()[i], char('A' + i));
+ }
+
+ {
+ // wchar_t is not necessarily 2-bytes
+ QArrayDataPointer<wchar_t> d = Q_ARRAY_LITERAL(wchar_t, L"ABCDEFGHIJ");
+ QCOMPARE(d->size, 10 + 1);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d->data()[i], wchar_t('A' + i));
+ }
+
+ {
+ SimpleVector<char> v = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ");
+
+ QVERIFY(!v.isNull());
+ QVERIFY(!v.isEmpty());
+ QCOMPARE(v.size(), size_t(11));
+ // v.capacity() is unspecified, for now
+
+#if defined(Q_COMPILER_VARIADIC_MACROS) \
+ && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+ QVERIFY(v.isStatic());
+#endif
+
+ QVERIFY(v.isSharable());
+ QCOMPARE((void *)(v.constBegin() + v.size()), (void *)v.constEnd());
+
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(const_(v)[i], char('A' + i));
+ QCOMPARE(const_(v)[10], char('\0'));
+ }
+}
+
+void tst_QArrayData::variadicLiterals()
+{
+#if defined(Q_COMPILER_VARIADIC_MACROS) \
+ && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+ {
+ QArrayDataPointer<int> d =
+ Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ QCOMPARE(d->size, 10);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d->data()[i], i);
+ }
+
+ {
+ QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char,
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
+ QCOMPARE(d->size, 10);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d->data()[i], char('A' + i));
+ }
+
+ {
+ QArrayDataPointer<const char *> d = Q_ARRAY_LITERAL(const char *,
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J");
+ QCOMPARE(d->size, 10);
+ for (int i = 0; i < 10; ++i) {
+ QCOMPARE(d->data()[i][0], char('A' + i));
+ QCOMPARE(d->data()[i][1], '\0');
+ }
+ }
+
+ {
+ SimpleVector<int> v = Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6);
+
+ QVERIFY(!v.isNull());
+ QVERIFY(!v.isEmpty());
+ QCOMPARE(v.size(), size_t(7));
+ // v.capacity() is unspecified, for now
+
+ QVERIFY(v.isStatic());
+
+ QVERIFY(v.isSharable());
+ QCOMPARE((void *)(v.constBegin() + v.size()), (void *)v.constEnd());
+
+ for (int i = 0; i < 7; ++i)
+ QCOMPARE(const_(v)[i], i);
+ }
+#else
+ QSKIP("Variadic Q_ARRAY_LITERAL not available in current configuration.");
+#endif // defined(Q_COMPILER_VARIADIC_MACROS)
+}
+
+#ifdef Q_COMPILER_RVALUE_REFS
+// std::remove_reference is in C++11, but requires library support
+template <class T> struct RemoveReference { typedef T Type; };
+template <class T> struct RemoveReference<T &> { typedef T Type; };
+
+// single-argument std::move is in C++11, but requires library support
+template <class T>
+typename RemoveReference<T>::Type &&cxx11Move(T &&t)
+{
+ return static_cast<typename RemoveReference<T>::Type &&>(t);
+}
+
+struct CompilerHasCxx11ImplicitMoves
+{
+ static bool value()
+ {
+ DetectImplicitMove d(cxx11Move(DetectImplicitMove()));
+ return d.constructor == DetectConstructor::MoveConstructor;
+ }
+
+ struct DetectConstructor
+ {
+ Q_DECL_CONSTEXPR DetectConstructor()
+ : constructor(DefaultConstructor)
+ {
+ }
+
+ Q_DECL_CONSTEXPR DetectConstructor(const DetectConstructor &)
+ : constructor(CopyConstructor)
+ {
+ }
+
+ Q_DECL_CONSTEXPR DetectConstructor(DetectConstructor &&)
+ : constructor(MoveConstructor)
+ {
+ }
+
+ enum Constructor {
+ DefaultConstructor,
+ CopyConstructor,
+ MoveConstructor
+ };
+
+ Constructor constructor;
+ };
+
+ struct DetectImplicitMove
+ : DetectConstructor
+ {
+ };
+};
+#endif
+
+void tst_QArrayData::rValueReferences()
+{
+#ifdef Q_COMPILER_RVALUE_REFS
+ if (!CompilerHasCxx11ImplicitMoves::value())
+ QSKIP("Implicit move ctor not supported in current configuration");
+
+ SimpleVector<int> v1(1, 42);
+ SimpleVector<int> v2;
+
+ const SimpleVector<int>::const_iterator begin = v1.constBegin();
+
+ QVERIFY(!v1.isNull());
+ QVERIFY(v2.isNull());
+
+ // move-assign
+ v2 = cxx11Move(v1);
+
+ QVERIFY(v1.isNull());
+ QVERIFY(!v2.isNull());
+ QCOMPARE(v2.constBegin(), begin);
+
+ SimpleVector<int> v3(cxx11Move(v2));
+
+ QVERIFY(v1.isNull());
+ QVERIFY(v2.isNull());
+ QVERIFY(!v3.isNull());
+ QCOMPARE(v3.constBegin(), begin);
+
+ QCOMPARE(v3.size(), size_t(1));
+ QCOMPARE(v3.front(), 42);
+#else
+ QSKIP("RValue references are not supported in current configuration");
+#endif
+}
+
+void tst_QArrayData::grow()
+{
+ SimpleVector<int> vector;
+
+ QCOMPARE(vector.size(), size_t(0));
+
+ size_t previousCapacity = vector.capacity();
+ size_t allocations = 0;
+ for (size_t i = 1; i <= (1 << 20); ++i) {
+ int source[1] = { int(i) };
+ vector.append(source, source + 1);
+ QCOMPARE(vector.size(), i);
+ if (vector.capacity() != previousCapacity) {
+ previousCapacity = vector.capacity();
+ ++allocations;
+ }
+ }
+ QCOMPARE(vector.size(), size_t(1 << 20));
+
+ // QArrayData::Grow prevents excessive allocations on a growing container
+ QVERIFY(allocations > 20 / 2);
+ QVERIFY(allocations < 20 * 2);
+
+ for (size_t i = 0; i < (1 << 20); ++i)
+ QCOMPARE(const_(vector).at(i), int(i + 1));
+}
+
+QTEST_APPLESS_MAIN(tst_QArrayData)
+#include "tst_qarraydata.moc"
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
index 5e53683abd..63900b0c55 100644
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
@@ -91,8 +91,14 @@ private slots:
void chop_data();
void chop();
void prepend();
+ void prependExtended_data();
+ void prependExtended();
void append();
+ void appendExtended_data();
+ void appendExtended();
void insert();
+ void insertExtended_data();
+ void insertExtended();
void remove_data();
void remove();
void replace_data();
@@ -130,11 +136,44 @@ private slots:
void byteRefDetaching() const;
void reserve();
+ void reserveExtended_data();
+ void reserveExtended();
void movablity_data();
void movablity();
void literals();
};
+struct StaticByteArrays {
+ struct Standard {
+ QByteArrayData data;
+ const char string[8];
+ } standard;
+ struct NotNullTerminated {
+ QByteArrayData data;
+ const char string[8];
+ } notNullTerminated;
+ struct Shifted {
+ QByteArrayData data;
+ const char dummy; // added to change offset of string
+ const char string[8];
+ } shifted;
+ struct ShiftedNotNullTerminated {
+ QByteArrayData data;
+ const char dummy; // added to change offset of string
+ const char string[8];
+ } shiftedNotNullTerminated;
+
+} statics = {{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) }, "data"}
+ ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) }, "dataBAD"}
+ ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) + sizeof(char) }, 0, "data"}
+ ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) + sizeof(char) }, 0, "dataBAD"}
+ };
+
+static const QStaticByteArrayData<1> &staticStandard = reinterpret_cast<QStaticByteArrayData<1> &>(statics.standard);
+static const QStaticByteArrayData<1> &staticNotNullTerminated = reinterpret_cast<QStaticByteArrayData<1> &>(statics.notNullTerminated);
+static const QStaticByteArrayData<1> &staticShifted = reinterpret_cast<QStaticByteArrayData<1> &>(statics.shifted);
+static const QStaticByteArrayData<1> &staticShiftedNotNullTerminated = reinterpret_cast<QStaticByteArrayData<1> &>(statics.shiftedNotNullTerminated);
+
tst_QByteArray::tst_QByteArray()
{
qRegisterMetaType<qulonglong>("qulonglong");
@@ -701,6 +740,35 @@ void tst_QByteArray::prepend()
QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8));
}
+void tst_QByteArray::prependExtended_data()
+{
+ QTest::addColumn<QByteArray>("array");
+ QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data"));
+ QTest::newRow("standard") << QByteArray(staticStandard);
+ QTest::newRow("shifted") << QByteArray(staticShifted);
+ QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated);
+ QTest::newRow("shiftedNotNullTerminated") << QByteArray(staticShiftedNotNullTerminated);
+ QTest::newRow("non static data") << QByteArray("data");
+ QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4);
+ QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4);
+}
+
+void tst_QByteArray::prependExtended()
+{
+ QFETCH(QByteArray, array);
+
+ QCOMPARE(QByteArray().prepend(array), QByteArray("data"));
+ QCOMPARE(QByteArray("").prepend(array), QByteArray("data"));
+
+ QCOMPARE(array.prepend((char*)0), QByteArray("data"));
+ QCOMPARE(array.prepend(QByteArray()), QByteArray("data"));
+ QCOMPARE(array.prepend("1"), QByteArray("1data"));
+ QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data"));
+ QCOMPARE(array.prepend('3'), QByteArray("321data"));
+ QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 321data", 9));
+ QCOMPARE(array.size(), 9);
+}
+
void tst_QByteArray::append()
{
QByteArray ba("foo");
@@ -714,6 +782,28 @@ void tst_QByteArray::append()
QCOMPARE(ba.size(), 7);
}
+void tst_QByteArray::appendExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::appendExtended()
+{
+ QFETCH(QByteArray, array);
+
+ QCOMPARE(QByteArray().append(array), QByteArray("data"));
+ QCOMPARE(QByteArray("").append(array), QByteArray("data"));
+
+ QCOMPARE(array.append((char*)0), QByteArray("data"));
+ QCOMPARE(array.append(QByteArray()), QByteArray("data"));
+ QCOMPARE(array.append("1"), QByteArray("data1"));
+ QCOMPARE(array.append(QByteArray("2")), QByteArray("data12"));
+ QCOMPARE(array.append('3'), QByteArray("data123"));
+ QCOMPARE(array.append("\0"), QByteArray("data123"));
+ QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123\0", 8));
+ QCOMPARE(array.size(), 8);
+}
+
void tst_QByteArray::insert()
{
QByteArray ba("Meal");
@@ -736,6 +826,18 @@ void tst_QByteArray::insert()
QCOMPARE(ba.size(), 5);
}
+void tst_QByteArray::insertExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::insertExtended()
+{
+ QFETCH(QByteArray, array);
+ QCOMPARE(array.insert(1, "i"), QByteArray("diata"));
+ QCOMPARE(array.size(), 5);
+}
+
void tst_QByteArray::remove_data()
{
QTest::addColumn<QByteArray>("src");
@@ -1078,18 +1180,25 @@ void tst_QByteArray::toULongLong()
// global function defined in qbytearray.cpp
void tst_QByteArray::qAllocMore()
{
- static const int t[] = {
- INT_MIN, INT_MIN + 1, -1234567, -66000, -1025,
- -3, -1, 0, +1, +3, +1025, +66000, +1234567, INT_MAX - 1, INT_MAX,
- INT_MAX/3
- };
- static const int N = sizeof(t)/sizeof(t[0]);
-
- // make sure qAllocMore() doesn't loop infinitely on any input
- for (int i = 0; i < N; ++i) {
- for (int j = 0; j < N; ++j) {
- ::qAllocMore(t[i], t[j]);
- }
+ using QT_PREPEND_NAMESPACE(qAllocMore);
+
+ // Not very important, but please behave :-)
+ QVERIFY(qAllocMore(0, 0) >= 0);
+
+ for (int i = 1; i < 1 << 8; i <<= 1)
+ QVERIFY(qAllocMore(i, 0) >= i);
+
+ for (int i = 1 << 8; i < 1 << 30; i <<= 1) {
+ const int alloc = qAllocMore(i, 0);
+
+ QVERIFY(alloc >= i);
+ QCOMPARE(qAllocMore(i - 8, 8), alloc - 8);
+ QCOMPARE(qAllocMore(i - 16, 16), alloc - 16);
+ QCOMPARE(qAllocMore(i - 24, 24), alloc - 24);
+ QCOMPARE(qAllocMore(i - 32, 32), alloc - 32);
+
+ QVERIFY(qAllocMore(i - 1, 0) >= i - 1);
+ QVERIFY(qAllocMore(i + 1, 0) >= i + 1);
}
}
@@ -1449,6 +1558,23 @@ void tst_QByteArray::repeated_data() const
<< QByteArray(("abc"))
<< QByteArray(("abcabcabcabc"))
<< 4;
+
+ QTest::newRow("static not null terminated")
+ << QByteArray(staticNotNullTerminated)
+ << QByteArray("datadatadatadata")
+ << 4;
+ QTest::newRow("static standard")
+ << QByteArray(staticStandard)
+ << QByteArray("datadatadatadata")
+ << 4;
+ QTest::newRow("static shifted not null terminated")
+ << QByteArray(staticShiftedNotNullTerminated)
+ << QByteArray("datadatadatadata")
+ << 4;
+ QTest::newRow("static shifted")
+ << QByteArray(staticShifted)
+ << QByteArray("datadatadatadata")
+ << 4;
}
void tst_QByteArray::byteRefDetaching() const
@@ -1501,6 +1627,22 @@ void tst_QByteArray::reserve()
nil2.reserve(0);
}
+void tst_QByteArray::reserveExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::reserveExtended()
+{
+ QFETCH(QByteArray, array);
+ array.reserve(1024);
+ QVERIFY(array.capacity() == 1024);
+ QCOMPARE(array, QByteArray("data"));
+ array.squeeze();
+ QCOMPARE(array, QByteArray("data"));
+ QCOMPARE(array.capacity(), array.size());
+}
+
void tst_QByteArray::movablity_data()
{
QTest::addColumn<QByteArray>("array");
@@ -1511,6 +1653,8 @@ void tst_QByteArray::movablity_data()
QTest::newRow("empty") << QByteArray("");
QTest::newRow("null") << QByteArray();
QTest::newRow("sss") << QByteArray(3, 's');
+
+ prependExtended_data();
}
void tst_QByteArray::movablity()
@@ -1587,8 +1731,8 @@ void tst_QByteArray::literals()
QVERIFY(str.length() == 4);
QVERIFY(str == "abcd");
- QVERIFY(str.data_ptr()->ref == -1);
- QVERIFY(str.data_ptr()->offset == 0);
+ QVERIFY(str.data_ptr()->ref.isStatic());
+ QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData));
const char *s = str.constData();
QByteArray str2 = str;
diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
index 934130d3ee..c883c1c5f6 100644
--- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp
+++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
@@ -48,6 +48,9 @@ class tst_QList : public QObject
Q_OBJECT
private slots:
+ void init();
+ void cleanup();
+
void length() const;
void lengthSignature() const;
void append() const;
@@ -84,8 +87,100 @@ private slots:
void initializeList() const;
void const_shared_null() const;
+ void setSharable1_data() const;
+ void setSharable1() const;
+ void setSharable2_data() const;
+ void setSharable2() const;
+
+private:
+ int dummyForGuard;
+};
+
+struct Complex
+{
+ Complex(int val)
+ : value(val)
+ , checkSum(this)
+ {
+ ++liveCount;
+ }
+
+ Complex(Complex const &other)
+ : value(other.value)
+ , checkSum(this)
+ {
+ ++liveCount;
+ }
+
+ Complex &operator=(Complex const &other)
+ {
+ check(); other.check();
+
+ value = other.value;
+ return *this;
+ }
+
+ ~Complex()
+ {
+ --liveCount;
+ check();
+ }
+
+ operator int() const { return value; }
+
+ bool operator==(Complex const &other) const
+ {
+ check(); other.check();
+ return value == other.value;
+ }
+
+ bool check() const
+ {
+ if (this != checkSum) {
+ ++errorCount;
+ return false;
+ }
+ return true;
+ }
+
+ 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; }
+
+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();
+}
+
+void tst_QList::cleanup()
+{
+ QCOMPARE(Complex::errors(), 0);
+
+ reinterpret_cast<Complex::Guard *>(&dummyForGuard)->~Guard();
+ QCOMPARE(Complex::errors(), 0);
+}
+
void tst_QList::length() const
{
/* Empty list. */
@@ -690,5 +785,82 @@ void tst_QList::const_shared_null() const
QVERIFY(!list2.isDetached());
}
+Q_DECLARE_METATYPE(QList<int>);
+Q_DECLARE_METATYPE(QList<Complex>);
+
+template <class T>
+void generateSetSharableData()
+{
+ QTest::addColumn<QList<T> >("list");
+ QTest::addColumn<int>("size");
+
+ QTest::newRow("null") << QList<T>() << 0;
+ QTest::newRow("non-empty") << (QList<T>() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5;
+}
+
+template <class T>
+void runSetSharableTest()
+{
+ QFETCH(QList<T>, list);
+ QFETCH(int, size);
+
+ QVERIFY(!list.isDetached()); // Shared with QTest
+
+ list.setSharable(true);
+
+ QCOMPARE(list.size(), size);
+
+ {
+ QList<T> copy(list);
+ QVERIFY(!copy.isDetached());
+ QVERIFY(copy.isSharedWith(list));
+ }
+
+ list.setSharable(false);
+ QVERIFY(list.isDetached() || list.isSharedWith(QList<T>()));
+
+ {
+ QList<T> copy(list);
+
+ QVERIFY(copy.isDetached() || copy.isSharedWith(QList<T>()));
+ QCOMPARE(copy.size(), size);
+ QCOMPARE(copy, list);
+ }
+
+ list.setSharable(true);
+
+ {
+ QList<T> copy(list);
+
+ QVERIFY(!copy.isDetached());
+ QVERIFY(copy.isSharedWith(list));
+ }
+
+ for (int i = 0; i < list.size(); ++i)
+ QCOMPARE(int(list[i]), i);
+
+ QCOMPARE(list.size(), size);
+}
+
+void tst_QList::setSharable1_data() const
+{
+ generateSetSharableData<int>();
+}
+
+void tst_QList::setSharable2_data() const
+{
+ generateSetSharableData<Complex>();
+}
+
+void tst_QList::setSharable1() const
+{
+ runSetSharableTest<int>();
+}
+
+void tst_QList::setSharable2() const
+{
+ runSetSharableTest<Complex>();
+}
+
QTEST_APPLESS_MAIN(tst_QList)
#include "tst_qlist.moc"
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index f9de2f0c05..7e12e42107 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -1751,7 +1751,7 @@ void tst_QLocale::dayName_data()
QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat;
QTest::newRow("ru_RU long") << QString("ru_RU") << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320\265\321\201\320\265\320\275\321\214\320\265") << 7 << QLocale::LongFormat;
- QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\222\321\201") << 7 << QLocale::ShortFormat;
+ QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
QTest::newRow("ru_RU narrow") << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat;
}
diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
index 7d0ef7d7e4..ac75c0e5bd 100644
--- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp
+++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
@@ -41,10 +41,10 @@
#define QT_STRICT_ITERATORS
+#include <qmap.h>
#include <QtTest/QtTest>
#include <QDebug>
-#include <qmap.h>
class tst_QMap : public QObject
{
@@ -74,6 +74,11 @@ private slots:
void qmultimap_specific();
void const_shared_null();
+
+ void equal_range();
+ void setSharable();
+
+ void insert();
};
typedef QMap<QString, QString> StringMap;
@@ -105,6 +110,11 @@ int MyClass::count = 0;
typedef QMap<QString, MyClass> MyMap;
+QDebug operator << (QDebug d, const MyClass &c) {
+ d << c.str;
+ return d;
+}
+
void tst_QMap::init()
{
MyClass::count = 0;
@@ -152,6 +162,7 @@ void tst_QMap::count()
map.insert( "Paul", MyClass("Tvete 6") );
QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.count("Paul"), 1 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
@@ -519,6 +530,7 @@ void tst_QMap::find()
for(i = 3; i < 10; ++i) {
compareString = testString.arg(i);
map1.insertMulti(4, compareString);
+ QCOMPARE(map1.count(4), i - 2);
}
QMap<int, QString>::const_iterator it=map1.constFind(4);
@@ -588,6 +600,33 @@ void tst_QMap::lowerUpperBound()
QCOMPARE(map1.lowerBound(2).key(), 5); // returns iterator to (5, "five")
QCOMPARE(map1.lowerBound(10).key(), 10); // returns iterator to (10, "ten")
QVERIFY(map1.lowerBound(999) == map1.end()); // returns end()
+
+ map1.insert(3, "three");
+ map1.insert(7, "seven");
+ map1.insertMulti(7, "seven_2");
+
+ QCOMPARE(map1.upperBound(0).key(), 1);
+ QCOMPARE(map1.upperBound(1).key(), 3);
+ QCOMPARE(map1.upperBound(2).key(), 3);
+ QCOMPARE(map1.upperBound(3).key(), 5);
+ QCOMPARE(map1.upperBound(7).key(), 10);
+ QVERIFY(map1.upperBound(10) == map1.end());
+ QVERIFY(map1.upperBound(999) == map1.end());
+
+ QCOMPARE(map1.lowerBound(0).key(), 1);
+ QCOMPARE(map1.lowerBound(1).key(), 1);
+ QCOMPARE(map1.lowerBound(2).key(), 3);
+ QCOMPARE(map1.lowerBound(3).key(), 3);
+ QCOMPARE(map1.lowerBound(4).key(), 5);
+ QCOMPARE(map1.lowerBound(5).key(), 5);
+ QCOMPARE(map1.lowerBound(6).key(), 7);
+ QCOMPARE(map1.lowerBound(7).key(), 7);
+ QCOMPARE(map1.lowerBound(6).value(), QString("seven_2"));
+ QCOMPARE(map1.lowerBound(7).value(), QString("seven_2"));
+ QCOMPARE((++map1.lowerBound(6)).value(), QString("seven"));
+ QCOMPARE((++map1.lowerBound(7)).value(), QString("seven"));
+ QCOMPARE(map1.lowerBound(10).key(), 10);
+ QVERIFY(map1.lowerBound(999) == map1.end());
}
void tst_QMap::mergeCompare()
@@ -846,10 +885,129 @@ void tst_QMap::const_shared_null()
QMap<int, QString> map2;
map2.setSharable(true);
QVERIFY(!map2.isDetached());
+}
+
+void tst_QMap::equal_range()
+{
+ QMap<int, QString> map;
+
+ QPair<QMap<int, QString>::iterator, QMap<int, QString>::iterator> result = map.equal_range(0);
+ QCOMPARE(result.first, map.end());
+ QCOMPARE(result.second, map.end());
+
+ map.insert(1, "one");
+
+ result = map.equal_range(0);
+ QCOMPARE(result.first, map.find(1));
+ QCOMPARE(result.second, map.find(1));
- QMap<int, QString> map3;
- map3.setInsertInOrder(true);
- map3.setInsertInOrder(false);
+ result = map.equal_range(1);
+ QCOMPARE(result.first, map.find(1));
+ QCOMPARE(result.second, map.end());
+
+ result = map.equal_range(2);
+ QCOMPARE(result.first, map.end());
+ QCOMPARE(result.second, map.end());
+
+ for (int i = -10; i < 10; i += 2)
+ map.insert(i, QString("%1").arg(i));
+
+ result = map.equal_range(0);
+ QCOMPARE(result.first, map.find(0));
+ QCOMPARE(result.second, map.find(1));
+
+ result = map.equal_range(1);
+ QCOMPARE(result.first, map.find(1));
+ QCOMPARE(result.second, map.find(2));
+
+ result = map.equal_range(2);
+ QCOMPARE(result.first, map.find(2));
+ QCOMPARE(result.second, map.find(4));
+
+ map.insertMulti(1, "another one");
+ result = map.equal_range(1);
+ QCOMPARE(result.first, map.find(1));
+ QCOMPARE(result.second, map.find(2));
+
+ QCOMPARE(map.count(1), 2);
+}
+
+template <class T>
+const T &const_(const T &t)
+{
+ return t;
+}
+
+void tst_QMap::setSharable()
+{
+ QMap<int, QString> map;
+
+ map.insert(1, "um");
+ map.insert(2, "dois");
+ map.insert(4, "quatro");
+ map.insert(5, "cinco");
+
+ map.setSharable(true);
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(const_(map)[4], QString("quatro"));
+
+ {
+ QMap<int, QString> copy(map);
+
+ QVERIFY(!map.isDetached());
+ QVERIFY(copy.isSharedWith(map));
+ }
+
+ map.setSharable(false);
+ QVERIFY(map.isDetached());
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(const_(map)[4], QString("quatro"));
+
+ {
+ QMap<int, QString> copy(map);
+
+ QVERIFY(map.isDetached());
+ QVERIFY(copy.isDetached());
+
+ QCOMPARE(copy.size(), 4);
+ QCOMPARE(const_(copy)[4], QString("quatro"));
+
+ QCOMPARE(map, copy);
+ }
+
+ map.setSharable(true);
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(const_(map)[4], QString("quatro"));
+
+ {
+ QMap<int, QString> copy(map);
+
+ QVERIFY(!map.isDetached());
+ QVERIFY(copy.isSharedWith(map));
+ }
+}
+
+void tst_QMap::insert()
+{
+ QMap<QString, float> map;
+ map.insert("cs/key1", 1);
+ map.insert("cs/key2", 2);
+ map.insert("cs/key1", 3);
+ QCOMPARE(map.count(), 2);
+
+ QMap<int, int> intMap;
+ for (int i = 0; i < 1000; ++i) {
+ intMap.insert(i, i);
+ }
+
+ QCOMPARE(intMap.size(), 1000);
+
+ for (int i = 0; i < 1000; ++i) {
+ QCOMPARE(intMap.value(i), i);
+ intMap.insert(i, -1);
+ QCOMPARE(intMap.size(), 1000);
+ QCOMPARE(intMap.value(i), -1);
+ }
}
QTEST_APPLESS_MAIN(tst_QMap)
diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
index 5b697a3509..f8b9abb359 100644
--- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
@@ -114,15 +114,19 @@ public:
}
};
-template <typename Base>
-class RefCountHack: public Base
+template<typename T> static inline
+QtSharedPointer::ExternalRefCountData *refCountData(const QtSharedPointer::ExternalRefCount<T> &b)
{
-public:
- using Base::d;
-};
-template<typename Base> static inline
-QtSharedPointer::ExternalRefCountData *refCountData(const Base &b)
-{ return static_cast<const RefCountHack<Base> *>(&b)->d; }
+ // access d-pointer:
+ struct Dummy {
+ void* value;
+ QtSharedPointer::ExternalRefCountData* data;
+ };
+ // sanity checks:
+ Q_STATIC_ASSERT(sizeof(QtSharedPointer::ExternalRefCount<T>) == sizeof(Dummy));
+ Q_ASSERT(static_cast<const Dummy*>(static_cast<const void*>(&b))->value == b.data());
+ return static_cast<const Dummy*>(static_cast<const void*>(&b))->data;
+}
class Data
{
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index f007d44262..7d4a9b5aba 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -41,6 +41,7 @@
#include <QtTest/QtTest>
#include <qregexp.h>
+#include <qregularexpression.h>
#include <qtextcodec.h>
#include <qtextstream.h>
#include <qstringlist.h>
@@ -194,6 +195,7 @@ private slots:
void localeAwareCompare();
void split_data();
void split();
+ void split_regexp_data();
void split_regexp();
void fromUtf16_data();
void fromUtf16();
@@ -1080,6 +1082,17 @@ void tst_QString::indexOf()
QCOMPARE( rx2.matchedLength(), -1 );
}
+ {
+ QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
+ if (!bcs)
+ options |= QRegularExpression::CaseInsensitiveOption;
+
+ QRegularExpression re(QRegularExpression::escape(needle), options);
+ QEXPECT_FAIL("data58", "QRegularExpression does not support case folding", Continue);
+ QEXPECT_FAIL("data59", "QRegularExpression does not support case folding", Continue);
+ QCOMPARE( haystack.indexOf(re, startpos), resultpos );
+ }
+
if (cs == Qt::CaseSensitive) {
QCOMPARE( haystack.indexOf(needle, startpos), resultpos );
QCOMPARE( haystack.indexOf(ref, startpos), resultpos );
@@ -1267,6 +1280,15 @@ void tst_QString::lastIndexOf()
QCOMPARE(rx1.matchedLength(), -1);
QCOMPARE(rx2.matchedLength(), -1);
}
+
+ {
+ QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
+ if (!caseSensitive)
+ options |= QRegularExpression::CaseInsensitiveOption;
+
+ QRegularExpression re(QRegularExpression::escape(needle), options);
+ QCOMPARE(haystack.lastIndexOf(re, from), expected);
+ }
}
if (cs == Qt::CaseSensitive) {
@@ -1302,6 +1324,9 @@ void tst_QString::count()
QCOMPARE(a.count( "", Qt::CaseInsensitive), 16);
QCOMPARE(a.count(QRegExp("[FG][HI]")),1);
QCOMPARE(a.count(QRegExp("[G][HE]")),2);
+ QCOMPARE(a.count(QRegularExpression("[FG][HI]")), 1);
+ QCOMPARE(a.count(QRegularExpression("[G][HE]")), 2);
+
CREATE_REF(QLatin1String("FG"));
QCOMPARE(a.count(ref),2);
@@ -1327,6 +1352,8 @@ void tst_QString::contains()
QVERIFY(a.contains( "", Qt::CaseInsensitive));
QVERIFY(a.contains(QRegExp("[FG][HI]")));
QVERIFY(a.contains(QRegExp("[G][HE]")));
+ QVERIFY(a.contains(QRegularExpression("[FG][HI]")));
+ QVERIFY(a.contains(QRegularExpression("[G][HE]")));
CREATE_REF(QLatin1String("FG"));
QVERIFY(a.contains(ref));
@@ -1421,16 +1448,69 @@ void tst_QString::mid()
QVERIFY(a.mid(9999).isNull());
QVERIFY(a.mid(9999,1).isNull());
+ QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
+ QVERIFY(a.mid(-100, 6).isEmpty());
+ QVERIFY(a.mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(a.mid(INT_MIN, -1), a);
+ QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
+ QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
+ QVERIFY(a.mid(INT_MAX).isNull());
+ QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(a.mid(-5, INT_MAX), a);
+ QCOMPARE(a.mid(-1, INT_MAX), a);
+ QCOMPARE(a.mid(0, INT_MAX), a);
+ QCOMPARE(a.mid(1, INT_MAX), QString("BCDEFGHIEfGEFG"));
+ QCOMPARE(a.mid(5, INT_MAX), QString("FGHIEfGEFG"));
+ QVERIFY(a.mid(20, INT_MAX).isNull());
+ QCOMPARE(a.mid(-1, -1), a);
+
QString n;
QVERIFY(n.mid(3,3).isNull());
QVERIFY(n.mid(0,0).isNull());
QVERIFY(n.mid(9999,0).isNull());
QVERIFY(n.mid(9999,1).isNull());
+ QVERIFY(n.mid(-1, 6).isNull());
+ QVERIFY(n.mid(-100, 6).isNull());
+ QVERIFY(n.mid(INT_MIN, 0).isNull());
+ QVERIFY(n.mid(INT_MIN, -1).isNull());
+ QVERIFY(n.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
+ QVERIFY(n.mid(-5, INT_MAX).isNull());
+ QVERIFY(n.mid(-1, INT_MAX).isNull());
+ QVERIFY(n.mid(0, INT_MAX).isNull());
+ QVERIFY(n.mid(1, INT_MAX).isNull());
+ QVERIFY(n.mid(5, INT_MAX).isNull());
+ QVERIFY(n.mid(20, INT_MAX).isNull());
+ QVERIFY(n.mid(-1, -1).isNull());
+
QString x = "Nine pineapples";
QCOMPARE(x.mid(5, 4), QString("pine"));
QCOMPARE(x.mid(5), QString("pineapples"));
+ QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
+ QVERIFY(x.mid(-100, 6).isEmpty());
+ QVERIFY(x.mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(x.mid(INT_MIN, -1), x);
+ QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
+ QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x);
+ QVERIFY(x.mid(INT_MAX).isNull());
+ QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(x.mid(-5, INT_MAX), x);
+ QCOMPARE(x.mid(-1, INT_MAX), x);
+ QCOMPARE(x.mid(0, INT_MAX), x);
+ QCOMPARE(x.mid(1, INT_MAX), QString("ine pineapples"));
+ QCOMPARE(x.mid(5, INT_MAX), QString("pineapples"));
+ QVERIFY(x.mid(20, INT_MAX).isNull());
+ QCOMPARE(x.mid(-1, -1), x);
}
void tst_QString::midRef()
@@ -1447,16 +1527,69 @@ void tst_QString::midRef()
QVERIFY(a.midRef(9999).toString().isEmpty());
QVERIFY(a.midRef(9999,1).toString().isEmpty());
+ QCOMPARE(a.midRef(-1, 6), a.midRef(0, 5));
+ QVERIFY(a.midRef(-100, 6).isEmpty());
+ QVERIFY(a.midRef(INT_MIN, 0).isEmpty());
+ QCOMPARE(a.midRef(INT_MIN, -1).toString(), a);
+ QVERIFY(a.midRef(INT_MIN, INT_MAX).isNull());
+ QVERIFY(a.midRef(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(a.midRef(INT_MIN + 2, INT_MAX), a.leftRef(1));
+ QCOMPARE(a.midRef(INT_MIN + a.size() + 1, INT_MAX).toString(), a);
+ QVERIFY(a.midRef(INT_MAX).isNull());
+ QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(a.midRef(-5, INT_MAX).toString(), a);
+ QCOMPARE(a.midRef(-1, INT_MAX).toString(), a);
+ QCOMPARE(a.midRef(0, INT_MAX).toString(), a);
+ QCOMPARE(a.midRef(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG"));
+ QCOMPARE(a.midRef(5, INT_MAX).toString(), QString("FGHIEfGEFG"));
+ QVERIFY(a.midRef(20, INT_MAX).isNull());
+ QCOMPARE(a.midRef(-1, -1).toString(), a);
+
QString n;
QVERIFY(n.midRef(3,3).toString().isEmpty());
QVERIFY(n.midRef(0,0).toString().isEmpty());
QVERIFY(n.midRef(9999,0).toString().isEmpty());
QVERIFY(n.midRef(9999,1).toString().isEmpty());
+ QVERIFY(n.midRef(-1, 6).isNull());
+ QVERIFY(n.midRef(-100, 6).isNull());
+ QVERIFY(n.midRef(INT_MIN, 0).isNull());
+ QVERIFY(n.midRef(INT_MIN, -1).isNull());
+ QVERIFY(n.midRef(INT_MIN, INT_MAX).isNull());
+ QVERIFY(n.midRef(INT_MIN + 1, INT_MAX).isNull());
+ QVERIFY(n.midRef(INT_MIN + 2, INT_MAX).isNull());
+ QVERIFY(n.midRef(INT_MIN + n.size() + 1, INT_MAX).isNull());
+ QVERIFY(n.midRef(INT_MAX).isNull());
+ QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull());
+ QVERIFY(n.midRef(-5, INT_MAX).isNull());
+ QVERIFY(n.midRef(-1, INT_MAX).isNull());
+ QVERIFY(n.midRef(0, INT_MAX).isNull());
+ QVERIFY(n.midRef(1, INT_MAX).isNull());
+ QVERIFY(n.midRef(5, INT_MAX).isNull());
+ QVERIFY(n.midRef(20, INT_MAX).isNull());
+ QVERIFY(n.midRef(-1, -1).isNull());
+
QString x = "Nine pineapples";
QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
+ QCOMPARE(x.midRef(-1, 6), x.midRef(0, 5));
+ QVERIFY(x.midRef(-100, 6).isEmpty());
+ QVERIFY(x.midRef(INT_MIN, 0).isEmpty());
+ QCOMPARE(x.midRef(INT_MIN, -1).toString(), x);
+ QVERIFY(x.midRef(INT_MIN, INT_MAX).isNull());
+ QVERIFY(x.midRef(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(x.midRef(INT_MIN + 2, INT_MAX), x.leftRef(1));
+ QCOMPARE(x.midRef(INT_MIN + x.size() + 1, INT_MAX).toString(), x);
+ QVERIFY(x.midRef(INT_MAX).isNull());
+ QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(x.midRef(-5, INT_MAX).toString(), x);
+ QCOMPARE(x.midRef(-1, INT_MAX).toString(), x);
+ QCOMPARE(x.midRef(0, INT_MAX).toString(), x);
+ QCOMPARE(x.midRef(1, INT_MAX).toString(), QString("ine pineapples"));
+ QCOMPARE(x.midRef(5, INT_MAX).toString(), QString("pineapples"));
+ QVERIFY(x.midRef(20, INT_MAX).isNull());
+ QCOMPARE(x.midRef(-1, -1).toString(), x);
}
void tst_QString::stringRef()
@@ -2066,6 +2199,9 @@ void tst_QString::replace_regexp()
QString s2 = string;
s2.replace( QRegExp(regexp), after );
QTEST( s2, "result" );
+ s2 = string;
+ s2.replace( QRegularExpression(regexp), after );
+ QTEST( s2, "result" );
}
void tst_QString::remove_uint_uint()
@@ -2130,8 +2266,13 @@ void tst_QString::remove_regexp()
QFETCH( QString, after );
if ( after.length() == 0 ) {
- string.remove( QRegExp(regexp) );
- QTEST( string, "result" );
+ QString s2 = string;
+ s2.remove( QRegExp(regexp) );
+ QTEST( s2, "result" );
+
+ s2 = string;
+ s2.remove( QRegularExpression(regexp) );
+ QTEST( s2, "result" );
} else {
QCOMPARE( 0, 0 ); // shut QtTest
}
@@ -3872,8 +4013,12 @@ void tst_QString::section()
QFETCH( bool, regexp );
if (regexp) {
QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString );
+ QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString );
} else {
QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString );
+ QCOMPARE( wholeString.section( QRegExp(QRegExp::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
+ QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
+
}
}
@@ -4394,6 +4539,7 @@ void tst_QString::split()
QFETCH(QStringList, result);
QRegExp rx = QRegExp(QRegExp::escape(sep));
+ QRegularExpression re(QRegularExpression::escape(sep));
QStringList list;
@@ -4401,6 +4547,8 @@ void tst_QString::split()
QVERIFY(list == result);
list = str.split(rx);
QVERIFY(list == result);
+ list = str.split(re);
+ QVERIFY(list == result);
if (sep.size() == 1) {
list = str.split(sep.at(0));
QVERIFY(list == result);
@@ -4410,6 +4558,8 @@ void tst_QString::split()
QVERIFY(list == result);
list = str.split(rx, QString::KeepEmptyParts);
QVERIFY(list == result);
+ list = str.split(re, QString::KeepEmptyParts);
+ QVERIFY(list == result);
if (sep.size() == 1) {
list = str.split(sep.at(0), QString::KeepEmptyParts);
QVERIFY(list == result);
@@ -4420,39 +4570,51 @@ void tst_QString::split()
QVERIFY(list == result);
list = str.split(rx, QString::SkipEmptyParts);
QVERIFY(list == result);
+ list = str.split(re, QString::SkipEmptyParts);
+ QVERIFY(list == result);
if (sep.size() == 1) {
list = str.split(sep.at(0), QString::SkipEmptyParts);
QVERIFY(list == result);
}
}
+void tst_QString::split_regexp_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("result");
+
+ QTest::newRow("data01") << "Some text\n\twith strange whitespace."
+ << "\\s+"
+ << (QStringList() << "Some" << "text" << "with" << "strange" << "whitespace." );
+
+ QTest::newRow("data02") << "This time, a normal English sentence."
+ << "\\W+"
+ << (QStringList() << "This" << "time" << "a" << "normal" << "English" << "sentence" << "");
+
+ QTest::newRow("data03") << "Now: this sentence fragment."
+ << "\\b"
+ << (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".");
+}
+
void tst_QString::split_regexp()
{
- QString str1 = "Some text\n\twith strange whitespace.";
- QStringList list1 = str1.split(QRegExp("\\s+"));
- QStringList result1;
- result1 << "Some" << "text" << "with" << "strange" << "whitespace.";
- QVERIFY(list1 == result1);
- list1 = str1.split(QRegExp("\\s"), QString::SkipEmptyParts);
- QVERIFY(list1 == result1);
-
- QString str2 = "This time, a normal English sentence.";
- QStringList list2 = str2.split(QRegExp("\\W+"));
- QStringList result2;
- result2 << "This" << "time" << "a" << "normal" << "English" << "sentence" << "";
- QVERIFY(list2 == result2);
- list2 = str2.split(QRegExp("\\W"), QString::SkipEmptyParts);
- result2.removeAll(QString());
- QVERIFY(list2 == result2);
-
- QString str3 = "Now: this sentence fragment.";
- QStringList list3 = str3.split(QRegExp("\\b"));
- QStringList result3;
- result3 << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".";
- QVERIFY(list3 == result3);
- list3 = str3.split(QRegExp("\\b"), QString::SkipEmptyParts);
- result3.removeAll(QString());
- QVERIFY(list3 == result3);
+ QFETCH(QString, string);
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, result);
+
+ QStringList list;
+ list = string.split(QRegExp(pattern));
+ QCOMPARE(list, result);
+ list = string.split(QRegularExpression(pattern));
+ QCOMPARE(list, result);
+
+ result.removeAll(QString());
+
+ list = string.split(QRegExp(pattern), QString::SkipEmptyParts);
+ QCOMPARE(list, result);
+ list = string.split(QRegularExpression(pattern), QString::SkipEmptyParts);
+ QCOMPARE(list, result);
}
void tst_QString::fromUtf16_data()
@@ -5056,8 +5218,8 @@ void tst_QString::literals()
QVERIFY(str.length() == 4);
QVERIFY(str == QLatin1String("abcd"));
- QVERIFY(str.data_ptr()->ref == -1);
- QVERIFY(str.data_ptr()->offset == 0);
+ QVERIFY(str.data_ptr()->ref.isStatic());
+ QVERIFY(str.data_ptr()->offset == sizeof(QStringData));
const QChar *s = str.constData();
QString str2 = str;
diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
index 6066f7c8e0..d02e649bdf 100644
--- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
+++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
@@ -41,6 +41,7 @@
#include <QtTest/QtTest>
#include <qregexp.h>
+#include <qregularexpression.h>
#include <qstringlist.h>
class tst_QStringList : public QObject
@@ -72,18 +73,37 @@ void tst_QStringList::indexOf_regExp()
{
QStringList list;
list << "harald" << "trond" << "vohi" << "harald";
+ {
+ QRegExp re(".*o.*");
- QRegExp re(".*o.*");
+ QCOMPARE(list.indexOf(re), 1);
+ QCOMPARE(list.indexOf(re, 2), 2);
+ QCOMPARE(list.indexOf(re, 3), -1);
- QCOMPARE(list.indexOf(re), 1);
- QCOMPARE(list.indexOf(re, 2), 2);
- QCOMPARE(list.indexOf(re, 3), -1);
+ QCOMPARE(list.indexOf(QRegExp(".*x.*")), -1);
+ QCOMPARE(list.indexOf(re, -1), -1);
+ QCOMPARE(list.indexOf(re, -3), 1);
+ QCOMPARE(list.indexOf(re, -9999), 1);
+ QCOMPARE(list.indexOf(re, 9999), -1);
- QCOMPARE(list.indexOf(QRegExp(".*x.*")), -1);
- QCOMPARE(list.indexOf(re, -1), -1);
- QCOMPARE(list.indexOf(re, -3), 1);
- QCOMPARE(list.indexOf(re, -9999), 1);
- QCOMPARE(list.indexOf(re, 9999), -1);
+ QCOMPARE(list.indexOf(QRegExp("[aeiou]")), -1);
+ }
+
+ {
+ QRegularExpression re(".*o.*");
+
+ QCOMPARE(list.indexOf(re), 1);
+ QCOMPARE(list.indexOf(re, 2), 2);
+ QCOMPARE(list.indexOf(re, 3), -1);
+
+ QCOMPARE(list.indexOf(QRegularExpression(".*x.*")), -1);
+ QCOMPARE(list.indexOf(re, -1), -1);
+ QCOMPARE(list.indexOf(re, -3), 1);
+ QCOMPARE(list.indexOf(re, -9999), 1);
+ QCOMPARE(list.indexOf(re, 9999), -1);
+
+ QCOMPARE(list.indexOf(QRegularExpression("[aeiou]")), -1);
+ }
}
void tst_QStringList::lastIndexOf_regExp()
@@ -91,17 +111,39 @@ void tst_QStringList::lastIndexOf_regExp()
QStringList list;
list << "harald" << "trond" << "vohi" << "harald";
- QRegExp re(".*o.*");
+ {
+ QRegExp re(".*o.*");
+
+ QCOMPARE(list.lastIndexOf(re), 2);
+ QCOMPARE(list.lastIndexOf(re, 2), 2);
+ QCOMPARE(list.lastIndexOf(re, 1), 1);
+
+ QCOMPARE(list.lastIndexOf(QRegExp(".*x.*")), -1);
+ QCOMPARE(list.lastIndexOf(re, -1), 2);
+ QCOMPARE(list.lastIndexOf(re, -3), 1);
+ QCOMPARE(list.lastIndexOf(re, -9999), -1);
+ QCOMPARE(list.lastIndexOf(re, 9999), 2);
+
+ QCOMPARE(list.lastIndexOf(QRegExp("[aeiou]")), -1);
+ }
+
+ {
+ QRegularExpression re(".*o.*");
+
+ QCOMPARE(list.lastIndexOf(re), 2);
+ QCOMPARE(list.lastIndexOf(re, 2), 2);
+ QCOMPARE(list.lastIndexOf(re, 1), 1);
+
+ QCOMPARE(list.lastIndexOf(QRegularExpression(".*x.*")), -1);
+ QCOMPARE(list.lastIndexOf(re, -1), 2);
+ QCOMPARE(list.lastIndexOf(re, -3), 1);
+ QCOMPARE(list.lastIndexOf(re, -9999), -1);
+ QCOMPARE(list.lastIndexOf(re, 9999), 2);
+
+ QCOMPARE(list.lastIndexOf(QRegularExpression("[aeiou]")), -1);
+ }
- QCOMPARE(list.lastIndexOf(re), 2);
- QCOMPARE(list.lastIndexOf(re, 2), 2);
- QCOMPARE(list.lastIndexOf(re, 1), 1);
- QCOMPARE(list.lastIndexOf(QRegExp(".*x.*")), -1);
- QCOMPARE(list.lastIndexOf(re, -1), 2);
- QCOMPARE(list.lastIndexOf(re, -3), 1);
- QCOMPARE(list.lastIndexOf(re, -9999), -1);
- QCOMPARE(list.lastIndexOf(re, 9999), 2);
}
void tst_QStringList::indexOf()
@@ -149,6 +191,12 @@ void tst_QStringList::filter()
list3 = list3.filter( QRegExp("[i]ll") );
list4 << "Bill Gates" << "Bill Clinton";
QCOMPARE( list3, list4 );
+
+ QStringList list5, list6;
+ list5 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
+ list5 = list5.filter( QRegularExpression("[i]ll") );
+ list6 << "Bill Gates" << "Bill Clinton";
+ QCOMPARE( list5, list6 );
}
void tst_QStringList::replaceInStrings()
@@ -170,6 +218,18 @@ void tst_QStringList::replaceInStrings()
list6 << "Bill Clinton" << "Bill Gates";
list5.replaceInStrings( QRegExp("^(.*), (.*)$"), "\\2 \\1" );
QCOMPARE( list5, list6 );
+
+ QStringList list7, list8;
+ list7 << "alpha" << "beta" << "gamma" << "epsilon";
+ list7.replaceInStrings( QRegularExpression("^a"), "o" );
+ list8 << "olpha" << "beta" << "gamma" << "epsilon";
+ QCOMPARE( list7, list8 );
+
+ QStringList list9, list10;
+ list9 << "Bill Clinton" << "Gates, Bill";
+ list10 << "Bill Clinton" << "Bill Gates";
+ list9.replaceInStrings( QRegularExpression("^(.*), (.*)$"), "\\2 \\1" );
+ QCOMPARE( list9, list10 );
}
void tst_QStringList::contains()
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
index c79aee4187..67ca547736 100644
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
@@ -85,6 +85,8 @@ private slots:
void initializeList();
void const_shared_null();
+ void setSharable_data();
+ void setSharable();
};
void tst_QVector::constructors() const
@@ -946,5 +948,97 @@ void tst_QVector::const_shared_null()
QVERIFY(!v2.isDetached());
}
+Q_DECLARE_METATYPE(QVector<int>);
+
+void tst_QVector::setSharable_data()
+{
+ QTest::addColumn<QVector<int> >("vector");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<int>("capacity");
+ QTest::addColumn<bool>("isCapacityReserved");
+
+ QVector<int> null;
+ QVector<int> empty(0, 5);
+ QVector<int> emptyReserved;
+ QVector<int> nonEmpty;
+ QVector<int> nonEmptyReserved;
+
+ emptyReserved.reserve(10);
+ nonEmptyReserved.reserve(15);
+
+ nonEmpty << 0 << 1 << 2 << 3 << 4;
+ nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6;
+
+ QVERIFY(emptyReserved.capacity() >= 10);
+ QVERIFY(nonEmptyReserved.capacity() >= 15);
+
+ QTest::newRow("null") << null << 0 << 0 << false;
+ QTest::newRow("empty") << empty << 0 << 0 << false;
+ QTest::newRow("empty, Reserved") << emptyReserved << 0 << 10 << true;
+ QTest::newRow("non-empty") << nonEmpty << 5 << 0 << false;
+ QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true;
+}
+
+void tst_QVector::setSharable()
+{
+ QFETCH(QVector<int>, vector);
+ QFETCH(int, size);
+ QFETCH(int, capacity);
+ QFETCH(bool, isCapacityReserved);
+
+ QVERIFY(!vector.isDetached()); // Shared with QTest
+
+ vector.setSharable(true);
+
+ QCOMPARE(vector.size(), size);
+ if (isCapacityReserved)
+ QVERIFY2(vector.capacity() >= capacity,
+ qPrintable(QString("Capacity is %1, expected at least %2.")
+ .arg(vector.capacity())
+ .arg(capacity)));
+
+ {
+ QVector<int> copy(vector);
+
+ QVERIFY(!copy.isDetached());
+ QVERIFY(copy.isSharedWith(vector));
+ }
+
+ vector.setSharable(false);
+ QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<int>()));
+
+ {
+ QVector<int> copy(vector);
+
+ QVERIFY(copy.isDetached() || copy.isSharedWith(QVector<int>()));
+ QCOMPARE(copy.size(), size);
+ if (isCapacityReserved)
+ QVERIFY2(copy.capacity() >= capacity,
+ qPrintable(QString("Capacity is %1, expected at least %2.")
+ .arg(vector.capacity())
+ .arg(capacity)));
+ QCOMPARE(copy, vector);
+ }
+
+ vector.setSharable(true);
+
+ {
+ QVector<int> copy(vector);
+
+ QVERIFY(!copy.isDetached());
+ QVERIFY(copy.isSharedWith(vector));
+ }
+
+ for (int i = 0; i < vector.size(); ++i)
+ QCOMPARE(vector[i], i);
+
+ QCOMPARE(vector.size(), size);
+ if (isCapacityReserved)
+ QVERIFY2(vector.capacity() >= capacity,
+ qPrintable(QString("Capacity is %1, expected at least %2.")
+ .arg(vector.capacity())
+ .arg(capacity)));
+}
+
QTEST_APPLESS_MAIN(tst_QVector)
#include "tst_qvector.moc"
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
index d8961559e5..38225e12f7 100644
--- a/tests/auto/corelib/tools/tools.pro
+++ b/tests/auto/corelib/tools/tools.pro
@@ -1,6 +1,7 @@
TEMPLATE=subdirs
SUBDIRS=\
qalgorithms \
+ qarraydata \
qbitarray \
qbytearray \
qbytearraymatcher \