From e12e2b43b7e6b42d17556eb8ed392c31589a0b4a Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 16 Oct 2020 20:52:48 +0200 Subject: Associative containers: add erase_if Use a trick similar to the one we use for their ranged constructors: support predicates that either take a container's iterator, or that take a std::pair (for STL compatibility). [ChangeLog][QtCore][QMap] Added removeIf() and erase_if(). [ChangeLog][QtCore][QMultiMap] Added removeIf() and erase_if(). [ChangeLog][QtCore][QHash] Added removeIf() and erase_if(). [ChangeLog][QtCore][QMultiHash] Added removeIf() and erase_if(). Change-Id: Ie40aadf6217d7a4126a626c390d530812ebcf020 Reviewed-by: Andrei Golubev Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- .../tst_containerapisymmetry.cpp | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'tests/auto/corelib') diff --git a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp index 4625353139..08fb9dcdc6 100644 --- a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp +++ b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp @@ -334,6 +334,9 @@ private: template void erase_if_impl() const; + template + void erase_if_associative_impl() const; + private Q_SLOTS: void erase_QList() { erase_impl>(); } void erase_QVarLengthArray() { erase_impl>(); } @@ -355,6 +358,10 @@ private Q_SLOTS: erase_if_impl>(); #endif } + void erase_if_QMap() { erase_if_associative_impl>(); } + void erase_if_QMultiMap() {erase_if_associative_impl>(); } + void erase_if_QHash() { erase_if_associative_impl>(); } + void erase_if_QMultIHash() { erase_if_associative_impl>(); } }; void tst_ContainerApiSymmetry::init() @@ -647,6 +654,17 @@ Container make(int size) return c; } +template +Container makeAssociative(int size) +{ + using K = typename Container::key_type; + using V = typename Container::mapped_type; + Container c; + for (int i = 1; i <= size; ++i) + c.insert(K(i), V(i)); + return c; +} + static QString s_string = QStringLiteral("\1\2\3\4\5\6\7"); template <> QString make(int size) { return s_string.left(size); } @@ -728,5 +746,54 @@ void tst_ContainerApiSymmetry::erase_if_impl() const QCOMPARE(c.size(), S(0)); } +template +void tst_ContainerApiSymmetry::erase_if_associative_impl() const +{ + using S = typename Container::size_type; + using K = typename Container::key_type; + using V = typename Container::mapped_type; + using I = typename Container::iterator; + using P = std::pair; + + auto c = makeAssociative(20); + QCOMPARE(c.size(), S(20)); + + auto result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 2 == 0; }); + QCOMPARE(result, S(10)); + QCOMPARE(c.size(), S(10)); + + result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 3 == 0; }); + QCOMPARE(result, S(3)); + QCOMPARE(c.size(), S(7)); + + result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 42 == 0; }); + QCOMPARE(result, S(0)); + QCOMPARE(c.size(), S(7)); + + result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 2 == 1; }); + QCOMPARE(result, S(7)); + QCOMPARE(c.size(), S(0)); + + // same, but with a predicate taking a Qt iterator + c = makeAssociative(20); + QCOMPARE(c.size(), S(20)); + + result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 2 == 0; }); + QCOMPARE(result, S(10)); + QCOMPARE(c.size(), S(10)); + + result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 3 == 0; }); + QCOMPARE(result, S(3)); + QCOMPARE(c.size(), S(7)); + + result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 42 == 0; }); + QCOMPARE(result, S(0)); + QCOMPARE(c.size(), S(7)); + + result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 2 == 1; }); + QCOMPARE(result, S(7)); + QCOMPARE(c.size(), S(0)); +} + QTEST_APPLESS_MAIN(tst_ContainerApiSymmetry) #include "tst_containerapisymmetry.moc" -- cgit v1.2.3