summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qmap/tst_qmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/tools/qmap/tst_qmap.cpp')
-rw-r--r--tests/auto/corelib/tools/qmap/tst_qmap.cpp1243
1 files changed, 1034 insertions, 209 deletions
diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
index 5385471b8b..6950dcf705 100644
--- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp
+++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
@@ -1,34 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qmap.h>
-#include <QtTest/QtTest>
+#include <QTest>
+
#include <QDebug>
+#include <QScopeGuard>
+
+using namespace Qt::StringLiterals;
QT_WARNING_DISABLE_DEPRECATED
@@ -47,6 +26,7 @@ private slots:
void beginEnd();
void firstLast();
void key();
+ void value();
void swap();
@@ -61,8 +41,13 @@ private slots:
void take();
void iterators();
+ void multimapIterators();
+ void iteratorsInEmptyMap();
void keyIterator();
+ void multimapKeyIterator();
void keyValueIterator();
+ void multimapKeyValueIterator();
+ void keyValueIteratorInEmptyMap();
void keys_values_uniqueKeys();
void qmultimap_specific();
@@ -78,6 +63,16 @@ private slots:
void testInsertMultiWithHint();
void eraseValidIteratorOnSharedMap();
void removeElementsInMap();
+ void toStdMap();
+
+ void multiMapStoresInReverseInsertionOrder();
+
+ // Tests for deprecated APIs.
+#if QT_DEPRECATED_SINCE(6, 0)
+ void deprecatedInsertMulti();
+ void deprecatedIteratorApis();
+ void deprecatedInsert();
+#endif // QT_DEPRECATED_SINCE(6, 0)
};
struct IdentityTracker {
@@ -114,6 +109,7 @@ public:
int MyClass::count = 0;
typedef QMap<QString, MyClass> MyMap;
+typedef QMultiMap<QString, MyClass> MyMultiMap;
QDebug operator << (QDebug d, const MyClass &c) {
d << c.str;
@@ -176,13 +172,21 @@ void tst_QMap::count()
{
MyMap map;
MyMap map2( map );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 0 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 0 );
QCOMPARE( MyClass::count, int(0) );
+ QCOMPARE(map.count("key"), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QVERIFY(!map.isDetached());
+ QVERIFY(!map2.isDetached());
// detach
map2["Hallo"] = MyClass( "Fritz" );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 1 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 1 );
+ QCOMPARE( map2.size(), 1 );
+ QVERIFY(!map.isDetached());
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 1 );
#endif
@@ -192,11 +196,11 @@ void tst_QMap::count()
{
typedef QMap<QString, MyClass> Map;
Map map;
- QCOMPARE( map.count(), 0);
+ QCOMPARE( map.size(), 0);
map.insert( "Torben", MyClass("Weis") );
- QCOMPARE( map.count(), 1 );
+ QCOMPARE( map.size(), 1 );
map.insert( "Claudia", MyClass("Sorg") );
- QCOMPARE( map.count(), 2 );
+ QCOMPARE( map.size(), 2 );
map.insert( "Lars", MyClass("Linzbach") );
map.insert( "Matthias", MyClass("Ettrich") );
map.insert( "Sue", MyClass("Paludo") );
@@ -204,7 +208,7 @@ void tst_QMap::count()
map.insert( "Haavard", MyClass("Nord") );
map.insert( "Arnt", MyClass("Gulbrandsen") );
map.insert( "Paul", MyClass("Tvete") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
map.insert( "Paul", MyClass("Tvete 1") );
map.insert( "Paul", MyClass("Tvete 2") );
map.insert( "Paul", MyClass("Tvete 3") );
@@ -212,69 +216,69 @@ void tst_QMap::count()
map.insert( "Paul", MyClass("Tvete 5") );
map.insert( "Paul", MyClass("Tvete 6") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
QCOMPARE( map.count("Paul"), 1 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
Map map2( map );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
- QVERIFY( map.count() == 9 );
+ QVERIFY( map2.size() == 10 );
+ QVERIFY( map.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
+ QVERIFY( map2.size() == 10 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map.remove( "Lars" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
map.remove( "Mist" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
@@ -288,22 +292,22 @@ void tst_QMap::count()
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 1 );
#endif
- QVERIFY( map.count() == 1 );
+ QVERIFY( map.size() == 1 );
(void)map["Torben"].str;
(void)map["Lars"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
+ QVERIFY( map.size() == 2 );
const Map& cmap = map;
(void)cmap["Depp"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
- QVERIFY( cmap.count() == 2 );
+ QVERIFY( map.size() == 2 );
+ QVERIFY( cmap.size() == 2 );
}
QCOMPARE( MyClass::count, 0 );
{
@@ -316,6 +320,45 @@ void tst_QMap::count()
QCOMPARE( MyClass::count, 0 );
}
QCOMPARE( MyClass::count, 0 );
+
+ {
+ QMultiMap<int, MyClass> map;
+ QMultiMap<int, MyClass> map2(map);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QCOMPARE(MyClass::count, 0);
+ QCOMPARE(map.count(1), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QVERIFY(!map.isDetached());
+ QVERIFY(!map2.isDetached());
+
+ // detach
+ map2.insert(0, MyClass("value0"));
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 1);
+ QCOMPARE(map2.size(), 1);
+ QVERIFY(!map.isDetached());
+ QCOMPARE(MyClass::count, 1);
+
+ map2.insert(1, MyClass("value1"));
+ map2.insert(2, MyClass("value2"));
+ QCOMPARE(map2.size(), 3);
+ QCOMPARE(MyClass::count, 3);
+
+ map2.insert(0, MyClass("value0_1"));
+ map2.insert(0, MyClass("value0_2"));
+ QCOMPARE(map2.size(), 5);
+ QCOMPARE(map2.count(0), 3);
+ QCOMPARE(MyClass::count, 5);
+
+ map2.clear();
+ QCOMPARE(map2.size(), 0);
+ QCOMPARE(MyClass::count, 0);
+
+ }
+ QCOMPARE(MyClass::count, 0);
}
void tst_QMap::clear()
@@ -323,18 +366,40 @@ void tst_QMap::clear()
{
MyMap map;
map.clear();
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
+ QVERIFY(!map.isDetached());
map.insert( "key", MyClass( "value" ) );
+ QVERIFY(!map.isEmpty());
map.clear();
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
map.insert( "key0", MyClass( "value0" ) );
map.insert( "key0", MyClass( "value1" ) );
map.insert( "key1", MyClass( "value2" ) );
+ QVERIFY(!map.isEmpty());
map.clear();
sanityCheckTree(map, __LINE__);
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
}
- QCOMPARE( MyClass::count, int(0) );
+ QCOMPARE(MyClass::count, int(0));
+
+ {
+ MyMultiMap map;
+ map.clear();
+ QVERIFY(map.isEmpty());
+ QVERIFY(!map.isDetached());
+ map.insert( "key", MyClass( "value" ) );
+ QVERIFY(!map.isEmpty());
+ map.clear();
+ QVERIFY(map.isEmpty());
+ map.insert( "key0", MyClass( "value0" ) );
+ map.insert( "key0", MyClass( "value1" ) );
+ map.insert( "key1", MyClass( "value2" ) );
+ QVERIFY(!map.isEmpty());
+ map.clear();
+ sanityCheckTree(map, __LINE__);
+ QVERIFY(map.isEmpty());
+ }
+ QCOMPARE(MyClass::count, int(0));
}
void tst_QMap::beginEnd()
@@ -370,7 +435,12 @@ void tst_QMap::beginEnd()
// detach
map2.insert( "2", "c" );
QVERIFY( map.constBegin() == map.constBegin() );
- QVERIFY( map.constBegin() != map2.constBegin() );
+
+ // comparing iterators between two different std::map is UB (and raises an
+ // assertion failure with MSVC debug-mode iterators), so we compare the
+ // elements' addresses.
+ QVERIFY(&map.constBegin().key() != &map2.constBegin().key());
+ QVERIFY(&map.constBegin().value() != &map2.constBegin().value());
}
void tst_QMap::firstLast()
@@ -409,6 +479,7 @@ void tst_QMap::key()
QMap<QString, int> map1;
QCOMPARE(map1.key(1), QString());
QCOMPARE(map1.key(1, def), def);
+ QVERIFY(!map1.isDetached());
map1.insert("one", 1);
QCOMPARE(map1.key(1), QLatin1String("one"));
@@ -439,6 +510,7 @@ void tst_QMap::key()
QMap<int, QString> map2;
QCOMPARE(map2.key("one"), 0);
QCOMPARE(map2.key("one", def), def);
+ QVERIFY(!map2.isDetached());
map2.insert(1, "one");
QCOMPARE(map2.key("one"), 1);
@@ -470,6 +542,82 @@ void tst_QMap::key()
QCOMPARE(map2.key("zero"), 0);
QCOMPARE(map2.key("zero", def), 0);
}
+
+ {
+ int def = -1;
+ QMultiMap<int, QString> multiMap;
+ QCOMPARE(multiMap.key("value0"), 0);
+ QCOMPARE(multiMap.key("value0", def), def);
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(1, "value1");
+ multiMap.insert(2, "value2");
+ multiMap.insert(1, "value1_1");
+
+ QCOMPARE(multiMap.key("value1"), 1);
+ QCOMPARE(multiMap.key("value1", def), 1);
+ QCOMPARE(multiMap.key("value1_1"), 1);
+ QCOMPARE(multiMap.key("value2"), 2);
+ QCOMPARE(multiMap.key("value3"), 0);
+ QCOMPARE(multiMap.key("value3", def), def);
+ }
+}
+
+void tst_QMap::value()
+{
+ const QString def = "default value";
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.value(1), QString());
+ QCOMPARE(map.value(1, def), def);
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ QCOMPARE(map.value(1), "value1");
+ QCOMPARE(map[1], "value1");
+ QCOMPARE(map.value(2), QString());
+ QCOMPARE(map.value(2, def), def);
+ QCOMPARE(map[2], QString());
+ QCOMPARE(map.size(), 2);
+
+ map.insert(2, "value2");
+ QCOMPARE(map.value(2), "value2");
+ QCOMPARE(map[2], "value2");
+
+ map.insert(1, "value3");
+ QCOMPARE(map.value(1), "value3");
+ QCOMPARE(map.value(1, def), "value3");
+ QCOMPARE(map[1], "value3");
+
+ const QMap<int, QString> constMap;
+ QVERIFY(!constMap.isDetached());
+ QCOMPARE(constMap.value(1, def), def);
+ QCOMPARE(constMap[1], QString());
+ QCOMPARE(constMap.size(), 0);
+ QVERIFY(!constMap.isDetached());
+ }
+ {
+ QMultiMap<int, QString> map;
+ QCOMPARE(map.value(1), QString());
+ QCOMPARE(map.value(1, def), def);
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ QCOMPARE(map.value(1), "value1");
+ QCOMPARE(map.value(2), QString());
+ QCOMPARE(map.value(2, def), def);
+
+ map.insert(2, "value2");
+ QCOMPARE(map.value(2), "value2");
+
+ map.insert(1, "value3");
+ // If multiple values exist, the most recently added is returned.
+ QCOMPARE(map.value(1), "value3");
+ QCOMPARE(map.value(1, def), "value3");
+
+ map.remove(1, "value3");
+ QCOMPARE(map.value(1), "value1");
+ }
}
void tst_QMap::swap()
@@ -492,16 +640,19 @@ void tst_QMap::operator_eq()
QMap<int, int> b;
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert(1,1);
b.insert(1,1);
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert(0,1);
b.insert(0,1);
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
// compare for inequality:
@@ -524,6 +675,7 @@ void tst_QMap::operator_eq()
QMap<QString, QString> b;
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert("Hello", "World");
@@ -532,6 +684,7 @@ void tst_QMap::operator_eq()
b.insert("Hello", "World");
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert("Goodbye", "cruel world");
@@ -548,6 +701,7 @@ void tst_QMap::operator_eq()
// empty keys and null keys match:
b.insert(QString(""), QString());
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
}
@@ -562,64 +716,135 @@ void tst_QMap::operator_eq()
}
}
-void tst_QMap::empty()
+template <typename T>
+void emptyTestMethod()
{
- QMap<int, QString> map1;
+ T map;
- QVERIFY(map1.isEmpty());
+ QVERIFY(map.isEmpty());
+ QVERIFY(map.empty());
+ QVERIFY(!map.isDetached());
- map1.insert(1, "one");
- QVERIFY(!map1.isEmpty());
+ map.insert(1, "one");
+ QVERIFY(!map.isEmpty());
+ QVERIFY(!map.empty());
- map1.clear();
- QVERIFY(map1.isEmpty());
+ map.clear();
+ QVERIFY(map.isEmpty());
+ QVERIFY(map.empty());
+}
+
+void tst_QMap::empty()
+{
+ emptyTestMethod<QMap<int, QString>>();
+ if (QTest::currentTestFailed())
+ return;
+ emptyTestMethod<QMultiMap<int, QString>>();
}
void tst_QMap::contains()
{
- QMap<int, QString> map1;
- int i;
+ {
+ QMap<int, QString> map1;
+ int i;
+
+ QVERIFY(!map1.contains(1));
+ QVERIFY(!map1.isDetached());
- map1.insert(1, "one");
- QVERIFY(map1.contains(1));
+ map1.insert(1, "one");
+ QVERIFY(map1.contains(1));
- for(i=2; i < 100; ++i)
- map1.insert(i, "teststring");
- for(i=99; i > 1; --i)
- QVERIFY(map1.contains(i));
+ for (i = 2; i < 100; ++i)
+ map1.insert(i, "teststring");
+ for (i = 99; i > 1; --i)
+ QVERIFY(map1.contains(i));
- map1.remove(43);
- QVERIFY(!map1.contains(43));
+ map1.remove(43);
+ QVERIFY(!map1.contains(43));
+ }
+
+ {
+ QMultiMap<int, QString> multiMap;
+ QVERIFY(!multiMap.contains(1));
+ QVERIFY(!multiMap.contains(1, "value1"));
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(1, "value1");
+ multiMap.insert(2, "value2");
+ multiMap.insert(1, "value1_1");
+
+ QVERIFY(multiMap.contains(1));
+ QVERIFY(multiMap.contains(1, "value1"));
+ QVERIFY(multiMap.contains(1, "value1_1"));
+ QVERIFY(multiMap.contains(2));
+ QVERIFY(multiMap.contains(2, "value2"));
+ QVERIFY(!multiMap.contains(2, "invalid_value"));
+
+ QVERIFY(!multiMap.contains(3));
+ multiMap.insert(3, "value3");
+ QVERIFY(multiMap.contains(3));
+
+ multiMap.remove(3);
+ QVERIFY(!multiMap.contains(3));
+ }
}
void tst_QMap::find()
{
- QMultiMap<int, QString> map1;
+ {
+ const QMap<int, QString> constMap;
+ QCOMPARE(constMap.find(1), constMap.end());
+ QVERIFY(!constMap.isDetached());
+
+ QMap<int, QString> map;
+ QCOMPARE(map.find(1), map.end());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ QCOMPARE(map.find(1).value(), u"value0");
+ QCOMPARE(map.find(5).value(), u"value5");
+ QCOMPARE(map.find(2).value(), u"value2");
+ QCOMPARE(map.find(4), map.end());
+ }
+
+ const QMultiMap<int, QString> constMap;
+ QCOMPARE(constMap.find(1), constMap.end());
+ QCOMPARE(constMap.find(1, "value"), constMap.end());
+ QVERIFY(!constMap.isDetached());
+
+ QMultiMap<int, QString> map;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
- QVERIFY(map1.find(1) == map1.end());
+ QCOMPARE(map.find(1), map.end());
+ QCOMPARE(map.find(1, "value1"), map.end());
- map1.insert(1,"Mensch");
- map1.insert(1,"Mayer");
- map1.insert(2,"Hej");
+ map.insert(1,"Mensch");
+ map.insert(1,"Mayer");
+ map.insert(2,"Hej");
- QCOMPARE(map1.find(1).value(), QLatin1String("Mayer"));
- QCOMPARE(map1.find(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.find(1).value(), QLatin1String("Mayer"));
+ QCOMPARE(map.find(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.find(1, "Mensch").value(), QLatin1String("Mensch"));
+ QCOMPARE(map.find(1, "Unknown Value"), map.end());
- for(i = 3; i < 10; ++i) {
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
- QCOMPARE(map1.count(4), i - 2);
+ map.insert(4, compareString);
+ QCOMPARE(map.count(4), i - 2);
}
- QMultiMap<int, QString>::const_iterator it=map1.constFind(4);
+ QMultiMap<int, QString>::iterator it = map.find(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != map.end() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
+ QCOMPARE(map.find(4, compareString), it);
++it;
++count;
}
@@ -628,32 +853,53 @@ void tst_QMap::find()
void tst_QMap::constFind()
{
- QMultiMap<int, QString> map1;
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.constFind(1), map.constEnd());
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ QCOMPARE(map.constFind(1).value(), QLatin1String("value0"));
+ QCOMPARE(map.constFind(5).value(), QLatin1String("value5"));
+ QCOMPARE(map.constFind(2).value(), QLatin1String("value2"));
+ QCOMPARE(map.constFind(4), map.constEnd());
+ }
+
+ QMultiMap<int, QString> map;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
- QVERIFY(map1.constFind(1) == map1.constEnd());
+ QCOMPARE(map.constFind(1), map.constEnd());
+ QCOMPARE(map.constFind(1, "value"), map.constEnd());
+ QVERIFY(!map.isDetached());
- map1.insert(1,"Mensch");
- map1.insert(1,"Mayer");
- map1.insert(2,"Hej");
+ map.insert(1,"Mensch");
+ map.insert(1,"Mayer");
+ map.insert(2,"Hej");
- QVERIFY(map1.constFind(4) == map1.constEnd());
+ QVERIFY(map.constFind(4) == map.constEnd());
- QCOMPARE(map1.constFind(1).value(), QLatin1String("Mayer"));
- QCOMPARE(map1.constFind(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.constFind(1).value(), QLatin1String("Mayer"));
+ QCOMPARE(map.constFind(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.constFind(1, "Mensch").value(), QLatin1String("Mensch"));
+ QCOMPARE(map.constFind(1, "Invalid Value"), map.constEnd());
- for(i = 3; i < 10; ++i) {
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
+ map.insert(4, compareString);
}
- QMultiMap<int, QString>::const_iterator it=map1.constFind(4);
+ QMultiMap<int, QString>::const_iterator it = map.constFind(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != map.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
+ QCOMPARE(map.constFind(4, compareString), it);
++it;
++count;
}
@@ -662,58 +908,128 @@ void tst_QMap::constFind()
void tst_QMap::lowerUpperBound()
{
- QMultiMap<int, QString> map1;
+ {
+ const QMap<int, QString> emptyConstMap;
+ QCOMPARE(emptyConstMap.lowerBound(1), emptyConstMap.constEnd());
+ QCOMPARE(emptyConstMap.upperBound(1), emptyConstMap.constEnd());
+ QVERIFY(!emptyConstMap.isDetached());
+
+ const QMap<int, QString> constMap { qMakePair(1, "one"),
+ qMakePair(5, "five"),
+ qMakePair(10, "ten") };
+
+ QCOMPARE(constMap.lowerBound(-1).key(), 1);
+ QCOMPARE(constMap.lowerBound(1).key(), 1);
+ QCOMPARE(constMap.lowerBound(3).key(), 5);
+ QCOMPARE(constMap.lowerBound(12), constMap.constEnd());
+
+ QCOMPARE(constMap.upperBound(-1).key(), 1);
+ QCOMPARE(constMap.upperBound(1).key(), 5);
+ QCOMPARE(constMap.upperBound(3).key(), 5);
+ QCOMPARE(constMap.upperBound(12), constMap.constEnd());
+
+ QMap<int, QString> map;
+
+ map.insert(1, "one");
+ map.insert(5, "five");
+ map.insert(10, "ten");
+ map.insert(3, "three");
+ map.insert(7, "seven");
+
+ QCOMPARE(map.lowerBound(0).key(), 1);
+ QCOMPARE(map.lowerBound(1).key(), 1);
+ QCOMPARE(map.lowerBound(2).key(), 3);
+ QCOMPARE(map.lowerBound(3).key(), 3);
+ QCOMPARE(map.lowerBound(4).key(), 5);
+ QCOMPARE(map.lowerBound(5).key(), 5);
+ QCOMPARE(map.lowerBound(6).key(), 7);
+ QCOMPARE(map.lowerBound(7).key(), 7);
+ QCOMPARE(map.lowerBound(10).key(), 10);
+ QCOMPARE(map.lowerBound(999), map.end());
+
+ QCOMPARE(map.upperBound(0).key(), 1);
+ QCOMPARE(map.upperBound(1).key(), 3);
+ QCOMPARE(map.upperBound(2).key(), 3);
+ QCOMPARE(map.upperBound(3).key(), 5);
+ QCOMPARE(map.upperBound(7).key(), 10);
+ QCOMPARE(map.upperBound(10), map.end());
+ QCOMPARE(map.upperBound(999), map.end());
+ }
- map1.insert(1, "one");
- map1.insert(5, "five");
- map1.insert(10, "ten");
+ const QMultiMap<int, QString> emptyConstMap;
+ QCOMPARE(emptyConstMap.lowerBound(1), emptyConstMap.constEnd());
+ QCOMPARE(emptyConstMap.upperBound(1), emptyConstMap.constEnd());
+ QVERIFY(!emptyConstMap.isDetached());
+ const QMultiMap<int, QString> constMap { qMakePair(1, "one"),
+ qMakePair(5, "five"),
+ qMakePair(10, "ten") };
+
+ QCOMPARE(constMap.lowerBound(-1).key(), 1);
+ QCOMPARE(constMap.lowerBound(1).key(), 1);
+ QCOMPARE(constMap.lowerBound(3).key(), 5);
+ QCOMPARE(constMap.lowerBound(12), constMap.constEnd());
+
+ QCOMPARE(constMap.upperBound(-1).key(), 1);
+ QCOMPARE(constMap.upperBound(1).key(), 5);
+ QCOMPARE(constMap.upperBound(3).key(), 5);
+ QCOMPARE(constMap.upperBound(12), constMap.constEnd());
+
+ QMultiMap<int, QString> map;
+
+ map.insert(1, "one");
+ map.insert(5, "five");
+ map.insert(10, "ten");
//Copied from documentation
- QCOMPARE(map1.upperBound(0).key(), 1); // returns iterator to (1, "one")
- QCOMPARE(map1.upperBound(1).key(), 5); // returns iterator to (5, "five")
- QCOMPARE(map1.upperBound(2).key(), 5); // returns iterator to (5, "five")
- QVERIFY(map1.upperBound(10) == map1.end()); // returns end()
- QVERIFY(map1.upperBound(999) == map1.end()); // returns end()
-
- QCOMPARE(map1.lowerBound(0).key(), 1); // returns iterator to (1, "one")
- QCOMPARE(map1.lowerBound(1).key(), 1); // returns iterator to (1, "one")
- 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(), QLatin1String("seven_2"));
- QCOMPARE(map1.lowerBound(7).value(), QLatin1String("seven_2"));
- QCOMPARE((++map1.lowerBound(6)).value(), QLatin1String("seven"));
- QCOMPARE((++map1.lowerBound(7)).value(), QLatin1String("seven"));
- QCOMPARE(map1.lowerBound(10).key(), 10);
- QVERIFY(map1.lowerBound(999) == map1.end());
+ QCOMPARE(map.upperBound(0).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.upperBound(1).key(), 5); // returns iterator to (5, "five")
+ QCOMPARE(map.upperBound(2).key(), 5); // returns iterator to (5, "five")
+ QVERIFY(map.upperBound(10) == map.end()); // returns end()
+ QVERIFY(map.upperBound(999) == map.end()); // returns end()
+
+ QCOMPARE(map.lowerBound(0).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.lowerBound(1).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.lowerBound(2).key(), 5); // returns iterator to (5, "five")
+ QCOMPARE(map.lowerBound(10).key(), 10); // returns iterator to (10, "ten")
+ QVERIFY(map.lowerBound(999) == map.end()); // returns end()
+
+ map.insert(3, "three");
+ map.insert(7, "seven");
+ map.insert(7, "seven_2");
+
+ QCOMPARE(map.upperBound(0).key(), 1);
+ QCOMPARE(map.upperBound(1).key(), 3);
+ QCOMPARE(map.upperBound(2).key(), 3);
+ QCOMPARE(map.upperBound(3).key(), 5);
+ QCOMPARE(map.upperBound(7).key(), 10);
+ QVERIFY(map.upperBound(10) == map.end());
+ QVERIFY(map.upperBound(999) == map.end());
+
+ QCOMPARE(map.lowerBound(0).key(), 1);
+ QCOMPARE(map.lowerBound(1).key(), 1);
+ QCOMPARE(map.lowerBound(2).key(), 3);
+ QCOMPARE(map.lowerBound(3).key(), 3);
+ QCOMPARE(map.lowerBound(4).key(), 5);
+ QCOMPARE(map.lowerBound(5).key(), 5);
+ QCOMPARE(map.lowerBound(6).key(), 7);
+ QCOMPARE(map.lowerBound(7).key(), 7);
+ QCOMPARE(map.lowerBound(6).value(), QLatin1String("seven_2"));
+ QCOMPARE(map.lowerBound(7).value(), QLatin1String("seven_2"));
+ QCOMPARE((++map.lowerBound(6)).value(), QLatin1String("seven"));
+ QCOMPARE((++map.lowerBound(7)).value(), QLatin1String("seven"));
+ QCOMPARE(map.lowerBound(10).key(), 10);
+ QVERIFY(map.lowerBound(999) == map.end());
}
void tst_QMap::mergeCompare()
{
- QMultiMap<int, QString> map1, map2, map3, map1b, map2b;
+ QMultiMap<int, QString> map1, map2, map3, map1b, map2b, map4;
+
+ // unite with an empty map does nothing
+ map1.unite(map2);
+ QVERIFY(!map1.isDetached());
map1.insert(1,"ett");
map1.insert(3,"tre");
@@ -743,18 +1059,43 @@ void tst_QMap::mergeCompare()
map3.insert(4, "fyra");
map3.insert(5, "fem");
- QVERIFY(map1 == map3);
+ QCOMPARE(map1, map3);
+
+ map4.unite(map3);
+ QCOMPARE(map4, map3);
}
void tst_QMap::take()
{
- QMap<int, QString> map;
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.take(1), QString());
+ QVERIFY(!map.isDetached());
- map.insert(2, "zwei");
- map.insert(3, "drei");
+ map.insert(2, "zwei");
+ map.insert(3, "drei");
- QCOMPARE(map.take(3), QLatin1String("drei"));
- QVERIFY(!map.contains(3));
+ QCOMPARE(map.take(3), QLatin1String("drei"));
+ QVERIFY(!map.contains(3));
+ }
+
+ {
+ QMultiMap<int, QString> multiMap;
+ QCOMPARE(multiMap.take(1), QString());
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(0, "value0");
+ multiMap.insert(1, "value1");
+ multiMap.insert(0, "value0_1");
+ multiMap.insert(0, "value0_2");
+
+ // The most recently inserted value is returned
+ QCOMPARE(multiMap.take(0), u"value0_2");
+ QCOMPARE(multiMap.take(0), u"value0_1");
+ QCOMPARE(multiMap.take(0), u"value0");
+ QCOMPARE(multiMap.take(0), QString());
+ QVERIFY(!multiMap.contains(0));
+ }
}
void tst_QMap::iterators()
@@ -834,14 +1175,125 @@ void tst_QMap::iterators()
}
}
+void tst_QMap::multimapIterators()
+{
+ QMultiMap<int, QString> map;
+ const QString testString = "Teststring %1-%2";
+
+ for (int i = 0; i < 5; ++i) {
+ // reverse order, because the last added is returned first.
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, testString.arg(i).arg(j));
+ }
+
+ // STL-style iterators
+ auto stlIt = map.begin();
+ QCOMPARE(stlIt.value(), u"Teststring 0-0");
+
+ stlIt++;
+ QCOMPARE(stlIt.value(), u"Teststring 0-1");
+
+ std::advance(stlIt, 10);
+ QCOMPARE(stlIt.value(), u"Teststring 2-1");
+
+ std::advance(stlIt, -4);
+ QCOMPARE(stlIt.value(), u"Teststring 1-2");
+
+ stlIt--;
+ QCOMPARE(stlIt.value(), u"Teststring 1-1");
+
+ // STL-style const iterators
+ auto cstlIt = map.cbegin();
+ QCOMPARE(cstlIt.value(), u"Teststring 0-0");
+
+ cstlIt++;
+ QCOMPARE(cstlIt.value(), u"Teststring 0-1");
+
+ std::advance(cstlIt, 16);
+ QCOMPARE(cstlIt.value(), u"Teststring 3-2");
+
+ std::advance(cstlIt, -6);
+ QCOMPARE(cstlIt.value(), u"Teststring 2-1");
+
+ cstlIt--;
+ QCOMPARE(cstlIt.value(), u"Teststring 2-0");
+
+ // Java-style iterator
+ QMultiMapIterator javaIt(map);
+ int i = 0;
+ int j = 0;
+ while (javaIt.hasNext()) {
+ javaIt.next();
+ QCOMPARE(javaIt.value(), testString.arg(i).arg(j));
+ if (++j == 5) {
+ j = 0;
+ i++;
+ }
+ }
+
+ i = 4;
+ j = 4;
+ while (javaIt.hasPrevious()) {
+ javaIt.previous();
+ QCOMPARE(javaIt.value(), testString.arg(i).arg(j));
+ if (--j < 0) {
+ j = 4;
+ i--;
+ }
+ }
+}
+
+template <typename T>
+void iteratorsInEmptyMapTestMethod()
+{
+ T map;
+ using ConstIter = typename T::const_iterator;
+ ConstIter it1 = map.cbegin();
+ ConstIter it2 = map.constBegin();
+ QVERIFY(it1 == it2 && it2 == ConstIter());
+ QVERIFY(!map.isDetached());
+
+ ConstIter it3 = map.cend();
+ ConstIter it4 = map.constEnd();
+ QVERIFY(it3 == it4 && it4 == ConstIter());
+ QVERIFY(!map.isDetached());
+
+ // to call const overloads of begin() and end()
+ const T map2;
+ ConstIter it5 = map2.begin();
+ ConstIter it6 = map2.end();
+ QVERIFY(it5 == it6 && it6 == ConstIter());
+ QVERIFY(!map2.isDetached());
+
+ using Iter = typename T::iterator;
+ Iter it7 = map.begin();
+ Iter it8 = map.end();
+ QVERIFY(it7 == it8);
+}
+
+void tst_QMap::iteratorsInEmptyMap()
+{
+ iteratorsInEmptyMapTestMethod<QMap<int, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ iteratorsInEmptyMapTestMethod<QMultiMap<int, int>>();
+}
+
void tst_QMap::keyIterator()
{
QMap<int, int> map;
+ using KeyIterator = QMap<int, int>::key_iterator;
+ KeyIterator it1 = map.keyBegin();
+ KeyIterator it2 = map.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!map.isDetached());
+
for (int i = 0; i < 100; ++i)
map.insert(i, i*100);
- QMap<int, int>::key_iterator key_it = map.keyBegin();
+ KeyIterator key_it = map.keyBegin();
QMap<int, int>::const_iterator it = map.cbegin();
for (int i = 0; i < 100; ++i) {
QCOMPARE(*key_it, it.key());
@@ -862,8 +1314,48 @@ void tst_QMap::keyIterator()
QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 99), 1);
// DefaultConstructible test
- typedef QMap<int, int>::key_iterator keyIterator;
- static_assert(std::is_default_constructible<keyIterator>::value);
+ static_assert(std::is_default_constructible<KeyIterator>::value);
+}
+
+void tst_QMap::multimapKeyIterator()
+{
+ QMultiMap<int, int> map;
+
+ using KeyIterator = QMultiMap<int, int>::key_iterator;
+ KeyIterator it1 = map.keyBegin();
+ KeyIterator it2 = map.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!map.isDetached());
+
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, 100 * i + j);
+ }
+
+ KeyIterator keyIt = map.keyBegin();
+ QMultiMap<int, int>::const_iterator it = map.cbegin();
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j) {
+ QCOMPARE(*keyIt, it.key());
+ ++keyIt;
+ ++it;
+ }
+ }
+
+ keyIt = std::find(map.keyBegin(), map.keyEnd(), 3);
+ it = std::find(map.cbegin(), map.cend(), 3 * 100);
+
+ QVERIFY(keyIt != map.keyEnd());
+ QCOMPARE(*keyIt, it.key());
+ QCOMPARE(*(keyIt++), (it++).key());
+ QCOMPARE(*(keyIt--), (it--).key());
+ QCOMPARE(*(++keyIt), (++it).key());
+ QCOMPARE(*(--keyIt), (--it).key());
+
+ QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 2), 5);
+
+ // DefaultConstructible test
+ static_assert(std::is_default_constructible<KeyIterator>::value);
}
void tst_QMap::keyValueIterator()
@@ -925,27 +1417,168 @@ void tst_QMap::keyValueIterator()
QCOMPARE(std::count(map.constKeyValueBegin(), map.constKeyValueEnd(), entry_type(key, value)), 1);
}
+void tst_QMap::multimapKeyValueIterator()
+{
+ QMultiMap<int, int> map;
+ using EntryType = QMultiMap<int, int>::const_key_value_iterator::value_type;
+
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, 100 * i + j);
+ }
+
+ auto keyValueIt = map.constKeyValueBegin();
+ auto it = map.cbegin();
+
+ for (int i = 0; i < map.size(); ++i) {
+ QVERIFY(keyValueIt != map.constKeyValueEnd());
+ QVERIFY(it != map.cend());
+
+ EntryType pair(it.key(), it.value());
+ QCOMPARE(*keyValueIt, pair);
+ QCOMPARE(keyValueIt->first, pair.first);
+ QCOMPARE(keyValueIt->second, pair.second);
+ ++keyValueIt;
+ ++it;
+ }
+
+ QVERIFY(keyValueIt == map.constKeyValueEnd());
+ QVERIFY(it == map.cend());
+
+ int key = 3;
+ int value = 100 * 3;
+ keyValueIt = std::find(map.constKeyValueBegin(), map.constKeyValueEnd(), EntryType(key, value));
+ it = std::find(map.cbegin(), map.cend(), value);
+
+ QVERIFY(keyValueIt != map.constKeyValueEnd());
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ ++it;
+ ++keyValueIt;
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ --it;
+ --keyValueIt;
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ std::advance(it, 5);
+ std::advance(keyValueIt, 5);
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ std::advance(it, -5);
+ std::advance(keyValueIt, -5);
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ key = 2;
+ value = 100 * 2 + 2;
+ auto cnt = std::count(map.constKeyValueBegin(), map.constKeyValueEnd(), EntryType(key, value));
+ QCOMPARE(cnt, 1);
+}
+
+template <typename T>
+void keyValueIteratorInEmptyMapTestMethod()
+{
+ T map;
+ using ConstKeyValueIter = typename T::const_key_value_iterator;
+
+ ConstKeyValueIter it1 = map.constKeyValueBegin();
+ ConstKeyValueIter it2 = map.constKeyValueEnd();
+ QVERIFY(it1 == it2 && it2 == ConstKeyValueIter());
+ QVERIFY(!map.isDetached());
+
+ const T map2;
+ ConstKeyValueIter it3 = map2.keyValueBegin();
+ ConstKeyValueIter it4 = map2.keyValueEnd();
+ QVERIFY(it3 == it4 && it4 == ConstKeyValueIter());
+ QVERIFY(!map2.isDetached());
+
+ using KeyValueIter = typename T::key_value_iterator;
+
+ KeyValueIter it5 = map.keyValueBegin();
+ KeyValueIter it6 = map.keyValueEnd();
+ QVERIFY(it5 == it6);
+}
+
+void tst_QMap::keyValueIteratorInEmptyMap()
+{
+ keyValueIteratorInEmptyMapTestMethod<QMap<int, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ keyValueIteratorInEmptyMapTestMethod<QMultiMap<int, int>>();
+}
+
void tst_QMap::keys_values_uniqueKeys()
{
+ {
+ QMap<QString, int> map;
+ QVERIFY(map.keys().isEmpty());
+ QVERIFY(map.keys(1).isEmpty());
+ QVERIFY(map.values().isEmpty());
+ QVERIFY(!map.isDetached());
+
+ map.insert("one", 1);
+ QCOMPARE(map.keys(), QStringList({ "one" }));
+ QCOMPARE(map.keys(1), QStringList({ "one" }));
+ QCOMPARE(map.values(), QList<int>({ 1 }));
+
+ map.insert("two", 2);
+ QCOMPARE(map.keys(), QStringList({ "one", "two" }));
+ QCOMPARE(map.keys(1), QStringList({ "one" }));
+ QCOMPARE(map.values(), QList<int>({ 1, 2 }));
+
+ map.insert("three", 2);
+ QCOMPARE(map.keys(), QStringList({ "one", "three", "two" }));
+ QCOMPARE(map.keys(2), QStringList({ "three", "two" }));
+ QCOMPARE(map.values(), QList<int>({ 1, 2, 2 }));
+
+ map.insert("one", 0);
+ QCOMPARE(map.keys(), QStringList({ "one", "three", "two" }));
+ QCOMPARE(map.keys(1), QStringList());
+ QCOMPARE(map.keys(0), QStringList({ "one" }));
+ QCOMPARE(map.keys(2), QStringList({ "three", "two" }));
+ QCOMPARE(map.values(), QList<int>({ 0, 2, 2 }));
+ }
+
QMultiMap<QString, int> map;
QVERIFY(map.keys().isEmpty());
+ QVERIFY(map.keys(1).isEmpty());
+ QVERIFY(map.uniqueKeys().isEmpty());
QVERIFY(map.values().isEmpty());
+ QVERIFY(map.values("key").isEmpty());
+ QVERIFY(!map.isDetached());
- map.insertMulti("alpha", 1);
+ map.insert("alpha", 1);
QVERIFY(map.keys() == (QList<QString>() << "alpha"));
QVERIFY(map.values() == (QList<int>() << 1));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha" }));
- map.insertMulti("beta", -2);
+ map.insert("beta", -2);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "beta"));
QVERIFY(map.values() == (QList<int>() << 1 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
- map.insertMulti("alpha", 2);
+ map.insert("alpha", 2);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
- map.insertMulti("beta", 4);
+ map.insert("beta", 4);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << 4 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
+ QVERIFY(map.values("beta") == QList<int>({ 4, -2 }));
+
+ map.insert("gamma", 2);
+ QVERIFY(map.keys() == QList<QString>({ "alpha", "alpha", "beta", "beta", "gamma" }));
+ QVERIFY(map.values() == QList<int>({ 2, 1, 4, -2, 2 }));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta", "gamma" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
+ QVERIFY(map.values("beta") == QList<int>({ 4, -2 }));
+ QVERIFY(map.values("gamma") == QList<int>({ 2 }));
+ QVERIFY(map.keys(2) == QList<QString>({ "alpha", "gamma" }));
}
void tst_QMap::qmultimap_specific()
@@ -968,26 +1601,26 @@ void tst_QMap::qmultimap_specific()
}
QVERIFY(map1.contains(9, 99));
- QCOMPARE(map1.count(), 45);
+ QCOMPARE(map1.size(), 45);
map1.remove(9, 99);
QVERIFY(!map1.contains(9, 99));
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(9, 99);
QVERIFY(!map1.contains(9, 99));
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.insert(1, 99);
map1.insert(1, 99);
- QCOMPARE(map1.count(), 46);
+ QCOMPARE(map1.size(), 46);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
{
QMultiMap<int, int>::const_iterator i = map1.constFind(1, 11);
@@ -1046,7 +1679,7 @@ void tst_QMap::qmultimap_specific()
map2.insert(42, 1);
map2.insert(10, 2);
map2.insert(48, 3);
- QCOMPARE(map1.count(), map2.count());
+ QCOMPARE(map1.size(), map2.size());
QVERIFY(map1.remove(42,5));
QVERIFY(map2.remove(42,5));
QVERIFY(map1 == map2);
@@ -1073,6 +1706,37 @@ void tst_QMap::const_shared_null()
void tst_QMap::equal_range()
{
+ {
+ const QMap<int, QString> constMap;
+ QCOMPARE(constMap.equal_range(1), qMakePair(constMap.constEnd(), constMap.constEnd()));
+ QVERIFY(!constMap.isDetached());
+
+ QMap<int, QString> map;
+ QCOMPARE(map.equal_range(1), qMakePair(map.end(), map.end()));
+
+ map.insert(1, "value1");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ auto pair = map.equal_range(1);
+ QCOMPARE(pair.first.value(), "value0");
+ QCOMPARE(pair.second.value(), "value5");
+ auto b = map.find(1);
+ auto e = map.find(5);
+ QCOMPARE(pair, qMakePair(b, e));
+
+ pair = map.equal_range(3);
+ QCOMPARE(pair.first.value(), "value5");
+ QCOMPARE(pair.second.value(), "value5");
+ QCOMPARE(pair, qMakePair(e, e));
+
+ QCOMPARE(map.equal_range(10), qMakePair(map.end(), map.end()));
+ }
+
+ const QMultiMap<int, QString> constMap;
+ QCOMPARE(constMap.equal_range(1), qMakePair(constMap.constEnd(), constMap.constEnd()));
+ QVERIFY(!constMap.isDetached());
+
QMultiMap<int, QString> map;
const QMultiMap<int, QString> &cmap = map;
@@ -1137,7 +1801,7 @@ void tst_QMap::equal_range()
QCOMPARE(cresult.first, cmap.find(2));
QCOMPARE(cresult.second, cmap.find(4));
- map.insertMulti(1, "another one");
+ map.insert(1, "another one");
result = map.equal_range(1);
QCOMPARE(result.first, map.find(1));
@@ -1150,19 +1814,13 @@ void tst_QMap::equal_range()
QCOMPARE(map.count(1), 2);
}
-template <class T>
-const T &const_(const T &t)
-{
- return t;
-}
-
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);
+ QCOMPARE(map.size(), 2);
QMap<int, int> intMap;
for (int i = 0; i < 1000; ++i) {
@@ -1233,12 +1891,15 @@ void testDetachWhenInsert()
dest.insert(3, 3);
Map<int, int> destCopy = dest;
- dest.insert(source);
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
QCOMPARE(source, referenceSource);
QCOMPARE(dest, referenceDestination);
- QCOMPARE(destCopy.count(), 1); // unchanged
+ QCOMPARE(destCopy.size(), 1); // unchanged
}
// copy insertion of shared map
@@ -1253,13 +1914,16 @@ void testDetachWhenInsert()
dest.insert(3, 3);
Map<int, int> destCopy = dest;
- dest.insert(source);
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
QCOMPARE(source, referenceSource);
QCOMPARE(sourceCopy, referenceSource);
QCOMPARE(dest, referenceDestination);
- QCOMPARE(destCopy.count(), 1); // unchanged
+ QCOMPARE(destCopy.size(), 1); // unchanged
}
// move insertion of non-shared map
@@ -1273,10 +1937,13 @@ void testDetachWhenInsert()
dest.insert(3, 3);
Map<int, int> destCopy = dest;
- dest.insert(source);
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
QCOMPARE(dest, referenceDestination);
- QCOMPARE(destCopy.count(), 1); // unchanged
+ QCOMPARE(destCopy.size(), 1); // unchanged
}
// move insertion of shared map
@@ -1291,18 +1958,33 @@ void testDetachWhenInsert()
dest.insert(3, 3);
Map<int, int> destCopy = dest;
- dest.insert(std::move(source));
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(std::move(source)); // QMap
+ else
+ dest.unite(std::move(source)); // QMultiMap
QCOMPARE(sourceCopy, referenceSource);
QCOMPARE(dest, referenceDestination);
- QCOMPARE(destCopy.count(), 1); // unchanged
+ QCOMPARE(destCopy.size(), 1); // unchanged
}
};
void tst_QMap::insertMap()
{
{
+ QMap<int, int> map1;
+ QMap<int, int> map2;
+ QVERIFY(map1.isEmpty());
+ QVERIFY(map2.isEmpty());
+
+ map1.insert(map2);
+ QVERIFY(map1.isEmpty());
+ QVERIFY(map2.isEmpty());
+ QVERIFY(!map1.isDetached());
+ QVERIFY(!map2.isDetached());
+ }
+ {
QMap<int, int> map;
map.insert(1, 1);
map.insert(2, 2);
@@ -1315,7 +1997,7 @@ void tst_QMap::insertMap()
map.insert(map2);
- QCOMPARE(map.count(), 5);
+ QCOMPARE(map.size(), 5);
for (int i = 0; i < 5; ++i)
QCOMPARE(map[i], i);
}
@@ -1330,7 +2012,7 @@ void tst_QMap::insertMap()
map.insert(map2);
- QCOMPARE(map.count(), 17);
+ QCOMPARE(map.size(), 17);
for (int i = 0; i < 10; ++i) {
// i * 3 == i except for i = 4, 8
QCOMPARE(map[i * 3], (i && i % 4 == 0) ? i - (i / 4) : i);
@@ -1352,7 +2034,7 @@ void tst_QMap::insertMap()
QMap<int, int> map2;
map.insert(map2);
- QCOMPARE(map.count(), 1);
+ QCOMPARE(map.size(), 1);
QCOMPARE(map[1], 1);
}
{
@@ -1361,8 +2043,12 @@ void tst_QMap::insertMap()
map2.insert(1, 1);
map.insert(map2);
- QCOMPARE(map.count(), 1);
+ QCOMPARE(map.size(), 1);
QCOMPARE(map[1], 1);
+
+ QMap<int, int> map3;
+ map3.insert(std::move(map2));
+ QCOMPARE(map3, map);
}
{
QMap<int, int> map;
@@ -1373,7 +2059,7 @@ void tst_QMap::insertMap()
// Test inserting into self, nothing should happen
map.insert(map);
- QCOMPARE(map.count(), 3);
+ QCOMPARE(map.size(), 3);
for (int i = 0; i < 3; ++i)
QCOMPARE(map[i], i);
}
@@ -1391,7 +2077,7 @@ void tst_QMap::insertMap()
map.insert(map2);
- QCOMPARE(map.count(), 1);
+ QCOMPARE(map.size(), 1);
}
testDetachWhenInsert<QMap>();
@@ -1453,7 +2139,7 @@ void tst_QMap::checkMostLeftNode()
void tst_QMap::initializerList()
{
QMap<int, QString> map = {{1, "bar"}, {1, "hello"}, {2, "initializer_list"}};
- QCOMPARE(map.count(), 2);
+ QCOMPARE(map.size(), 2);
QCOMPARE(map[1], QString("hello"));
QCOMPARE(map[2], QString("initializer_list"));
@@ -1463,9 +2149,9 @@ void tst_QMap::initializerList()
// QCOMPARE(stdm[1], QString("bar"));
QMultiMap<QString, int> multiMap{{"il", 1}, {"il", 2}, {"il", 3}};
- QCOMPARE(multiMap.count(), 3);
+ QCOMPARE(multiMap.size(), 3);
QList<int> values = multiMap.values("il");
- QCOMPARE(values.count(), 3);
+ QCOMPARE(values.size(), 3);
QMap<int, int> emptyMap{};
QVERIFY(emptyMap.isEmpty());
@@ -1547,48 +2233,48 @@ void tst_QMap::testInsertMultiWithHint()
{
QMultiMap<int, int> map;
- map.insertMulti(map.end(), 64, 65);
+ map.insert(map.end(), 64, 65);
map.insert(128, 129);
map.insert(256, 257);
sanityCheckTree(map, __LINE__);
- map.insertMulti(map.end(), 512, 513);
- map.insertMulti(map.end(), 512, 513 * 2);
+ map.insert(map.end(), 512, 513);
+ map.insert(map.end(), 512, 513 * 2);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 5);
- map.insertMulti(map.end(), 256, 258); // wrong hint
+ map.insert(map.end(), 256, 258); // wrong hint
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 6);
- QMultiMap<int, int>::iterator i = map.insertMulti(map.constBegin(), 256, 259); // wrong hint
+ QMultiMap<int, int>::iterator i = map.insert(map.constBegin(), 256, 259); // wrong hint
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 7);
- QMultiMap<int, int>::iterator j = map.insertMulti(map.constBegin(), 69, 66);
+ QMultiMap<int, int>::iterator j = map.insert(map.constBegin(), 69, 66);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 8);
- j = map.insertMulti(j, 68, 259);
+ j = map.insert(j, 68, 259);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 9);
- j = map.insertMulti(j, 67, 67);
+ j = map.insert(j, 67, 67);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 10);
- i = map.insertMulti(i, 256, 259);
+ i = map.insert(i, 256, 259);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 11);
- i = map.insertMulti(i, 256, 260);
+ i = map.insert(i, 256, 260);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 12);
- map.insertMulti(i, 64, 67);
+ map.insert(i, 64, 67);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 13);
- map.insertMulti(map.constBegin(), 20, 20);
+ map.insert(map.constBegin(), 20, 20);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 14);
}
@@ -1597,9 +2283,9 @@ void tst_QMap::eraseValidIteratorOnSharedMap()
{
QMultiMap<int, int> a, b;
a.insert(10, 10);
- a.insertMulti(10, 40);
- a.insertMulti(10, 25);
- a.insertMulti(10, 30);
+ a.insert(10, 40);
+ a.insert(10, 25);
+ a.insert(10, 30);
a.insert(20, 20);
QMultiMap<int, int>::iterator i = a.begin();
@@ -1624,8 +2310,8 @@ void tst_QMap::eraseValidIteratorOnSharedMap()
// Border cases
QMultiMap <QString, QString> ms1, ms2, ms3;
ms1.insert("foo", "bar");
- ms1.insertMulti("foo", "quux");
- ms1.insertMulti("foo", "bar");
+ ms1.insert("foo", "quux");
+ ms1.insert("foo", "bar");
QMultiMap <QString, QString>::iterator si = ms1.begin();
ms2 = ms1;
@@ -1661,6 +2347,14 @@ void tst_QMap::removeElementsInMap()
};
{
+ QMap<int, int> map;
+ QCOMPARE(map.remove(1), 0);
+ QVERIFY(!map.isDetached());
+
+ auto cnt = map.removeIf([](QMap<int, int>::iterator) { return true; });
+ QCOMPARE(cnt, 0);
+ }
+ {
QMap<SharedInt, int> map {
{ SharedInt(1), 1 },
{ SharedInt(2), 2 },
@@ -1718,9 +2412,21 @@ void tst_QMap::removeElementsInMap()
QCOMPARE(map.size(), 0);
QCOMPARE(map2.size(), 4);
+
+ auto cnt = map2.removeIf([](auto it) { return (*it % 2) == 0; });
+ QCOMPARE(cnt, 2);
+ QCOMPARE(map2.size(), 2);
}
{
+ QMultiMap<int, int> map;
+ QCOMPARE(map.remove(1), 0);
+ QVERIFY(!map.isDetached());
+
+ auto cnt = map.removeIf([](QMultiMap<int, int>::iterator) { return true; });
+ QCOMPARE(cnt, 0);
+ }
+ {
QMultiMap<SharedInt, int> multimap {
{ SharedInt(1), 10 },
{ SharedInt(1), 11 },
@@ -1817,8 +2523,127 @@ void tst_QMap::removeElementsInMap()
QCOMPARE(multimap.size(), 0);
QCOMPARE(multimap2.size(), 12);
+
+ auto cnt = multimap2.removeIf([](auto it) { return (*it % 2) == 0; });
+ QCOMPARE(cnt, 8);
+ QCOMPARE(multimap2.size(), 4);
}
}
+template <typename QtMap, typename StdMap>
+void toStdMapTestMethod(const StdMap &expectedMap)
+{
+ QtMap map;
+ QVERIFY(map.isEmpty());
+ auto stdMap = map.toStdMap();
+ QVERIFY(stdMap.empty());
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(3, "value3");
+ map.insert(1, "value0");
+
+ stdMap = map.toStdMap();
+ QCOMPARE(stdMap, expectedMap);
+}
+
+void tst_QMap::toStdMap()
+{
+ const std::map<int, QString> expectedMap { {1, "value0"}, {2, "value2"}, {3, "value3"} };
+ toStdMapTestMethod<QMap<int, QString>>(expectedMap);
+ if (QTest::currentTestFailed())
+ return;
+
+ const std::multimap<int, QString> expectedMultiMap {
+ {1, "value0"}, {1, "value1"}, {2, "value2"}, {3, "value3"} };
+ toStdMapTestMethod<QMultiMap<int, QString>>(expectedMultiMap);
+}
+
+void tst_QMap::multiMapStoresInReverseInsertionOrder()
+{
+ const QString strings[] = {
+ u"zero"_s,
+ u"null"_s,
+ u"nada"_s,
+ };
+ {
+ QMultiMap<int, QString> map;
+ for (const QString &string : strings)
+ map.insert(0, string);
+ auto printOnFailure = qScopeGuard([&] { qDebug() << map; });
+ QVERIFY(std::equal(map.begin(), map.end(),
+ std::rbegin(strings), std::rend(strings)));
+ printOnFailure.dismiss();
+ }
+}
+
+#if QT_DEPRECATED_SINCE(6, 0)
+void tst_QMap::deprecatedInsertMulti()
+{
+ QMultiMap<int, QString> referenceMap;
+ referenceMap.insert(1, "value1");
+ referenceMap.insert(2, "value2");
+ referenceMap.insert(3, "value3");
+ referenceMap.insert(1, "value1_2");
+ referenceMap.insert(referenceMap.find(2), 2, "value2_2");
+ referenceMap.insert(referenceMap.end(), 1, "value1_3");
+
+ QMultiMap<int, QString> deprecatedMap;
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ deprecatedMap.insertMulti(1, "value1");
+ deprecatedMap.insertMulti(2, "value2");
+ deprecatedMap.insertMulti(3, "value3");
+ deprecatedMap.insertMulti(1, "value1_2");
+ deprecatedMap.insertMulti(deprecatedMap.find(2), 2, "value2_2");
+ deprecatedMap.insertMulti(deprecatedMap.end(), 1, "value1_3");
+QT_WARNING_POP
+
+ QCOMPARE(deprecatedMap, referenceMap);
+}
+
+void tst_QMap::deprecatedIteratorApis()
+{
+ QMap<int, QString> map;
+ QString testString = "Teststring %1";
+ for (int i = 1; i < 100; ++i)
+ map.insert(i, testString.arg(i));
+
+ auto it = map.begin();
+ QCOMPARE(it.value(), QLatin1String("Teststring 1"));
+ QT_IGNORE_DEPRECATIONS(it += 5;)
+ QCOMPARE(it.value(), QLatin1String("Teststring 6"));
+ QT_IGNORE_DEPRECATIONS(it = it - 3;)
+ QCOMPARE(it.value(), QLatin1String("Teststring 3"));
+
+ auto cit = map.constBegin();
+ QCOMPARE(cit.value(), QLatin1String("Teststring 1"));
+ QT_IGNORE_DEPRECATIONS(cit += 5;)
+ QCOMPARE(cit.value(), QLatin1String("Teststring 6"));
+ QT_IGNORE_DEPRECATIONS(cit = cit - 3;)
+ QCOMPARE(cit.value(), QLatin1String("Teststring 3"));
+}
+
+void tst_QMap::deprecatedInsert()
+{
+ QMultiMap<int, QString> refMap;
+ refMap.insert(1, "value1");
+ refMap.insert(2, "value2");
+ refMap.insert(3, "value3");
+
+ QMultiMap<int, QString> depMap = refMap;
+
+ QMultiMap<int, QString> otherMap;
+ otherMap.insert(1, "value1_2");
+ otherMap.insert(3, "value3_2");
+ otherMap.insert(4, "value4");
+
+ refMap.unite(otherMap);
+ QT_IGNORE_DEPRECATIONS(depMap.insert(otherMap);)
+
+ QCOMPARE(refMap, depMap);
+}
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
QTEST_APPLESS_MAIN(tst_QMap)
#include "tst_qmap.moc"