summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qduplicatetracker_p.h20
-rw-r--r--tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp44
2 files changed, 56 insertions, 8 deletions
diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h
index 9f7b7a9e40..41b7590d46 100644
--- a/src/corelib/tools/qduplicatetracker_p.h
+++ b/src/corelib/tools/qduplicatetracker_p.h
@@ -89,6 +89,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;
void reserve(qsizetype n) { set.reserve(n); }
[[nodiscard]] bool hasSeen(const T &s)
@@ -117,11 +124,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 f4f038ca94..41a1e791a7 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
@@ -173,12 +179,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));
+ }
}
}