diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2021-07-12 10:10:38 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2021-07-27 17:44:30 +0200 |
commit | 8c49ae522d184deb5a9118ba2368629709ff6e85 (patch) | |
tree | 877f1302e2ac2cfc82555ddf4a71d303a9dd4465 | |
parent | 6b400e3147dcfd8cc3a393ace1bd118c93762e0c (diff) |
QDuplicateTracker: bring back appendTo() &&
This reverts commit c19695ab953c979f15bbc72c4f4a453e9a114cf6.
Just because QSet has limited API doesn't mean we can't provide this
in an efficient way for std::unordered_set :P
Added tests.
Pick-to: 6.2
Change-Id: I4f8f0e60c810acdc666cf34f929845227ed87f3b
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/corelib/tools/qduplicatetracker_p.h | 20 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp | 44 |
2 files changed, 56 insertions, 8 deletions
diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h index 565d592ac2..8d64ee5371 100644 --- a/src/corelib/tools/qduplicatetracker_p.h +++ b/src/corelib/tools/qduplicatetracker_p.h @@ -105,6 +105,13 @@ class QDuplicateTracker { #endif Q_DISABLE_COPY_MOVE(QDuplicateTracker); public: + static constexpr inline bool uses_pmr = + #ifdef __cpp_lib_memory_resource + true + #else + false + #endif + ; QDuplicateTracker() = default; explicit QDuplicateTracker(qsizetype n) #ifdef __cpp_lib_memory_resource @@ -125,11 +132,22 @@ public: } template <typename C> - void appendTo(C &c) const + void appendTo(C &c) const & { for (const auto &e : set) c.push_back(e); } + + template <typename C> + void appendTo(C &c) && + { + if constexpr (uses_pmr) { + while (!set.empty()) + c.push_back(std::move(set.extract(set.begin()).value())); + } else { + return appendTo(c); // lvalue version + } + } }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp index 6462ef0dd7..12a4103060 100644 --- a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp +++ b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp @@ -94,9 +94,15 @@ void tst_QDuplicateTracker::appendTo() QVERIFY(!tracker.hasSeen(2)); QList<int> c; - tracker.appendTo(c); + std::move(tracker).appendTo(c); std::sort(c.begin(), c.end()); QCOMPARE(c, QList<int>({ 0, 1, 2 })); + if (QDuplicateTracker<int, 2>::uses_pmr) { + // the following is only true if we use the std container + QVERIFY(!tracker.hasSeen(0)); + QVERIFY(!tracker.hasSeen(1)); + QVERIFY(!tracker.hasSeen(2)); + } } struct ConstructionCounted @@ -172,12 +178,36 @@ void tst_QDuplicateTracker::appendTo_special() QVERIFY(!tracker.hasSeen(1)); QVERIFY(!tracker.hasSeen(2)); QVERIFY(!tracker.hasSeen(3)); - QList<ConstructionCounted> a; - a.reserve(3); - tracker.appendTo(a); - for (const auto &counter : a) { - QCOMPARE(counter.moves, 1); - QCOMPARE(counter.copies, 1); + + QVERIFY(tracker.hasSeen(1)); + QVERIFY(tracker.hasSeen(2)); + QVERIFY(tracker.hasSeen(3)); + { + QList<ConstructionCounted> a; + a.reserve(3); + tracker.appendTo(a); + for (const auto &counter : a) { + QCOMPARE(counter.moves, 1); + QCOMPARE(counter.copies, 1); + } + } + QVERIFY(tracker.hasSeen(1)); + QVERIFY(tracker.hasSeen(2)); + QVERIFY(tracker.hasSeen(3)); + { + QList<ConstructionCounted> a; + a.reserve(3); + std::move(tracker).appendTo(a); + if (QDuplicateTracker<ConstructionCounted>::uses_pmr) { + // the following is only true if we use the std container + for (const auto &counter : a) { + QCOMPARE(counter.moves, 2); + QCOMPARE(counter.copies, 0); + } + QVERIFY(!tracker.hasSeen(1)); + QVERIFY(!tracker.hasSeen(2)); + QVERIFY(!tracker.hasSeen(3)); + } } } |