QDuplicateTracker: bring back appendTo() &&
This reverts commit c19695ab95
.
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>
This commit is contained in:
parent
6b400e3147
commit
8c49ae522d
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user