30class QDuplicateTracker {
31#ifdef __cpp_lib_memory_resource
32 template <
typename HT>
34 size_t storedSeed = QHashSeed::globalSeed();
35 size_t operator()(
const HT &t)
const {
36 return QHashPrivate::calculateHash(t, storedSeed);
40 struct node_guesstimate {
void *next; size_t hash; T value; };
41 static constexpr size_t bufferSize(size_t N) {
42 return N *
sizeof(
void*)
43 + N *
sizeof(node_guesstimate);
46 char buffer[bufferSize(Prealloc)];
47 std::pmr::monotonic_buffer_resource res{buffer,
sizeof buffer};
48 using Set = std::pmr::unordered_set<T, QHasher<T>>;
49 Set set{Prealloc, &res};
51 class Set :
public QSet<T> {
52 qsizetype setSize = 0;
54 explicit Set(qsizetype n) : QSet<T>{}
57 auto insert(
const T &e) {
58 auto it = QSet<T>::insert(e);
59 const auto n =
this->size();
60 return std::pair{it, std::exchange(setSize, n) != n};
64 auto it = QSet<T>::insert(std::move(e));
65 const auto n =
this->size();
66 return std::pair{it, std::exchange(setSize, n) != n};
71 Q_DISABLE_COPY_MOVE(QDuplicateTracker)
73 static constexpr inline bool uses_pmr =
74 #ifdef __cpp_lib_memory_resource
80 QDuplicateTracker() {}
81 explicit QDuplicateTracker(qsizetype n)
82#ifdef __cpp_lib_memory_resource
83 : set{size_t(n), &res}
88 Q_DECL_DEPRECATED_X(
"Pass the capacity to reserve() to the ctor instead.")
89 void reserve(qsizetype n) { set.reserve(n); }
90 [[nodiscard]]
bool hasSeen(
const T &s)
92 return !set.insert(s).second;
94 [[nodiscard]]
bool hasSeen(T &&s)
96 return !set.insert(std::move(s)).second;
99 [[nodiscard]]
bool contains(
const T &s)
const
101 return set.find(s) != set.end();
104 template <
typename C>
105 void appendTo(C &c)
const &
107 for (
const auto &e : set)
111 template <
typename C>
112 void appendTo(C &c) &&
114 if constexpr (uses_pmr) {
116 c.push_back(std::move(set.extract(set.begin()).value()));
124#ifdef __cpp_lib_memory_resource
134 set = Set{Prealloc, &res};