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));
703 if (bucket.isUnused())
705 return bucket.node();
720 return {
it.toIterator(
this),
true };
730 return {
it.toIterator(
this),
false };
733 void erase(
Bucket bucket)
noexcept(std::is_nothrow_destructible<Node>::value)
735 Q_ASSERT(bucket.span->hasNode(bucket.index));
736 bucket.span->erase(bucket.index);
742 next.advanceWrapped(
this);
749 if (newBucket ==
next) {
752 }
else if (newBucket == bucket) {
754 if (
next.span == bucket.span) {
755 bucket.span->moveLocal(
next.index, bucket.index);
758 bucket.span->moveFromSpan(*
next.span,
next.index, bucket.index);
774template <
typename Node>
790 bool atEnd() const noexcept {
return !
d; }
809 {
return !(*
this ==
other); }
816template <
typename Key,
typename T>
840 for (
typename std::initializer_list<std::pair<Key,T> >::const_iterator
it =
list.
begin();
it !=
list.
end(); ++
it)
851 static_assert(std::is_nothrow_destructible_v<Key>,
"Types with throwing destructors are not supported in Qt containers.");
852 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
854 if (
d && !
d->ref.deref())
864 if (
d && !
d->ref.deref())
872 :
d(std::exchange(
other.d,
nullptr))
875 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(
QHash)
877 template <
typename InputIterator>
878 QHash(InputIterator
f, InputIterator l);
880 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
889 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
901 template <
typename AKey = Key,
typename AT = T>
911 if (
i ==
end() || !
i.i.node()->valuesEqual(
it.i.node()))
917 template <
typename AKey = Key,
typename AT = T>
919 {
return !(*
this ==
other); }
926 inline bool isEmpty() const noexcept {
return !
d ||
d->size == 0; }
946 inline bool isDetached() const noexcept {
return d && !
d->ref.isShared(); }
951 if (
d && !
d->ref.deref())
960 auto it =
d->findBucket(
key);
961 size_t bucket =
it.toBucketIndex(
d);
970 template <
typename Predicate>
979 auto it =
d->findBucket(
key);
980 size_t bucket =
it.toBucketIndex(
d);
986 T
value =
it.node()->takeValue();
995 return d->findNode(
key) !=
nullptr;
1003 const Key *keyImpl(
const T &
value)
const noexcept
1006 const_iterator
i =
begin();
1007 while (
i !=
end()) {
1020 if (
auto *k = keyImpl(
value))
1027 if (
auto *k = keyImpl(
value))
1034 T *valueImpl(
const Key &
key)
const noexcept
1046 if (T *
v = valueImpl(
key))
1054 if (T *
v = valueImpl(
key))
1057 return defaultValue;
1068 return result.it.node()->value;
1081 while (
i !=
end()) {
1083 res.append(
i.key());
1090 class const_iterator;
1110 inline const
Key &
key() const noexcept {
return i.node()->key; }
1111 inline T &
value() const noexcept {
return i.node()->value; }
1153 inline const Key &
key() const noexcept {
return i.node()->key; }
1154 inline const T &
value() const noexcept {
return i.node()->value; }
1155 inline const T &
operator*() const noexcept {
return i.node()->value; }
1156 inline const T *
operator->() const noexcept {
return &
i.node()->value; }
1240 auto second =
first;
1249 auto second =
first;
1262 auto it =
d->findBucket(
key);
1263 size_t bucket =
it.toBucketIndex(
d);
1274 auto it =
d->findBucket(
key);
1303 template <
typename ...Args>
1310 template <
typename ...Args>
1314 if (
d->shouldGrow())
1315 return emplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
1316 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1319 const auto copy = *
this;
1321 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1332 template <
typename ...Args>
1333 iterator emplace_helper(
Key &&
key, Args &&...
args)
1339 result.it.node()->emplaceValue(std::forward<Args>(
args)...);
1340 return iterator(
result.it);
1346template <
typename Key,
typename T>
1369 for (
typename std::initializer_list<std::pair<Key,T> >::const_iterator
it =
list.
begin();
it !=
list.
end(); ++
it)
1373 template <
typename InputIterator>
1376 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
1384 template <
typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
1400 static_assert(std::is_nothrow_destructible_v<Key>,
"Types with throwing destructors are not supported in Qt containers.");
1401 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
1403 if (
d && !
d->ref.deref())
1413 if (
d && !
d->ref.deref())
1416 m_size =
other.m_size;
1421 :
d(std::exchange(
other.d,
nullptr)),
1422 m_size(std::exchange(
other.m_size, 0))
1444 std::swap(m_size,
other.m_size);
1448 template <
typename AKey = Key,
typename AT = T>
1453 if (m_size !=
other.m_size)
1460 if (
d->size !=
other.d->size)
1463 auto *
n =
d->findNode(
it.node()->key);
1470 if (oe->
value ==
e->value)
1482 template <
typename AKey = Key,
typename AT = T>
1484 {
return !(*
this ==
other); }
1492 inline bool isEmpty() const noexcept {
return !m_size; }
1508 inline bool isDetached() const noexcept {
return d && !
d->ref.isShared(); }
1513 if (
d && !
d->ref.deref())
1523 auto it =
d->findBucket(
key);
1524 size_t bucket =
it.toBucketIndex(
d);
1536 template <
typename Predicate>
1545 auto it =
d->findBucket(
key);
1546 size_t bucket =
it.toBucketIndex(
d);
1554 T
t = std::move(
e->value);
1556 it.node()->value =
e->next;
1571 return d->findNode(
key) !=
nullptr;
1575 const Key *keyImpl(
const T &
value)
const noexcept
1578 auto i =
d->begin();
1579 while (
i !=
d->end()) {
1580 Chain *
e =
i.node()->value;
1582 return &
i.node()->key;
1592 if (
auto *k = keyImpl(
value))
1599 if (
auto *k = keyImpl(
value))
1606 T *valueImpl(
const Key &
key)
const noexcept
1612 return &
n->value->value;
1620 if (
auto *
v = valueImpl(
key))
1627 if (
auto *
v = valueImpl(
key))
1630 return defaultValue;
1639 if (!
result.initialized) {
1643 return result.it.node()->value->value;
1655 auto i =
d->begin();
1656 while (
i !=
d->end()) {
1657 res.append(
i.node()->key);
1669 while (
i !=
end()) {
1671 res.append(
i.key());
1693 class const_iterator;
1704 if (!
it.atEnd() && !
e) {
1705 e = &
it.node()->value;
1719 inline const
Key &
key() const noexcept {
return i.node()->key; }
1720 inline T &
value() const noexcept {
return (*e)->value; }
1721 inline T &
operator*() const noexcept {
return (*e)->value; }
1756 if (!
it.atEnd() && !
e) {
1757 e = &
it.node()->value;
1772 inline const Key &
key() const noexcept {
return i.node()->key; }
1773 inline T &
value() const noexcept {
return (*e)->value; }
1774 inline T &
operator*() const noexcept {
return (*e)->value; }
1851 if (
d->ref.isShared()) {
1862 i =
d->detachedIterator(
i);
1863 e = &
i.node()->value;
1883 if (
i.e == &
i.i.node()->value) {
1908 auto it =
d->findBucket(
key);
1909 size_t bucket =
it.toBucketIndex(
d);
1925 auto it =
d->findBucket(
key);
1935 template <
typename ...Args>
1941 template <
typename ...Args>
1945 if (
d->shouldGrow())
1946 return emplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
1947 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1950 const auto copy = *
this;
1952 return emplace_helper(std::move(
key), std::forward<Args>(
args)...);
1968 template <
typename ...Args>
1974 template <
typename ...Args>
1978 if (
d->shouldGrow())
1979 return emplaceReplace_helper(std::move(
key), T(std::forward<Args>(
args)...));
1980 return emplaceReplace_helper(std::move(
key), std::forward<Args>(
args)...);
1983 const auto copy = *
this;
1985 return emplaceReplace_helper(std::move(
key), std::forward<Args>(
args)...);
1989 { this->
unite(other);
return *
this; }
1997 auto n =
d->findNode(
key);
2000 return n->value->contains(
value);
2007 auto it =
d->findBucket(
key);
2008 size_t bucket =
it.toBucketIndex(
d);
2026 if (!
it.node()->value)
2037 auto it =
d->findBucket(
key);
2054 auto it =
d->findBucket(
key);
2085 while (
i !=
end &&
i.key() ==
key) {
2097 }
else if (
other.isEmpty()) {
2102 for (
auto cit =
copy.cbegin(); cit !=
copy.cend(); ++cit)
2110 for (
auto cit =
other.cbegin(); cit !=
other.cend(); ++cit)
2117 if (!
other.isDetached()) {
2123 emplace(std::move(
it.node()->key), std::move(
it.node()->takeValue()));
2132 auto pair = std::as_const(*this).equal_range(
key);
2141 auto bucket =
d->findBucket(
key);
2142 if (bucket.isUnused())
2144 auto it = bucket.toIterator(
d);
2151 void detach_helper()
2157 Data *dd =
new Data(*d);
2158 if (!
d->ref.deref())
2163 template<
typename... Args>
2170 result.it.node()->insertMulti(std::forward<Args>(
args)...);
2175 template<
typename... Args>
2179 if (!
result.initialized) {
2183 result.it.node()->emplaceValue(std::forward<Args>(
args)...);
2194template <
class Key,
class T>
2201 size_t h = combine(
seed,
it.key());
2203 hash += combine(
h,
it.value());
2208template <
class Key,
class T>
2215 size_t h = combine(
seed,
it.key());
2217 hash += combine(
h,
it.value());
2222template <
typename Key,
typename T,
typename Predicate>
2228template <
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.
qsizetype size_type
Typedef for int.
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.
T mapped_type
Typedef for T.
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
bool isDetached() const noexcept
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)
qsizetype difference_type
Typedef for ptrdiff_t.
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
QPair< const_iterator, const_iterator > equal_range(const Key &key) const 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.
QPair< iterator, iterator > equal_range(const Key &key)
size_t bucket_count() const noexcept
void insert(const QHash &hash)
auto asKeyValueRange() &&
const_iterator cend() const noexcept
auto asKeyValueRange() const &
QHash(InputIterator f, InputIterator l)
const_iterator ConstIterator
Qt-style synonym for QHash::const_iterator.
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.
Key key_type
Typedef for Key.
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
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
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
QPair< iterator, iterator > equal_range(const Key &key)
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...
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
QPair< 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...
const T operator[](const Key &key) const noexcept
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)
void reserveIfForwardIterator(Container *, InputIterator, InputIterator)
QT_POPCOUNT_RELAXED_CONSTEXPR uint qCountLeadingZeroBits(quint32 v) noexcept
static jboolean copy(JNIEnv *, jobject)
std::pair< T1, T2 > QPair
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]
GLsizei const GLfloat * v
[13]
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
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
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
Node * findNode(const Key &key) const noexcept
QHashPrivate::iterator< Node > iterator
static Data * detached(Data *d)
iterator detachedIterator(iterator other) const noexcept
constexpr iterator end() const noexcept
Bucket findBucket(const Key &key) 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)
InsertionResult findOrInsert(const Key &key) noexcept
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
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 >)
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