Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhash.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5// Qt-Security score:significant reason:default
6
7// for rand_s, _CRT_RAND_S must be #defined before #including stdlib.h.
8// put it at the beginning so some indirect inclusion doesn't break it
9#ifndef _CRT_RAND_S
10#define _CRT_RAND_S
11#endif
12#include <stdlib.h>
13#include <stdint.h>
14
15#include "qhash.h"
16
17#ifdef truncate
18#undef truncate
19#endif
20
21#include <qbitarray.h>
22#include <qstring.h>
23#include <qglobal.h>
24#include <qbytearray.h>
25#include <qdatetime.h>
26#include <qbasicatomic.h>
27#include <qendian.h>
28#include <private/qrandom_p.h>
29#include <private/qsimd_p.h>
30
31#ifndef QT_BOOTSTRAPPED
32#include <qcoreapplication.h>
33#include <qrandom.h>
34#include <private/qlocale_tools_p.h>
35#endif // QT_BOOTSTRAPPED
36
37// Implementation of SipHash algorithm
38#include "../../3rdparty/siphash/siphash.cpp"
39
40#include <array>
41#include <limits.h>
42
43#if defined(QT_NO_DEBUG) && !defined(NDEBUG)
44# define NDEBUG
45#endif
46#include <assert.h>
47
48#ifdef Q_CC_GNU
49# define Q_DECL_HOT_FUNCTION __attribute__((hot))
50#else
51# define Q_DECL_HOT_FUNCTION
52#endif
53
55
56void qt_from_latin1(char16_t *dst, const char *str, size_t size) noexcept; // qstring.cpp
57
58// We assume that pointers and size_t have the same size. If that assumption should fail
59// on a platform the code selecting the different methods below needs to be fixed.
60static_assert(sizeof(size_t) == QT_POINTER_SIZE, "size_t and pointers have different size.");
61
62namespace {
63struct HashSeedStorage
64{
65 static constexpr int SeedCount = 2;
66 QBasicAtomicInteger<quintptr> seeds[SeedCount] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) };
67
68#if !QT_SUPPORTS_INIT_PRIORITY || defined(QT_BOOTSTRAPPED)
69 constexpr HashSeedStorage() = default;
70#else
71 HashSeedStorage() { initialize(0); }
72#endif
73
74 enum State {
75 OverriddenByEnvironment = -1,
76 JustInitialized,
77 AlreadyInitialized
78 };
79 struct StateResult {
80 quintptr requestedSeed;
81 State state;
82 };
83
84 StateResult state(int which = -1);
85 Q_DECL_HOT_FUNCTION QHashSeed currentSeed(int which)
86 {
87 return { state(which).requestedSeed };
88 }
89
90 void resetSeed()
91 {
92#ifndef QT_BOOTSTRAPPED
93 if (state().state < AlreadyInitialized)
94 return;
95
96 // update the public seed
97 QRandomGenerator *generator = QRandomGenerator::system();
98 seeds[0].storeRelaxed(sizeof(size_t) > sizeof(quint32)
99 ? generator->generate64() : generator->generate());
100#endif
101 }
102
103 void clearSeed()
104 {
105 state();
106 seeds[0].storeRelaxed(0); // always write (smaller code)
107 }
108
109private:
110 Q_NEVER_INLINE Q_DECL_COLD_FUNCTION StateResult initialize(int which) noexcept;
111};
112
113[[maybe_unused]] HashSeedStorage::StateResult HashSeedStorage::initialize(int which) noexcept
114{
115 StateResult result = { 0, OverriddenByEnvironment };
116#ifdef QT_BOOTSTRAPPED
117 Q_UNUSED(which);
118 Q_UNREACHABLE_RETURN(result);
119#else
120 // can't use qEnvironmentVariableIntValue (reentrancy)
121 const char *seedstr = getenv("QT_HASH_SEED");
122 if (seedstr) {
123 auto r = qstrntoll(seedstr, strlen(seedstr), 10);
124 if (r.used > 0 && size_t(r.used) == strlen(seedstr)) {
125 if (r.result) {
126 // can't use qWarning here (reentrancy)
127 fprintf(stderr, "QT_HASH_SEED: forced seed value is not 0; ignored.\n");
128 }
129
130 // we don't have to store to the seed, since it's pre-initialized by
131 // the compiler to zero
132 return result;
133 }
134 }
135
136 // update the full seed
137 auto x = qt_initial_random_value();
138 for (int i = 0; i < SeedCount; ++i) {
139 seeds[i].storeRelaxed(x.data[i]);
140 if (which == i)
141 result.requestedSeed = x.data[i];
142 }
143 result.state = JustInitialized;
144 return result;
145#endif
146}
147
148inline HashSeedStorage::StateResult HashSeedStorage::state(int which)
149{
150 constexpr quintptr BadSeed = quintptr(Q_UINT64_C(0x5555'5555'5555'5555));
151 StateResult result = { BadSeed, AlreadyInitialized };
152
153#if defined(QT_BOOTSTRAPPED)
154 result = { 0, OverriddenByEnvironment };
155#elif !QT_SUPPORTS_INIT_PRIORITY
156 // dynamic initialization
157 static auto once = [&]() {
158 result = initialize(which);
159 return true;
160 }();
161 Q_UNUSED(once);
162#endif
163
164 if (result.state == AlreadyInitialized && which >= 0)
165 return { seeds[which].loadRelaxed(), AlreadyInitialized };
166 return result;
167}
168} // unnamed namespace
169
170/*
171 The QHash seed itself.
172*/
173#ifdef Q_DECL_INIT_PRIORITY
174Q_DECL_INIT_PRIORITY(05)
175#else
176Q_CONSTINIT
177#endif
178static HashSeedStorage qt_qhash_seed;
179
180/*
181 * Hashing for memory segments is based on the public domain MurmurHash2 by
182 * Austin Appleby. See http://murmurhash.googlepages.com/
183 */
184#if QT_POINTER_SIZE == 4
185Q_NEVER_INLINE Q_DECL_HOT_FUNCTION
186static inline uint murmurhash(const void *key, uint len, uint seed) noexcept
187{
188 // 'm' and 'r' are mixing constants generated offline.
189 // They're not really 'magic', they just happen to work well.
190
191 const unsigned int m = 0x5bd1e995;
192 const int r = 24;
193
194 // Initialize the hash to a 'random' value
195
196 unsigned int h = seed ^ len;
197
198 // Mix 4 bytes at a time into the hash
199
200 const unsigned char *data = reinterpret_cast<const unsigned char *>(key);
201 const unsigned char *end = data + (len & ~3);
202
203 while (data != end) {
204 size_t k;
205 memcpy(&k, data, sizeof(uint));
206
207 k *= m;
208 k ^= k >> r;
209 k *= m;
210
211 h *= m;
212 h ^= k;
213
214 data += 4;
215 }
216
217 // Handle the last few bytes of the input array
218 len &= 3;
219 if (len) {
220 unsigned int k = 0;
221 end += len;
222
223 while (data != end) {
224 k <<= 8;
225 k |= *data;
226 ++data;
227 }
228 h ^= k;
229 h *= m;
230 }
231
232 // Do a few final mixes of the hash to ensure the last few
233 // bytes are well-incorporated.
234
235 h ^= h >> 13;
236 h *= m;
237 h ^= h >> 15;
238
239 return h;
240}
241
242#else
243Q_NEVER_INLINE Q_DECL_HOT_FUNCTION
244static inline uint64_t murmurhash(const void *key, uint64_t len, uint64_t seed) noexcept
245{
246 const uint64_t m = 0xc6a4a7935bd1e995ULL;
247 const int r = 47;
248
249 uint64_t h = seed ^ (len * m);
250
251 const unsigned char *data = reinterpret_cast<const unsigned char *>(key);
252 const unsigned char *end = data + (len & ~7ul);
253
254 while (data != end) {
255 uint64_t k;
256 memcpy(&k, data, sizeof(uint64_t));
257
258 k *= m;
259 k ^= k >> r;
260 k *= m;
261
262 h ^= k;
263 h *= m;
264
265 data += 8;
266 }
267
268 len &= 7;
269 if (len) {
270 // handle the last few bytes of input
271 size_t k = 0;
272 end += len;
273
274 while (data != end) {
275 k <<= 8;
276 k |= *data;
277 ++data;
278 }
279 h ^= k;
280 h *= m;
281 }
282
283 h ^= h >> r;
284 h *= m;
285 h ^= h >> r;
286
287 return h;
288}
289
290#endif
291
293 None = 0,
295};
296
297template <ZeroExtension = None> static size_t
298qHashBits_fallback(const uchar *p, size_t size, size_t seed, size_t seed2) noexcept;
299template <> size_t qHashBits_fallback<None>(const uchar *p, size_t size, size_t seed, size_t seed2) noexcept
300{
301 if (size <= QT_POINTER_SIZE)
302 return murmurhash(p, size, seed);
303
304 return siphash(reinterpret_cast<const uchar *>(p), size, seed, seed2);
305}
306
307template <> size_t qHashBits_fallback<ByteToWord>(const uchar *data, size_t size, size_t seed, size_t seed2) noexcept
308{
309 auto quick_from_latin1 = [](char16_t *dest, const uchar *data, size_t size) {
310 // Quick, "inlined" version for very short blocks
311 std::copy_n(data, size, dest);
312 };
313 if (size <= QT_POINTER_SIZE / 2) {
314 std::array<char16_t, QT_POINTER_SIZE / 2> buf;
315 quick_from_latin1(buf.data(), data, size);
316 return murmurhash(buf.data(), size * 2, seed);
317 }
318
319 constexpr size_t TailSizeMask = sizeof(void *) / 2 - 1;
320 std::array<char16_t, 256> buf;
321 SipHash<> siphash(size * 2, seed, seed2);
322 ptrdiff_t offset = 0;
323 for ( ; offset + buf.size() < size; offset += buf.size()) {
324 qt_from_latin1(buf.data(), reinterpret_cast<const char *>(data) + offset, buf.size());
325 siphash.addBlock(reinterpret_cast<uint8_t *>(buf.data()), sizeof(buf));
326 }
327 if (size_t n = size - offset; n > TailSizeMask) {
328 n &= ~TailSizeMask;
329 qt_from_latin1(buf.data(), reinterpret_cast<const char *>(data) + offset, n);
330 siphash.addBlock(reinterpret_cast<uint8_t *>(buf.data()), n * 2);
331 offset += n;
332 }
333
334 quick_from_latin1(buf.data(), data + offset, size - offset);
335 return siphash.finalize(reinterpret_cast<uint8_t *>(buf.data()), (size - offset) * 2);
336}
337
338#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) // GCC
339# define QHASH_AES_SANITIZER_BUILD
340#elif __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) // Clang
341# define QHASH_AES_SANITIZER_BUILD
342#endif
343
344// When built with a sanitizer, aeshash() is rightfully reported to have a
345// heap-buffer-overflow issue. However, we consider it to be safe in this
346// specific case and overcome the problem by correctly discarding the
347// out-of-range bits. To allow building the code with sanitizer,
348// QHASH_AES_SANITIZER_BUILD is used to disable aeshash() usage.
349#if QT_COMPILER_SUPPORTS_HERE(AES) && QT_COMPILER_SUPPORTS_HERE(SSE4_2) &&
350 !defined(QHASH_AES_SANITIZER_BUILD)
351# define AESHASH
352# define QT_FUNCTION_TARGET_STRING_AES_AVX2 "avx2,aes"
353# define QT_FUNCTION_TARGET_STRING_AES_AVX512
354 QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE_AVX512 ","
355 QT_FUNCTION_TARGET_STRING_AES
356# define QT_FUNCTION_TARGET_STRING_VAES_AVX512
357 QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE_AVX512 ","
358 QT_FUNCTION_TARGET_STRING_VAES
359# undef QHASH_AES_SANITIZER_BUILD
360# if QT_POINTER_SIZE == 8
361# define mm_set1_epz _mm_set1_epi64x
362# define mm_cvtsz_si128 _mm_cvtsi64_si128
363# define mm_cvtsi128_sz _mm_cvtsi128_si64
364# define mm256_set1_epz _mm256_set1_epi64x
365# else
366# define mm_set1_epz _mm_set1_epi32
367# define mm_cvtsz_si128 _mm_cvtsi32_si128
368# define mm_cvtsi128_sz _mm_cvtsi128_si32
369# define mm256_set1_epz _mm256_set1_epi32
370# endif
371
372namespace {
373 // This is inspired by the algorithm in the Go language. See:
374 // https://github.com/golang/go/blob/01b6cf09fc9f272d9db3d30b4c93982f4911d120/src/runtime/asm_amd64.s#L1105
375 // https://github.com/golang/go/blob/01b6cf09fc9f272d9db3d30b4c93982f4911d120/src/runtime/asm_386.s#L908
376 //
377 // Even though we're using the AESENC instruction from the CPU, this code
378 // is not encryption and this routine makes no claim to be
379 // cryptographically secure. We're simply using the instruction that performs
380 // the scrambling round (step 3 in [1]) because it's just very good at
381 // spreading the bits around.
382 //
383 // Note on Latin-1 hashing (ZX == ByteToWord): for simplicity of the
384 // algorithm, we pass sizes equivalent to the UTF-16 content (ZX == None).
385 // That means we must multiply by 2 on entry, divide by 2 on pointer
386 // advancing, and load half as much data from memory (though we produce
387 // exactly as much data in registers). The compilers appear to optimize
388 // this out.
389 //
390 // [1] https://en.wikipedia.org/wiki/Advanced_Encryption_Standard#High-level_description_of_the_algorithm
391
392 template <ZeroExtension ZX, typename T> static const T *advance(const T *ptr, ptrdiff_t n)
393 {
394 if constexpr (ZX == None)
395 return ptr + n;
396
397 // see note above on ZX == ByteToWord hashing
398 auto p = reinterpret_cast<const uchar *>(ptr);
399 n *= sizeof(T);
400 return reinterpret_cast<const T *>(p + n/2);
401 }
402
403 template <ZeroExtension> static __m128i loadu128(const void *ptr);
404 template <> Q_ALWAYS_INLINE QT_FUNCTION_TARGET(AES) __m128i loadu128<None>(const void *ptr)
405 {
406 return _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
407 }
408 template <> Q_ALWAYS_INLINE QT_FUNCTION_TARGET(AES) __m128i loadu128<ByteToWord>(const void *ptr)
409 {
410 // use a MOVQ followed by PMOVZXBW
411 // the compiler usually combines them as a single, loading PMOVZXBW
412 __m128i data = _mm_loadl_epi64(static_cast<const __m128i *>(ptr));
413 return _mm_cvtepu8_epi16(data);
414 }
415
416 // hash 16 bytes, running 3 scramble rounds of AES on itself (like label "final1")
417 Q_ALWAYS_INLINE static void QT_FUNCTION_TARGET(AES) QT_VECTORCALL
418 hash16bytes(__m128i &state0, __m128i data)
419 {
420 state0 = _mm_xor_si128(state0, data);
421 state0 = _mm_aesenc_si128(state0, state0);
422 state0 = _mm_aesenc_si128(state0, state0);
423 state0 = _mm_aesenc_si128(state0, state0);
424 }
425
426 // hash twice 16 bytes, running 2 scramble rounds of AES on itself
427 template <ZeroExtension ZX>
428 static void QT_FUNCTION_TARGET(AES) QT_VECTORCALL
429 hash2x16bytes(__m128i &state0, __m128i &state1, const __m128i *src0, const __m128i *src1)
430 {
431 __m128i data0 = loadu128<ZX>(src0);
432 __m128i data1 = loadu128<ZX>(src1);
433 state0 = _mm_xor_si128(data0, state0);
434 state1 = _mm_xor_si128(data1, state1);
435 state0 = _mm_aesenc_si128(state0, state0);
436 state1 = _mm_aesenc_si128(state1, state1);
437 state0 = _mm_aesenc_si128(state0, state0);
438 state1 = _mm_aesenc_si128(state1, state1);
439 }
440
441 struct AESHashSeed
442 {
443 __m128i state0;
444 __m128i mseed2;
445 AESHashSeed(size_t seed, size_t seed2) QT_FUNCTION_TARGET(AES);
446 __m128i state1() const QT_FUNCTION_TARGET(AES);
447 __m256i state0_256() const QT_FUNCTION_TARGET(AES_AVX2)
448 { return _mm256_set_m128i(state1(), state0); }
449 };
450} // unnamed namespace
451
452Q_ALWAYS_INLINE AESHashSeed::AESHashSeed(size_t seed, size_t seed2)
453{
454 __m128i mseed = mm_cvtsz_si128(seed);
455 mseed2 = mm_set1_epz(seed2);
456
457 // mseed (epi16) = [ seed, seed >> 16, seed >> 32, seed >> 48, len, 0, 0, 0 ]
458 mseed = _mm_insert_epi16(mseed, short(seed), 4);
459 // mseed (epi16) = [ seed, seed >> 16, seed >> 32, seed >> 48, len, len, len, len ]
460 mseed = _mm_shufflehi_epi16(mseed, 0);
461
462 // merge with the process-global seed
463 __m128i key = _mm_xor_si128(mseed, mseed2);
464
465 // scramble the key
466 __m128i state0 = _mm_aesenc_si128(key, key);
467 this->state0 = state0;
468}
469
470Q_ALWAYS_INLINE __m128i AESHashSeed::state1() const
471{
472 {
473 // unlike the Go code, we don't have more per-process seed
474 __m128i state1 = _mm_aesenc_si128(state0, mseed2);
475 return state1;
476 }
477}
478
479template <ZeroExtension ZX>
480static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL
481aeshash128_16to32(__m128i state0, __m128i state1, const __m128i *src, const __m128i *srcend)
482{
483 {
484 const __m128i *src2 = advance<ZX>(srcend, -1);
485 if (advance<ZX>(src, 1) < srcend) {
486 // epilogue: between 16 and 31 bytes
487 hash2x16bytes<ZX>(state0, state1, src, src2);
488 } else if (src != srcend) {
489 // epilogue: between 1 and 16 bytes, overlap with the end
490 __m128i data = loadu128<ZX>(src2);
491 hash16bytes(state0, data);
492 }
493
494 // combine results:
495 state0 = _mm_xor_si128(state0, state1);
496 }
497
498 return mm_cvtsi128_sz(state0);
499}
500
501// load all 16 bytes and mask off the bytes past the end of the source
502static const qint8 maskarray[] = {
503 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
504 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
505};
506
507// load 16 bytes ending at the data end, then shuffle them to the beginning
508static const qint8 shufflecontrol[] = {
509 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
510 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
511};
512
513template <ZeroExtension ZX>
514static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL
515aeshash128_lt16(__m128i state0, const __m128i *src, const __m128i *srcend, size_t len)
516{
517 if (len) {
518 // We're going to load 16 bytes and mask zero the part we don't care
519 // (the hash of a short string is different from the hash of a longer
520 // including NULLs at the end because the length is in the key)
521 // WARNING: this may produce valgrind warnings, but it's safe
522
523 constexpr quintptr CachelineSize = 64;
524 __m128i data;
525
526 if ((quintptr(src) & (CachelineSize / 2)) == 0) {
527 // lower half of the cacheline:
528 __m128i mask = _mm_loadu_si128(reinterpret_cast<const __m128i *>(maskarray + 15 - len));
529 data = loadu128<ZX>(src);
530 data = _mm_and_si128(data, mask);
531 } else {
532 // upper half of the cacheline:
533 __m128i control = _mm_loadu_si128(reinterpret_cast<const __m128i *>(shufflecontrol + 15 - len));
534 data = loadu128<ZX>(advance<ZX>(srcend, -1));
535 data = _mm_shuffle_epi8(data, control);
536 }
537
538 hash16bytes(state0, data);
539 }
540 return mm_cvtsi128_sz(state0);
541}
542
543template <ZeroExtension ZX>
544static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL
545aeshash128_ge32(__m128i state0, __m128i state1, const __m128i *src, const __m128i *srcend)
546{
547 // main loop: scramble two 16-byte blocks
548 for ( ; advance<ZX>(src, 2) < srcend; src = advance<ZX>(src, 2))
549 hash2x16bytes<ZX>(state0, state1, src, advance<ZX>(src, 1));
550
551 return aeshash128_16to32<ZX>(state0, state1, src, srcend);
552}
553
554# if QT_COMPILER_SUPPORTS_HERE(VAES)
555template <ZeroExtension> static __m256i loadu256(const void *ptr);
556template <> Q_ALWAYS_INLINE QT_FUNCTION_TARGET(VAES) __m256i loadu256<None>(const void *ptr)
557{
558 return _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
559}
560template <> Q_ALWAYS_INLINE QT_FUNCTION_TARGET(VAES) __m256i loadu256<ByteToWord>(const void *ptr)
561{
562 // VPMOVZXBW xmm, ymm
563 __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
564 return _mm256_cvtepu8_epi16(data);
565}
566
567template <ZeroExtension ZX>
568static size_t QT_FUNCTION_TARGET(VAES_AVX512) QT_VECTORCALL
569aeshash256_lt32_avx256(__m256i state0, const uchar *p, size_t len)
570{
571 __m128i state0_128 = _mm256_castsi256_si128(state0);
572 if (len) {
573 __m256i data;
574 if constexpr (ZX == None) {
575 __mmask32 mask = _bzhi_u32(-1, unsigned(len));
576 data = _mm256_maskz_loadu_epi8(mask, p);
577 } else {
578 __mmask16 mask = _bzhi_u32(-1, unsigned(len) / 2);
579 __m128i data0 = _mm_maskz_loadu_epi8(mask, p);
580 data = _mm256_cvtepu8_epi16(data0);
581 }
582 __m128i data0 = _mm256_castsi256_si128(data);
583 if (len >= sizeof(__m128i)) {
584 state0 = _mm256_xor_si256(state0, data);
585 state0 = _mm256_aesenc_epi128(state0, state0);
586 state0 = _mm256_aesenc_epi128(state0, state0);
587 // we're XOR'ing the two halves so we skip the third AESENC
588 // state0 = _mm256_aesenc_epi128(state0, state0);
589
590 // XOR the two halves and extract
591 __m128i low = _mm256_extracti128_si256(state0, 0);
592 __m128i high = _mm256_extracti128_si256(state0, 1);
593 state0_128 = _mm_xor_si128(low, high);
594 } else {
595 hash16bytes(state0_128, data0);
596 }
597 }
598 return mm_cvtsi128_sz(state0_128);
599}
600
601template <ZeroExtension ZX>
602static size_t QT_FUNCTION_TARGET(VAES) QT_VECTORCALL
603aeshash256_ge32(__m256i state0, const __m128i *s, const __m128i *end, size_t len)
604{
605 static const auto hash32bytes = [](__m256i &state0, __m256i data) QT_FUNCTION_TARGET(VAES) {
606 state0 = _mm256_xor_si256(state0, data);
607 state0 = _mm256_aesenc_epi128(state0, state0);
608 state0 = _mm256_aesenc_epi128(state0, state0);
609 state0 = _mm256_aesenc_epi128(state0, state0);
610 };
611
612 // hash twice 32 bytes, running 2 scramble rounds of AES on itself
613 const auto hash2x32bytes = [](__m256i &state0, __m256i &state1, const void *src0,
614 const void *src1) QT_FUNCTION_TARGET(VAES) {
615 __m256i data0 = loadu256<ZX>(src0);
616 __m256i data1 = loadu256<ZX>(src1);
617 state0 = _mm256_xor_si256(data0, state0);
618 state1 = _mm256_xor_si256(data1, state1);
619 state0 = _mm256_aesenc_epi128(state0, state0);
620 state1 = _mm256_aesenc_epi128(state1, state1);
621 state0 = _mm256_aesenc_epi128(state0, state0);
622 state1 = _mm256_aesenc_epi128(state1, state1);
623 };
624
625 const __m256i *src = reinterpret_cast<const __m256i *>(s);
626 const __m256i *srcend = reinterpret_cast<const __m256i *>(end);
627
628 __m256i state1 = _mm256_aesenc_epi128(state0, mm256_set1_epz(len));
629
630 // main loop: scramble two 32-byte blocks
631 for ( ; advance<ZX>(src, 2) < srcend; src = advance<ZX>(src, 2))
632 hash2x32bytes(state0, state1, src, advance<ZX>(src, 1));
633
634 const __m256i *src2 = advance<ZX>(srcend, -1);
635 if (advance<ZX>(src, 1) < srcend) {
636 // epilogue: between 32 and 31 bytes
637 hash2x32bytes(state0, state1, src, src2);
638 } else if (src != srcend) {
639 // epilogue: between 1 and 32 bytes, overlap with the end
640 __m256i data = loadu256<ZX>(src2);
641 hash32bytes(state0, data);
642 }
643
644 // combine results:
645 state0 = _mm256_xor_si256(state0, state1);
646
647 // XOR the two halves and extract
648 __m128i low = _mm256_extracti128_si256(state0, 0);
649 __m128i high = _mm256_extracti128_si256(state0, 1);
650 return mm_cvtsi128_sz(_mm_xor_si128(low, high));
651}
652
653template <ZeroExtension ZX>
654static size_t QT_FUNCTION_TARGET(VAES)
655aeshash256(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept
656{
657 AESHashSeed state(seed, seed2);
658 auto src = reinterpret_cast<const __m128i *>(p);
659 const auto srcend = reinterpret_cast<const __m128i *>(advance<ZX>(p, len));
660
661 if (len < sizeof(__m128i))
662 return aeshash128_lt16<ZX>(state.state0, src, srcend, len);
663
664 if (len <= sizeof(__m256i))
665 return aeshash128_16to32<ZX>(state.state0, state.state1(), src, srcend);
666
667 return aeshash256_ge32<ZX>(state.state0_256(), src, srcend, len);
668}
669
670template <ZeroExtension ZX>
671static size_t QT_FUNCTION_TARGET(VAES_AVX512)
672aeshash256_avx256(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept
673{
674 AESHashSeed state(seed, seed2);
675 auto src = reinterpret_cast<const __m128i *>(p);
676 const auto srcend = reinterpret_cast<const __m128i *>(advance<ZX>(p, len));
677
678 if (len <= sizeof(__m256i))
679 return aeshash256_lt32_avx256<ZX>(state.state0_256(), p, len);
680
681 return aeshash256_ge32<ZX>(state.state0_256(), src, srcend, len);
682}
683# endif // VAES
684
685template <ZeroExtension ZX>
686static size_t QT_FUNCTION_TARGET(AES)
687aeshash128(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept
688{
689 AESHashSeed state(seed, seed2);
690 auto src = reinterpret_cast<const __m128i *>(p);
691 const auto srcend = reinterpret_cast<const __m128i *>(advance<ZX>(p, len));
692
693 if (len < sizeof(__m128i))
694 return aeshash128_lt16<ZX>(state.state0, src, srcend, len);
695
696 if (len <= sizeof(__m256i))
697 return aeshash128_16to32<ZX>(state.state0, state.state1(), src, srcend);
698
699 return aeshash128_ge32<ZX>(state.state0, state.state1(), src, srcend);
700}
701
702template <ZeroExtension ZX = None>
703static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept
704{
705 if constexpr (ZX == ByteToWord)
706 len *= 2; // see note above on ZX == ByteToWord hashing
707
708# if QT_COMPILER_SUPPORTS_HERE(VAES)
709 if (qCpuHasFeature(VAES)) {
710 if (qCpuHasFeature(AVX512VL))
711 return aeshash256_avx256<ZX>(p, len, seed, seed2);
712 return aeshash256<ZX>(p, len, seed, seed2);
713 }
714# endif
715 return aeshash128<ZX>(p, len, seed, seed2);
716}
717#endif // x86 AESNI
718
719#if defined(Q_PROCESSOR_ARM) && QT_COMPILER_SUPPORTS_HERE(CRYPTO) && !defined(QHASH_AES_SANITIZER_BUILD) && !defined(QT_BOOTSTRAPPED)
720QT_FUNCTION_TARGET(AES)
721static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept
722{
723 uint8x16_t key;
724# if QT_POINTER_SIZE == 8
725 uint64x2_t vseed = vcombine_u64(vcreate_u64(seed), vcreate_u64(seed2));
726 key = vreinterpretq_u8_u64(vseed);
727# else
728
729 uint32x2_t vseed = vmov_n_u32(seed);
730 vseed = vset_lane_u32(seed2, vseed, 1);
731 key = vreinterpretq_u8_u32(vcombine_u32(vseed, vseed));
732# endif
733
734 // Compared to x86 AES, ARM splits each round into two instructions
735 // and includes the pre-xor instead of the post-xor.
736 const auto hash16bytes = [](uint8x16_t &state0, uint8x16_t data) QT_FUNCTION_TARGET(AES) {
737 auto state1 = state0;
738 state0 = vaeseq_u8(state0, data);
739 state0 = vaesmcq_u8(state0);
740 auto state2 = state0;
741 state0 = vaeseq_u8(state0, state1);
742 state0 = vaesmcq_u8(state0);
743 auto state3 = state0;
744 state0 = vaeseq_u8(state0, state2);
745 state0 = vaesmcq_u8(state0);
746 state0 = veorq_u8(state0, state3);
747 };
748
749 uint8x16_t state0 = key;
750
751 if (len < 8)
752 goto lt8;
753 if (len < 16)
754 goto lt16;
755 if (len < 32)
756 goto lt32;
757
758 // rounds of 32 bytes
759 {
760 // Make state1 = ~state0:
761 uint8x16_t state1 = veorq_u8(state0, vdupq_n_u8(255));
762
763 // do simplified rounds of 32 bytes: unlike the Go code, we only
764 // scramble twice and we keep 256 bits of state
765 const auto *e = p + len - 31;
766 while (p < e) {
767 uint8x16_t data0 = vld1q_u8(p);
768 uint8x16_t data1 = vld1q_u8(p + 16);
769 auto oldstate0 = state0;
770 auto oldstate1 = state1;
771 state0 = vaeseq_u8(state0, data0);
772 state1 = vaeseq_u8(state1, data1);
773 state0 = vaesmcq_u8(state0);
774 state1 = vaesmcq_u8(state1);
775 auto laststate0 = state0;
776 auto laststate1 = state1;
777 state0 = vaeseq_u8(state0, oldstate0);
778 state1 = vaeseq_u8(state1, oldstate1);
779 state0 = vaesmcq_u8(state0);
780 state1 = vaesmcq_u8(state1);
781 state0 = veorq_u8(state0, laststate0);
782 state1 = veorq_u8(state1, laststate1);
783 p += 32;
784 }
785 state0 = veorq_u8(state0, state1);
786 }
787 len &= 0x1f;
788
789 // do we still have 16 or more bytes?
790 if (len & 0x10) {
791lt32:
792 uint8x16_t data = vld1q_u8(p);
793 hash16bytes(state0, data);
794 p += 16;
795 }
796 len &= 0xf;
797
798 if (len & 0x08) {
799lt16:
800 uint8x8_t data8 = vld1_u8(p);
801 uint8x16_t data = vcombine_u8(data8, vdup_n_u8(0));
802 hash16bytes(state0, data);
803 p += 8;
804 }
805 len &= 0x7;
806
807lt8:
808 if (len) {
809 // load the last chunk of data
810 // We're going to load 8 bytes and mask zero the part we don't care
811 // (the hash of a short string is different from the hash of a longer
812 // including NULLs at the end because the length is in the key)
813 // WARNING: this may produce valgrind warnings, but it's safe
814
815 uint8x8_t data8;
816
817 if (Q_LIKELY(quintptr(p + 8) & 0xff8)) {
818 // same page, we definitely can't fault:
819 // load all 8 bytes and mask off the bytes past the end of the source
820 static const qint8 maskarray[] = {
821 -1, -1, -1, -1, -1, -1, -1,
822 0, 0, 0, 0, 0, 0, 0,
823 };
824 uint8x8_t mask = vld1_u8(reinterpret_cast<const quint8 *>(maskarray) + 7 - len);
825 data8 = vld1_u8(p);
826 data8 = vand_u8(data8, mask);
827 } else {
828 // too close to the end of the page, it could fault:
829 // load 8 bytes ending at the data end, then shuffle them to the beginning
830 static const qint8 shufflecontrol[] = {
831 1, 2, 3, 4, 5, 6, 7,
832 -1, -1, -1, -1, -1, -1, -1,
833 };
834 uint8x8_t control = vld1_u8(reinterpret_cast<const quint8 *>(shufflecontrol) + 7 - len);
835 data8 = vld1_u8(p - 8 + len);
836 data8 = vtbl1_u8(data8, control);
837 }
838 uint8x16_t data = vcombine_u8(data8, vdup_n_u8(0));
839 hash16bytes(state0, data);
840 }
841
842 // extract state0
843# if QT_POINTER_SIZE == 8
844 return vgetq_lane_u64(vreinterpretq_u64_u8(state0), 0);
845# else
846 return vgetq_lane_u32(vreinterpretq_u32_u8(state0), 0);
847# endif
848}
849#endif
850
851size_t qHashBits(const void *p, size_t size, size_t seed) noexcept
852{
853#ifdef QT_BOOTSTRAPPED
854 // the seed is always 0 in bootstrapped mode (no seed generation code),
855 // so help the compiler do dead code elimination
856 seed = 0;
857#endif
858 // mix in the length as a secondary seed. For seed == 0, seed2 must be
859 // size, to match what we used to do prior to Qt 6.2.
860 size_t seed2 = size;
861 if (seed)
862 seed2 = qt_qhash_seed.currentSeed(1);
863
864 auto data = reinterpret_cast<const uchar *>(p);
865#ifdef AESHASH
866 if (seed && qCpuHasFeature(AES) && qCpuHasFeature(SSE4_2))
867 return aeshash(data, size, seed, seed2);
868#elif defined(Q_PROCESSOR_ARM) && QT_COMPILER_SUPPORTS_HERE(CRYPTO) && !defined(QHASH_AES_SANITIZER_BUILD) && !defined(QT_BOOTSTRAPPED)
869 if (seed && qCpuHasFeature(AES))
870 return aeshash(data, size, seed, seed2);
871#endif
872
873 return qHashBits_fallback<>(data, size, seed, seed2);
874}
875
876size_t qHash(QByteArrayView key, size_t seed) noexcept
877{
878 return qHashBits(key.constData(), size_t(key.size()), seed);
879}
880
881size_t qHash(QStringView key, size_t seed) noexcept
882{
883 return qHashBits(key.data(), key.size()*sizeof(QChar), seed);
884}
885
886#ifndef QT_BOOTSTRAPPED
887size_t qHash(const QBitArray &bitArray, size_t seed) noexcept
888{
889 qsizetype m = bitArray.d.size() - 1;
890 size_t result = qHashBits(reinterpret_cast<const uchar *>(bitArray.d.constData()), size_t(qMax(0, m)), seed);
891
892 // deal with the last 0 to 7 bits manually, because we can't trust that
893 // the padding is initialized to 0 in bitArray.d
894 qsizetype n = bitArray.size();
895 if (n & 0x7)
896 result = ((result << 4) + bitArray.d.at(m)) & ((1 << n) - 1);
897 return result;
898}
899#endif
900
901size_t qHash(QLatin1StringView key, size_t seed) noexcept
902{
903#ifdef QT_BOOTSTRAPPED
904 // the seed is always 0 in bootstrapped mode (no seed generation code),
905 // so help the compiler do dead code elimination
906 seed = 0;
907#endif
908
909 auto data = reinterpret_cast<const uchar *>(key.data());
910 size_t size = key.size();
911
912 // Mix in the length as a secondary seed.
913 // Multiplied by 2 to match the byte size of the equiavlent UTF-16 string.
914 size_t seed2 = size * 2;
915 if (seed)
916 seed2 = qt_qhash_seed.currentSeed(1);
917
918#if defined(AESHASH)
919 if (seed && qCpuHasFeature(AES) && qCpuHasFeature(SSE4_2))
920 return aeshash<ByteToWord>(data, size, seed, seed2);
921#endif
922 return qHashBits_fallback<ByteToWord>(data, size, seed, seed2);
923}
924
925/*!
926 \class QHashSeed
927 \inmodule QtCore
928 \since 6.2
929
930 The QHashSeed class is used to convey the QHash seed. This is used
931 internally by QHash and provides three static member functions to allow
932 users to obtain the hash and to reset it.
933
934 QHash and the qHash() functions implement what is called as "salted hash".
935 The intent is that different applications and different instances of the
936 same application will produce different hashing values for the same input,
937 thus causing the ordering of elements in QHash to be unpredictable by
938 external observers. This improves the applications' resilience against
939 attacks that attempt to force hashing tables into degenerate mode.
940
941 Most applications will not need to deal directly with the hash seed, as
942 QHash will do so when needed. However, applications may wish to use this
943 for their own purposes in the same way as QHash does: as an
944 application-global random value (but see \l QRandomGenerator too). Note
945 that the global hash seed may change during the application's lifetime, if
946 the resetRandomGlobalSeed() function is called. Users of the global hash
947 need to store the value they are using and not rely on getting it again.
948
949 This class also implements functionality to set the hash seed to a
950 deterministic value, which the qHash() functions will take to mean that
951 they should use a fixed hashing function on their data too. This
952 functionality is only meant to be used in debugging applications. This
953 behavior can also be controlled by setting the \c QT_HASH_SEED environment
954 variable to the value zero (any other value is ignored).
955
956 \sa QHash, QRandomGenerator
957*/
958
959/*!
960 \fn QHashSeed::QHashSeed(size_t data)
961
962 Constructs a new QHashSeed object using \a data as the seed.
963 */
964
965/*!
966 \fn QHashSeed::operator size_t() const
967
968 Converts the returned hash seed into a \c size_t.
969 */
970
971/*!
972 \threadsafe
973
974 Returns the current global QHash seed. The value returned by this function
975 will be zero if setDeterministicGlobalSeed() has been called or if the
976 \c{QT_HASH_SEED} environment variable is set to zero.
977 */
978QHashSeed QHashSeed::globalSeed() noexcept
979{
980 return qt_qhash_seed.currentSeed(0);
981}
982
983/*!
984 \threadsafe
985
986 Forces the Qt hash seed to a deterministic value (zero) and asks the
987 qHash() functions to use a pre-determined hashing function. This mode is
988 only useful for debugging and should not be used in production code.
989
990 Regular operation can be restored by calling resetRandomGlobalSeed().
991 */
992void QHashSeed::setDeterministicGlobalSeed()
993{
994 qt_qhash_seed.clearSeed();
995}
996
997/*!
998 \threadsafe
999
1000 Reseeds the Qt hashing seed to a new, random value. Calling this function
1001 is not necessary, but long-running applications may want to do so after a
1002 long period of time in which information about its hash may have been
1003 exposed to potential attackers.
1004
1005 If the environment variable \c QT_HASH_SEED is set to zero, calling this
1006 function will result in a no-op.
1007
1008 Qt never calls this function during the execution of the application, but
1009 unless the \c QT_HASH_SEED variable is set to 0, the hash seed returned by
1010 globalSeed() will be a random value as if this function had been called.
1011 */
1012void QHashSeed::resetRandomGlobalSeed()
1013{
1014 qt_qhash_seed.resetSeed();
1015}
1016
1017#if QT_DEPRECATED_SINCE(6,6)
1018/*! \relates QHash
1019 \since 5.6
1020 \deprecated [6.6] Use QHashSeed::globalSeed() instead.
1021
1022 Returns the current global QHash seed.
1023
1024 The seed is set in any newly created QHash. See
1025 \l{The hashing function}{qHash} about how this seed is being used by QHash.
1026
1027 \sa QHashSeed, QHashSeed::globalSeed()
1028 */
1029int qGlobalQHashSeed()
1030{
1031 return int(QHashSeed::globalSeed() & INT_MAX);
1032}
1033
1034/*! \relates QHash
1035 \since 5.6
1036 \deprecated [6.6] Use QHashSeed instead.
1037
1038 Sets the global QHash seed to \a newSeed.
1039
1040 Manually setting the global QHash seed value should be done only for testing
1041 and debugging purposes, when deterministic and reproducible behavior on a QHash
1042 is needed. We discourage to do it in production code as it can make your
1043 application susceptible to \l{algorithmic complexity attacks}.
1044
1045 From Qt 5.10 and onwards, the only allowed values are 0 and -1. Passing the
1046 value -1 will reinitialize the global QHash seed to a random value, while
1047 the value of 0 is used to request a stable algorithm for C++ primitive
1048 types types (like \c int) and string types (QString, QByteArray).
1049
1050 The seed is set in any newly created QHash. See
1051 \l{The hashing function}{qHash} about how this seed is being used by QHash.
1052
1053 If the environment variable \c QT_HASH_SEED is set, calling this function will
1054 result in a no-op.
1055
1056 \sa QHashSeed::globalSeed(), QHashSeed
1057 */
1058void qSetGlobalQHashSeed(int newSeed)
1059{
1060 if (Q_LIKELY(newSeed == 0 || newSeed == -1)) {
1061 if (newSeed == 0)
1062 QHashSeed::setDeterministicGlobalSeed();
1063 else
1064 QHashSeed::resetRandomGlobalSeed();
1065 } else {
1066 // can't use qWarning here (reentrancy)
1067 fprintf(stderr, "qSetGlobalQHashSeed: forced seed value is not 0; ignoring call\n");
1068 }
1069}
1070#endif // QT_DEPRECATED_SINCE(6,6)
1071
1072/*!
1073 \internal
1074
1075 Private copy of the implementation of the Qt 4 qHash algorithm for strings,
1076 (that is, QChar-based arrays, so all QString-like classes),
1077 to be used wherever the result is somehow stored or reused across multiple
1078 Qt versions. The public qHash implementation can change at any time,
1079 therefore one must not rely on the fact that it will always give the same
1080 results.
1081
1082 The qt_hash functions must *never* change their results.
1083
1084 This function can hash discontiguous memory by invoking it on each chunk,
1085 passing the previous's result in the next call's \a chained argument.
1086*/
1087uint qt_hash(QStringView key, uint chained) noexcept
1088{
1089 uint h = chained;
1090
1091 for (auto c: key) {
1092 h = (h << 4) + c.unicode();
1093 h ^= (h & 0xf0000000) >> 23;
1094 }
1095 h &= 0x0fffffff;
1096 return h;
1097}
1098
1099/*!
1100 \fn template <typename T1, typename T2> size_t qHash(const std::pair<T1, T2> &key, size_t seed = 0)
1101 \since 5.7
1102 \qhashbuiltinTS{T1}{T2}
1103*/
1104
1105/*!
1106 \fn template <typename T> size_t qHash(std::nullopt_t key, size_t seed = 0)
1107 \since 6.12
1108 \qhashbuiltin
1109
1110 \sa qHash(const std::optional<T> &, size_t)
1111*/
1112
1113/*!
1114 \fn template <typename T> size_t qHash(const std::optional<T> &key, size_t seed = 0)
1115 \since 6.12
1116 \qhashbuiltinT{T}
1117
1118 This is equivalent to
1119 \code
1120 key ? qHash(*key, seed) : qHash(std::nullopt, seed);
1121 \endcode
1122
1123 In particular, if \a key is engaged (\c{has_value()}), the hash value of \a
1124 key is guaranteed to be the same as that of \c{key.value()}, and all
1125 disengaged (\c{!has_value()}) optionals, of any type, hash to the same
1126 value.
1127
1128 \sa qHash(std::nullopt_t, size_t)
1129*/
1130
1131/*!
1132 \fn template <typename... T> size_t qHashMulti(size_t seed, const T &...args)
1133 \relates QHash
1134 \since 6.0
1135
1136 Returns the hash value for the \a{args}, using \a seed to seed
1137 the calculation, by successively applying qHash() to each
1138 element and combining the hash values into a single one.
1139
1140 Note that the order of the arguments is significant. If order does
1141 not matter, use qHashMultiCommutative() instead. If you are hashing raw
1142 memory, use qHashBits(); if you are hashing a range, use qHashRange().
1143
1144 This function is provided as a convenience to implement qHash() for
1145 your own custom types. For example, here's how you could implement
1146 a qHash() overload for a class \c{Employee}:
1147
1148 \snippet code/src_corelib_tools_qhash.cpp 13
1149
1150 \sa qHashMultiCommutative, qHashRange
1151*/
1152
1153/*!
1154 \fn template <typename... T> size_t qHashMultiCommutative(size_t seed, const T &...args)
1155 \relates QHash
1156 \since 6.0
1157
1158 Returns the hash value for the \a{args}, using \a seed to seed
1159 the calculation, by successively applying qHash() to each
1160 element and combining the hash values into a single one.
1161
1162 The order of the arguments is insignificant. If order does
1163 matter, use qHashMulti() instead, as it may produce better quality
1164 hashing. If you are hashing raw memory, use qHashBits(); if you are
1165 hashing a range, use qHashRange().
1166
1167 This function is provided as a convenience to implement qHash() for
1168 your own custom types.
1169
1170 \sa qHashMulti, qHashRange
1171*/
1172
1173/*! \fn template <typename InputIterator> size_t qHashRange(InputIterator first, InputIterator last, size_t seed = 0)
1174 \relates QHash
1175 \since 5.5
1176
1177 Returns the hash value for the range [\a{first},\a{last}), using \a seed
1178 to seed the calculation, by successively applying qHash() to each
1179 element and combining the hash values into a single one.
1180
1181 The return value of this function depends on the order of elements
1182 in the range. That means that
1183
1184 \snippet code/src_corelib_tools_qhash.cpp 30
1185
1186 and
1187 \snippet code/src_corelib_tools_qhash.cpp 31
1188
1189 hash to \b{different} values. If order does not matter, for example for hash
1190 tables, use qHashRangeCommutative() instead. If you are hashing raw
1191 memory, use qHashBits().
1192
1193 Use this function only to implement qHash() for your own custom
1194 types. For example, here's how you could implement a qHash() overload for
1195 std::vector<int>:
1196
1197 \snippet code/src_corelib_tools_qhash.cpp qhashrange
1198
1199 It bears repeating that the implementation of qHashRange() - like
1200 the qHash() overloads offered by Qt - may change at any time. You
1201 \b{must not} rely on the fact that qHashRange() will give the same
1202 results (for the same inputs) across different Qt versions, even
1203 if qHash() for the element type would.
1204
1205 \sa qHashBits(), qHashRangeCommutative()
1206*/
1207
1208/*! \fn template <typename InputIterator> size_t qHashRangeCommutative(InputIterator first, InputIterator last, size_t seed = 0)
1209 \relates QHash
1210 \since 5.5
1211
1212 Returns the hash value for the range [\a{first},\a{last}), using \a seed
1213 to seed the calculation, by successively applying qHash() to each
1214 element and combining the hash values into a single one.
1215
1216 The return value of this function does not depend on the order of
1217 elements in the range. That means that
1218
1219 \snippet code/src_corelib_tools_qhash.cpp 30
1220
1221 and
1222 \snippet code/src_corelib_tools_qhash.cpp 31
1223
1224 hash to the \b{same} values. If order matters, for example, for vectors
1225 and arrays, use qHashRange() instead. If you are hashing raw
1226 memory, use qHashBits().
1227
1228 Use this function only to implement qHash() for your own custom
1229 types. For example, here's how you could implement a qHash() overload for
1230 std::unordered_set<int>:
1231
1232 \snippet code/src_corelib_tools_qhash.cpp qhashrangecommutative
1233
1234 It bears repeating that the implementation of
1235 qHashRangeCommutative() - like the qHash() overloads offered by Qt
1236 - may change at any time. You \b{must not} rely on the fact that
1237 qHashRangeCommutative() will give the same results (for the same
1238 inputs) across different Qt versions, even if qHash() for the
1239 element type would.
1240
1241 \sa qHashBits(), qHashRange()
1242*/
1243
1244/*! \fn size_t qHashBits(const void *p, size_t len, size_t seed = 0)
1245 \relates QHash
1246 \since 5.4
1247
1248 Returns the hash value for the memory block of size \a len pointed
1249 to by \a p, using \a seed to seed the calculation.
1250
1251 Use this function only to implement qHash() for your own custom
1252 types. For example, here's how you could implement a qHash() overload for
1253 std::vector<int>:
1254
1255 \snippet code/src_corelib_tools_qhash.cpp qhashbits
1256
1257 This takes advantage of the fact that std::vector lays out its data
1258 contiguously. If that is not the case, or the contained type has
1259 padding, you should use qHashRange() instead.
1260
1261 It bears repeating that the implementation of qHashBits() - like
1262 the qHash() overloads offered by Qt - may change at any time. You
1263 \b{must not} rely on the fact that qHashBits() will give the same
1264 results (for the same inputs) across different Qt versions.
1265
1266 \sa qHashRange(), qHashRangeCommutative()
1267*/
1268
1269/*!
1270 \fn template <typename T, std::enable_if_t<std::is_same_v<T, bool>, bool> = true> size_t qHash(T key, size_t seed)
1271 \since 6.9
1272
1273 \qhashbuiltin
1274
1275 \note This is qHash(bool), constrained to accept only arguments of type bool,
1276 not arguments of types that merely convert to bool.
1277
1278 \note In Qt versions prior to 6.9, this overload was unintendedly provided by
1279 an undocumented 1-to-2-arg qHash adapter template function, with identical behavior.
1280*/
1281
1282/*! \fn size_t qHash(char key, size_t seed = 0)
1283 \since 5.0
1284 \qhashbuiltin
1285*/
1286
1287/*! \fn size_t qHash(uchar key, size_t seed = 0)
1288 \since 5.0
1289 \qhashbuiltin
1290*/
1291
1292/*! \fn size_t qHash(signed char key, size_t seed = 0)
1293 \since 5.0
1294 \qhashbuiltin
1295*/
1296
1297/*! \fn size_t qHash(ushort key, size_t seed = 0)
1298 \since 5.0
1299 \qhashbuiltin
1300*/
1301
1302/*! \fn size_t qHash(short key, size_t seed = 0)
1303 \since 5.0
1304 \qhashbuiltin
1305*/
1306
1307/*! \fn size_t qHash(uint key, size_t seed = 0)
1308 \since 5.0
1309 \qhashbuiltin
1310*/
1311
1312/*! \fn size_t qHash(int key, size_t seed = 0)
1313 \since 5.0
1314 \qhashbuiltin
1315*/
1316
1317/*! \fn size_t qHash(ulong key, size_t seed = 0)
1318 \since 5.0
1319 \qhashbuiltin
1320*/
1321
1322/*! \fn size_t qHash(long key, size_t seed = 0)
1323 \since 5.0
1324 \qhashbuiltin
1325*/
1326
1327/*! \fn size_t qHash(quint64 key, size_t seed = 0)
1328 \since 5.0
1329 \qhashbuiltin
1330*/
1331
1332/*! \fn size_t qHash(qint64 key, size_t seed = 0)
1333 \since 5.0
1334 \qhashbuiltin
1335*/
1336
1337/*! \fn size_t qHash(quint128 key, size_t seed = 0)
1338 \since 6.8
1339 \qhashbuiltin
1340
1341 \note This function is only available on platforms that support a native
1342 128-bit integer type.
1343*/
1344
1345/*! \fn size_t qHash(qint128 key, size_t seed = 0)
1346 \since 6.8
1347 \qhashbuiltin
1348
1349 \note This function is only available on platforms that support a native
1350 128-bit integer type.
1351 */
1352
1353/*! \fn size_t qHash(char8_t key, size_t seed = 0)
1354 \since 6.0
1355 \qhashbuiltin
1356*/
1357
1358/*! \fn size_t qHash(char16_t key, size_t seed = 0)
1359 \since 6.0
1360 \qhashbuiltin
1361*/
1362
1363/*! \fn size_t qHash(char32_t key, size_t seed = 0)
1364 \since 6.0
1365 \qhashbuiltin
1366*/
1367
1368/*! \fn size_t qHash(wchar_t key, size_t seed = 0)
1369 \since 6.0
1370 \qhashbuiltin
1371*/
1372
1373/*! \fn size_t qHash(float key, size_t seed = 0) noexcept
1374 \since 5.3
1375 \qhashbuiltin
1376*/
1377
1378/*!
1379 \since 5.3
1380 \qhashbuiltin
1381*/
1382size_t qHash(double key, size_t seed) noexcept
1383{
1384 // ensure -0 gets mapped to 0
1385 key += 0.0;
1386 if constexpr (sizeof(double) == sizeof(size_t)) {
1387 size_t k;
1388 memcpy(&k, &key, sizeof(double));
1389 return QHashPrivate::hash(k, seed);
1390 } else {
1391 return murmurhash(&key, sizeof(key), seed);
1392 }
1393}
1394
1395/*!
1396 \since 5.3
1397 \qhashbuiltin
1398*/
1399size_t qHash(long double key, size_t seed) noexcept
1400{
1401 // detect the actual size of long double's payload, not the space it
1402 // occupies in memory
1403 using Limits = std::numeric_limits<long double>;
1404 constexpr size_t SignSize = Limits::is_signed;
1405 constexpr quint64 ExponentRange = Limits::max_exponent - Limits::min_exponent;
1406 constexpr size_t ExponentSize = 64 - qCountLeadingZeroBits(ExponentRange);
1407 constexpr size_t Size = (Limits::digits + SignSize + ExponentSize) / 8;
1408
1409 if constexpr (sizeof(long double) == sizeof(double) || !Limits::is_iec559) {
1410 return qHash(double(key));
1411 } else {
1412#if defined(Q_PROCESSOR_X86) && defined(Q_CC_GNU_ONLY) && !defined(__LONG_DOUBLE_128__)
1413 // Check our calculation was right. long double is either:
1414 // 8 (matches the block above)
1415 // 10 (standard x87's IEEE 754 extended precision)
1416 // 16 (-mlong-double-128; Clang doesn't define __LONG_DOUBLE_128__)
1417 static_assert(Size == 10);
1418#endif
1419 alignas(long double) quint8 buffer[sizeof(long double)];
1420
1421 // ensure -0 gets mapped to 0
1422 key += static_cast<long double>(0.0);
1423 qToUnaligned(key, buffer);
1424
1425 // Work around: https://issuetracker.google.com/issues/400937647
1426 // An over-eager Bionic diagnostic in NDK 30 Clang LLVM 21.0.0:
1427 // "error: 'memset' will set 0 bytes; maybe the arguments got flipped? [-Werror,-Wuser-defined-warnings]""
1428 // Note! Trying to work around the problem with an if-constexpr does not work.
1429 size_t paddingSize = sizeof(long double) - Size;
1430 if (paddingSize > 0) {
1431 if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
1432 (memset)(buffer, 0, paddingSize);
1433 else
1434 (memset)(buffer + Size, 0, paddingSize);
1435 }
1436 return murmurhash(buffer, sizeof(long double), seed);
1437 }
1438}
1439
1440/*!
1441 \fn template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = true> size_t qHash(Enum key, size_t seed)
1442 \since 6.5
1443 \qhashbuiltin
1444
1445 \note Prior to Qt 6.5, unscoped enums relied on the integer overloads of this
1446 function due to implicit conversion to their underlying integer types.
1447 For scoped enums, you had to implement an overload yourself. This is still the
1448 backwards-compatible fix to remain compatible with older Qt versions.
1449*/
1450
1451/*! \fn size_t qHash(const QChar key, size_t seed = 0)
1452 \since 5.0
1453 \qhashold{QHash}
1454*/
1455
1456/*! \fn size_t qHash(const QByteArray &key, size_t seed = 0)
1457 \since 5.0
1458 \qhashold{QHash}
1459*/
1460
1461/*! \fn size_t qHash(QByteArrayView key, size_t seed = 0)
1462 \since 6.0
1463 \qhashold{QHash}
1464*/
1465
1466/*! \fn size_t qHash(const QBitArray &key, size_t seed = 0)
1467 \since 5.0
1468 \qhashold{QHash}
1469*/
1470
1471/*! \fn size_t qHash(const QString &key, size_t seed = 0)
1472 \since 5.0
1473 \qhashold{QHash}
1474*/
1475
1476/*! \fn size_t qHash(QLatin1StringView key, size_t seed = 0)
1477 \since 5.0
1478 \qhashold{QHash}
1479*/
1480
1481/*! \fn template <class T> size_t qHash(const T *key, size_t seed = 0)
1482 \since 5.0
1483 \qhashbuiltin
1484*/
1485
1486/*! \fn size_t qHash(std::nullptr_t key, size_t seed = 0)
1487 \since 6.0
1488 \qhashbuiltin
1489*/
1490
1491/*! \fn template<typename T> bool qHashEquals(const T &a, const T &b)
1492 \relates QHash
1493 \since 6.0
1494 \internal
1495
1496 This method is being used by QHash to compare two keys. Returns true if the
1497 keys \a a and \a b are considered equal for hashing purposes.
1498
1499 The default implementation returns the result of (a == b). It can be reimplemented
1500 for a certain type if the equality operator is not suitable for hashing purposes.
1501 This is for example the case if the equality operator uses qFuzzyCompare to compare
1502 floating point values.
1503*/
1504
1505
1506/*!
1507 \class QHash
1508 \inmodule QtCore
1509 \brief The QHash class is a template class that provides a hash-table-based dictionary.
1510 \compares equality
1511
1512 \ingroup tools
1513 \ingroup shared
1514 \ingroup containers
1515
1516 \reentrant
1517
1518 QHash<Key, T> is one of Qt's generic \l{container classes}, where
1519 \a Key is the type used for lookup keys and \a T is the mapped value
1520 type. It stores (key, value) pairs and provides very fast lookup of
1521 the value associated with a key.
1522
1523 QHash provides very similar functionality to QMap. The
1524 differences are:
1525
1526 \list
1527 \li QHash provides faster lookups than QMap. (See \l{Algorithmic
1528 Complexity} for details.)
1529 \li When iterating over a QMap, the items are always sorted by
1530 key. With QHash, the items are arbitrarily ordered.
1531 \li The key type of a QMap must provide operator<(). The key
1532 type of a QHash must provide operator==() and a global
1533 hash function called qHash() (see \l{The hashing function}{qHash}).
1534 \endlist
1535
1536 Here's an example QHash with QString keys and \c int values:
1537 \snippet code/src_corelib_tools_qhash.cpp 0
1538
1539 To insert a (key, value) pair into the hash, you can use operator[]():
1540
1541 \snippet code/src_corelib_tools_qhash.cpp 1
1542
1543 This inserts the following three (key, value) pairs into the
1544 QHash: ("one", 1), ("three", 3), and ("seven", 7). Another way to
1545 insert items into the hash is to use insert():
1546
1547 \snippet code/src_corelib_tools_qhash.cpp 2
1548
1549 To look up a value, use operator[]() or value():
1550
1551 \snippet code/src_corelib_tools_qhash.cpp 3
1552
1553 If there is no item with the specified key in the hash, these
1554 functions return a \l{default-constructed value}.
1555
1556 If you want to check whether the hash contains a particular key,
1557 use contains():
1558
1559 \snippet code/src_corelib_tools_qhash.cpp 4
1560
1561 There is also a value() overload that uses its second argument as
1562 a default value if there is no item with the specified key:
1563
1564 \snippet code/src_corelib_tools_qhash.cpp 5
1565
1566 In general, we recommend that you use contains() and value()
1567 rather than operator[]() for looking up a key in a hash. The
1568 reason is that operator[]() silently inserts an item into the
1569 hash if no item exists with the same key (unless the hash is
1570 const). For example, the following code snippet will create 1000
1571 items in memory:
1572
1573 \snippet code/src_corelib_tools_qhash.cpp 6
1574
1575 To avoid this problem, replace \c hash[i] with \c hash.value(i)
1576 in the code above.
1577
1578 Internally, QHash uses a hash table to perform lookups. This
1579 hash table automatically grows to
1580 provide fast lookups without wasting too much memory. You can
1581 still control the size of the hash table by calling reserve() if
1582 you already know approximately how many items the QHash will
1583 contain, but this isn't necessary to obtain good performance. You
1584 can also call capacity() to retrieve the hash table's size.
1585
1586 QHash will not shrink automatically if items are removed from the
1587 table. To minimize the memory used by the hash, call squeeze().
1588
1589 To iterate through all the (key, value) pairs stored in a
1590 QHash, use \l {asKeyValueRange}():
1591
1592 \snippet code/src_corelib_tools_qhash.cpp 8
1593
1594 This function returns a range object that can be used with structured
1595 bindings. For manual iterator control, you can also use traditional
1596 \l{STL-style iterators} (QHash::const_iterator and QHash::iterator):
1597
1598 \snippet code/src_corelib_tools_qhash.cpp qhash-iterator-stl-style
1599
1600 To modify values, use iterators:
1601
1602 \snippet code/src_corelib_tools_qhash.cpp qhash-iterator-modify-values
1603
1604 QHash also provides \l{Java-style iterators} (QHashIterator and
1605 QMutableHashIterator) for compatibility.
1606
1607 QHash is unordered, so an iterator's sequence cannot be assumed
1608 to be predictable. If ordering by key is required, use a QMap.
1609
1610 A QHash allows only one value per key. If you call
1611 insert() with a key that already exists in the QHash, the
1612 previous value is erased. For example:
1613
1614 \snippet code/src_corelib_tools_qhash.cpp 9
1615
1616 If you need to store multiple entries for the same key in the
1617 hash table, use \l{QMultiHash}.
1618
1619 If you only need to extract the values from a hash (not the keys),
1620 you can also use range-based for:
1621
1622 \snippet code/src_corelib_tools_qhash.cpp 12
1623
1624 Items can be removed from the hash in several ways. One way is to
1625 call remove(); this will remove any item with the given key.
1626 Another way is to use QMutableHashIterator::remove(). In addition,
1627 you can clear the entire hash using clear().
1628
1629 QHash's key and value data types must be \l{assignable data
1630 types}. You cannot, for example, store a QWidget as a value;
1631 instead, store a QWidget *.
1632
1633 \section2 The hashing function
1634
1635 A QHash's key type has additional requirements other than being an
1636 assignable data type: it must provide operator==(), and there must also be
1637 a hashing function that returns a hash value for an argument of the
1638 key's type.
1639
1640 The hashing function computes a numeric value based on a key. It
1641 can use any algorithm imaginable, as long as it always returns
1642 the same value if given the same argument. In other words, if
1643 \c{e1 == e2}, then \c{hash(e1) == hash(e2)} must hold as well.
1644 However, to obtain good performance, the hashing function should
1645 attempt to return different hash values for different keys to the
1646 largest extent possible.
1647
1648 A hashing function for a key type \c{K} may be provided in two
1649 different ways.
1650
1651 The first way is by having an overload of \c{qHash()} in \c{K}'s
1652 namespace. The \c{qHash()} function must have one of these signatures:
1653
1654 \snippet code/src_corelib_tools_qhash.cpp 32
1655
1656 The two-arguments overloads take an unsigned integer that should be used to
1657 seed the calculation of the hash function. This seed is provided by QHash
1658 in order to prevent a family of \l{algorithmic complexity attacks}.
1659
1660 \note In Qt 6 it is possible to define a \c{qHash()} overload
1661 taking only one argument; support for this is deprecated. Starting
1662 with Qt 7, it will be mandatory to use a two-arguments overload. If
1663 both a one-argument and a two-arguments overload are defined for a
1664 key type, the latter is used by QHash (note that you can simply
1665 define a two-arguments version, and use a default value for the
1666 seed parameter). In Qt 6 it is possible to disable support for the
1667 single argument qHash overload by defining the
1668 \c{QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD} macro.
1669
1670 The second way to provide a hashing function is by specializing
1671 the \c{std::hash} class for the key type \c{K}, and providing a
1672 suitable function call operator for it:
1673
1674 \snippet code/src_corelib_tools_qhash.cpp 33
1675
1676 The seed argument has the same meaning as for \c{qHash()},
1677 and may be left out.
1678
1679 This second way allows to reuse the same hash function between
1680 QHash and the C++ Standard Library unordered associative containers.
1681 If both a \c{qHash()} overload and a \c{std::hash} specializations
1682 are provided for a type, then the \c{qHash()} overload is preferred.
1683
1684 Here's a partial list of the C++ and Qt types that can serve as keys in a
1685 QHash: any integer type (char, unsigned long, etc.), any pointer type,
1686 QChar, QString, and QByteArray. For all of these, the \c <QHash> header
1687 defines a qHash() function that computes an adequate hash value. Many other
1688 Qt classes also declare a qHash overload for their type; please refer to
1689 the documentation of each class.
1690
1691 If you want to use other types as the key, make sure that you provide
1692 operator==() and a hash implementation.
1693
1694 The convenience qHashMulti() function can be used to implement
1695 qHash() for a custom type, where one usually wants to produce a
1696 hash value from multiple fields:
1697
1698 Example:
1699 \snippet code/src_corelib_tools_qhash.cpp 13
1700
1701 In the example above, we've relied on Qt's own implementation of
1702 qHash() for QString and QDate to give us a hash value for the
1703 employee's name and date of birth respectively.
1704
1705 Note that the implementation of the qHash() overloads offered by Qt
1706 may change at any time. You \b{must not} rely on the fact that qHash()
1707 will give the same results (for the same inputs) across different Qt
1708 versions.
1709
1710 \section2 Algorithmic complexity attacks
1711
1712 All hash tables are vulnerable to a particular class of denial of service
1713 attacks, in which the attacker carefully pre-computes a set of different
1714 keys that are going to be hashed in the same bucket of a hash table (or
1715 even have the very same hash value). The attack aims at getting the
1716 worst-case algorithmic behavior (O(n) instead of amortized O(1), see
1717 \l{Algorithmic Complexity} for the details) when the data is fed into the
1718 table.
1719
1720 In order to avoid this worst-case behavior, the calculation of the hash
1721 value done by qHash() can be salted by a random seed, that nullifies the
1722 attack's extent. This seed is automatically generated by QHash once per
1723 process, and then passed by QHash as the second argument of the
1724 two-arguments overload of the qHash() function.
1725
1726 This randomization of QHash is enabled by default. Even though programs
1727 should never depend on a particular QHash ordering, there may be situations
1728 where you temporarily need deterministic behavior, for example for debugging or
1729 regression testing. To disable the randomization, define the environment
1730 variable \c QT_HASH_SEED to have the value 0. Alternatively, you can call
1731 the QHashSeed::setDeterministicGlobalSeed() function.
1732
1733 \sa QHashIterator, QMutableHashIterator, QMap, QSet
1734*/
1735
1736/*! \fn template <class Key, class T> QHash<Key, T>::QHash()
1737
1738 Constructs an empty hash.
1739
1740 \sa clear()
1741*/
1742
1743/*!
1744 \fn template <class Key, class T> QHash<Key, T>::QHash(QHash &&other)
1745
1746 Move-constructs a QHash instance, making it point at the same
1747 object that \a other was pointing to.
1748
1749 \since 5.2
1750*/
1751
1752/*! \fn template <class Key, class T> QHash<Key, T>::QHash(std::initializer_list<std::pair<Key,T> > list)
1753 \since 5.1
1754
1755 Constructs a hash with a copy of each of the elements in the
1756 initializer list \a list.
1757*/
1758
1759/*! \fn template <class Key, class T> template <class InputIterator> QHash<Key, T>::QHash(InputIterator begin, InputIterator end)
1760 \since 5.14
1761
1762 Constructs a hash with a copy of each of the elements in the iterator range
1763 [\a begin, \a end). Either the elements iterated by the range must be
1764 objects with \c{first} and \c{second} data members (like \c{std::pair}),
1765 convertible to \c Key and to \c T respectively; or the
1766 iterators must have \c{key()} and \c{value()} member functions, returning a
1767 key convertible to \c Key and a value convertible to \c T respectively.
1768*/
1769
1770/*! \fn template <class Key, class T> QHash<Key, T>::QHash(const QHash &other)
1771
1772 Constructs a copy of \a other.
1773
1774 This operation occurs in \l{constant time}, because QHash is
1775 \l{implicitly shared}. This makes returning a QHash from a
1776 function very fast. If a shared instance is modified, it will be
1777 copied (copy-on-write), and this takes \l{linear time}.
1778
1779 \sa operator=()
1780*/
1781
1782/*! \fn template <class Key, class T> QHash<Key, T>::~QHash()
1783
1784 Destroys the hash. References to the values in the hash and all
1785 iterators of this hash become invalid.
1786*/
1787
1788/*! \fn template <class Key, class T> QHash &QHash<Key, T>::operator=(const QHash &other)
1789
1790 Assigns \a other to this hash and returns a reference to this hash.
1791*/
1792
1793/*!
1794 \fn template <class Key, class T> QHash &QHash<Key, T>::operator=(QHash &&other)
1795
1796 Move-assigns \a other to this QHash instance.
1797
1798 \since 5.2
1799*/
1800
1801/*! \fn template <class Key, class T> void QHash<Key, T>::swap(QHash &other)
1802 \since 4.8
1803 \memberswap{hash}
1804*/
1805
1806/*! \fn template <class Key, class T> void QMultiHash<Key, T>::swap(QMultiHash &other)
1807 \since 4.8
1808 \memberswap{multi-hash}
1809*/
1810
1811/*! \fn template <class Key, class T> bool QHash<Key, T>::operator==(const QHash &lhs, const QHash &rhs)
1812
1813 Returns \c true if \a lhs hash is equal to \a rhs hash; otherwise returns
1814 \c false.
1815
1816 Two hashes are considered equal if they contain the same (key,
1817 value) pairs.
1818
1819 This function requires the value type to implement \c operator==().
1820
1821 \sa operator!=()
1822*/
1823
1824/*! \fn template <class Key, class T> bool QHash<Key, T>::operator!=(const QHash &lhs, const QHash &rhs)
1825
1826 Returns \c true if \a lhs hash is not equal to \a rhs hash; otherwise
1827 returns \c false.
1828
1829 Two hashes are considered equal if they contain the same (key,
1830 value) pairs.
1831
1832 This function requires the value type to implement \c operator==().
1833
1834 \sa operator==()
1835*/
1836
1837/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::size() const
1838
1839 Returns the number of items in the hash.
1840
1841 \sa isEmpty(), count()
1842*/
1843
1844/*! \fn template <class Key, class T> bool QHash<Key, T>::isEmpty() const
1845
1846 Returns \c true if the hash contains no items; otherwise returns
1847 false.
1848
1849 \sa size()
1850*/
1851
1852/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::capacity() const
1853
1854 Returns the number of buckets in the QHash's internal hash table.
1855
1856 The sole purpose of this function is to provide a means of fine
1857 tuning QHash's memory usage. In general, you will rarely ever
1858 need to call this function. If you want to know how many items are
1859 in the hash, call size().
1860
1861 \sa reserve(), squeeze()
1862*/
1863
1864/*! \fn template <class Key, class T> float QHash<Key, T>::load_factor() const noexcept
1865
1866 Returns the current load factor of the QHash's internal hash table.
1867 This is the same as capacity()/size(). The implementation used
1868 will aim to keep the load factor between 0.25 and 0.5. This avoids
1869 having too many hash table collisions that would degrade performance.
1870
1871 Even with a low load factor, the implementation of the hash table has a
1872 very low memory overhead.
1873
1874 This method purely exists for diagnostic purposes and you should rarely
1875 need to call it yourself.
1876
1877 \sa reserve(), squeeze()
1878*/
1879
1880
1881/*! \fn template <class Key, class T> void QHash<Key, T>::reserve(qsizetype size)
1882
1883 Ensures that the QHash's internal hash table has space to store at
1884 least \a size items without having to grow the hash table.
1885
1886 This implies that the hash table will contain at least 2 * \a size buckets
1887 to ensure good performance
1888
1889 This function is useful for code that needs to build a huge hash
1890 and wants to avoid repeated reallocation. For example:
1891
1892 \snippet code/src_corelib_tools_qhash.cpp 14
1893
1894 Ideally, \a size should be the maximum number of items expected
1895 in the hash. QHash will then choose the smallest possible
1896 number of buckets that will allow storing \a size items in the table
1897 without having to grow the internal hash table. If \a size
1898 is an underestimate, the worst that will happen is that the QHash
1899 will be a bit slower.
1900
1901 In general, you will rarely ever need to call this function.
1902 QHash's internal hash table automatically grows to
1903 provide good performance without wasting too much memory.
1904
1905 \sa squeeze(), capacity()
1906*/
1907
1908/*! \fn template <class Key, class T> void QHash<Key, T>::squeeze()
1909
1910 Reduces the size of the QHash's internal hash table to save
1911 memory.
1912
1913 The sole purpose of this function is to provide a means of fine
1914 tuning QHash's memory usage. In general, you will rarely ever
1915 need to call this function.
1916
1917 \sa reserve(), capacity()
1918*/
1919
1920/*! \fn template <class Key, class T> void QHash<Key, T>::detach()
1921
1922 \internal
1923
1924 Detaches this hash from any other hashes with which it may share
1925 data.
1926
1927 \sa isDetached()
1928*/
1929
1930/*! \fn template <class Key, class T> bool QHash<Key, T>::isDetached() const
1931
1932 \internal
1933
1934 Returns \c true if the hash's internal data isn't shared with any
1935 other hash object; otherwise returns \c false.
1936
1937 \sa detach()
1938*/
1939
1940/*! \fn template <class Key, class T> bool QHash<Key, T>::isSharedWith(const QHash &other) const
1941
1942 \internal
1943
1944 Returns true if the internal hash table of this QHash is shared with \a other, otherwise false.
1945*/
1946
1947/*! \fn template <class Key, class T> void QHash<Key, T>::clear()
1948
1949 Removes all items from the hash and frees up all memory used by it.
1950
1951 \sa remove()
1952*/
1953
1954/*! \fn template <class Key, class T> bool QHash<Key, T>::remove(const Key &key)
1955
1956 Removes the item that has the \a key from the hash.
1957 Returns true if the key exists in the hash and the item has been removed,
1958 and false otherwise.
1959
1960 \sa clear(), take()
1961*/
1962
1963/*! \fn template <class Key, class T> template <typename Predicate> qsizetype QHash<Key, T>::removeIf(Predicate pred)
1964 \since 6.1
1965
1966 Removes all elements for which the predicate \a pred returns true
1967 from the hash.
1968
1969 The function supports predicates which take either an argument of
1970 type \c{QHash<Key, T>::iterator}, or an argument of type
1971 \c{std::pair<const Key &, T &>}.
1972
1973 Returns the number of elements removed, if any.
1974
1975 \sa clear(), take()
1976*/
1977
1978/*! \fn template <class Key, class T> T QHash<Key, T>::take(const Key &key)
1979
1980 Removes the item with the \a key from the hash and returns
1981 the value associated with it.
1982
1983 If the item does not exist in the hash, the function simply
1984 returns a \l{default-constructed value}.
1985
1986 If you don't use the return value, remove() is more efficient.
1987
1988 \sa remove()
1989*/
1990
1991/*! \fn template <class Key, class T> bool QHash<Key, T>::contains(const Key &key) const
1992
1993 Returns \c true if the hash contains an item with the \a key;
1994 otherwise returns \c false.
1995
1996 \sa count()
1997*/
1998
1999/*! \fn template <class Key, class T> T QHash<Key, T>::value(const Key &key) const
2000 \fn template <class Key, class T> T QHash<Key, T>::value(const Key &key, const T &defaultValue) const
2001 \overload
2002
2003 Returns the value associated with the \a key.
2004
2005 If the hash contains no item with the \a key, the function
2006 returns \a defaultValue, or a \l{default-constructed value} if this
2007 parameter has not been supplied.
2008*/
2009
2010/*! \fn template <class Key, class T> T &QHash<Key, T>::operator[](const Key &key)
2011
2012 Returns the value associated with the \a key as a modifiable
2013 reference.
2014
2015 If the hash contains no item with the \a key, the function inserts
2016 a \l{default-constructed value} into the hash with the \a key, and
2017 returns a reference to it.
2018
2019//! [qhash-iterator-invalidation-func-desc]
2020 \warning Returned iterators/references should be considered invalidated
2021 the next time you call a non-const function on the hash, or when the
2022 hash is destroyed.
2023//! [qhash-iterator-invalidation-func-desc]
2024
2025 \sa insert(), value()
2026*/
2027
2028/*! \fn template <class Key, class T> const T QHash<Key, T>::operator[](const Key &key) const
2029
2030 \overload
2031
2032 Same as value().
2033*/
2034
2035/*! \fn template <class Key, class T> QList<Key> QHash<Key, T>::keys() const
2036
2037 Returns a list containing all the keys in the hash, in an
2038 arbitrary order.
2039
2040 The order is guaranteed to be the same as that used by values().
2041
2042 This function creates a new list, in \l {linear time}. The time and memory
2043 use that entails can be avoided by iterating from \l keyBegin() to
2044 \l keyEnd().
2045
2046 \sa values(), key()
2047*/
2048
2049/*! \fn template <class Key, class T> QList<Key> QHash<Key, T>::keys(const T &value) const
2050
2051 \overload
2052
2053 Returns a list containing all the keys associated with value \a
2054 value, in an arbitrary order.
2055
2056 This function can be slow (\l{linear time}), because QHash's
2057 internal data structure is optimized for fast lookup by key, not
2058 by value.
2059*/
2060
2061/*! \fn template <class Key, class T> QList<T> QHash<Key, T>::values() const
2062
2063 Returns a list containing all the values in the hash, in an
2064 arbitrary order.
2065
2066 The order is guaranteed to be the same as that used by keys().
2067
2068 This function creates a new list, in \l {linear time}. The time and memory
2069 use that entails can be avoided by iterating from \l keyValueBegin() to
2070 \l keyValueEnd().
2071
2072 \sa keys(), value()
2073*/
2074
2075/*!
2076 \fn template <class Key, class T> Key QHash<Key, T>::key(const T &value) const
2077 \fn template <class Key, class T> Key QHash<Key, T>::key(const T &value, const Key &defaultKey) const
2078 \since 4.3
2079
2080 Returns the first key mapped to \a value. If the hash contains no item
2081 mapped to \a value, returns \a defaultKey, or a \l{default-constructed
2082 value}{default-constructed key} if this parameter has not been supplied.
2083
2084 This function can be slow (\l{linear time}), because QHash's
2085 internal data structure is optimized for fast lookup by key, not
2086 by value.
2087*/
2088
2089/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::count(const Key &key) const
2090
2091 Returns the number of items associated with the \a key.
2092
2093 \sa contains()
2094*/
2095
2096/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::count() const
2097
2098 \overload
2099
2100 Same as size().
2101*/
2102
2103/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::begin()
2104
2105 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
2106 the hash.
2107
2108 \include qhash.cpp qhash-iterator-invalidation-func-desc
2109
2110 \sa constBegin(), end()
2111*/
2112
2113/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::begin() const
2114
2115 \overload
2116
2117 \include qhash.cpp qhash-iterator-invalidation-func-desc
2118*/
2119
2120/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::cbegin() const
2121 \since 5.0
2122
2123 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
2124 in the hash.
2125
2126 \include qhash.cpp qhash-iterator-invalidation-func-desc
2127
2128 \sa begin(), cend()
2129*/
2130
2131/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constBegin() const
2132
2133 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
2134 in the hash.
2135
2136 \include qhash.cpp qhash-iterator-invalidation-func-desc
2137
2138 \sa begin(), constEnd()
2139*/
2140
2141/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::keyBegin() const
2142 \since 5.6
2143
2144 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
2145 in the hash.
2146
2147 \include qhash.cpp qhash-iterator-invalidation-func-desc
2148
2149 \sa keyEnd()
2150*/
2151
2152/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::end()
2153
2154 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
2155 after the last item in the hash.
2156
2157 \include qhash.cpp qhash-iterator-invalidation-func-desc
2158
2159 \sa begin(), constEnd()
2160*/
2161
2162/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::end() const
2163
2164 \overload
2165
2166 \include qhash.cpp qhash-iterator-invalidation-func-desc
2167*/
2168
2169/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constEnd() const
2170
2171 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2172 item after the last item in the hash.
2173
2174 \include qhash.cpp qhash-iterator-invalidation-func-desc
2175
2176 \sa constBegin(), end()
2177*/
2178
2179/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::cend() const
2180 \since 5.0
2181
2182 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2183 item after the last item in the hash.
2184
2185 \include qhash.cpp qhash-iterator-invalidation-func-desc
2186
2187 \sa cbegin(), end()
2188*/
2189
2190/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::keyEnd() const
2191 \since 5.6
2192
2193 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2194 item after the last key in the hash.
2195
2196 \include qhash.cpp qhash-iterator-invalidation-func-desc
2197
2198 \sa keyBegin()
2199*/
2200
2201/*! \fn template <class Key, class T> QHash<Key, T>::key_value_iterator QHash<Key, T>::keyValueBegin()
2202 \since 5.10
2203
2204 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2205 in the hash.
2206
2207 \include qhash.cpp qhash-iterator-invalidation-func-desc
2208
2209 \sa keyValueEnd()
2210*/
2211
2212/*! \fn template <class Key, class T> QHash<Key, T>::key_value_iterator QHash<Key, T>::keyValueEnd()
2213 \since 5.10
2214
2215 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2216 entry after the last entry in the hash.
2217
2218 \include qhash.cpp qhash-iterator-invalidation-func-desc
2219
2220 \sa keyValueBegin()
2221*/
2222
2223/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::keyValueBegin() const
2224 \since 5.10
2225
2226 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2227 in the hash.
2228
2229 \include qhash.cpp qhash-iterator-invalidation-func-desc
2230
2231 \sa keyValueEnd()
2232*/
2233
2234/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::constKeyValueBegin() const
2235 \since 5.10
2236
2237 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2238 in the hash.
2239
2240 \include qhash.cpp qhash-iterator-invalidation-func-desc
2241
2242 \sa keyValueBegin()
2243*/
2244
2245/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::keyValueEnd() const
2246 \since 5.10
2247
2248 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2249 entry after the last entry in the hash.
2250
2251 \include qhash.cpp qhash-iterator-invalidation-func-desc
2252
2253 \sa keyValueBegin()
2254*/
2255
2256/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::constKeyValueEnd() const
2257 \since 5.10
2258
2259 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2260 entry after the last entry in the hash.
2261
2262 \include qhash.cpp qhash-iterator-invalidation-func-desc
2263
2264 \sa constKeyValueBegin()
2265*/
2266
2267/*! \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() &
2268 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const &
2269 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() &&
2270 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const &&
2271 \since 6.4
2272
2273 Returns a range object that allows iteration over this hash as
2274 key/value pairs. For instance, this range object can be used in a
2275 range-based for loop, in combination with a structured binding declaration:
2276
2277 \snippet code/src_corelib_tools_qhash.cpp 34
2278
2279 Note that both the key and the value obtained this way are
2280 references to the ones in the hash. Specifically, mutating the value
2281 will modify the hash itself.
2282
2283 \include qhash.cpp qhash-iterator-invalidation-func-desc
2284
2285 \sa QKeyValueIterator
2286*/
2287
2288/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::erase(const_iterator pos)
2289 \since 5.7
2290
2291 Removes the (key, value) pair associated with the iterator \a pos
2292 from the hash, and returns an iterator to the next item in the
2293 hash.
2294
2295 This function never causes QHash to
2296 rehash its internal data structure. This means that it can safely
2297 be called while iterating, and won't affect the order of items in
2298 the hash. For example:
2299
2300 \snippet code/src_corelib_tools_qhash.cpp 15
2301
2302 \include qhash.cpp qhash-iterator-invalidation-func-desc
2303
2304 \sa remove(), take(), find()
2305*/
2306
2307/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::find(const Key &key)
2308
2309 Returns an iterator pointing to the item with the \a key in the
2310 hash.
2311
2312 If the hash contains no item with the \a key, the function
2313 returns end().
2314
2315 If the hash contains multiple items with the \a key, this
2316 function returns an iterator that points to the most recently
2317 inserted value. The other values are accessible by incrementing
2318 the iterator. For example, here's some code that iterates over all
2319 the items with the same key:
2320
2321 \snippet code/src_corelib_tools_qhash.cpp 16
2322
2323 \include qhash.cpp qhash-iterator-invalidation-func-desc
2324
2325 \sa value(), values()
2326*/
2327
2328/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::find(const Key &key) const
2329
2330 \overload
2331
2332 \include qhash.cpp qhash-iterator-invalidation-func-desc
2333*/
2334
2335/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constFind(const Key &key) const
2336 \since 4.1
2337
2338 Returns an iterator pointing to the item with the \a key in the
2339 hash.
2340
2341 If the hash contains no item with the \a key, the function
2342 returns constEnd().
2343
2344 \include qhash.cpp qhash-iterator-invalidation-func-desc
2345
2346 \sa find()
2347*/
2348
2349/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &key, const T &value)
2350
2351 Inserts a new item with the \a key and a value of \a value.
2352
2353 If there is already an item with the \a key, that item's value
2354 is replaced with \a value.
2355
2356 Inserting a key/value pair with an existing key replaces
2357 the existing value.
2358
2359 Returns an iterator pointing to the new/updated element.
2360
2361 \include qhash.cpp qhash-iterator-invalidation-func-desc
2362*/
2363
2364/*!
2365 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &key, T &&value)
2366 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(Key &&key, const T &value)
2367 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(Key &&key, T &&value)
2368 \since 6.11
2369 \overload
2370*/
2371
2372/*!
2373 \fn template <class Key, class T> template <typename ...Args> QHash<Key, T>::iterator QHash<Key, T>::emplace(const Key &key, Args&&... args)
2374 \fn template <class Key, class T> template <typename ...Args> QHash<Key, T>::iterator QHash<Key, T>::emplace(Key &&key, Args&&... args)
2375
2376 Inserts a new element into the container. This new element
2377 is constructed in-place using \a args as the arguments for its
2378 construction. If the element already exists in the container, it
2379 is replaced.
2380
2381 Returns an iterator pointing to the new element.
2382
2383 \include qhash.cpp qhash-iterator-invalidation-func-desc
2384*/
2385
2386/*!
2387 \class QHash::TryEmplaceResult
2388 \inmodule QtCore
2389 \since 6.9
2390 \ingroup tools
2391 \brief The TryEmplaceResult class is used to represent the result of a tryEmplace() operation.
2392
2393 The \c{TryEmplaceResult} class is used in QHash to represent the result
2394 of a tryEmplace() operation. It holds an \l{iterator} to the newly
2395 created item, or to the pre-existing item that prevented the insertion, and
2396 a boolean, \l{inserted}, denoting whether the insertion took place.
2397
2398 \sa QHash, QHash::tryEmplace()
2399*/
2400
2401/*!
2402 \variable QHash::TryEmplaceResult::iterator
2403
2404 Holds the iterator to the newly inserted element, or the element that
2405 prevented the insertion.
2406*/
2407
2408/*!
2409 \variable QHash::TryEmplaceResult::inserted
2410
2411 This value is \c{false} if there was already an entry with the same key.
2412*/
2413
2414/*!
2415 \fn template <class Key, class T> template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryEmplace(const Key &key, Args &&...args)
2416 \fn template <class Key, class T> template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryEmplace(Key &&key, Args &&...args)
2417 \fn template <class Key, class T> template <typename K, typename... Args, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryEmplace(K &&key, Args &&...args)
2418 \since 6.9
2419
2420 Inserts a new item with the \a key and a value constructed from \a args.
2421 If an item with \a key already exists, no insertion takes place.
2422
2423 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2424 \l{QHash::TryEmplaceResult::}{iterator} to the newly created item, or
2425 to the pre-existing item that prevented the insertion, and a boolean,
2426 \l{QHash::TryEmplaceResult::}{inserted}, denoting whether the insertion
2427 took place.
2428
2429 For example, this can be used to avoid the pattern of comparing old and
2430 new size or double-lookups. Where you might previously have written code like:
2431
2432 \code
2433 QHash<int, MyType> hash;
2434 // [...]
2435 int myKey = getKey();
2436 qsizetype oldSize = hash.size();
2437 MyType &elem = hash[myKey];
2438 if (oldSize != hash.size()) // Size changed: new element!
2439 initialize(elem);
2440 // [use elem...]
2441 \endcode
2442
2443 You can instead write:
2444
2445 \code
2446 QHash<int, MyType> hash;
2447 // [...]
2448 int myKey = getKey();
2449 auto result = hash.tryEmplace(myKey);
2450 if (result.inserted) // New element!
2451 initialize(*result.iterator);
2452 // [use result.iterator...]
2453 \endcode
2454
2455 \sa emplace(), tryInsert(), insertOrAssign()
2456*/
2457
2458/*!
2459 \fn template <class Key, class T> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryInsert(const Key &key, const T &value)
2460 \fn template <class Key, class T> template <typename K, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryInsert(K &&key, const T &value)
2461 \since 6.9
2462
2463 Inserts a new item with the \a key and a value of \a value.
2464 If an item with \a key already exists, no insertion takes place.
2465
2466 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2467 \l{QHash::TryEmplaceResult::}{iterator} to the newly created item, or to the pre-existing item
2468 that prevented the insertion, and a boolean, \l{QHash::TryEmplaceResult::}{inserted}, denoting
2469 whether the insertion took place.
2470
2471 \sa insert(), tryEmplace(), insertOrAssign()
2472*/
2473
2474/*!
2475 \fn template <class Key, class T> template <typename K, typename... Args, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> iterator QHash<Key, T>::try_emplace(const_iterator hint, K &&key, Args &&...args)
2476 \fn template <class Key, class T> template <typename... Args> iterator QHash<Key, T>::try_emplace(const_iterator hint, const Key &key, Args &&...args)
2477 \fn template <class Key, class T> template <typename... Args> iterator QHash<Key, T>::try_emplace(const_iterator hint, Key &&key, Args &&...args)
2478 \since 6.9
2479
2480 Inserts a new item with the \a key and a value constructed from \a args.
2481 If an item with \a key already exists, no insertion takes place.
2482
2483 Returns the iterator of the inserted item, or to the item that prevented the
2484 insertion.
2485
2486 \a hint is ignored.
2487
2488 These functions are provided for compatibility with the standard library.
2489
2490 \sa emplace(), tryEmplace(), tryInsert(), insertOrAssign()
2491*/
2492
2493/*!
2494 \fn template <class Key, class T> template <typename... Args> std::pair<iterator, bool> QHash<Key, T>::try_emplace(const Key &key, Args &&...args)
2495 \fn template <class Key, class T> template <typename... Args> std::pair<iterator, bool> QHash<Key, T>::try_emplace(Key &&key, Args &&...args)
2496 \fn template <class Key, class T> template <typename K, typename... Args, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> std::pair<iterator, bool> QHash<Key, T>::try_emplace(K &&key, Args &&...args)
2497 \since 6.9
2498
2499 Inserts a new item with the \a key and a value constructed from \a args.
2500 If an item with \a key already exists, no insertion takes place.
2501
2502 Returns a pair consisting of an iterator to the inserted item (or to the
2503 item that prevented the insertion), and a bool denoting whether the
2504 insertion took place.
2505
2506 These functions are provided for compatibility with the standard library.
2507
2508 \sa emplace(), tryEmplace(), tryInsert(), insertOrAssign()
2509*/
2510
2511/*!
2512 \fn template <class Key, class T> template <typename Value> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::insertOrAssign(const Key &key, Value &&value)
2513 \fn template <class Key, class T> template <typename Value> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::insertOrAssign(Key &&key, Value &&value)
2514 \fn template <class Key, class T> template <typename K, typename Value, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::insertOrAssign(K &&key, Value &&value)
2515 \since 6.9
2516
2517 Attempts to insert an item with the \a key and \a value.
2518 If an item with \a key already exists its value is overwritten with \a value.
2519
2520 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2521 \l{QHash::TryEmplaceResult::}{iterator} to the item, and a boolean,
2522 \l{QHash::TryEmplaceResult::}{inserted}, denoting whether the item was newly created (\c{true})
2523 or if it previously existed (\c{false}).
2524
2525 \sa insert(), tryEmplace(), tryInsert()
2526*/
2527
2528/*!
2529 \fn template <class Key, class T> template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(const Key &key, Value &&value)
2530 \fn template <class Key, class T> template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(Key &&key, Value &&value)
2531 \fn template <class Key, class T> template <typename K, typename Value, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(K &&key, Value &&value)
2532 \since 6.9
2533
2534 Attempts to insert an item with the \a key and \a value.
2535 If an item with \a key already exists its value is overwritten with \a value.
2536
2537 Returns a pair consisting of an iterator pointing to the item, and a
2538 boolean, denoting whether the item was newly created (\c{true}) or if it
2539 previously existed (\c{false}).
2540
2541 These functions are provided for compatibility with the standard library.
2542
2543 \sa insert(), tryEmplace(), tryInsert(), insertOrAssign()
2544*/
2545
2546/*!
2547 \fn template <class Key, class T> template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(const_iterator hint, const Key &key, Value &&value)
2548 \fn template <class Key, class T> template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(const_iterator hint, Key &&key, Value &&value)
2549 \fn template <class Key, class T> template <typename K, typename Value, QHash<Key, T>::if_heterogeneously_searchable<K> = true, QHash<Key, T>::if_key_constructible_from<K> = true> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash<Key, T>::insert_or_assign(const_iterator hint, K &&key, Value &&value)
2550 \since 6.9
2551
2552 Attempts to insert an item with the \a key and \a value.
2553 If an item with \a key already exists its value is overwritten with \a value.
2554
2555 Returns a pair consisting of an iterator pointing to the item, and a
2556 boolean, denoting whether the item was newly created (\c{true}) or if it
2557 previously existed (\c{false}).
2558
2559 \a hint is ignored.
2560
2561 These functions are provided for compatibility with the standard library.
2562
2563 \sa insert(), tryEmplace(), insertOrAssign()
2564*/
2565
2566/*! \fn template <class Key, class T> void QHash<Key, T>::insert(const QHash &other)
2567 \since 5.15
2568
2569 Inserts all the items in the \a other hash into this hash.
2570
2571 If a key is common to both hashes, its value will be replaced with the
2572 value stored in \a other.
2573*/
2574
2575/*! \fn template <class Key, class T> bool QHash<Key, T>::empty() const
2576
2577 This function is provided for STL compatibility. It is equivalent
2578 to isEmpty(), returning true if the hash is empty; otherwise
2579 returns \c false.
2580*/
2581
2582/*! \fn template <class Key, class T> std::pair<iterator, iterator> QMultiHash<Key, T>::equal_range(const Key &key)
2583 \since 5.7
2584
2585 Returns a pair of iterators delimiting the range of values \c{[first, second)}, that
2586 are stored under \a key. If the range is empty then both iterators will be equal to end().
2587
2588 \include qhash.cpp qhash-iterator-invalidation-func-desc
2589*/
2590
2591/*!
2592 \fn template <class Key, class T> std::pair<const_iterator, const_iterator> QMultiHash<Key, T>::equal_range(const Key &key) const
2593 \overload
2594 \since 5.7
2595
2596 \include qhash.cpp qhash-iterator-invalidation-func-desc
2597*/
2598
2599/*! \typedef QHash::ConstIterator
2600
2601 Qt-style synonym for QHash::const_iterator.
2602*/
2603
2604/*! \typedef QHash::Iterator
2605
2606 Qt-style synonym for QHash::iterator.
2607*/
2608
2609/*! \typedef QHash::difference_type
2610
2611 Typedef for ptrdiff_t. Provided for STL compatibility.
2612*/
2613
2614/*! \typedef QHash::key_type
2615
2616 Typedef for Key. Provided for STL compatibility.
2617*/
2618
2619/*! \typedef QHash::mapped_type
2620
2621 Typedef for T. Provided for STL compatibility.
2622*/
2623
2624/*! \typedef QHash::size_type
2625
2626 Typedef for int. Provided for STL compatibility.
2627*/
2628
2629/*! \typedef QHash::iterator::difference_type
2630 \internal
2631*/
2632
2633/*! \typedef QHash::iterator::iterator_category
2634 \internal
2635*/
2636
2637/*! \typedef QHash::iterator::pointer
2638 \internal
2639*/
2640
2641/*! \typedef QHash::iterator::reference
2642 \internal
2643*/
2644
2645/*! \typedef QHash::iterator::value_type
2646 \internal
2647*/
2648
2649/*! \typedef QHash::const_iterator::difference_type
2650 \internal
2651*/
2652
2653/*! \typedef QHash::const_iterator::iterator_category
2654 \internal
2655*/
2656
2657/*! \typedef QHash::const_iterator::pointer
2658 \internal
2659*/
2660
2661/*! \typedef QHash::const_iterator::reference
2662 \internal
2663*/
2664
2665/*! \typedef QHash::const_iterator::value_type
2666 \internal
2667*/
2668
2669/*! \typedef QHash::key_iterator::difference_type
2670 \internal
2671*/
2672
2673/*! \typedef QHash::key_iterator::iterator_category
2674 \internal
2675*/
2676
2677/*! \typedef QHash::key_iterator::pointer
2678 \internal
2679*/
2680
2681/*! \typedef QHash::key_iterator::reference
2682 \internal
2683*/
2684
2685/*! \typedef QHash::key_iterator::value_type
2686 \internal
2687*/
2688
2689/*! \class QHash::iterator
2690 \inmodule QtCore
2691 \brief The QHash::iterator class provides an STL-style non-const iterator for QHash.
2692
2693 QHash<Key, T>::iterator allows you to iterate over a QHash
2694 and to modify the value (but not the key) associated
2695 with a particular key. If you want to iterate over a const QHash,
2696 you should use QHash::const_iterator. It is generally good
2697 practice to use QHash::const_iterator on a non-const QHash as
2698 well, unless you need to change the QHash through the iterator.
2699 Const iterators are slightly faster, and can improve code
2700 readability.
2701
2702 The default QHash::iterator constructor creates an uninitialized
2703 iterator. You must initialize it using a QHash function like
2704 QHash::begin(), QHash::end(), or QHash::find() before you can
2705 start iterating. Here's a typical loop that prints all the (key,
2706 value) pairs stored in a hash:
2707
2708 \snippet code/src_corelib_tools_qhash.cpp 17
2709
2710 Unlike QMap, which orders its items by key, QHash stores its
2711 items in an arbitrary order.
2712
2713 Here's an example that increments every value stored in the QHash
2714 by 2:
2715
2716 \snippet code/src_corelib_tools_qhash.cpp 18
2717
2718 To remove elements from a QHash you can use erase_if(QHash<Key, T> &map, Predicate pred):
2719
2720 \snippet code/src_corelib_tools_qhash.cpp 21
2721
2722 Multiple iterators can be used on the same hash. However, be aware
2723 that any modification performed directly on the QHash (inserting and
2724 removing items) can cause the iterators to become invalid.
2725
2726 Inserting items into the hash or calling methods such as QHash::reserve()
2727 or QHash::squeeze() can invalidate all iterators pointing into the hash.
2728 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
2729 to grow/shrink its internal hash table.
2730 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
2731
2732 If you need to keep iterators over a long period of time, we recommend
2733 that you use QMap rather than QHash.
2734
2735 \warning Iterators on implicitly shared containers do not work
2736 exactly like STL-iterators. You should avoid copying a container
2737 while iterators are active on that container. For more information,
2738 read \l{Implicit sharing iterator problem}.
2739
2740 \sa QHash::const_iterator, QHash::key_iterator, QHash::key_value_iterator
2741*/
2742
2743/*! \fn template <class Key, class T> QHash<Key, T>::iterator::iterator()
2744
2745 Constructs an uninitialized iterator.
2746
2747 Functions like key(), value(), and operator++() must not be
2748 called on an uninitialized iterator. Use operator=() to assign a
2749 value to it before using it.
2750
2751 \sa QHash::begin(), QHash::end()
2752*/
2753
2754/*! \fn template <class Key, class T> const Key &QHash<Key, T>::iterator::key() const
2755
2756 Returns the current item's key as a const reference.
2757
2758 There is no direct way of changing an item's key through an
2759 iterator, although it can be done by calling QHash::erase()
2760 followed by QHash::insert().
2761
2762 \sa value()
2763*/
2764
2765/*! \fn template <class Key, class T> T &QHash<Key, T>::iterator::value() const
2766
2767 Returns a modifiable reference to the current item's value.
2768
2769 You can change the value of an item by using value() on
2770 the left side of an assignment, for example:
2771
2772 \snippet code/src_corelib_tools_qhash.cpp 22
2773
2774 \sa key(), operator*()
2775*/
2776
2777/*! \fn template <class Key, class T> T &QHash<Key, T>::iterator::operator*() const
2778
2779 Returns a modifiable reference to the current item's value.
2780
2781 Same as value().
2782
2783 \sa key()
2784*/
2785
2786/*! \fn template <class Key, class T> T *QHash<Key, T>::iterator::operator->() const
2787
2788 Returns a pointer to the current item's value.
2789
2790 \sa value()
2791*/
2792
2793/*!
2794 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator==(const iterator &other) const
2795 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator==(const const_iterator &other) const
2796
2797 Returns \c true if \a other points to the same item as this
2798 iterator; otherwise returns \c false.
2799
2800 \sa operator!=()
2801*/
2802
2803/*!
2804 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator!=(const iterator &other) const
2805 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator!=(const const_iterator &other) const
2806
2807 Returns \c true if \a other points to a different item than this
2808 iterator; otherwise returns \c false.
2809
2810 \sa operator==()
2811*/
2812
2813/*!
2814 \fn template <class Key, class T> QHash<Key, T>::iterator &QHash<Key, T>::iterator::operator++()
2815
2816 The prefix ++ operator (\c{++i}) advances the iterator to the
2817 next item in the hash and returns an iterator to the new current
2818 item.
2819
2820 Calling this function on QHash::end() leads to undefined results.
2821*/
2822
2823/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::iterator::operator++(int)
2824
2825 \overload
2826
2827 The postfix ++ operator (\c{i++}) advances the iterator to the
2828 next item in the hash and returns an iterator to the previously
2829 current item.
2830*/
2831
2832/*! \class QHash::const_iterator
2833 \inmodule QtCore
2834 \brief The QHash::const_iterator class provides an STL-style const iterator for QHash.
2835
2836 QHash<Key, T>::const_iterator allows you to iterate over a
2837 QHash. If you want to modify the QHash as you
2838 iterate over it, you must use QHash::iterator instead. It is
2839 generally good practice to use QHash::const_iterator on a
2840 non-const QHash as well, unless you need to change the QHash
2841 through the iterator. Const iterators are slightly faster, and
2842 can improve code readability.
2843
2844 The default QHash::const_iterator constructor creates an
2845 uninitialized iterator. You must initialize it using a QHash
2846 function like QHash::cbegin(), QHash::cend(), or
2847 QHash::constFind() before you can start iterating. Here's a typical
2848 loop that prints all the (key, value) pairs stored in a hash:
2849
2850 \snippet code/src_corelib_tools_qhash.cpp 23
2851
2852 Unlike QMap, which orders its items by key, QHash stores its
2853 items in an arbitrary order. The only guarantee is that items that
2854 share the same key (because they were inserted using
2855 a QMultiHash) will appear consecutively, from the most
2856 recently to the least recently inserted value.
2857
2858 Multiple iterators can be used on the same hash. However, be aware
2859 that any modification performed directly on the QHash (inserting and
2860 removing items) can cause the iterators to become invalid.
2861
2862 Inserting items into the hash or calling methods such as QHash::reserve()
2863 or QHash::squeeze() can invalidate all iterators pointing into the hash.
2864 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
2865 to grow/shrink its internal hash table.
2866 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
2867
2868 You can however safely use iterators to remove entries from the hash
2869 using the QHash::erase() method. This function can safely be called while
2870 iterating, and won't affect the order of items in the hash.
2871
2872 \warning Iterators on implicitly shared containers do not work
2873 exactly like STL-iterators. You should avoid copying a container
2874 while iterators are active on that container. For more information,
2875 read \l{Implicit sharing iterator problem}.
2876
2877 \sa QHash::iterator, QHash::key_iterator, QHash::const_key_value_iterator
2878*/
2879
2880/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator::const_iterator()
2881
2882 Constructs an uninitialized iterator.
2883
2884 Functions like key(), value(), and operator++() must not be
2885 called on an uninitialized iterator. Use operator=() to assign a
2886 value to it before using it.
2887
2888 \sa QHash::constBegin(), QHash::constEnd()
2889*/
2890
2891/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator::const_iterator(const iterator &other)
2892
2893 Constructs a copy of \a other.
2894*/
2895
2896/*! \fn template <class Key, class T> const Key &QHash<Key, T>::const_iterator::key() const
2897
2898 Returns the current item's key.
2899
2900 \sa value()
2901*/
2902
2903/*! \fn template <class Key, class T> const T &QHash<Key, T>::const_iterator::value() const
2904
2905 Returns the current item's value.
2906
2907 \sa key(), operator*()
2908*/
2909
2910/*! \fn template <class Key, class T> const T &QHash<Key, T>::const_iterator::operator*() const
2911
2912 Returns the current item's value.
2913
2914 Same as value().
2915
2916 \sa key()
2917*/
2918
2919/*! \fn template <class Key, class T> const T *QHash<Key, T>::const_iterator::operator->() const
2920
2921 Returns a pointer to the current item's value.
2922
2923 \sa value()
2924*/
2925
2926/*! \fn template <class Key, class T> bool QHash<Key, T>::const_iterator::operator==(const const_iterator &other) const
2927
2928 Returns \c true if \a other points to the same item as this
2929 iterator; otherwise returns \c false.
2930
2931 \sa operator!=()
2932*/
2933
2934/*! \fn template <class Key, class T> bool QHash<Key, T>::const_iterator::operator!=(const const_iterator &other) const
2935
2936 Returns \c true if \a other points to a different item than this
2937 iterator; otherwise returns \c false.
2938
2939 \sa operator==()
2940*/
2941
2942/*!
2943 \fn template <class Key, class T> QHash<Key, T>::const_iterator &QHash<Key, T>::const_iterator::operator++()
2944
2945 The prefix ++ operator (\c{++i}) advances the iterator to the
2946 next item in the hash and returns an iterator to the new current
2947 item.
2948
2949 Calling this function on QHash::end() leads to undefined results.
2950*/
2951
2952/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::const_iterator::operator++(int)
2953
2954 \overload
2955
2956 The postfix ++ operator (\c{i++}) advances the iterator to the
2957 next item in the hash and returns an iterator to the previously
2958 current item.
2959*/
2960
2961/*! \class QHash::key_iterator
2962 \inmodule QtCore
2963 \since 5.6
2964 \brief The QHash::key_iterator class provides an STL-style const iterator for QHash keys.
2965
2966 QHash::key_iterator is essentially the same as QHash::const_iterator
2967 with the difference that operator*() and operator->() return a key
2968 instead of a value.
2969
2970 For most uses QHash::iterator and QHash::const_iterator should be used,
2971 you can easily access the key by calling QHash::iterator::key():
2972
2973 \snippet code/src_corelib_tools_qhash.cpp 27
2974
2975 However, to have interoperability between QHash's keys and STL-style
2976 algorithms we need an iterator that dereferences to a key instead
2977 of a value. With QHash::key_iterator we can apply an algorithm to a
2978 range of keys without having to call QHash::keys(), which is inefficient
2979 as it costs one QHash iteration and memory allocation to create a temporary
2980 QList.
2981
2982 \snippet code/src_corelib_tools_qhash.cpp 28
2983
2984 QHash::key_iterator is const, it's not possible to modify the key.
2985
2986 The default QHash::key_iterator constructor creates an uninitialized
2987 iterator. You must initialize it using a QHash function like
2988 QHash::keyBegin() or QHash::keyEnd().
2989
2990 \warning Iterators on implicitly shared containers do not work
2991 exactly like STL-iterators. You should avoid copying a container
2992 while iterators are active on that container. For more information,
2993 read \l{Implicit sharing iterator problem}.
2994
2995 \sa QHash::const_iterator, QHash::iterator
2996*/
2997
2998/*! \fn template <class Key, class T> const T &QHash<Key, T>::key_iterator::operator*() const
2999
3000 Returns the current item's key.
3001*/
3002
3003/*! \fn template <class Key, class T> const T *QHash<Key, T>::key_iterator::operator->() const
3004
3005 Returns a pointer to the current item's key.
3006*/
3007
3008/*! \fn template <class Key, class T> bool QHash<Key, T>::key_iterator::operator==(key_iterator other) const
3009
3010 Returns \c true if \a other points to the same item as this
3011 iterator; otherwise returns \c false.
3012
3013 \sa operator!=()
3014*/
3015
3016/*! \fn template <class Key, class T> bool QHash<Key, T>::key_iterator::operator!=(key_iterator other) const
3017
3018 Returns \c true if \a other points to a different item than this
3019 iterator; otherwise returns \c false.
3020
3021 \sa operator==()
3022*/
3023
3024/*!
3025 \fn template <class Key, class T> QHash<Key, T>::key_iterator &QHash<Key, T>::key_iterator::operator++()
3026
3027 The prefix ++ operator (\c{++i}) advances the iterator to the
3028 next item in the hash and returns an iterator to the new current
3029 item.
3030
3031 Calling this function on QHash::keyEnd() leads to undefined results.
3032
3033*/
3034
3035/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::key_iterator::operator++(int)
3036
3037 \overload
3038
3039 The postfix ++ operator (\c{i++}) advances the iterator to the
3040 next item in the hash and returns an iterator to the previous
3041 item.
3042*/
3043
3044/*! \fn template <class Key, class T> const_iterator QHash<Key, T>::key_iterator::base() const
3045 Returns the underlying const_iterator this key_iterator is based on.
3046*/
3047
3048/*! \typedef QHash::const_key_value_iterator
3049 \inmodule QtCore
3050 \since 5.10
3051 \brief The QHash::const_key_value_iterator typedef provides an STL-style const iterator for QHash.
3052
3053 QHash::const_key_value_iterator is essentially the same as QHash::const_iterator
3054 with the difference that operator*() returns a key/value pair instead of a
3055 value.
3056
3057 \sa QKeyValueIterator
3058*/
3059
3060/*! \typedef QHash::key_value_iterator
3061 \inmodule QtCore
3062 \since 5.10
3063 \brief The QHash::key_value_iterator typedef provides an STL-style iterator for QHash.
3064
3065 QHash::key_value_iterator is essentially the same as QHash::iterator
3066 with the difference that operator*() returns a key/value pair instead of a
3067 value.
3068
3069 \sa QKeyValueIterator
3070*/
3071
3072/*! \fn template <class Key, class T> QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash)
3073 \relates QHash
3074
3075 Writes the hash \a hash to stream \a out.
3076
3077 This function requires the key and value types to implement \c
3078 operator<<().
3079
3080 \sa {Serializing Qt Data Types}
3081*/
3082
3083/*! \fn template <class Key, class T> QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)
3084 \relates QHash
3085
3086 Reads a hash from stream \a in into \a hash.
3087
3088 This function requires the key and value types to implement \c
3089 operator>>().
3090
3091 \sa {Serializing Qt Data Types}
3092*/
3093
3094/*! \class QMultiHash
3095 \inmodule QtCore
3096 \brief The QMultiHash class provides a multi-valued hash table.
3097 \compares equality
3098
3099 \ingroup tools
3100 \ingroup shared
3101 \ingroup containers
3102
3103 \reentrant
3104
3105 QMultiHash<Key, T> is one of Qt's generic \l{container classes}, where
3106 \a Key is the type used for lookup keys and \a T is the mapped value type.
3107 It provides a hash table that allows multiple values for the same key.
3108
3109 QMultiHash mostly mirrors QHash's API. For example, you can use isEmpty() to test
3110 whether the hash is empty, and you can traverse a QMultiHash using
3111 QHash's iterator classes (for example, QHashIterator). But opposed to
3112 QHash, it provides an insert() function that allows the insertion of
3113 multiple items with the same key. The replace() function corresponds to
3114 QHash::insert(). It also provides convenient operator+() and
3115 operator+=().
3116
3117 Unlike QMultiMap, QMultiHash does not provide ordering of the
3118 inserted items. The only guarantee is that items that
3119 share the same key will appear consecutively, from the most
3120 recently to the least recently inserted value.
3121
3122 Example:
3123 \snippet code/src_corelib_tools_qhash.cpp 24
3124
3125 Unlike QHash, QMultiHash provides no operator[]. Use value() or
3126 replace() if you want to access the most recently inserted item
3127 with a certain key.
3128
3129 If you want to retrieve all the values for a single key, you can
3130 use values(const Key &key), which returns a QList<T>:
3131
3132 \snippet code/src_corelib_tools_qhash.cpp 25
3133
3134 The items that share the same key are available from most
3135 recently to least recently inserted.
3136
3137 A more efficient approach is to call find() to get
3138 the STL-style iterator for the first item with a key and iterate from
3139 there:
3140
3141 \snippet code/src_corelib_tools_qhash.cpp 26
3142
3143 QMultiHash's key and value data types must be \l{assignable data
3144 types}. You cannot, for example, store a QWidget as a value;
3145 instead, store a QWidget *. In addition, QMultiHash's key type
3146 must provide operator==(), and there must also be a qHash() function
3147 in the type's namespace that returns a hash value for an argument of the
3148 key's type. See the QHash documentation for details.
3149
3150 \sa QHash, QHashIterator, QMutableHashIterator, QMultiMap
3151*/
3152
3153/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash()
3154
3155 Constructs an empty hash.
3156*/
3157
3158/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash(std::initializer_list<std::pair<Key,T> > list)
3159 \since 5.1
3160
3161 Constructs a multi-hash with a copy of each of the elements in the
3162 initializer list \a list.
3163*/
3164
3165/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash(const QHash<Key, T> &other)
3166
3167 Constructs a copy of \a other (which can be a QHash or a
3168 QMultiHash).
3169*/
3170
3171/*! \fn template <class Key, class T> template <class InputIterator> QMultiHash<Key, T>::QMultiHash(InputIterator begin, InputIterator end)
3172 \since 5.14
3173
3174 Constructs a multi-hash with a copy of each of the elements in the iterator range
3175 [\a begin, \a end). Either the elements iterated by the range must be
3176 objects with \c{first} and \c{second} data members (like \c{std::pair}),
3177 convertible to \c Key and to \c T respectively; or the
3178 iterators must have \c{key()} and \c{value()} member functions, returning a
3179 key convertible to \c Key and a value convertible to \c T respectively.
3180*/
3181
3182/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::replace(const Key &key, const T &value)
3183
3184 Inserts a new item with the \a key and a value of \a value.
3185
3186 If there is already an item with the \a key, that item's value
3187 is replaced with \a value.
3188
3189 If there are multiple items with the \a key, the most
3190 recently inserted item's value is replaced with \a value.
3191
3192 Returns an iterator pointing to the new/updated element.
3193
3194 \include qhash.cpp qhash-iterator-invalidation-func-desc
3195
3196 \sa insert()
3197*/
3198
3199/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(const Key &key, const T &value)
3200
3201 Inserts a new item with the \a key and a value of \a value.
3202
3203 If there is already an item with the same key in the hash, this
3204 function will simply create a new one. (This behavior is
3205 different from replace(), which overwrites the value of an
3206 existing item.)
3207
3208 QMultiHash allows duplicate keys. Inserting a key that
3209 already exists adds another entry instead of overwriting
3210 it. The order of items in QMultHash is not guaranteed.
3211
3212 Returns an iterator pointing to the new element.
3213
3214 \include qhash.cpp qhash-iterator-invalidation-func-desc
3215
3216 \sa replace()
3217*/
3218
3219/*!
3220 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(const Key &key, T &&value)
3221 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(Key &&key, const T &value)
3222 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(Key &&key, T &&value)
3223 \since 6.11
3224 \overload
3225*/
3226
3227/*!
3228 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplace(const Key &key, Args&&... args)
3229 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplace(Key &&key, Args&&... args)
3230
3231 Inserts a new element into the container. This new element
3232 is constructed in-place using \a args as the arguments for its
3233 construction.
3234
3235 If there is already an item with the same key in the hash, this
3236 function will simply create a new one. (This behavior is
3237 different from replace(), which overwrites the value of an
3238 existing item.)
3239
3240 Returns an iterator pointing to the new element.
3241
3242 \include qhash.cpp qhash-iterator-invalidation-func-desc
3243
3244 \sa insert
3245*/
3246
3247/*!
3248 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplaceReplace(const Key &key, Args&&... args)
3249 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplaceReplace(Key &&key, Args&&... args)
3250
3251 Inserts a new element into the container. This new element
3252 is constructed in-place using \a args as the arguments for its
3253 construction.
3254
3255 If there is already an item with the same key in the hash, that item's
3256 value is replaced with a value constructed from \a args.
3257
3258 Returns an iterator pointing to the new element.
3259
3260 \include qhash.cpp qhash-iterator-invalidation-func-desc
3261
3262 \sa replace, emplace
3263*/
3264
3265/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::erase(const_iterator pos)
3266 \since 5.7
3267
3268 Removes the (key, value) pair associated with the iterator \a pos
3269 from the hash, and returns an iterator to the next item in the
3270 hash.
3271
3272 This function never causes QMultiHash to
3273 rehash its internal data structure. This means that it can safely
3274 be called while iterating, and won't affect the order of items in
3275 the hash. For example:
3276
3277 \snippet code/src_corelib_tools_qhash.cpp 15multihash
3278
3279 \include qhash.cpp qhash-iterator-invalidation-func-desc
3280
3281 \sa remove(), take(), find()
3282*/
3283
3284/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::unite(const QMultiHash &other)
3285 \since 5.13
3286
3287 Inserts all the items in the \a other hash into this hash
3288 and returns a reference to this hash.
3289
3290 \sa insert()
3291*/
3292
3293
3294/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::unite(const QHash<Key, T> &other)
3295 \since 6.0
3296
3297 Inserts all the items in the \a other hash into this hash
3298 and returns a reference to this hash.
3299
3300 \sa insert()
3301*/
3302
3303/*! \fn template <class Key, class T> QList<Key> QMultiHash<Key, T>::uniqueKeys() const
3304 \since 5.13
3305
3306 Returns a list containing all the keys in the map. Keys that occur multiple
3307 times in the map occur only once in the returned list.
3308
3309 \sa keys(), values()
3310*/
3311
3312/*! \fn template <class Key, class T> T QMultiHash<Key, T>::value(const Key &key) const
3313 \fn template <class Key, class T> T QMultiHash<Key, T>::value(const Key &key, const T &defaultValue) const
3314
3315 Returns the value associated with the \a key.
3316
3317 If the hash contains no item with the \a key, the function
3318 returns \a defaultValue, or a \l{default-constructed value} if this
3319 parameter has not been supplied.
3320
3321 If there are multiple
3322 items for the \a key in the hash, the value of the most recently
3323 inserted one is returned.
3324*/
3325
3326/*! \fn template <class Key, class T> QList<T> QMultiHash<Key, T>::values(const Key &key) const
3327 \overload
3328
3329 Returns a list of all the values associated with the \a key,
3330 from the most recently inserted to the least recently inserted.
3331
3332 \sa count(), insert()
3333*/
3334
3335/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::operator[](const Key &key)
3336
3337 Returns the value associated with the \a key as a modifiable reference.
3338
3339 If the hash contains no item with the \a key, the function inserts
3340 a \l{default-constructed value} into the hash with the \a key, and
3341 returns a reference to it.
3342
3343 If the hash contains multiple items with the \a key, this function returns
3344 a reference to the most recently inserted value.
3345
3346 \include qhash.cpp qhash-iterator-invalidation-func-desc
3347
3348 \sa insert(), value()
3349*/
3350
3351/*!
3352 \fn template <class Key, class T> bool QMultiHash<Key, T>::operator==(const QMultiHash &lhs, const QMultiHash &rhs)
3353
3354 Returns \c true if \a lhs multihash equals to the \a rhs multihash;
3355 otherwise returns \c false.
3356
3357 Two multihashes are considered equal if they contain the same (key, value)
3358 pairs.
3359
3360 This function requires the value type to implement \c {operator==()}.
3361
3362 \sa operator!=()
3363*/
3364
3365/*!
3366 \fn template <class Key, class T> bool QMultiHash<Key, T>::operator!=(const QMultiHash &lhs, const QMultiHash &rhs)
3367
3368 Returns \c true if \a lhs multihash is not equal to the \a rhs multihash;
3369 otherwise returns \c false.
3370
3371 Two multihashes are considered equal if they contain the same (key, value)
3372 pairs.
3373
3374 This function requires the value type to implement \c {operator==()}.
3375
3376 \sa operator==()
3377*/
3378
3379/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::operator+=(const QMultiHash &other)
3380
3381 Inserts all the items in the \a other hash into this hash
3382 and returns a reference to this hash.
3383
3384 \sa unite(), insert()
3385*/
3386
3387/*! \fn template <class Key, class T> QMultiHash QMultiHash<Key, T>::operator+(const QMultiHash &other) const
3388
3389 Returns a hash that contains all the items in this hash in
3390 addition to all the items in \a other. If a key is common to both
3391 hashes, the resulting hash will contain the key multiple times.
3392
3393 \sa operator+=()
3394*/
3395
3396/*!
3397 \fn template <class Key, class T> bool QMultiHash<Key, T>::contains(const Key &key, const T &value) const
3398 \since 4.3
3399
3400 Returns \c true if the hash contains an item with the \a key and
3401 \a value; otherwise returns \c false.
3402
3403 \sa count()
3404*/
3405
3406/*!
3407 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::remove(const Key &key)
3408 \since 4.3
3409
3410 Removes all the items that have the \a key from the hash.
3411 Returns the number of items removed.
3412
3413 \sa remove(const Key &key, const T &value)
3414*/
3415
3416/*!
3417 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::remove(const Key &key, const T &value)
3418 \since 4.3
3419
3420 Removes all the items that have the \a key and the value \a
3421 value from the hash. Returns the number of items removed.
3422
3423 \sa remove()
3424*/
3425
3426/*!
3427 \fn template <class Key, class T> void QMultiHash<Key, T>::clear()
3428 \since 4.3
3429
3430 Removes all items from the hash and frees up all memory used by it.
3431
3432 \sa remove()
3433*/
3434
3435/*! \fn template <class Key, class T> template <typename Predicate> qsizetype QMultiHash<Key, T>::removeIf(Predicate pred)
3436 \since 6.1
3437
3438 Removes all elements for which the predicate \a pred returns true
3439 from the multi hash.
3440
3441 The function supports predicates which take either an argument of
3442 type \c{QMultiHash<Key, T>::iterator}, or an argument of type
3443 \c{std::pair<const Key &, T &>}.
3444
3445 Returns the number of elements removed, if any.
3446
3447 \sa clear(), take()
3448*/
3449
3450/*! \fn template <class Key, class T> T QMultiHash<Key, T>::take(const Key &key)
3451
3452 Removes the item with the \a key from the hash and returns
3453 the value associated with it.
3454
3455 If the item does not exist in the hash, the function simply
3456 returns a \l{default-constructed value}. If there are multiple
3457 items for \a key in the hash, only the most recently inserted one
3458 is removed.
3459
3460 If you don't use the return value, remove() is more efficient.
3461
3462 \sa remove()
3463*/
3464
3465/*! \fn template <class Key, class T> QList<Key> QMultiHash<Key, T>::keys() const
3466
3467 Returns a list containing all the keys in the hash, in an
3468 arbitrary order. Keys that occur multiple times in the hash
3469 also occur multiple times in the list.
3470
3471 The order is guaranteed to be the same as that used by values().
3472
3473 This function creates a new list, in \l {linear time}. The time and memory
3474 use that entails can be avoided by iterating from \l keyBegin() to
3475 \l keyEnd().
3476
3477 \sa values(), key()
3478*/
3479
3480/*! \fn template <class Key, class T> QList<T> QMultiHash<Key, T>::values() const
3481
3482 Returns a list containing all the values in the hash, in an
3483 arbitrary order. If a key is associated with multiple values, all of
3484 its values will be in the list, and not just the most recently
3485 inserted one.
3486
3487 The order is guaranteed to be the same as that used by keys().
3488
3489 This function creates a new list, in \l {linear time}. The time and memory
3490 use that entails can be avoided by iterating from \l keyValueBegin() to
3491 \l keyValueEnd().
3492
3493 \sa keys(), value()
3494*/
3495
3496/*!
3497 \fn template <class Key, class T> Key QMultiHash<Key, T>::key(const T &value) const
3498 \fn template <class Key, class T> Key QMultiHash<Key, T>::key(const T &value, const Key &defaultKey) const
3499 \since 4.3
3500
3501 Returns the first key mapped to \a value. If the hash contains no item
3502 mapped to \a value, returns \a defaultKey, or a \l{default-constructed
3503 value}{default-constructed key} if this parameter has not been supplied.
3504
3505 This function can be slow (\l{linear time}), because QMultiHash's
3506 internal data structure is optimized for fast lookup by key, not
3507 by value.
3508*/
3509
3510/*!
3511 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::count(const Key &key, const T &value) const
3512 \since 4.3
3513
3514 Returns the number of items with the \a key and \a value.
3515
3516 \sa contains()
3517*/
3518
3519/*!
3520 \fn template <class Key, class T> typename QMultiHash<Key, T>::iterator QMultiHash<Key, T>::find(const Key &key, const T &value)
3521 \since 4.3
3522
3523 Returns an iterator pointing to the item with the \a key and \a value.
3524 If the hash contains no such item, the function returns end().
3525
3526 If the hash contains multiple items with the \a key and \a value, the
3527 iterator returned points to the most recently inserted item.
3528
3529 \include qhash.cpp qhash-iterator-invalidation-func-desc
3530*/
3531
3532/*!
3533 \fn template <class Key, class T> typename QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::find(const Key &key, const T &value) const
3534 \since 4.3
3535 \overload
3536
3537 \include qhash.cpp qhash-iterator-invalidation-func-desc
3538*/
3539
3540/*!
3541 \fn template <class Key, class T> typename QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constFind(const Key &key, const T &value) const
3542 \since 4.3
3543
3544 Returns an iterator pointing to the item with the \a key and the
3545 \a value in the hash.
3546
3547 If the hash contains no such item, the function returns
3548 constEnd().
3549
3550 \include qhash.cpp qhash-iterator-invalidation-func-desc
3551*/
3552
3553/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::begin()
3554
3555 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
3556 the hash.
3557
3558 \include qhash.cpp qhash-iterator-invalidation-func-desc
3559
3560 \sa constBegin(), end()
3561*/
3562
3563/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::begin() const
3564
3565 \overload
3566
3567 \include qhash.cpp qhash-iterator-invalidation-func-desc
3568*/
3569
3570/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::cbegin() const
3571 \since 5.0
3572
3573 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
3574 in the hash.
3575
3576 \include qhash.cpp qhash-iterator-invalidation-func-desc
3577
3578 \sa begin(), cend()
3579*/
3580
3581/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constBegin() const
3582
3583 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
3584 in the hash.
3585
3586 \include qhash.cpp qhash-iterator-invalidation-func-desc
3587
3588 \sa begin(), constEnd()
3589*/
3590
3591/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::keyBegin() const
3592 \since 5.6
3593
3594 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
3595 in the hash.
3596
3597 \include qhash.cpp qhash-iterator-invalidation-func-desc
3598
3599 \sa keyEnd()
3600*/
3601
3602/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::end()
3603
3604 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
3605 after the last item in the hash.
3606
3607 \include qhash.cpp qhash-iterator-invalidation-func-desc
3608
3609 \sa begin(), constEnd()
3610*/
3611
3612/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::end() const
3613
3614 \overload
3615*/
3616
3617/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constEnd() const
3618
3619 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3620 item after the last item in the hash.
3621
3622 \include qhash.cpp qhash-iterator-invalidation-func-desc
3623
3624 \sa constBegin(), end()
3625*/
3626
3627/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::cend() const
3628 \since 5.0
3629
3630 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3631 item after the last item in the hash.
3632
3633 \include qhash.cpp qhash-iterator-invalidation-func-desc
3634
3635 \sa cbegin(), end()
3636*/
3637
3638/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::keyEnd() const
3639 \since 5.6
3640
3641 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3642 item after the last key in the hash.
3643
3644 \include qhash.cpp qhash-iterator-invalidation-func-desc
3645
3646 \sa keyBegin()
3647*/
3648
3649/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_value_iterator QMultiHash<Key, T>::keyValueBegin()
3650 \since 5.10
3651
3652 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3653 in the hash.
3654
3655 \include qhash.cpp qhash-iterator-invalidation-func-desc
3656
3657 \sa keyValueEnd()
3658*/
3659
3660/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_value_iterator QMultiHash<Key, T>::keyValueEnd()
3661 \since 5.10
3662
3663 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3664 entry after the last entry in the hash.
3665
3666 \include qhash.cpp qhash-iterator-invalidation-func-desc
3667
3668 \sa keyValueBegin()
3669*/
3670
3671/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::keyValueBegin() const
3672 \since 5.10
3673
3674 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3675 in the hash.
3676
3677 \include qhash.cpp qhash-iterator-invalidation-func-desc
3678
3679 \sa keyValueEnd()
3680*/
3681
3682/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::constKeyValueBegin() const
3683 \since 5.10
3684
3685 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3686 in the hash.
3687
3688 \include qhash.cpp qhash-iterator-invalidation-func-desc
3689
3690 \sa keyValueBegin()
3691*/
3692
3693/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::keyValueEnd() const
3694 \since 5.10
3695
3696 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3697 entry after the last entry in the hash.
3698
3699 \include qhash.cpp qhash-iterator-invalidation-func-desc
3700
3701 \sa keyValueBegin()
3702*/
3703
3704/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::constKeyValueEnd() const
3705 \since 5.10
3706
3707 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3708 entry after the last entry in the hash.
3709
3710 \include qhash.cpp qhash-iterator-invalidation-func-desc
3711
3712 \sa constKeyValueBegin()
3713*/
3714
3715/*! \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() &
3716 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const &
3717 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() &&
3718 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const &&
3719 \since 6.4
3720
3721 Returns a range object that allows iteration over this hash as
3722 key/value pairs. For instance, this range object can be used in a
3723 range-based for loop, in combination with a structured binding declaration:
3724
3725 \snippet code/src_corelib_tools_qhash.cpp 35
3726
3727 Note that both the key and the value obtained this way are
3728 references to the ones in the hash. Specifically, mutating the value
3729 will modify the hash itself.
3730
3731 \include qhash.cpp qhash-iterator-invalidation-func-desc
3732
3733 \sa QKeyValueIterator
3734*/
3735
3736/*! \class QMultiHash::iterator
3737 \inmodule QtCore
3738 \brief The QMultiHash::iterator class provides an STL-style non-const iterator for QMultiHash.
3739
3740 QMultiHash<Key, T>::iterator allows you to iterate over a QMultiHash
3741 and to modify the value (but not the key) associated
3742 with a particular key. If you want to iterate over a const QMultiHash,
3743 you should use QMultiHash::const_iterator. It is generally good
3744 practice to use QMultiHash::const_iterator on a non-const QMultiHash as
3745 well, unless you need to change the QMultiHash through the iterator.
3746 Const iterators are slightly faster, and can improve code
3747 readability.
3748
3749 The default QMultiHash::iterator constructor creates an uninitialized
3750 iterator. You must initialize it using a QMultiHash function like
3751 QMultiHash::begin(), QMultiHash::end(), or QMultiHash::find() before you can
3752 start iterating. Here's a typical loop that prints all the (key,
3753 value) pairs stored in a hash:
3754
3755 \snippet code/src_corelib_tools_qhash.cpp 17
3756
3757 Unlike QMap, which orders its items by key, QMultiHash stores its
3758 items in an arbitrary order.
3759
3760 Here's an example that increments every value stored in the QMultiHash
3761 by 2:
3762
3763 \snippet code/src_corelib_tools_qhash.cpp 18
3764
3765 To remove elements from a QMultiHash you can use erase_if(QMultiHash<Key, T> &map, Predicate pred):
3766
3767 \snippet code/src_corelib_tools_qhash.cpp 21
3768
3769 Multiple iterators can be used on the same hash. However, be aware
3770 that any modification performed directly on the QHash (inserting and
3771 removing items) can cause the iterators to become invalid.
3772
3773 Inserting items into the hash or calling methods such as QHash::reserve()
3774 or QHash::squeeze() can invalidate all iterators pointing into the hash.
3775 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
3776 to grow/shrink its internal hash table.
3777 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
3778
3779 If you need to keep iterators over a long period of time, we recommend
3780 that you use QMultiMap rather than QHash.
3781
3782 \warning Iterators on implicitly shared containers do not work
3783 exactly like STL-iterators. You should avoid copying a container
3784 while iterators are active on that container. For more information,
3785 read \l{Implicit sharing iterator problem}.
3786
3787 \sa QMultiHash::const_iterator, QMultiHash::key_iterator, QMultiHash::key_value_iterator
3788*/
3789
3790/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator::iterator()
3791
3792 Constructs an uninitialized iterator.
3793
3794 Functions like key(), value(), and operator++() must not be
3795 called on an uninitialized iterator. Use operator=() to assign a
3796 value to it before using it.
3797
3798 \sa QMultiHash::begin(), QMultiHash::end()
3799*/
3800
3801/*! \fn template <class Key, class T> const Key &QMultiHash<Key, T>::iterator::key() const
3802
3803 Returns the current item's key as a const reference.
3804
3805 There is no direct way of changing an item's key through an
3806 iterator, although it can be done by calling QMultiHash::erase()
3807 followed by QMultiHash::insert().
3808
3809 \sa value()
3810*/
3811
3812/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::iterator::value() const
3813
3814 Returns a modifiable reference to the current item's value.
3815
3816 You can change the value of an item by using value() on
3817 the left side of an assignment, for example:
3818
3819 \snippet code/src_corelib_tools_qhash.cpp 22
3820
3821 \sa key(), operator*()
3822*/
3823
3824/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::iterator::operator*() const
3825
3826 Returns a modifiable reference to the current item's value.
3827
3828 Same as value().
3829
3830 \sa key()
3831*/
3832
3833/*! \fn template <class Key, class T> T *QMultiHash<Key, T>::iterator::operator->() const
3834
3835 Returns a pointer to the current item's value.
3836
3837 \sa value()
3838*/
3839
3840/*!
3841 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator==(const iterator &other) const
3842 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator==(const const_iterator &other) const
3843
3844 Returns \c true if \a other points to the same item as this
3845 iterator; otherwise returns \c false.
3846
3847 \sa operator!=()
3848*/
3849
3850/*!
3851 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator!=(const iterator &other) const
3852 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator!=(const const_iterator &other) const
3853
3854 Returns \c true if \a other points to a different item than this
3855 iterator; otherwise returns \c false.
3856
3857 \sa operator==()
3858*/
3859
3860/*!
3861 \fn template <class Key, class T> QMultiHash<Key, T>::iterator &QMultiHash<Key, T>::iterator::operator++()
3862
3863 The prefix ++ operator (\c{++i}) advances the iterator to the
3864 next item in the hash and returns an iterator to the new current
3865 item.
3866
3867 Calling this function on QMultiHash::end() leads to undefined results.
3868*/
3869
3870/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::iterator::operator++(int)
3871
3872 \overload
3873
3874 The postfix ++ operator (\c{i++}) advances the iterator to the
3875 next item in the hash and returns an iterator to the previously
3876 current item.
3877*/
3878
3879/*! \class QMultiHash::const_iterator
3880 \inmodule QtCore
3881 \brief The QMultiHash::const_iterator class provides an STL-style const iterator for QMultiHash.
3882
3883 QMultiHash<Key, T>::const_iterator allows you to iterate over a
3884 QMultiHash. If you want to modify the QMultiHash as you
3885 iterate over it, you must use QMultiHash::iterator instead. It is
3886 generally good practice to use QMultiHash::const_iterator on a
3887 non-const QMultiHash as well, unless you need to change the QMultiHash
3888 through the iterator. Const iterators are slightly faster, and
3889 can improve code readability.
3890
3891 The default QMultiHash::const_iterator constructor creates an
3892 uninitialized iterator. You must initialize it using a QMultiHash
3893 function like QMultiHash::cbegin(), QMultiHash::cend(), or
3894 QMultiHash::constFind() before you can start iterating. Here's a typical
3895 loop that prints all the (key, value) pairs stored in a hash:
3896
3897 \snippet code/src_corelib_tools_qhash.cpp 23
3898
3899 Unlike QMap, which orders its items by key, QMultiHash stores its
3900 items in an arbitrary order. The only guarantee is that items that
3901 share the same key (because they were inserted using
3902 a QMultiHash) will appear consecutively, from the most
3903 recently to the least recently inserted value.
3904
3905 Multiple iterators can be used on the same hash. However, be aware
3906 that any modification performed directly on the QMultiHash (inserting and
3907 removing items) can cause the iterators to become invalid.
3908
3909 Inserting items into the hash or calling methods such as QMultiHash::reserve()
3910 or QMultiHash::squeeze() can invalidate all iterators pointing into the hash.
3911 Iterators are guaranteed to stay valid only as long as the QMultiHash doesn't have
3912 to grow/shrink it's internal hash table.
3913 Using any iterator after a rehashing operation ahs occurred will lead to undefined behavior.
3914
3915 If you need to keep iterators over a long period of time, we recommend
3916 that you use QMultiMap rather than QMultiHash.
3917
3918 \warning Iterators on implicitly shared containers do not work
3919 exactly like STL-iterators. You should avoid copying a container
3920 while iterators are active on that container. For more information,
3921 read \l{Implicit sharing iterator problem}.
3922
3923 \sa QMultiHash::iterator, QMultiHash::key_iterator, QMultiHash::const_key_value_iterator
3924*/
3925
3926/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator::const_iterator()
3927
3928 Constructs an uninitialized iterator.
3929
3930 Functions like key(), value(), and operator++() must not be
3931 called on an uninitialized iterator. Use operator=() to assign a
3932 value to it before using it.
3933
3934 \sa QMultiHash::constBegin(), QMultiHash::constEnd()
3935*/
3936
3937/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator::const_iterator(const iterator &other)
3938
3939 Constructs a copy of \a other.
3940*/
3941
3942/*! \fn template <class Key, class T> const Key &QMultiHash<Key, T>::const_iterator::key() const
3943
3944 Returns the current item's key.
3945
3946 \sa value()
3947*/
3948
3949/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::const_iterator::value() const
3950
3951 Returns the current item's value.
3952
3953 \sa key(), operator*()
3954*/
3955
3956/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::const_iterator::operator*() const
3957
3958 Returns the current item's value.
3959
3960 Same as value().
3961
3962 \sa key()
3963*/
3964
3965/*! \fn template <class Key, class T> const T *QMultiHash<Key, T>::const_iterator::operator->() const
3966
3967 Returns a pointer to the current item's value.
3968
3969 \sa value()
3970*/
3971
3972/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::const_iterator::operator==(const const_iterator &other) const
3973
3974 Returns \c true if \a other points to the same item as this
3975 iterator; otherwise returns \c false.
3976
3977 \sa operator!=()
3978*/
3979
3980/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::const_iterator::operator!=(const const_iterator &other) const
3981
3982 Returns \c true if \a other points to a different item than this
3983 iterator; otherwise returns \c false.
3984
3985 \sa operator==()
3986*/
3987
3988/*!
3989 \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator &QMultiHash<Key, T>::const_iterator::operator++()
3990
3991 The prefix ++ operator (\c{++i}) advances the iterator to the
3992 next item in the hash and returns an iterator to the new current
3993 item.
3994
3995 Calling this function on QMultiHash::end() leads to undefined results.
3996*/
3997
3998/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::const_iterator::operator++(int)
3999
4000 \overload
4001
4002 The postfix ++ operator (\c{i++}) advances the iterator to the
4003 next item in the hash and returns an iterator to the previously
4004 current item.
4005*/
4006
4007/*! \class QMultiHash::key_iterator
4008 \inmodule QtCore
4009 \since 5.6
4010 \brief The QMultiHash::key_iterator class provides an STL-style const iterator for QMultiHash keys.
4011
4012 QMultiHash::key_iterator is essentially the same as QMultiHash::const_iterator
4013 with the difference that operator*() and operator->() return a key
4014 instead of a value.
4015
4016 For most uses QMultiHash::iterator and QMultiHash::const_iterator should be used,
4017 you can easily access the key by calling QMultiHash::iterator::key():
4018
4019 \snippet code/src_corelib_tools_qhash.cpp 27
4020
4021 However, to have interoperability between QMultiHash's keys and STL-style
4022 algorithms we need an iterator that dereferences to a key instead
4023 of a value. With QMultiHash::key_iterator we can apply an algorithm to a
4024 range of keys without having to call QMultiHash::keys(), which is inefficient
4025 as it costs one QMultiHash iteration and memory allocation to create a temporary
4026 QList.
4027
4028 \snippet code/src_corelib_tools_qhash.cpp 28
4029
4030 QMultiHash::key_iterator is const, it's not possible to modify the key.
4031
4032 The default QMultiHash::key_iterator constructor creates an uninitialized
4033 iterator. You must initialize it using a QMultiHash function like
4034 QMultiHash::keyBegin() or QMultiHash::keyEnd().
4035
4036 \warning Iterators on implicitly shared containers do not work
4037 exactly like STL-iterators. You should avoid copying a container
4038 while iterators are active on that container. For more information,
4039 read \l{Implicit sharing iterator problem}.
4040
4041 \sa QMultiHash::const_iterator, QMultiHash::iterator
4042*/
4043
4044/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::key_iterator::operator*() const
4045
4046 Returns the current item's key.
4047*/
4048
4049/*! \fn template <class Key, class T> const T *QMultiHash<Key, T>::key_iterator::operator->() const
4050
4051 Returns a pointer to the current item's key.
4052*/
4053
4054/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::key_iterator::operator==(key_iterator other) const
4055
4056 Returns \c true if \a other points to the same item as this
4057 iterator; otherwise returns \c false.
4058
4059 \sa operator!=()
4060*/
4061
4062/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::key_iterator::operator!=(key_iterator other) const
4063
4064 Returns \c true if \a other points to a different item than this
4065 iterator; otherwise returns \c false.
4066
4067 \sa operator==()
4068*/
4069
4070/*!
4071 \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator &QMultiHash<Key, T>::key_iterator::operator++()
4072
4073 The prefix ++ operator (\c{++i}) advances the iterator to the
4074 next item in the hash and returns an iterator to the new current
4075 item.
4076
4077 Calling this function on QMultiHash::keyEnd() leads to undefined results.
4078*/
4079
4080/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::key_iterator::operator++(int)
4081
4082 \overload
4083
4084 The postfix ++ operator (\c{i++}) advances the iterator to the
4085 next item in the hash and returns an iterator to the previous
4086 item.
4087*/
4088
4089/*! \fn template <class Key, class T> const_iterator QMultiHash<Key, T>::key_iterator::base() const
4090 Returns the underlying const_iterator this key_iterator is based on.
4091*/
4092
4093/*! \typedef QMultiHash::const_key_value_iterator
4094 \inmodule QtCore
4095 \since 5.10
4096 \brief The QMultiHash::const_key_value_iterator typedef provides an STL-style const iterator for QMultiHash.
4097
4098 QMultiHash::const_key_value_iterator is essentially the same as QMultiHash::const_iterator
4099 with the difference that operator*() returns a key/value pair instead of a
4100 value.
4101
4102 \sa QKeyValueIterator
4103*/
4104
4105/*! \typedef QMultiHash::key_value_iterator
4106 \inmodule QtCore
4107 \since 5.10
4108 \brief The QMultiHash::key_value_iterator typedef provides an STL-style iterator for QMultiHash.
4109
4110 QMultiHash::key_value_iterator is essentially the same as QMultiHash::iterator
4111 with the difference that operator*() returns a key/value pair instead of a
4112 value.
4113
4114 \sa QKeyValueIterator
4115*/
4116
4117/*! \fn template <class Key, class T> QDataStream &operator<<(QDataStream &out, const QMultiHash<Key, T>& hash)
4118 \relates QMultiHash
4119
4120 Writes the hash \a hash to stream \a out.
4121
4122 This function requires the key and value types to implement \c
4123 operator<<().
4124
4125 \sa {Serializing Qt Data Types}
4126*/
4127
4128/*! \fn template <class Key, class T> QDataStream &operator>>(QDataStream &in, QMultiHash<Key, T> &hash)
4129 \relates QMultiHash
4130
4131 Reads a hash from stream \a in into \a hash.
4132
4133 This function requires the key and value types to implement \c
4134 operator>>().
4135
4136 \sa {Serializing Qt Data Types}
4137*/
4138
4139/*!
4140 \fn template <class Key, class T> size_t qHash(const QHash<Key, T> &key, size_t seed = 0)
4141 \since 5.8
4142 \qhasholdTS{QHash}{Key}{T}
4143*/
4144
4145/*!
4146 \fn template <class Key, class T> size_t qHash(const QMultiHash<Key, T> &key, size_t seed = 0)
4147 \since 5.8
4148 \qhasholdTS{QMultiHash}{Key}{T}
4149*/
4150
4151/*! \fn template <typename Key, typename T, typename Predicate> qsizetype erase_if(QHash<Key, T> &hash, Predicate pred)
4152 \relates QHash
4153 \since 6.1
4154
4155 Removes all elements for which the predicate \a pred returns true
4156 from the hash \a hash.
4157
4158 The function supports predicates which take either an argument of
4159 type \c{QHash<Key, T>::iterator}, or an argument of type
4160 \c{std::pair<const Key &, T &>}.
4161
4162 Returns the number of elements removed, if any.
4163*/
4164
4165/*! \fn template <typename Key, typename T, typename Predicate> qsizetype erase_if(QMultiHash<Key, T> &hash, Predicate pred)
4166 \relates QMultiHash
4167 \since 6.1
4168
4169 Removes all elements for which the predicate \a pred returns true
4170 from the multi hash \a hash.
4171
4172 The function supports predicates which take either an argument of
4173 type \c{QMultiHash<Key, T>::iterator}, or an argument of type
4174 \c{std::pair<const Key &, T &>}.
4175
4176 Returns the number of elements removed, if any.
4177*/
4178
4179/*! \macro QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD
4180 \relates QHash
4181 \since 6.11
4182
4183 Defining this macro disables the support for \l{The hashing function}{qHash}
4184 overloads that only take one argument; in other words, for
4185 \l{The hashing function}{qHash} overloads that do not also accept a seed.
4186 Support for the single-argument overloads of \l{The hashing function}{qHash}
4187 is deprecated and will be removed in Qt 7.
4188
4189 \sa {The hashing function}
4190*/
4191
4192#ifdef QT_HAS_CONSTEXPR_BITOPS
4193namespace QHashPrivate {
4194static_assert(qPopulationCount(SpanConstants::NEntries) == 1,
4195 "NEntries must be a power of 2 for bucketForHash() to work.");
4196
4197// ensure the size of a Span does not depend on the template parameters
4198using Node1 = Node<int, int>;
4199static_assert(sizeof(Span<Node1>) == sizeof(Span<Node<char, void *>>));
4200static_assert(sizeof(Span<Node1>) == sizeof(Span<Node<qsizetype, QHashDummyValue>>));
4201static_assert(sizeof(Span<Node1>) == sizeof(Span<Node<QString, QVariant>>));
4202static_assert(sizeof(Span<Node1>) > SpanConstants::NEntries);
4203static_assert(qNextPowerOfTwo(sizeof(Span<Node1>)) == SpanConstants::NEntries * 2);
4204
4205// ensure allocations are always a power of two, at a minimum NEntries,
4206// obeying the fomula
4207// qNextPowerOfTwo(2 * N);
4208// without overflowing
4209static constexpr size_t NEntries = SpanConstants::NEntries;
4210static_assert(GrowthPolicy::bucketsForCapacity(1) == NEntries);
4211static_assert(GrowthPolicy::bucketsForCapacity(NEntries / 2 + 0) == NEntries);
4212static_assert(GrowthPolicy::bucketsForCapacity(NEntries / 2 + 1) == 2 * NEntries);
4213static_assert(GrowthPolicy::bucketsForCapacity(NEntries * 1 - 1) == 2 * NEntries);
4214static_assert(GrowthPolicy::bucketsForCapacity(NEntries * 1 + 0) == 4 * NEntries);
4215static_assert(GrowthPolicy::bucketsForCapacity(NEntries * 1 + 1) == 4 * NEntries);
4216static_assert(GrowthPolicy::bucketsForCapacity(NEntries * 2 - 1) == 4 * NEntries);
4217static_assert(GrowthPolicy::bucketsForCapacity(NEntries * 2 + 0) == 8 * NEntries);
4218static_assert(GrowthPolicy::bucketsForCapacity(SIZE_MAX / 4) == SIZE_MAX / 2 + 1);
4219static_assert(GrowthPolicy::bucketsForCapacity(SIZE_MAX / 2) == SIZE_MAX);
4220static_assert(GrowthPolicy::bucketsForCapacity(SIZE_MAX) == SIZE_MAX);
4221}
4222#endif
4223
4224QT_END_NAMESPACE
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define __has_feature(x)
size_t qHashBits(const void *p, size_t size, size_t seed) noexcept
Definition qhash.cpp:851
size_t qHashBits_fallback< None >(const uchar *p, size_t size, size_t seed, size_t seed2) noexcept
Definition qhash.cpp:299
size_t qHash(double key, size_t seed) noexcept
Definition qhash.cpp:1382
size_t qHashBits_fallback< ByteToWord >(const uchar *data, size_t size, size_t seed, size_t seed2) noexcept
Definition qhash.cpp:307
static size_t qHashBits_fallback(const uchar *p, size_t size, size_t seed, size_t seed2) noexcept
ZeroExtension
Definition qhash.cpp:292
@ ByteToWord
Definition qhash.cpp:294
@ None
Definition qhash.cpp:293
size_t qHash(QByteArrayView key, size_t seed) noexcept
Definition qhash.cpp:876
size_t qHash(long double key, size_t seed) noexcept
Definition qhash.cpp:1399
#define Q_DECL_HOT_FUNCTION
Definition qhash.cpp:51
uint qt_hash(QStringView key, uint chained) noexcept
Definition qhash.cpp:1087
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192
Q_CORE_EXPORT void qt_from_latin1(char16_t *dst, const char *str, size_t size) noexcept
Definition qstring.cpp:921