8#include <QtCore/qalgorithms.h>
9#include <QtCore/qcontainertools_impl.h>
10#include <QtCore/qhashfunctions.h>
11#include <QtCore/qiterator.h>
12#include <QtCore/qlist.h>
13#include <QtCore/qrefcount.h>
15#include <initializer_list>
29template <
typename T,
typename =
void>
34 std::is_convertible_v<decltype(qHash(std::declval<const T &>(), std::declval<size_t>())),
size_t>
37template <
typename T,
typename =
void>
42 std::is_convertible_v<decltype(std::hash<T>()(std::declval<const T &>(), std::declval<size_t>())),
size_t>
45template <
typename T,
typename =
void>
50 std::is_convertible_v<decltype(std::hash<T>()(std::declval<const T &>())),
size_t>
56 if constexpr (HasQHashOverload<T>) {
58 }
else if constexpr (HasStdHashSpecializationWithSeed<T>) {
59 return std::hash<T>()(
t,
seed);
60 }
else if constexpr (HasStdHashSpecializationWithoutSeed<T>) {
62 return std::hash<T>()(
t);
64 static_assert(
sizeof(T) == 0,
"The key type must have a qHash overload or a std::hash specialization");
69template <
typename Key,
typename T>
77 template<
typename ...Args>
79 {
new (
n)
Node{ std::move(k), T(std::forward<Args>(
args)...) }; }
80 template<
typename ...Args>
82 {
new (
n)
Node{
Key(k), T(std::forward<Args>(
args)...) }; }
83 template<
typename ...Args>
90 return std::move(
value);
95template <
typename Key>
101 template<
typename ...Args>
103 {
new (
n)
Node{ std::move(k) }; }
104 template<
typename ...Args>
106 {
new (
n)
Node{ k }; }
107 template<
typename ...Args>
147template <
typename Key,
typename T>
157 template<
typename ...Args>
160 template<
typename ...Args>
202 template<
typename ...Args>
206 e->next = std::exchange(
value, e);
208 template<
typename ...Args>
211 value->value = T(std::forward<Args>(
args)...);
215template<
typename Node>
238template<
typename Node>
268 if constexpr (!std::is_trivially_destructible<Node>::value) {
290 void erase(
size_t bucket)
noexcept(std::is_nothrow_destructible<Node>::value)
343 void moveFromSpan(
Span &fromSpan,
size_t fromIndex,
size_t to)
noexcept(std::is_nothrow_move_constructible_v<Node>)
356 size_t fromOffset = fromSpan.offsets[fromIndex];
358 Entry &fromEntry = fromSpan.entries[fromOffset];
360 if constexpr (isRelocatable<Node>()) {
361 memcpy(&toEntry, &fromEntry,
sizeof(
Entry));
363 new (&toEntry.node())
Node(std::move(fromEntry.node()));
364 fromEntry.node().~Node();
366 fromEntry.nextFree() = fromSpan.nextFree;
367 fromSpan.nextFree =
static_cast<unsigned char>(fromOffset);
397 if constexpr (isRelocatable<Node>()) {
416namespace GrowthPolicy {
419 constexpr int SizeDigits = std::numeric_limits<size_t>::digits;
423 if (requestedCapacity <= 64)
434 return (std::numeric_limits<size_t>::max)();
435 return size_t(1) << (SizeDigits -
count + 1);
439 return hash & (nBuckets - 1);
443template <
typename Node>
446template <
typename Node>
462 return (std::numeric_limits<ptrdiff_t>::max)() /
sizeof(
Span);
487 advance_impl(
d,
d->spans);
491 advance_impl(
d,
nullptr);
517 return lhs.span == rhs.span && lhs.index == rhs.index;
521 void advance_impl(
const Data *
d,
Span *whenAtEnd)
noexcept
541 constexpr qptrdiff MaxSpanCount = (std::numeric_limits<qptrdiff>::max)() /
sizeof(
Span);
550 return R{
new Span[nSpans], nSpans };
562 for (
size_t s = 0;
s < nSpans; ++
s) {
571 new (newNode)
Node(
n);
647 for (
size_t s = 0;
s < oldNSpans; ++
s) {
656 new (newNode)
Node(std::move(
n));
682 static_assert(std::is_same_v<std::remove_cv_t<Key>, K> ||
683 QHashHeterogeneousSearch<std::remove_cv_t<Key>, K>
::value);
705 if (bucket.isUnused())
707 return bucket.node();
722 return {
it.toIterator(
this),
true };
732 return {
it.toIterator(
this),
false };
735 void erase(
Bucket bucket)
noexcept(std::is_nothrow_destructible<Node>::value)
737 Q_ASSERT(bucket.span->hasNode(bucket.index));
738 bucket.span->erase(bucket.index);
744 next.advanceWrapped(
this);
751 if (newBucket ==
next) {
754 }
else if (newBucket == bucket) {
756 if (
next.span == bucket.span) {
757 bucket.span->moveLocal(
next.index, bucket.index);
760 bucket.span->moveFromSpan(*
next.span,
next.index, bucket.index);
765 newBucket.advanceWrapped(
this);
776template <
typename Node>
780 const Data<Node> *
d =
nullptr;
792 bool atEnd() const noexcept {
return !
d; }
811 {
return !(*
this ==
other); }
818template <
typename Key,
typename T>
853 static_assert(std::is_nothrow_destructible_v<Key>,
"Types with throwing destructors are not supported in Qt containers.");
854 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
856 if (
d && !
d->ref.deref())
866 if (
d && !
d->ref.deref())
874 :
d(std::exchange(
other.d,
nullptr))
877 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(
QHash)
879 template <
typename InputIterator>
880 QHash(InputIterator
f, InputIterator l);
882 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
891 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
903 template <
typename AKey = Key,
typename AT = T>
913 if (
i ==
end() || !
i.i.node()->valuesEqual(
it.i.node()))
919 template <
typename AKey = Key,
typename AT = T>
921 {
return !(*
this ==
other); }
928 inline bool isEmpty() const noexcept {
return !
d ||
d->size == 0; }
948 inline bool isDetached() const noexcept {
return d && !
d->ref.isShared(); }
953 if (
d && !
d->ref.deref())
960 return removeImpl(
key);
963 template <
typename K>
bool removeImpl(
const K &
key)
967 auto it =
d->findBucket(
key);
968 size_t bucket =
it.toBucketIndex(
d);
970 it =
typename Data::Bucket(
d, bucket);
979 template <
typename Predicate>
987 return takeImpl(
key);
990 template <
typename K> T takeImpl(
const K &
key)
994 auto it =
d->findBucket(
key);
995 size_t bucket =
it.toBucketIndex(
d);
997 it =
typename Data::Bucket(
d, bucket);
1001 T
value =
it.node()->takeValue();
1011 return d->findNode(
key) !=
nullptr;
1019 template <
typename Fn>
Key keyImpl(
const T &
value, Fn &&defaultFn)
const noexcept
1023 while (
i !=
end()) {
1036 return keyImpl(
value, [] {
return Key(); });
1040 return keyImpl(
value, [&] {
return defaultKey; });
1044 template <
typename K,
typename Fn> T valueImpl(
const K &
key, Fn &&defaultValue)
const noexcept
1051 return defaultValue();
1056 return valueImpl(
key, [] {
return T(); });
1061 return valueImpl(
key, [&] {
return defaultValue; });
1066 return operatorIndexImpl(
key);
1069 template <
typename K> T &operatorIndexImpl(
const K &
key)
1077 return result.it.node()->value;
1091 while (
i !=
end()) {
1093 res.append(
i.key());
1120 inline const
Key &
key() const noexcept {
return i.node()->key; }
1121 inline T &
value() const noexcept {
return i.node()->value; }
1163 inline const Key &
key() const noexcept {
return i.node()->key; }
1164 inline const T &
value() const noexcept {
return i.node()->value; }
1165 inline const T &
operator*() const noexcept {
return i.node()->value; }
1166 inline const T *
operator->() const noexcept {
return &
i.node()->value; }
1249 return equal_range_impl(*
this,
key);
1253 return equal_range_impl(*
this,
key);
1256 template <
typename Hash,
typename K>
static auto equal_range_impl(Hash &self,
const K &
key)
1259 auto second =
first;
1260 if (second !=
decltype(
first){})
1262 return std::make_pair(
first, second);
1265 template <
typename K>
iterator findImpl(
const K &
key)
1269 auto it =
d->findBucket(
key);
1270 size_t bucket =
it.toBucketIndex(d);
1272 it =
typename Data::Bucket(d, bucket);
1281 auto it =
d->findBucket(
key);
1293 return findImpl(
key);
1297 return constFindImpl(
key);
1323 template <
typename ...Args>
1330 template <
typename ...Args>
1334 if (
d->shouldGrow())
1335 return emplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
1336 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1339 const auto copy = *
this;
1341 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1352 template <
typename ...Args>
1359 result.it.node()->emplaceValue(std::forward<Args>(
args)...);
1364#ifdef __cpp_concepts
1365 bool remove(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1367 return removeImpl(
key);
1369 T
take(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1371 return takeImpl(
key);
1373 bool contains(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1377 qsizetype count(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1381 T
value(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
1383 return valueImpl(
key, [] {
return T(); });
1385 T
value(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key,
const T &defaultValue)
const noexcept
1387 return valueImpl(
key, [&] {
return defaultValue; });
1389 T &
operator[](
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1391 return operatorIndexImpl(
key);
1393 const T
operator[](
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
1397 std::pair<iterator, iterator>
1398 equal_range(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1400 return equal_range_impl(*
this,
key);
1402 std::pair<const_iterator, const_iterator>
1403 equal_range(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
1405 return equal_range_impl(*
this,
key);
1407 iterator find(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
1409 return findImpl(
key);
1411 const_iterator find(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
1413 return constFindImpl(
key);
1423template <
typename Key,
typename T>
1450 template <
typename InputIterator>
1453 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
1461 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
1477 static_assert(std::is_nothrow_destructible_v<Key>,
"Types with throwing destructors are not supported in Qt containers.");
1478 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
1480 if (
d && !
d->ref.deref())
1490 if (
d && !
d->ref.deref())
1493 m_size =
other.m_size;
1498 :
d(std::exchange(
other.d,
nullptr)),
1499 m_size(std::exchange(
other.m_size, 0))
1521 std::swap(m_size,
other.m_size);
1525 template <
typename AKey = Key,
typename AT = T>
1530 if (m_size !=
other.m_size)
1537 if (
d->size !=
other.d->size)
1540 auto *
n =
d->findNode(
it.node()->key);
1547 if (oe->value == e->
value)
1559 template <
typename AKey = Key,
typename AT = T>
1561 {
return !(*
this ==
other); }
1569 inline bool isEmpty() const noexcept {
return !m_size; }
1585 inline bool isDetached() const noexcept {
return d && !
d->ref.isShared(); }
1590 if (
d && !
d->ref.deref())
1598 return removeImpl(
key);
1601 template <
typename K>
qsizetype removeImpl(
const K &
key)
1605 auto it =
d->findBucket(
key);
1606 size_t bucket =
it.toBucketIndex(d);
1608 it =
typename Data::Bucket(d, bucket);
1620 template <
typename Predicate>
1628 return takeImpl(
key);
1631 template <
typename K> T takeImpl(
const K &
key)
1635 auto it =
d->findBucket(
key);
1636 size_t bucket =
it.toBucketIndex(d);
1638 it =
typename Data::Bucket(d, bucket);
1642 Chain *e =
it.node()->value;
1644 T
t = std::move(e->value);
1646 it.node()->value = e->next;
1662 return d->findNode(
key) !=
nullptr;
1666 template <
typename Fn>
Key keyImpl(
const T &
value, Fn &&defaultValue)
const noexcept
1669 auto i =
d->begin();
1670 while (
i !=
d->end()) {
1671 Chain *e =
i.node()->value;
1672 if (e->contains(
value))
1673 return i.node()->key;
1678 return defaultValue();
1683 return keyImpl(
value, [] {
return Key(); });
1687 return keyImpl(
value, [&] {
return defaultKey; });
1691 template <
typename K,
typename Fn> T valueImpl(
const K &
key, Fn &&defaultValue)
const noexcept
1697 return n->value->value;
1700 return defaultValue();
1705 return valueImpl(
key, [] {
return T(); });
1709 return valueImpl(
key, [&] {
return defaultValue; });
1714 return operatorIndexImpl(
key);
1717 template <
typename K> T &operatorIndexImpl(
const K &
key)
1723 if (!
result.initialized) {
1727 return result.it.node()->value->value;
1740 auto i =
d->begin();
1741 while (
i !=
d->end()) {
1742 res.append(
i.node()->key);
1754 while (
i !=
end()) {
1756 res.append(
i.key());
1765 return valuesImpl(
key);
1768 template <
typename K> QList<T> valuesImpl(
const K &
key)
const
1774 Chain *e =
n->value;
1793 Chain **e =
nullptr;
1796 if (!
it.atEnd() && !e) {
1797 e = &
it.node()->value;
1811 inline const
Key &
key() const noexcept {
return i.node()->key; }
1812 inline T &
value() const noexcept {
return (*e)->value; }
1813 inline T &
operator*() const noexcept {
return (*e)->value; }
1845 Chain **e =
nullptr;
1848 if (!
it.atEnd() && !e) {
1849 e = &
it.node()->value;
1864 inline const Key &
key() const noexcept {
return i.node()->key; }
1865 inline T &
value() const noexcept {
return (*e)->value; }
1866 inline T &
operator*() const noexcept {
return (*e)->value; }
1943 if (
d->ref.isShared()) {
1954 i =
d->detachedIterator(
i);
1975 if (
i.e == &
i.i.node()->value) {
1998 template <
typename K>
iterator findImpl(
const K &
key)
2002 auto it =
d->findBucket(
key);
2003 size_t bucket =
it.toBucketIndex(d);
2005 it =
typename Data::Bucket(d, bucket);
2015 auto it =
d->findBucket(
key);
2023 return findImpl(
key);
2027 return constFindImpl(
key);
2031 return constFindImpl(
key);
2039 template <
typename ...Args>
2045 template <
typename ...Args>
2049 if (
d->shouldGrow())
2050 return emplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
2051 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
2054 const auto copy = *
this;
2056 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
2072 template <
typename ...Args>
2078 template <
typename ...Args>
2082 if (
d->shouldGrow())
2083 return emplaceReplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
2084 return emplaceReplace_helper(std::move(
key), std::forward<Args>(
args)...);
2087 const auto copy = *
this;
2089 return emplaceReplace_helper(std::move(
key), std::forward<Args>(
args)...);
2093 { this->
unite(other);
return *
this; }
2102 template <
typename K>
bool containsImpl(
const K &
key,
const T &
value)
const noexcept
2106 auto n =
d->findNode(
key);
2109 return n->value->contains(
value);
2122 auto it =
d->findBucket(
key);
2123 size_t bucket =
it.toBucketIndex(d);
2125 it =
typename Data::Bucket(d, bucket);
2130 Chain **e = &
it.node()->value;
2141 if (!
it.node()->value)
2151 return countImpl(
key);
2154 template <
typename K>
qsizetype countImpl(
const K &
key)
const noexcept
2158 auto it =
d->findBucket(
key);
2162 Chain *e =
it.node()->value;
2177 template <
typename K>
qsizetype countImpl(
const K &
key,
const T &
value)
const noexcept
2181 auto it =
d->findBucket(
key);
2185 Chain *e =
it.node()->value;
2187 if (e->value ==
value)
2208 while (
i !=
end &&
i.key() ==
key) {
2235 }
else if (
other.isEmpty()) {
2240 for (
auto cit =
copy.cbegin(); cit !=
copy.cend(); ++cit)
2248 for (
auto cit =
other.cbegin(); cit !=
other.cend(); ++cit)
2255 if (!
other.isDetached()) {
2261 emplace(std::move(
it.node()->key), std::move(
it.node()->takeValue()));
2268 return equal_range_impl(
key);
2271 template <
typename K> std::pair<iterator, iterator> equal_range_impl(
const K &
key)
2275 auto pair = std::as_const(*this).equal_range(
key);
2282 return equal_range_impl(
key);
2285 template <
typename K> std::pair<const_iterator, const_iterator> equal_range_impl(
const K &
key)
const noexcept
2290 auto bucket =
d->findBucket(
key);
2291 if (bucket.isUnused())
2293 auto it = bucket.toIterator(d);
2299 void detach_helper()
2305 Data *dd =
new Data(*d);
2306 if (!
d->ref.deref())
2311 template<
typename... Args>
2318 result.it.node()->insertMulti(std::forward<Args>(
args)...);
2323 template<
typename... Args>
2327 if (!
result.initialized) {
2331 result.it.node()->emplaceValue(std::forward<Args>(
args)...);
2337#ifdef __cpp_concepts
2340 return removeImpl(
key);
2342 T
take(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
2344 return takeImpl(
key);
2346 bool contains(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2350 return d->findNode(
key) !=
nullptr;
2352 T
value(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2354 return valueImpl(
key, [] {
return T(); });
2356 T
value(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key,
const T &defaultValue)
const noexcept
2358 return valueImpl(
key, [&] {
return defaultValue; });
2360 T &
operator[](
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
2362 return operatorIndexImpl(
key);
2364 const T
operator[](
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2368 QList<T>
values(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
2370 return valuesImpl(
key);
2372 iterator find(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
2374 return findImpl(
key);
2378 return constFindImpl(
key);
2380 const_iterator find(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2382 return constFindImpl(
key);
2384 bool contains(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key,
const T &
value)
const noexcept
2392 qsizetype count(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2394 return countImpl(
key);
2396 qsizetype count(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key,
const T &
value)
const noexcept
2400 iterator find(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key,
const T &
value)
2412 std::pair<iterator, iterator>
2413 equal_range(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
2415 return equal_range_impl(
key);
2417 std::pair<const_iterator, const_iterator>
2418 equal_range(
const QHashPrivate::HeterogeneouslySearchableWith<Key>
auto &
key)
const noexcept
2420 return equal_range_impl(
key);
2430template <
class Key,
class T>
2437 size_t h = combine(
seed,
it.key());
2439 hash += combine(
h,
it.value());
2444template <
class Key,
class T>
2451 size_t h = combine(
seed,
it.key());
2453 hash += combine(
h,
it.value());
2458template <
typename Key,
typename T,
typename Predicate>
2464template <
typename Key,
typename T,
typename Predicate>
const_iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool operator==(const const_iterator &o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
bool operator!=(const const_iterator &o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
const T & value() const noexcept
Returns the current item's value.
const T & operator*() const noexcept
Returns the current item's value.
std::forward_iterator_tag iterator_category
constexpr const_iterator() noexcept=default
Constructs an uninitialized iterator.
const_iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
const T * operator->() const noexcept
Returns a pointer to the current item's value.
const Key & key() const noexcept
Returns the current item's key.
bool operator==(const const_iterator &o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
bool operator!=(const const_iterator &o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
T & value() const noexcept
Returns a modifiable reference to the current item's value.
constexpr iterator() noexcept=default
Constructs an uninitialized iterator.
bool operator==(const iterator &o) const noexcept
std::forward_iterator_tag iterator_category
T * operator->() const noexcept
Returns a pointer to the current item's value.
T & operator*() const noexcept
Returns a modifiable reference to the current item's value.
iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool operator!=(const iterator &o) const noexcept
key_iterator() noexcept=default
key_iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
const_iterator base() const noexcept
Returns the underlying const_iterator this key_iterator is based on.
const Key * operator->() const noexcept
Returns a pointer to the current item's key.
bool operator!=(key_iterator o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
key_iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
const_iterator::iterator_category iterator_category
bool operator==(key_iterator o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
const Key & operator*() const noexcept
Returns the current item's key.
key_iterator keyEnd() const noexcept
void squeeze()
Reduces the size of the QHash's internal hash table to save memory.
std::pair< const_iterator, const_iterator > equal_range(const Key &key) const noexcept
bool remove(const Key &key)
Removes the item that has the key from the hash.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
const_iterator cbegin() const noexcept
qsizetype size() const noexcept
Returns the number of items in the hash.
T & operator[](const Key &key)
Returns the value associated with the key as a modifiable reference.
float load_factor() const noexcept
Returns the current load factor of the QHash's internal hash table.
~QHash()
Destroys the hash.
QHash(QHash &&other) noexcept
Move-constructs a QHash instance, making it point at the same object that other was pointing to.
QHash(InputIterator f, InputIterator l)
const_iterator constFind(const Key &key) const noexcept
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
qsizetype size_type
Typedef for int.
key_value_iterator keyValueEnd()
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
key_value_iterator keyValueBegin()
auto asKeyValueRange() const &&
void reserve(qsizetype size)
Ensures that the QHash's internal hash table has space to store at least size items without having to...
iterator emplace(const Key &key, Args &&... args)
T value(const Key &key, const T &defaultValue) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
const T operator[](const Key &key) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it.
const_key_value_iterator constKeyValueEnd() const noexcept
qsizetype difference_type
Typedef for ptrdiff_t.
bool isDetached() const noexcept
Key key_type
Typedef for Key.
QKeyValueIterator< const Key &, T &, iterator > key_value_iterator
\inmodule QtCore
iterator Iterator
Qt-style synonym for QHash::iterator.
QKeyValueIterator< const Key &, const T &, const_iterator > const_key_value_iterator
\inmodule QtCore
Key key(const T &value, const Key &defaultKey) const noexcept
static float max_load_factor() noexcept
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
iterator erase(const_iterator it)
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
QTypeTraits::compare_eq_result_container< QHash, AKey, AT > operator==(const QHash &other) const noexcept
Returns true if other is equal to this hash; otherwise returns false.
const_key_value_iterator keyValueEnd() const noexcept
key_iterator keyBegin() const noexcept
const_key_value_iterator keyValueBegin() const noexcept
qsizetype count() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype removeIf(Predicate pred)
T value(const Key &key) const noexcept
void swap(QHash &other) noexcept
bool isSharedWith(const QHash &other) const noexcept
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
QHash & operator=(const QHash &other) noexcept(std::is_nothrow_destructible< Node >::value)
Assigns other to this hash and returns a reference to this hash.
size_t bucket_count() const noexcept
void insert(const QHash &hash)
auto asKeyValueRange() &&
friend class const_iterator
const_iterator cend() const noexcept
auto asKeyValueRange() const &
QHash(InputIterator f, InputIterator l)
std::pair< iterator, iterator > equal_range(const Key &key)
const_iterator ConstIterator
Qt-style synonym for QHash::const_iterator.
T mapped_type
Typedef for T.
static size_t max_bucket_count() noexcept
const_iterator find(const Key &key) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Key key(const T &value) const noexcept
const T & const_reference
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
QList< Key > keys(const T &value) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QTypeTraits::compare_eq_result_container< QHash, AKey, AT > operator!=(const QHash &other) const noexcept
Returns true if other is not equal to this hash; otherwise returns false.
bool empty() const noexcept
This function is provided for STL compatibility.
qsizetype count(const Key &key) const noexcept
Returns the number of items associated with the key.
qsizetype capacity() const noexcept
Returns the number of buckets in the QHash's internal hash table.
bool isEmpty() const noexcept
Returns true if the hash contains no items; otherwise returns false.
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
QHash() noexcept=default
Constructs an empty hash.
iterator emplace(Key &&key, Args &&... args)
Inserts a new element into the container.
QHash(const QHash &other) noexcept
Constructs a copy of other.
const_key_value_iterator constKeyValueBegin() const noexcept
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
const_iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
T & value() const noexcept
Returns the current item's value.
const Key & key() const noexcept
Returns the current item's key.
std::forward_iterator_tag iterator_category
bool operator!=(const const_iterator &o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
T * operator->() const noexcept
Returns a pointer to the current item's value.
constexpr const_iterator() noexcept=default
Constructs an uninitialized iterator.
T & operator*() const noexcept
Returns the current item's value.
const_iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool operator==(const const_iterator &o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
T & value() const noexcept
Returns a modifiable reference to the current item's value.
constexpr iterator() noexcept=default
Constructs an uninitialized iterator.
bool operator==(const const_iterator &o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
T * operator->() const noexcept
Returns a pointer to the current item's value.
bool operator!=(const iterator &o) const noexcept
bool operator!=(const const_iterator &o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
bool operator==(const iterator &o) const noexcept
T & operator*() const noexcept
Returns a modifiable reference to the current item's value.
iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::forward_iterator_tag iterator_category
const_iterator base() const noexcept
Returns the underlying const_iterator this key_iterator is based on.
const_iterator::iterator_category iterator_category
key_iterator() noexcept=default
const Key * operator->() const noexcept
Returns a pointer to the current item's key.
bool operator!=(key_iterator o) const noexcept
Returns true if other points to a different item than this iterator; otherwise returns false.
key_iterator operator++(int) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
key_iterator & operator++() noexcept
The prefix ++ operator ({++i}) advances the iterator to the next item in the hash and returns an iter...
bool operator==(key_iterator o) const noexcept
Returns true if other points to the same item as this iterator; otherwise returns false.
const Key & operator*() const noexcept
Returns the current item's key.
const_key_value_iterator constKeyValueEnd() const noexcept
const_iterator find(const Key &key) const noexcept
const_key_value_iterator keyValueBegin() const noexcept
const_iterator find(const Key &key, const T &value) const noexcept
const_key_value_iterator keyValueEnd() const noexcept
QMultiHash & unite(const QHash< Key, T > &other)
iterator find(const Key &key, const T &value)
QMultiHash(const QHash< Key, T > &other)
Constructs a copy of other (which can be a QHash or a QMultiHash).
bool contains(const Key &key, const T &value) const noexcept
const_iterator constFind(const Key &key, const T &value) const noexcept
std::pair< iterator, iterator > equal_range(const Key &key)
QMultiHash(QHash< Key, T > &&other)
QTypeTraits::compare_eq_result_container< QMultiHash, AKey, AT > operator==(const QMultiHash &other) const noexcept
iterator find(const Key &key)
auto asKeyValueRange() &&
float load_factor() const noexcept
bool isSharedWith(const QMultiHash &other) const noexcept
key_value_iterator keyValueBegin() noexcept
QMultiHash(const QMultiHash &other) noexcept
std::pair< const_iterator, const_iterator > equal_range(const Key &key) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
iterator detach(const_iterator it)
QMultiHash & operator=(QMultiHash &&other) noexcept(std::is_nothrow_destructible< Node >::value)
qsizetype count(const Key &key, const T &value) const noexcept
const_iterator cbegin() const noexcept
key_iterator keyBegin() const noexcept
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
iterator emplace(const Key &key, Args &&... args)
QMultiHash(QMultiHash &&other) noexcept
bool empty() const noexcept
auto asKeyValueRange() const &
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
static size_t max_bucket_count() noexcept
QMultiHash(InputIterator f, InputIterator l)
QKeyValueIterator< const Key &, const T &, const_iterator > const_key_value_iterator
\inmodule QtCore
bool isDetached() const noexcept
T value(const Key &key) const noexcept
QList< T > values(const Key &key) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
iterator emplace(Key &&key, Args &&... args)
Inserts a new element into the container.
const_iterator cend() const noexcept
qsizetype removeIf(Predicate pred)
iterator emplaceReplace(Key &&key, Args &&... args)
Inserts a new element into the container.
QMultiHash & unite(const QMultiHash &other)
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
Key key(const T &value) const noexcept
QMultiHash(InputIterator f, InputIterator l)
qsizetype capacity() const noexcept
bool contains(const Key &key) const noexcept
qsizetype difference_type
QMultiHash & operator+=(const QMultiHash &other)
Inserts all the items in the other hash into this hash and returns a reference to this hash.
QMultiHash & operator=(const QMultiHash &other) noexcept(std::is_nothrow_destructible< Node >::value)
void swap(QMultiHash &other) noexcept
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
T & operator[](const Key &key)
Returns the value associated with the key as a modifiable reference.
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it.
qsizetype remove(const Key &key)
const_iterator ConstIterator
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QMultiHash & unite(QHash< Key, T > &&other)
const T & const_reference
size_t bucket_count() const noexcept
void reserve(qsizetype size)
bool isEmpty() const noexcept
iterator emplaceReplace(const Key &key, Args &&... args)
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
QMultiHash() noexcept=default
Constructs an empty hash.
QList< Key > uniqueKeys() const
QList< Key > keys(const T &value) const
T value(const Key &key, const T &defaultValue) const noexcept
Returns the value associated with the key.
qsizetype size() const noexcept
key_value_iterator keyValueEnd() noexcept
iterator replace(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
friend class const_iterator
qsizetype count(const Key &key) const noexcept
Key key(const T &value, const Key &defaultKey) const noexcept
const_key_value_iterator constKeyValueBegin() const noexcept
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
iterator erase(const_iterator it)
qsizetype remove(const Key &key, const T &value)
key_iterator keyEnd() const noexcept
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
qsizetype count() const noexcept
QKeyValueIterator< const Key &, T &, iterator > key_value_iterator
\inmodule QtCore
QTypeTraits::compare_eq_result_container< QMultiHash, AKey, AT > operator!=(const QMultiHash &other) const noexcept
const_iterator constFind(const Key &key) const noexcept
QMultiHash operator+(const QMultiHash &other) const
Returns a hash that contains all the items in this hash in addition to all the items in other.
auto asKeyValueRange() const &&
static float max_load_factor() noexcept
const T operator[](const Key &key) const noexcept
iterator erase(const_iterator i)
iterator insert(const T &value)
QHash< int, QWidget * > hash
[35multi]
QSet< QString >::iterator it
constexpr size_t bucketForHash(size_t nBuckets, size_t hash) noexcept
constexpr size_t bucketsForCapacity(size_t requestedCapacity) noexcept
constexpr bool isRelocatable()
constexpr bool HasStdHashSpecializationWithoutSeed
size_t calculateHash(const T &t, size_t seed=0)
constexpr bool HasQHashOverload
constexpr bool HasStdHashSpecializationWithSeed
Combined button and popup list for selecting options.
std::enable_if_t< std::conjunction_v< QTypeTraits::has_operator_equal_container< Container, T >... >, bool > compare_eq_result_container
auto associative_erase_if(Container &c, Predicate &pred)
QKeyValueRange(Map &) -> QKeyValueRange< Map & >
void reserveIfForwardIterator(Container *, InputIterator, InputIterator)
QT_POPCOUNT_RELAXED_CONSTEXPR uint qCountLeadingZeroBits(quint32 v) noexcept
static jboolean copy(JNIEnv *, jobject)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
size_t qHash(const QHash< Key, T > &key, size_t seed=0) noexcept(noexcept(qHash(std::declval< Key & >())) &&noexcept(qHash(std::declval< T & >())))
qsizetype erase_if(QHash< Key, T > &hash, Predicate pred)
bool qHashEquals(const T &a, const T &b)
#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C)
#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C)
constexpr const T & qMax(const T &a, const T &b)
GLenum GLsizei GLsizei GLint * values
[15]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLfloat GLfloat GLfloat GLfloat h
GLuint GLsizei const GLuint const GLintptr * offsets
GLenum GLenum GLsizei void GLsizei void void * span
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Q_CHECK_PTR(a=new int[80])
bool operator==(const QHashDummyValue &) const noexcept
friend bool operator==(Bucket lhs, Bucket rhs) noexcept
size_t offset() const noexcept
bool isUnused() const noexcept
Bucket(const Data *d, size_t bucket) noexcept
Bucket(Span *s, size_t i) noexcept
void advance(const Data *d) noexcept
Node & nodeAtOffset(size_t offset)
iterator toIterator(const Data *d) const noexcept
friend bool operator!=(Bucket lhs, Bucket rhs) noexcept
void advanceWrapped(const Data *d) noexcept
Bucket(iterator it) noexcept
size_t toBucketIndex(const Data *d) const noexcept
void reallocationHelper(const Data &other, size_t nSpans, bool resized)
iterator begin() const noexcept
QHashPrivate::Span< Node > Span
size_t nextBucket(size_t bucket) const noexcept
typename Node::ValueType T
InsertionResult findOrInsert(const K &key) noexcept
Node * findNode(const K &key) const noexcept
QHashPrivate::iterator< Node > iterator
static Data * detached(Data *d)
iterator detachedIterator(iterator other) const noexcept
constexpr iterator end() const noexcept
bool shouldGrow() const noexcept
typename Node::KeyType Key
void rehash(size_t sizeHint=0)
void erase(Bucket bucket) noexcept(std::is_nothrow_destructible< Node >::value)
static Data * detached(Data *d, size_t size)
float loadFactor() const noexcept
static auto allocateSpans(size_t numBuckets)
Data(const Data &other, size_t reserved)
static constexpr size_t maxNumBuckets() noexcept
Bucket findBucket(const K &key) const noexcept
qsizetype free() noexcept(std::is_nothrow_destructible_v< T >)
bool contains(const T &val) const noexcept
static qsizetype freeChain(MultiNode *n) noexcept(std::is_nothrow_destructible_v< T >)
MultiNode(MultiNode &&other)
void insertMulti(Args &&... args)
MultiNode(const MultiNode &other)
static void createInPlace(MultiNode *n, const Key &k, Args &&... args)
MultiNode(const Key &k, Chain *c)
static void createInPlace(MultiNode *n, Key &&k, Args &&... args)
MultiNode(Key &&k, Chain *c) noexcept(std::is_nothrow_move_assignable_v< Key >)
MultiNodeChain< T > Chain
void emplaceValue(Args &&... args)
static void createInPlace(Node *n, const Key &k, Args &&...)
void emplaceValue(Args &&...)
bool valuesEqual(const Node *) const
static void createInPlace(Node *n, Key &&k, Args &&...)
void emplaceValue(Args &&... args)
bool valuesEqual(const Node *other) const
static void createInPlace(Node *n, const Key &k, Args &&... args)
static void createInPlace(Node *n, Key &&k, Args &&... args)
T && takeValue() noexcept(std::is_nothrow_move_assignable_v< T >)
static constexpr size_t SpanShift
static constexpr size_t LocalBucketMask
static constexpr size_t UnusedEntry
static constexpr size_t NEntries
struct QHashPrivate::Span::Entry::@178 storage
unsigned char & nextFree()
const Node & at(size_t i) const noexcept
void moveLocal(size_t from, size_t to) noexcept
void freeData() noexcept(std::is_nothrow_destructible< Node >::value)
void erase(size_t bucket) noexcept(std::is_nothrow_destructible< Node >::value)
unsigned char offsets[SpanConstants::NEntries]
Node & atOffset(size_t o) noexcept
size_t offset(size_t i) const noexcept
bool hasNode(size_t i) const noexcept
void moveFromSpan(Span &fromSpan, size_t fromIndex, size_t to) noexcept(std::is_nothrow_move_constructible_v< Node >)
const Node & atOffset(size_t o) const noexcept
Node & at(size_t i) noexcept
Node * node() const noexcept
size_t span() const noexcept
iterator operator++() noexcept
size_t index() const noexcept
bool isUnused() const noexcept
bool operator!=(iterator other) const noexcept
bool atEnd() const noexcept
bool operator==(iterator other) const noexcept
static Q_CORE_EXPORT QHashSeed globalSeed() noexcept
\threadsafe