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 \l{qHash} about how this seed
1025 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 \l{qHash} about how this seed
1051 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{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 \target qHash
1634 \section2 The hashing function
1635
1636 A QHash's key type has additional requirements other than being an
1637 assignable data type: it must provide operator==(), and there must also be
1638 a hashing function that returns a hash value for an argument of the
1639 key's type.
1640
1641 The hashing function computes a numeric value based on a key. It
1642 can use any algorithm imaginable, as long as it always returns
1643 the same value if given the same argument. In other words, if
1644 \c{e1 == e2}, then \c{hash(e1) == hash(e2)} must hold as well.
1645 However, to obtain good performance, the hashing function should
1646 attempt to return different hash values for different keys to the
1647 largest extent possible.
1648
1649 A hashing function for a key type \c{K} may be provided in two
1650 different ways.
1651
1652 The first way is by having an overload of \c{qHash()} in \c{K}'s
1653 namespace. The \c{qHash()} function must have one of these signatures:
1654
1655 \snippet code/src_corelib_tools_qhash.cpp 32
1656
1657 The two-arguments overloads take an unsigned integer that should be used to
1658 seed the calculation of the hash function. This seed is provided by QHash
1659 in order to prevent a family of \l{algorithmic complexity attacks}.
1660
1661 \note In Qt 6 it is possible to define a \c{qHash()} overload
1662 taking only one argument; support for this is deprecated. Starting
1663 with Qt 7, it will be mandatory to use a two-arguments overload. If
1664 both a one-argument and a two-arguments overload are defined for a
1665 key type, the latter is used by QHash (note that you can simply
1666 define a two-arguments version, and use a default value for the
1667 seed parameter). In Qt 6 it is possible to disable support for the
1668 single argument qHash overload by defining the
1669 \c{QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD} macro.
1670
1671 The second way to provide a hashing function is by specializing
1672 the \c{std::hash} class for the key type \c{K}, and providing a
1673 suitable function call operator for it:
1674
1675 \snippet code/src_corelib_tools_qhash.cpp 33
1676
1677 The seed argument has the same meaning as for \c{qHash()},
1678 and may be left out.
1679
1680 This second way allows to reuse the same hash function between
1681 QHash and the C++ Standard Library unordered associative containers.
1682 If both a \c{qHash()} overload and a \c{std::hash} specializations
1683 are provided for a type, then the \c{qHash()} overload is preferred.
1684
1685 Here's a partial list of the C++ and Qt types that can serve as keys in a
1686 QHash: any integer type (char, unsigned long, etc.), any pointer type,
1687 QChar, QString, and QByteArray. For all of these, the \c <QHash> header
1688 defines a qHash() function that computes an adequate hash value. Many other
1689 Qt classes also declare a qHash overload for their type; please refer to
1690 the documentation of each class.
1691
1692 If you want to use other types as the key, make sure that you provide
1693 operator==() and a hash implementation.
1694
1695 The convenience qHashMulti() function can be used to implement
1696 qHash() for a custom type, where one usually wants to produce a
1697 hash value from multiple fields:
1698
1699 Example:
1700 \snippet code/src_corelib_tools_qhash.cpp 13
1701
1702 In the example above, we've relied on Qt's own implementation of
1703 qHash() for QString and QDate to give us a hash value for the
1704 employee's name and date of birth respectively.
1705
1706 Note that the implementation of the qHash() overloads offered by Qt
1707 may change at any time. You \b{must not} rely on the fact that qHash()
1708 will give the same results (for the same inputs) across different Qt
1709 versions.
1710
1711 \section2 Algorithmic complexity attacks
1712
1713 All hash tables are vulnerable to a particular class of denial of service
1714 attacks, in which the attacker carefully pre-computes a set of different
1715 keys that are going to be hashed in the same bucket of a hash table (or
1716 even have the very same hash value). The attack aims at getting the
1717 worst-case algorithmic behavior (O(n) instead of amortized O(1), see
1718 \l{Algorithmic Complexity} for the details) when the data is fed into the
1719 table.
1720
1721 In order to avoid this worst-case behavior, the calculation of the hash
1722 value done by qHash() can be salted by a random seed, that nullifies the
1723 attack's extent. This seed is automatically generated by QHash once per
1724 process, and then passed by QHash as the second argument of the
1725 two-arguments overload of the qHash() function.
1726
1727 This randomization of QHash is enabled by default. Even though programs
1728 should never depend on a particular QHash ordering, there may be situations
1729 where you temporarily need deterministic behavior, for example for debugging or
1730 regression testing. To disable the randomization, define the environment
1731 variable \c QT_HASH_SEED to have the value 0. Alternatively, you can call
1732 the QHashSeed::setDeterministicGlobalSeed() function.
1733
1734 \sa QHashIterator, QMutableHashIterator, QMap, QSet
1735*/
1736
1737/*! \fn template <class Key, class T> QHash<Key, T>::QHash()
1738
1739 Constructs an empty hash.
1740
1741 \sa clear()
1742*/
1743
1744/*!
1745 \fn template <class Key, class T> QHash<Key, T>::QHash(QHash &&other)
1746
1747 Move-constructs a QHash instance, making it point at the same
1748 object that \a other was pointing to.
1749
1750 \since 5.2
1751*/
1752
1753/*! \fn template <class Key, class T> QHash<Key, T>::QHash(std::initializer_list<std::pair<Key,T> > list)
1754 \since 5.1
1755
1756 Constructs a hash with a copy of each of the elements in the
1757 initializer list \a list.
1758*/
1759
1760/*! \fn template <class Key, class T> template <class InputIterator> QHash<Key, T>::QHash(InputIterator begin, InputIterator end)
1761 \since 5.14
1762
1763 Constructs a hash with a copy of each of the elements in the iterator range
1764 [\a begin, \a end). Either the elements iterated by the range must be
1765 objects with \c{first} and \c{second} data members (like \c{std::pair}),
1766 convertible to \c Key and to \c T respectively; or the
1767 iterators must have \c{key()} and \c{value()} member functions, returning a
1768 key convertible to \c Key and a value convertible to \c T respectively.
1769*/
1770
1771/*! \fn template <class Key, class T> QHash<Key, T>::QHash(const QHash &other)
1772
1773 Constructs a copy of \a other.
1774
1775 This operation occurs in \l{constant time}, because QHash is
1776 \l{implicitly shared}. This makes returning a QHash from a
1777 function very fast. If a shared instance is modified, it will be
1778 copied (copy-on-write), and this takes \l{linear time}.
1779
1780 \sa operator=()
1781*/
1782
1783/*! \fn template <class Key, class T> QHash<Key, T>::~QHash()
1784
1785 Destroys the hash. References to the values in the hash and all
1786 iterators of this hash become invalid.
1787*/
1788
1789/*! \fn template <class Key, class T> QHash &QHash<Key, T>::operator=(const QHash &other)
1790
1791 Assigns \a other to this hash and returns a reference to this hash.
1792*/
1793
1794/*!
1795 \fn template <class Key, class T> QHash &QHash<Key, T>::operator=(QHash &&other)
1796
1797 Move-assigns \a other to this QHash instance.
1798
1799 \since 5.2
1800*/
1801
1802/*! \fn template <class Key, class T> void QHash<Key, T>::swap(QHash &other)
1803 \since 4.8
1804 \memberswap{hash}
1805*/
1806
1807/*! \fn template <class Key, class T> void QMultiHash<Key, T>::swap(QMultiHash &other)
1808 \since 4.8
1809 \memberswap{multi-hash}
1810*/
1811
1812/*! \fn template <class Key, class T> bool QHash<Key, T>::operator==(const QHash &lhs, const QHash &rhs)
1813
1814 Returns \c true if \a lhs hash is equal to \a rhs hash; otherwise returns
1815 \c false.
1816
1817 Two hashes are considered equal if they contain the same (key,
1818 value) pairs.
1819
1820 This function requires the value type to implement \c operator==().
1821
1822 \sa operator!=()
1823*/
1824
1825/*! \fn template <class Key, class T> bool QHash<Key, T>::operator!=(const QHash &lhs, const QHash &rhs)
1826
1827 Returns \c true if \a lhs hash is not equal to \a rhs hash; otherwise
1828 returns \c false.
1829
1830 Two hashes are considered equal if they contain the same (key,
1831 value) pairs.
1832
1833 This function requires the value type to implement \c operator==().
1834
1835 \sa operator==()
1836*/
1837
1838/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::size() const
1839
1840 Returns the number of items in the hash.
1841
1842 \sa isEmpty(), count()
1843*/
1844
1845/*! \fn template <class Key, class T> bool QHash<Key, T>::isEmpty() const
1846
1847 Returns \c true if the hash contains no items; otherwise returns
1848 false.
1849
1850 \sa size()
1851*/
1852
1853/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::capacity() const
1854
1855 Returns the number of buckets in the QHash's internal hash table.
1856
1857 The sole purpose of this function is to provide a means of fine
1858 tuning QHash's memory usage. In general, you will rarely ever
1859 need to call this function. If you want to know how many items are
1860 in the hash, call size().
1861
1862 \sa reserve(), squeeze()
1863*/
1864
1865/*! \fn template <class Key, class T> float QHash<Key, T>::load_factor() const noexcept
1866
1867 Returns the current load factor of the QHash's internal hash table.
1868 This is the same as capacity()/size(). The implementation used
1869 will aim to keep the load factor between 0.25 and 0.5. This avoids
1870 having too many hash table collisions that would degrade performance.
1871
1872 Even with a low load factor, the implementation of the hash table has a
1873 very low memory overhead.
1874
1875 This method purely exists for diagnostic purposes and you should rarely
1876 need to call it yourself.
1877
1878 \sa reserve(), squeeze()
1879*/
1880
1881
1882/*! \fn template <class Key, class T> void QHash<Key, T>::reserve(qsizetype size)
1883
1884 Ensures that the QHash's internal hash table has space to store at
1885 least \a size items without having to grow the hash table.
1886
1887 This implies that the hash table will contain at least 2 * \a size buckets
1888 to ensure good performance
1889
1890 This function is useful for code that needs to build a huge hash
1891 and wants to avoid repeated reallocation. For example:
1892
1893 \snippet code/src_corelib_tools_qhash.cpp 14
1894
1895 Ideally, \a size should be the maximum number of items expected
1896 in the hash. QHash will then choose the smallest possible
1897 number of buckets that will allow storing \a size items in the table
1898 without having to grow the internal hash table. If \a size
1899 is an underestimate, the worst that will happen is that the QHash
1900 will be a bit slower.
1901
1902 In general, you will rarely ever need to call this function.
1903 QHash's internal hash table automatically grows to
1904 provide good performance without wasting too much memory.
1905
1906 \sa squeeze(), capacity()
1907*/
1908
1909/*! \fn template <class Key, class T> void QHash<Key, T>::squeeze()
1910
1911 Reduces the size of the QHash's internal hash table to save
1912 memory.
1913
1914 The sole purpose of this function is to provide a means of fine
1915 tuning QHash's memory usage. In general, you will rarely ever
1916 need to call this function.
1917
1918 \sa reserve(), capacity()
1919*/
1920
1921/*! \fn template <class Key, class T> void QHash<Key, T>::detach()
1922
1923 \internal
1924
1925 Detaches this hash from any other hashes with which it may share
1926 data.
1927
1928 \sa isDetached()
1929*/
1930
1931/*! \fn template <class Key, class T> bool QHash<Key, T>::isDetached() const
1932
1933 \internal
1934
1935 Returns \c true if the hash's internal data isn't shared with any
1936 other hash object; otherwise returns \c false.
1937
1938 \sa detach()
1939*/
1940
1941/*! \fn template <class Key, class T> bool QHash<Key, T>::isSharedWith(const QHash &other) const
1942
1943 \internal
1944
1945 Returns true if the internal hash table of this QHash is shared with \a other, otherwise false.
1946*/
1947
1948/*! \fn template <class Key, class T> void QHash<Key, T>::clear()
1949
1950 Removes all items from the hash and frees up all memory used by it.
1951
1952 \sa remove()
1953*/
1954
1955/*! \fn template <class Key, class T> bool QHash<Key, T>::remove(const Key &key)
1956
1957 Removes the item that has the \a key from the hash.
1958 Returns true if the key exists in the hash and the item has been removed,
1959 and false otherwise.
1960
1961 \sa clear(), take()
1962*/
1963
1964/*! \fn template <class Key, class T> template <typename Predicate> qsizetype QHash<Key, T>::removeIf(Predicate pred)
1965 \since 6.1
1966
1967 Removes all elements for which the predicate \a pred returns true
1968 from the hash.
1969
1970 The function supports predicates which take either an argument of
1971 type \c{QHash<Key, T>::iterator}, or an argument of type
1972 \c{std::pair<const Key &, T &>}.
1973
1974 Returns the number of elements removed, if any.
1975
1976 \sa clear(), take()
1977*/
1978
1979/*! \fn template <class Key, class T> T QHash<Key, T>::take(const Key &key)
1980
1981 Removes the item with the \a key from the hash and returns
1982 the value associated with it.
1983
1984 If the item does not exist in the hash, the function simply
1985 returns a \l{default-constructed value}.
1986
1987 If you don't use the return value, remove() is more efficient.
1988
1989 \sa remove()
1990*/
1991
1992/*! \fn template <class Key, class T> bool QHash<Key, T>::contains(const Key &key) const
1993
1994 Returns \c true if the hash contains an item with the \a key;
1995 otherwise returns \c false.
1996
1997 \sa count()
1998*/
1999
2000/*! \fn template <class Key, class T> T QHash<Key, T>::value(const Key &key) const
2001 \fn template <class Key, class T> T QHash<Key, T>::value(const Key &key, const T &defaultValue) const
2002 \overload
2003
2004 Returns the value associated with the \a key.
2005
2006 If the hash contains no item with the \a key, the function
2007 returns \a defaultValue, or a \l{default-constructed value} if this
2008 parameter has not been supplied.
2009*/
2010
2011/*! \fn template <class Key, class T> T &QHash<Key, T>::operator[](const Key &key)
2012
2013 Returns the value associated with the \a key as a modifiable
2014 reference.
2015
2016 If the hash contains no item with the \a key, the function inserts
2017 a \l{default-constructed value} into the hash with the \a key, and
2018 returns a reference to it.
2019
2020//! [qhash-iterator-invalidation-func-desc]
2021 \warning Returned iterators/references should be considered invalidated
2022 the next time you call a non-const function on the hash, or when the
2023 hash is destroyed.
2024//! [qhash-iterator-invalidation-func-desc]
2025
2026 \sa insert(), value()
2027*/
2028
2029/*! \fn template <class Key, class T> const T QHash<Key, T>::operator[](const Key &key) const
2030
2031 \overload
2032
2033 Same as value().
2034*/
2035
2036/*! \fn template <class Key, class T> QList<Key> QHash<Key, T>::keys() const
2037
2038 Returns a list containing all the keys in the hash, in an
2039 arbitrary order.
2040
2041 The order is guaranteed to be the same as that used by values().
2042
2043 This function creates a new list, in \l {linear time}. The time and memory
2044 use that entails can be avoided by iterating from \l keyBegin() to
2045 \l keyEnd().
2046
2047 \sa values(), key()
2048*/
2049
2050/*! \fn template <class Key, class T> QList<Key> QHash<Key, T>::keys(const T &value) const
2051
2052 \overload
2053
2054 Returns a list containing all the keys associated with value \a
2055 value, in an arbitrary order.
2056
2057 This function can be slow (\l{linear time}), because QHash's
2058 internal data structure is optimized for fast lookup by key, not
2059 by value.
2060*/
2061
2062/*! \fn template <class Key, class T> QList<T> QHash<Key, T>::values() const
2063
2064 Returns a list containing all the values in the hash, in an
2065 arbitrary order.
2066
2067 The order is guaranteed to be the same as that used by keys().
2068
2069 This function creates a new list, in \l {linear time}. The time and memory
2070 use that entails can be avoided by iterating from \l keyValueBegin() to
2071 \l keyValueEnd().
2072
2073 \sa keys(), value()
2074*/
2075
2076/*!
2077 \fn template <class Key, class T> Key QHash<Key, T>::key(const T &value) const
2078 \fn template <class Key, class T> Key QHash<Key, T>::key(const T &value, const Key &defaultKey) const
2079 \since 4.3
2080
2081 Returns the first key mapped to \a value. If the hash contains no item
2082 mapped to \a value, returns \a defaultKey, or a \l{default-constructed
2083 value}{default-constructed key} if this parameter has not been supplied.
2084
2085 This function can be slow (\l{linear time}), because QHash's
2086 internal data structure is optimized for fast lookup by key, not
2087 by value.
2088*/
2089
2090/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::count(const Key &key) const
2091
2092 Returns the number of items associated with the \a key.
2093
2094 \sa contains()
2095*/
2096
2097/*! \fn template <class Key, class T> qsizetype QHash<Key, T>::count() const
2098
2099 \overload
2100
2101 Same as size().
2102*/
2103
2104/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::begin()
2105
2106 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
2107 the hash.
2108
2109 \include qhash.cpp qhash-iterator-invalidation-func-desc
2110
2111 \sa constBegin(), end()
2112*/
2113
2114/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::begin() const
2115
2116 \overload
2117
2118 \include qhash.cpp qhash-iterator-invalidation-func-desc
2119*/
2120
2121/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::cbegin() const
2122 \since 5.0
2123
2124 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
2125 in the hash.
2126
2127 \include qhash.cpp qhash-iterator-invalidation-func-desc
2128
2129 \sa begin(), cend()
2130*/
2131
2132/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constBegin() const
2133
2134 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
2135 in the hash.
2136
2137 \include qhash.cpp qhash-iterator-invalidation-func-desc
2138
2139 \sa begin(), constEnd()
2140*/
2141
2142/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::keyBegin() const
2143 \since 5.6
2144
2145 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
2146 in the hash.
2147
2148 \include qhash.cpp qhash-iterator-invalidation-func-desc
2149
2150 \sa keyEnd()
2151*/
2152
2153/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::end()
2154
2155 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
2156 after the last item in the hash.
2157
2158 \include qhash.cpp qhash-iterator-invalidation-func-desc
2159
2160 \sa begin(), constEnd()
2161*/
2162
2163/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::end() const
2164
2165 \overload
2166
2167 \include qhash.cpp qhash-iterator-invalidation-func-desc
2168*/
2169
2170/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constEnd() const
2171
2172 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2173 item after the last item in the hash.
2174
2175 \include qhash.cpp qhash-iterator-invalidation-func-desc
2176
2177 \sa constBegin(), end()
2178*/
2179
2180/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::cend() const
2181 \since 5.0
2182
2183 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2184 item after the last item in the hash.
2185
2186 \include qhash.cpp qhash-iterator-invalidation-func-desc
2187
2188 \sa cbegin(), end()
2189*/
2190
2191/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::keyEnd() const
2192 \since 5.6
2193
2194 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2195 item after the last key in the hash.
2196
2197 \include qhash.cpp qhash-iterator-invalidation-func-desc
2198
2199 \sa keyBegin()
2200*/
2201
2202/*! \fn template <class Key, class T> QHash<Key, T>::key_value_iterator QHash<Key, T>::keyValueBegin()
2203 \since 5.10
2204
2205 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2206 in the hash.
2207
2208 \include qhash.cpp qhash-iterator-invalidation-func-desc
2209
2210 \sa keyValueEnd()
2211*/
2212
2213/*! \fn template <class Key, class T> QHash<Key, T>::key_value_iterator QHash<Key, T>::keyValueEnd()
2214 \since 5.10
2215
2216 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2217 entry after the last entry in the hash.
2218
2219 \include qhash.cpp qhash-iterator-invalidation-func-desc
2220
2221 \sa keyValueBegin()
2222*/
2223
2224/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::keyValueBegin() const
2225 \since 5.10
2226
2227 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2228 in the hash.
2229
2230 \include qhash.cpp qhash-iterator-invalidation-func-desc
2231
2232 \sa keyValueEnd()
2233*/
2234
2235/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::constKeyValueBegin() const
2236 \since 5.10
2237
2238 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
2239 in the hash.
2240
2241 \include qhash.cpp qhash-iterator-invalidation-func-desc
2242
2243 \sa keyValueBegin()
2244*/
2245
2246/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::keyValueEnd() const
2247 \since 5.10
2248
2249 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2250 entry after the last entry in the hash.
2251
2252 \include qhash.cpp qhash-iterator-invalidation-func-desc
2253
2254 \sa keyValueBegin()
2255*/
2256
2257/*! \fn template <class Key, class T> QHash<Key, T>::const_key_value_iterator QHash<Key, T>::constKeyValueEnd() const
2258 \since 5.10
2259
2260 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
2261 entry after the last entry in the hash.
2262
2263 \include qhash.cpp qhash-iterator-invalidation-func-desc
2264
2265 \sa constKeyValueBegin()
2266*/
2267
2268/*! \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() &
2269 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const &
2270 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() &&
2271 \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const &&
2272 \since 6.4
2273
2274 Returns a range object that allows iteration over this hash as
2275 key/value pairs. For instance, this range object can be used in a
2276 range-based for loop, in combination with a structured binding declaration:
2277
2278 \snippet code/src_corelib_tools_qhash.cpp 34
2279
2280 Note that both the key and the value obtained this way are
2281 references to the ones in the hash. Specifically, mutating the value
2282 will modify the hash itself.
2283
2284 \include qhash.cpp qhash-iterator-invalidation-func-desc
2285
2286 \sa QKeyValueIterator
2287*/
2288
2289/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::erase(const_iterator pos)
2290 \since 5.7
2291
2292 Removes the (key, value) pair associated with the iterator \a pos
2293 from the hash, and returns an iterator to the next item in the
2294 hash.
2295
2296 This function never causes QHash to
2297 rehash its internal data structure. This means that it can safely
2298 be called while iterating, and won't affect the order of items in
2299 the hash. For example:
2300
2301 \snippet code/src_corelib_tools_qhash.cpp 15
2302
2303 \include qhash.cpp qhash-iterator-invalidation-func-desc
2304
2305 \sa remove(), take(), find()
2306*/
2307
2308/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::find(const Key &key)
2309
2310 Returns an iterator pointing to the item with the \a key in the
2311 hash.
2312
2313 If the hash contains no item with the \a key, the function
2314 returns end().
2315
2316 If the hash contains multiple items with the \a key, this
2317 function returns an iterator that points to the most recently
2318 inserted value. The other values are accessible by incrementing
2319 the iterator. For example, here's some code that iterates over all
2320 the items with the same key:
2321
2322 \snippet code/src_corelib_tools_qhash.cpp 16
2323
2324 \include qhash.cpp qhash-iterator-invalidation-func-desc
2325
2326 \sa value(), values()
2327*/
2328
2329/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::find(const Key &key) const
2330
2331 \overload
2332
2333 \include qhash.cpp qhash-iterator-invalidation-func-desc
2334*/
2335
2336/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::constFind(const Key &key) const
2337 \since 4.1
2338
2339 Returns an iterator pointing to the item with the \a key in the
2340 hash.
2341
2342 If the hash contains no item with the \a key, the function
2343 returns constEnd().
2344
2345 \include qhash.cpp qhash-iterator-invalidation-func-desc
2346
2347 \sa find()
2348*/
2349
2350/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &key, const T &value)
2351
2352 Inserts a new item with the \a key and a value of \a value.
2353
2354 If there is already an item with the \a key, that item's value
2355 is replaced with \a value.
2356
2357 Inserting a key/value pair with an existing key replaces
2358 the existing value.
2359
2360 Returns an iterator pointing to the new/updated element.
2361
2362 \include qhash.cpp qhash-iterator-invalidation-func-desc
2363*/
2364
2365/*!
2366 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &key, T &&value)
2367 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(Key &&key, const T &value)
2368 \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insert(Key &&key, T &&value)
2369 \since 6.11
2370 \overload
2371*/
2372
2373/*!
2374 \fn template <class Key, class T> template <typename ...Args> QHash<Key, T>::iterator QHash<Key, T>::emplace(const Key &key, Args&&... args)
2375 \fn template <class Key, class T> template <typename ...Args> QHash<Key, T>::iterator QHash<Key, T>::emplace(Key &&key, Args&&... args)
2376
2377 Inserts a new element into the container. This new element
2378 is constructed in-place using \a args as the arguments for its
2379 construction. If the element already exists in the container, it
2380 is replaced.
2381
2382 Returns an iterator pointing to the new element.
2383
2384 \include qhash.cpp qhash-iterator-invalidation-func-desc
2385*/
2386
2387/*!
2388 \class QHash::TryEmplaceResult
2389 \inmodule QtCore
2390 \since 6.9
2391 \ingroup tools
2392 \brief The TryEmplaceResult class is used to represent the result of a tryEmplace() operation.
2393
2394 The \c{TryEmplaceResult} class is used in QHash to represent the result
2395 of a tryEmplace() operation. It holds an \l{iterator} to the newly
2396 created item, or to the pre-existing item that prevented the insertion, and
2397 a boolean, \l{inserted}, denoting whether the insertion took place.
2398
2399 \sa QHash, QHash::tryEmplace()
2400*/
2401
2402/*!
2403 \variable QHash::TryEmplaceResult::iterator
2404
2405 Holds the iterator to the newly inserted element, or the element that
2406 prevented the insertion.
2407*/
2408
2409/*!
2410 \variable QHash::TryEmplaceResult::inserted
2411
2412 This value is \c{false} if there was already an entry with the same key.
2413*/
2414
2415/*!
2416 \fn template <class Key, class T> template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryEmplace(const Key &key, Args &&...args)
2417 \fn template <class Key, class T> template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryEmplace(Key &&key, Args &&...args)
2418 \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)
2419 \since 6.9
2420
2421 Inserts a new item with the \a key and a value constructed from \a args.
2422 If an item with \a key already exists, no insertion takes place.
2423
2424 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2425 \l{QHash::TryEmplaceResult::}{iterator} to the newly created item, or
2426 to the pre-existing item that prevented the insertion, and a boolean,
2427 \l{QHash::TryEmplaceResult::}{inserted}, denoting whether the insertion
2428 took place.
2429
2430 For example, this can be used to avoid the pattern of comparing old and
2431 new size or double-lookups. Where you might previously have written code like:
2432
2433 \code
2434 QHash<int, MyType> hash;
2435 // [...]
2436 int myKey = getKey();
2437 qsizetype oldSize = hash.size();
2438 MyType &elem = hash[myKey];
2439 if (oldSize != hash.size()) // Size changed: new element!
2440 initialize(elem);
2441 // [use elem...]
2442 \endcode
2443
2444 You can instead write:
2445
2446 \code
2447 QHash<int, MyType> hash;
2448 // [...]
2449 int myKey = getKey();
2450 auto result = hash.tryEmplace(myKey);
2451 if (result.inserted) // New element!
2452 initialize(*result.iterator);
2453 // [use result.iterator...]
2454 \endcode
2455
2456 \sa emplace(), tryInsert(), insertOrAssign()
2457*/
2458
2459/*!
2460 \fn template <class Key, class T> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::tryInsert(const Key &key, const T &value)
2461 \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)
2462 \since 6.9
2463
2464 Inserts a new item with the \a key and a value of \a value.
2465 If an item with \a key already exists, no insertion takes place.
2466
2467 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2468 \l{QHash::TryEmplaceResult::}{iterator} to the newly created item, or to the pre-existing item
2469 that prevented the insertion, and a boolean, \l{QHash::TryEmplaceResult::}{inserted}, denoting
2470 whether the insertion took place.
2471
2472 \sa insert(), tryEmplace(), insertOrAssign()
2473*/
2474
2475/*!
2476 \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)
2477 \fn template <class Key, class T> template <typename... Args> iterator QHash<Key, T>::try_emplace(const_iterator hint, const Key &key, Args &&...args)
2478 \fn template <class Key, class T> template <typename... Args> iterator QHash<Key, T>::try_emplace(const_iterator hint, Key &&key, Args &&...args)
2479 \since 6.9
2480
2481 Inserts a new item with the \a key and a value constructed from \a args.
2482 If an item with \a key already exists, no insertion takes place.
2483
2484 Returns the iterator of the inserted item, or to the item that prevented the
2485 insertion.
2486
2487 \a hint is ignored.
2488
2489 These functions are provided for compatibility with the standard library.
2490
2491 \sa emplace(), tryEmplace(), tryInsert(), insertOrAssign()
2492*/
2493
2494/*!
2495 \fn template <class Key, class T> template <typename... Args> std::pair<iterator, bool> QHash<Key, T>::try_emplace(const Key &key, Args &&...args)
2496 \fn template <class Key, class T> template <typename... Args> std::pair<iterator, bool> QHash<Key, T>::try_emplace(Key &&key, Args &&...args)
2497 \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)
2498 \since 6.9
2499
2500 Inserts a new item with the \a key and a value constructed from \a args.
2501 If an item with \a key already exists, no insertion takes place.
2502
2503 Returns a pair consisting of an iterator to the inserted item (or to the
2504 item that prevented the insertion), and a bool denoting whether the
2505 insertion took place.
2506
2507 These functions are provided for compatibility with the standard library.
2508
2509 \sa emplace(), tryEmplace(), tryInsert(), insertOrAssign()
2510*/
2511
2512/*!
2513 \fn template <class Key, class T> template <typename Value> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::insertOrAssign(const Key &key, Value &&value)
2514 \fn template <class Key, class T> template <typename Value> QHash<Key, T>::TryEmplaceResult QHash<Key, T>::insertOrAssign(Key &&key, Value &&value)
2515 \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)
2516 \since 6.9
2517
2518 Attempts to insert an item with the \a key and \a value.
2519 If an item with \a key already exists its value is overwritten with \a value.
2520
2521 Returns an instance of \l{TryEmplaceResult}, a structure that holds an
2522 \l{QHash::TryEmplaceResult::}{iterator} to the item, and a boolean,
2523 \l{QHash::TryEmplaceResult::}{inserted}, denoting whether the item was newly created (\c{true})
2524 or if it previously existed (\c{false}).
2525
2526 \sa insert(), tryEmplace(), tryInsert()
2527*/
2528
2529/*!
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(const Key &key, Value &&value)
2531 \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)
2532 \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)
2533 \since 6.9
2534
2535 Attempts to insert an item with the \a key and \a value.
2536 If an item with \a key already exists its value is overwritten with \a value.
2537
2538 Returns a pair consisting of an iterator pointing to the item, and a
2539 boolean, denoting whether the item was newly created (\c{true}) or if it
2540 previously existed (\c{false}).
2541
2542 These functions are provided for compatibility with the standard library.
2543
2544 \sa insert(), tryEmplace(), tryInsert(), insertOrAssign()
2545*/
2546
2547/*!
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, const Key &key, Value &&value)
2549 \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)
2550 \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)
2551 \since 6.9
2552
2553 Attempts to insert an item with the \a key and \a value.
2554 If an item with \a key already exists its value is overwritten with \a value.
2555
2556 Returns a pair consisting of an iterator pointing to the item, and a
2557 boolean, denoting whether the item was newly created (\c{true}) or if it
2558 previously existed (\c{false}).
2559
2560 \a hint is ignored.
2561
2562 These functions are provided for compatibility with the standard library.
2563
2564 \sa insert(), tryEmplace(), insertOrAssign()
2565*/
2566
2567/*! \fn template <class Key, class T> void QHash<Key, T>::insert(const QHash &other)
2568 \since 5.15
2569
2570 Inserts all the items in the \a other hash into this hash.
2571
2572 If a key is common to both hashes, its value will be replaced with the
2573 value stored in \a other.
2574*/
2575
2576/*! \fn template <class Key, class T> bool QHash<Key, T>::empty() const
2577
2578 This function is provided for STL compatibility. It is equivalent
2579 to isEmpty(), returning true if the hash is empty; otherwise
2580 returns \c false.
2581*/
2582
2583/*! \fn template <class Key, class T> std::pair<iterator, iterator> QMultiHash<Key, T>::equal_range(const Key &key)
2584 \since 5.7
2585
2586 Returns a pair of iterators delimiting the range of values \c{[first, second)}, that
2587 are stored under \a key. If the range is empty then both iterators will be equal to end().
2588
2589 \include qhash.cpp qhash-iterator-invalidation-func-desc
2590*/
2591
2592/*!
2593 \fn template <class Key, class T> std::pair<const_iterator, const_iterator> QMultiHash<Key, T>::equal_range(const Key &key) const
2594 \overload
2595 \since 5.7
2596
2597 \include qhash.cpp qhash-iterator-invalidation-func-desc
2598*/
2599
2600/*! \typedef QHash::ConstIterator
2601
2602 Qt-style synonym for QHash::const_iterator.
2603*/
2604
2605/*! \typedef QHash::Iterator
2606
2607 Qt-style synonym for QHash::iterator.
2608*/
2609
2610/*! \typedef QHash::difference_type
2611
2612 Typedef for ptrdiff_t. Provided for STL compatibility.
2613*/
2614
2615/*! \typedef QHash::key_type
2616
2617 Typedef for Key. Provided for STL compatibility.
2618*/
2619
2620/*! \typedef QHash::mapped_type
2621
2622 Typedef for T. Provided for STL compatibility.
2623*/
2624
2625/*! \typedef QHash::size_type
2626
2627 Typedef for int. Provided for STL compatibility.
2628*/
2629
2630/*! \typedef QHash::iterator::difference_type
2631 \internal
2632*/
2633
2634/*! \typedef QHash::iterator::iterator_category
2635 \internal
2636*/
2637
2638/*! \typedef QHash::iterator::pointer
2639 \internal
2640*/
2641
2642/*! \typedef QHash::iterator::reference
2643 \internal
2644*/
2645
2646/*! \typedef QHash::iterator::value_type
2647 \internal
2648*/
2649
2650/*! \typedef QHash::const_iterator::difference_type
2651 \internal
2652*/
2653
2654/*! \typedef QHash::const_iterator::iterator_category
2655 \internal
2656*/
2657
2658/*! \typedef QHash::const_iterator::pointer
2659 \internal
2660*/
2661
2662/*! \typedef QHash::const_iterator::reference
2663 \internal
2664*/
2665
2666/*! \typedef QHash::const_iterator::value_type
2667 \internal
2668*/
2669
2670/*! \typedef QHash::key_iterator::difference_type
2671 \internal
2672*/
2673
2674/*! \typedef QHash::key_iterator::iterator_category
2675 \internal
2676*/
2677
2678/*! \typedef QHash::key_iterator::pointer
2679 \internal
2680*/
2681
2682/*! \typedef QHash::key_iterator::reference
2683 \internal
2684*/
2685
2686/*! \typedef QHash::key_iterator::value_type
2687 \internal
2688*/
2689
2690/*! \class QHash::iterator
2691 \inmodule QtCore
2692 \brief The QHash::iterator class provides an STL-style non-const iterator for QHash.
2693
2694 QHash<Key, T>::iterator allows you to iterate over a QHash
2695 and to modify the value (but not the key) associated
2696 with a particular key. If you want to iterate over a const QHash,
2697 you should use QHash::const_iterator. It is generally good
2698 practice to use QHash::const_iterator on a non-const QHash as
2699 well, unless you need to change the QHash through the iterator.
2700 Const iterators are slightly faster, and can improve code
2701 readability.
2702
2703 The default QHash::iterator constructor creates an uninitialized
2704 iterator. You must initialize it using a QHash function like
2705 QHash::begin(), QHash::end(), or QHash::find() before you can
2706 start iterating. Here's a typical loop that prints all the (key,
2707 value) pairs stored in a hash:
2708
2709 \snippet code/src_corelib_tools_qhash.cpp 17
2710
2711 Unlike QMap, which orders its items by key, QHash stores its
2712 items in an arbitrary order.
2713
2714 Here's an example that increments every value stored in the QHash
2715 by 2:
2716
2717 \snippet code/src_corelib_tools_qhash.cpp 18
2718
2719 To remove elements from a QHash you can use erase_if(QHash<Key, T> &map, Predicate pred):
2720
2721 \snippet code/src_corelib_tools_qhash.cpp 21
2722
2723 Multiple iterators can be used on the same hash. However, be aware
2724 that any modification performed directly on the QHash (inserting and
2725 removing items) can cause the iterators to become invalid.
2726
2727 Inserting items into the hash or calling methods such as QHash::reserve()
2728 or QHash::squeeze() can invalidate all iterators pointing into the hash.
2729 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
2730 to grow/shrink its internal hash table.
2731 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
2732
2733 If you need to keep iterators over a long period of time, we recommend
2734 that you use QMap rather than QHash.
2735
2736 \warning Iterators on implicitly shared containers do not work
2737 exactly like STL-iterators. You should avoid copying a container
2738 while iterators are active on that container. For more information,
2739 read \l{Implicit sharing iterator problem}.
2740
2741 \sa QHash::const_iterator, QHash::key_iterator, QHash::key_value_iterator
2742*/
2743
2744/*! \fn template <class Key, class T> QHash<Key, T>::iterator::iterator()
2745
2746 Constructs an uninitialized iterator.
2747
2748 Functions like key(), value(), and operator++() must not be
2749 called on an uninitialized iterator. Use operator=() to assign a
2750 value to it before using it.
2751
2752 \sa QHash::begin(), QHash::end()
2753*/
2754
2755/*! \fn template <class Key, class T> const Key &QHash<Key, T>::iterator::key() const
2756
2757 Returns the current item's key as a const reference.
2758
2759 There is no direct way of changing an item's key through an
2760 iterator, although it can be done by calling QHash::erase()
2761 followed by QHash::insert().
2762
2763 \sa value()
2764*/
2765
2766/*! \fn template <class Key, class T> T &QHash<Key, T>::iterator::value() const
2767
2768 Returns a modifiable reference to the current item's value.
2769
2770 You can change the value of an item by using value() on
2771 the left side of an assignment, for example:
2772
2773 \snippet code/src_corelib_tools_qhash.cpp 22
2774
2775 \sa key(), operator*()
2776*/
2777
2778/*! \fn template <class Key, class T> T &QHash<Key, T>::iterator::operator*() const
2779
2780 Returns a modifiable reference to the current item's value.
2781
2782 Same as value().
2783
2784 \sa key()
2785*/
2786
2787/*! \fn template <class Key, class T> T *QHash<Key, T>::iterator::operator->() const
2788
2789 Returns a pointer to the current item's value.
2790
2791 \sa value()
2792*/
2793
2794/*!
2795 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator==(const iterator &other) const
2796 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator==(const const_iterator &other) const
2797
2798 Returns \c true if \a other points to the same item as this
2799 iterator; otherwise returns \c false.
2800
2801 \sa operator!=()
2802*/
2803
2804/*!
2805 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator!=(const iterator &other) const
2806 \fn template <class Key, class T> bool QHash<Key, T>::iterator::operator!=(const const_iterator &other) const
2807
2808 Returns \c true if \a other points to a different item than this
2809 iterator; otherwise returns \c false.
2810
2811 \sa operator==()
2812*/
2813
2814/*!
2815 \fn template <class Key, class T> QHash<Key, T>::iterator &QHash<Key, T>::iterator::operator++()
2816
2817 The prefix ++ operator (\c{++i}) advances the iterator to the
2818 next item in the hash and returns an iterator to the new current
2819 item.
2820
2821 Calling this function on QHash::end() leads to undefined results.
2822*/
2823
2824/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::iterator::operator++(int)
2825
2826 \overload
2827
2828 The postfix ++ operator (\c{i++}) advances the iterator to the
2829 next item in the hash and returns an iterator to the previously
2830 current item.
2831*/
2832
2833/*! \class QHash::const_iterator
2834 \inmodule QtCore
2835 \brief The QHash::const_iterator class provides an STL-style const iterator for QHash.
2836
2837 QHash<Key, T>::const_iterator allows you to iterate over a
2838 QHash. If you want to modify the QHash as you
2839 iterate over it, you must use QHash::iterator instead. It is
2840 generally good practice to use QHash::const_iterator on a
2841 non-const QHash as well, unless you need to change the QHash
2842 through the iterator. Const iterators are slightly faster, and
2843 can improve code readability.
2844
2845 The default QHash::const_iterator constructor creates an
2846 uninitialized iterator. You must initialize it using a QHash
2847 function like QHash::cbegin(), QHash::cend(), or
2848 QHash::constFind() before you can start iterating. Here's a typical
2849 loop that prints all the (key, value) pairs stored in a hash:
2850
2851 \snippet code/src_corelib_tools_qhash.cpp 23
2852
2853 Unlike QMap, which orders its items by key, QHash stores its
2854 items in an arbitrary order. The only guarantee is that items that
2855 share the same key (because they were inserted using
2856 a QMultiHash) will appear consecutively, from the most
2857 recently to the least recently inserted value.
2858
2859 Multiple iterators can be used on the same hash. However, be aware
2860 that any modification performed directly on the QHash (inserting and
2861 removing items) can cause the iterators to become invalid.
2862
2863 Inserting items into the hash or calling methods such as QHash::reserve()
2864 or QHash::squeeze() can invalidate all iterators pointing into the hash.
2865 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
2866 to grow/shrink its internal hash table.
2867 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
2868
2869 You can however safely use iterators to remove entries from the hash
2870 using the QHash::erase() method. This function can safely be called while
2871 iterating, and won't affect the order of items in the hash.
2872
2873 \warning Iterators on implicitly shared containers do not work
2874 exactly like STL-iterators. You should avoid copying a container
2875 while iterators are active on that container. For more information,
2876 read \l{Implicit sharing iterator problem}.
2877
2878 \sa QHash::iterator, QHash::key_iterator, QHash::const_key_value_iterator
2879*/
2880
2881/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator::const_iterator()
2882
2883 Constructs an uninitialized iterator.
2884
2885 Functions like key(), value(), and operator++() must not be
2886 called on an uninitialized iterator. Use operator=() to assign a
2887 value to it before using it.
2888
2889 \sa QHash::constBegin(), QHash::constEnd()
2890*/
2891
2892/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator::const_iterator(const iterator &other)
2893
2894 Constructs a copy of \a other.
2895*/
2896
2897/*! \fn template <class Key, class T> const Key &QHash<Key, T>::const_iterator::key() const
2898
2899 Returns the current item's key.
2900
2901 \sa value()
2902*/
2903
2904/*! \fn template <class Key, class T> const T &QHash<Key, T>::const_iterator::value() const
2905
2906 Returns the current item's value.
2907
2908 \sa key(), operator*()
2909*/
2910
2911/*! \fn template <class Key, class T> const T &QHash<Key, T>::const_iterator::operator*() const
2912
2913 Returns the current item's value.
2914
2915 Same as value().
2916
2917 \sa key()
2918*/
2919
2920/*! \fn template <class Key, class T> const T *QHash<Key, T>::const_iterator::operator->() const
2921
2922 Returns a pointer to the current item's value.
2923
2924 \sa value()
2925*/
2926
2927/*! \fn template <class Key, class T> bool QHash<Key, T>::const_iterator::operator==(const const_iterator &other) const
2928
2929 Returns \c true if \a other points to the same item as this
2930 iterator; otherwise returns \c false.
2931
2932 \sa operator!=()
2933*/
2934
2935/*! \fn template <class Key, class T> bool QHash<Key, T>::const_iterator::operator!=(const const_iterator &other) const
2936
2937 Returns \c true if \a other points to a different item than this
2938 iterator; otherwise returns \c false.
2939
2940 \sa operator==()
2941*/
2942
2943/*!
2944 \fn template <class Key, class T> QHash<Key, T>::const_iterator &QHash<Key, T>::const_iterator::operator++()
2945
2946 The prefix ++ operator (\c{++i}) advances the iterator to the
2947 next item in the hash and returns an iterator to the new current
2948 item.
2949
2950 Calling this function on QHash::end() leads to undefined results.
2951*/
2952
2953/*! \fn template <class Key, class T> QHash<Key, T>::const_iterator QHash<Key, T>::const_iterator::operator++(int)
2954
2955 \overload
2956
2957 The postfix ++ operator (\c{i++}) advances the iterator to the
2958 next item in the hash and returns an iterator to the previously
2959 current item.
2960*/
2961
2962/*! \class QHash::key_iterator
2963 \inmodule QtCore
2964 \since 5.6
2965 \brief The QHash::key_iterator class provides an STL-style const iterator for QHash keys.
2966
2967 QHash::key_iterator is essentially the same as QHash::const_iterator
2968 with the difference that operator*() and operator->() return a key
2969 instead of a value.
2970
2971 For most uses QHash::iterator and QHash::const_iterator should be used,
2972 you can easily access the key by calling QHash::iterator::key():
2973
2974 \snippet code/src_corelib_tools_qhash.cpp 27
2975
2976 However, to have interoperability between QHash's keys and STL-style
2977 algorithms we need an iterator that dereferences to a key instead
2978 of a value. With QHash::key_iterator we can apply an algorithm to a
2979 range of keys without having to call QHash::keys(), which is inefficient
2980 as it costs one QHash iteration and memory allocation to create a temporary
2981 QList.
2982
2983 \snippet code/src_corelib_tools_qhash.cpp 28
2984
2985 QHash::key_iterator is const, it's not possible to modify the key.
2986
2987 The default QHash::key_iterator constructor creates an uninitialized
2988 iterator. You must initialize it using a QHash function like
2989 QHash::keyBegin() or QHash::keyEnd().
2990
2991 \warning Iterators on implicitly shared containers do not work
2992 exactly like STL-iterators. You should avoid copying a container
2993 while iterators are active on that container. For more information,
2994 read \l{Implicit sharing iterator problem}.
2995
2996 \sa QHash::const_iterator, QHash::iterator
2997*/
2998
2999/*! \fn template <class Key, class T> const T &QHash<Key, T>::key_iterator::operator*() const
3000
3001 Returns the current item's key.
3002*/
3003
3004/*! \fn template <class Key, class T> const T *QHash<Key, T>::key_iterator::operator->() const
3005
3006 Returns a pointer to the current item's key.
3007*/
3008
3009/*! \fn template <class Key, class T> bool QHash<Key, T>::key_iterator::operator==(key_iterator other) const
3010
3011 Returns \c true if \a other points to the same item as this
3012 iterator; otherwise returns \c false.
3013
3014 \sa operator!=()
3015*/
3016
3017/*! \fn template <class Key, class T> bool QHash<Key, T>::key_iterator::operator!=(key_iterator other) const
3018
3019 Returns \c true if \a other points to a different item than this
3020 iterator; otherwise returns \c false.
3021
3022 \sa operator==()
3023*/
3024
3025/*!
3026 \fn template <class Key, class T> QHash<Key, T>::key_iterator &QHash<Key, T>::key_iterator::operator++()
3027
3028 The prefix ++ operator (\c{++i}) advances the iterator to the
3029 next item in the hash and returns an iterator to the new current
3030 item.
3031
3032 Calling this function on QHash::keyEnd() leads to undefined results.
3033
3034*/
3035
3036/*! \fn template <class Key, class T> QHash<Key, T>::key_iterator QHash<Key, T>::key_iterator::operator++(int)
3037
3038 \overload
3039
3040 The postfix ++ operator (\c{i++}) advances the iterator to the
3041 next item in the hash and returns an iterator to the previous
3042 item.
3043*/
3044
3045/*! \fn template <class Key, class T> const_iterator QHash<Key, T>::key_iterator::base() const
3046 Returns the underlying const_iterator this key_iterator is based on.
3047*/
3048
3049/*! \typedef QHash::const_key_value_iterator
3050 \inmodule QtCore
3051 \since 5.10
3052 \brief The QHash::const_key_value_iterator typedef provides an STL-style const iterator for QHash.
3053
3054 QHash::const_key_value_iterator is essentially the same as QHash::const_iterator
3055 with the difference that operator*() returns a key/value pair instead of a
3056 value.
3057
3058 \sa QKeyValueIterator
3059*/
3060
3061/*! \typedef QHash::key_value_iterator
3062 \inmodule QtCore
3063 \since 5.10
3064 \brief The QHash::key_value_iterator typedef provides an STL-style iterator for QHash.
3065
3066 QHash::key_value_iterator is essentially the same as QHash::iterator
3067 with the difference that operator*() returns a key/value pair instead of a
3068 value.
3069
3070 \sa QKeyValueIterator
3071*/
3072
3073/*! \fn template <class Key, class T> QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash)
3074 \relates QHash
3075
3076 Writes the hash \a hash to stream \a out.
3077
3078 This function requires the key and value types to implement \c
3079 operator<<().
3080
3081 \sa {Serializing Qt Data Types}
3082*/
3083
3084/*! \fn template <class Key, class T> QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)
3085 \relates QHash
3086
3087 Reads a hash from stream \a in into \a hash.
3088
3089 This function requires the key and value types to implement \c
3090 operator>>().
3091
3092 \sa {Serializing Qt Data Types}
3093*/
3094
3095/*! \class QMultiHash
3096 \inmodule QtCore
3097 \brief The QMultiHash class provides a multi-valued hash table.
3098 \compares equality
3099
3100 \ingroup tools
3101 \ingroup shared
3102 \ingroup containers
3103
3104 \reentrant
3105
3106 QMultiHash<Key, T> is one of Qt's generic \l{container classes}, where
3107 \a Key is the type used for lookup keys and \a T is the mapped value type.
3108 It provides a hash table that allows multiple values for the same key.
3109
3110 QMultiHash mostly mirrors QHash's API. For example, you can use isEmpty() to test
3111 whether the hash is empty, and you can traverse a QMultiHash using
3112 QHash's iterator classes (for example, QHashIterator). But opposed to
3113 QHash, it provides an insert() function that allows the insertion of
3114 multiple items with the same key. The replace() function corresponds to
3115 QHash::insert(). It also provides convenient operator+() and
3116 operator+=().
3117
3118 Unlike QMultiMap, QMultiHash does not provide ordering of the
3119 inserted items. The only guarantee is that items that
3120 share the same key will appear consecutively, from the most
3121 recently to the least recently inserted value.
3122
3123 Example:
3124 \snippet code/src_corelib_tools_qhash.cpp 24
3125
3126 Unlike QHash, QMultiHash provides no operator[]. Use value() or
3127 replace() if you want to access the most recently inserted item
3128 with a certain key.
3129
3130 If you want to retrieve all the values for a single key, you can
3131 use values(const Key &key), which returns a QList<T>:
3132
3133 \snippet code/src_corelib_tools_qhash.cpp 25
3134
3135 The items that share the same key are available from most
3136 recently to least recently inserted.
3137
3138 A more efficient approach is to call find() to get
3139 the STL-style iterator for the first item with a key and iterate from
3140 there:
3141
3142 \snippet code/src_corelib_tools_qhash.cpp 26
3143
3144 QMultiHash's key and value data types must be \l{assignable data
3145 types}. You cannot, for example, store a QWidget as a value;
3146 instead, store a QWidget *. In addition, QMultiHash's key type
3147 must provide operator==(), and there must also be a qHash() function
3148 in the type's namespace that returns a hash value for an argument of the
3149 key's type. See the QHash documentation for details.
3150
3151 \sa QHash, QHashIterator, QMutableHashIterator, QMultiMap
3152*/
3153
3154/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash()
3155
3156 Constructs an empty hash.
3157*/
3158
3159/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash(std::initializer_list<std::pair<Key,T> > list)
3160 \since 5.1
3161
3162 Constructs a multi-hash with a copy of each of the elements in the
3163 initializer list \a list.
3164*/
3165
3166/*! \fn template <class Key, class T> QMultiHash<Key, T>::QMultiHash(const QHash<Key, T> &other)
3167
3168 Constructs a copy of \a other (which can be a QHash or a
3169 QMultiHash).
3170*/
3171
3172/*! \fn template <class Key, class T> template <class InputIterator> QMultiHash<Key, T>::QMultiHash(InputIterator begin, InputIterator end)
3173 \since 5.14
3174
3175 Constructs a multi-hash with a copy of each of the elements in the iterator range
3176 [\a begin, \a end). Either the elements iterated by the range must be
3177 objects with \c{first} and \c{second} data members (like \c{std::pair}),
3178 convertible to \c Key and to \c T respectively; or the
3179 iterators must have \c{key()} and \c{value()} member functions, returning a
3180 key convertible to \c Key and a value convertible to \c T respectively.
3181*/
3182
3183/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::replace(const Key &key, const T &value)
3184
3185 Inserts a new item with the \a key and a value of \a value.
3186
3187 If there is already an item with the \a key, that item's value
3188 is replaced with \a value.
3189
3190 If there are multiple items with the \a key, the most
3191 recently inserted item's value is replaced with \a value.
3192
3193 Returns an iterator pointing to the new/updated element.
3194
3195 \include qhash.cpp qhash-iterator-invalidation-func-desc
3196
3197 \sa insert()
3198*/
3199
3200/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(const Key &key, const T &value)
3201
3202 Inserts a new item with the \a key and a value of \a value.
3203
3204 If there is already an item with the same key in the hash, this
3205 function will simply create a new one. (This behavior is
3206 different from replace(), which overwrites the value of an
3207 existing item.)
3208
3209 QMultiHash allows duplicate keys. Inserting a key that
3210 already exists adds another entry instead of overwriting
3211 it. The order of items in QMultHash is not guaranteed.
3212
3213 Returns an iterator pointing to the new element.
3214
3215 \include qhash.cpp qhash-iterator-invalidation-func-desc
3216
3217 \sa replace()
3218*/
3219
3220/*!
3221 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(const Key &key, T &&value)
3222 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(Key &&key, const T &value)
3223 \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::insert(Key &&key, T &&value)
3224 \since 6.11
3225 \overload
3226*/
3227
3228/*!
3229 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplace(const Key &key, Args&&... args)
3230 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplace(Key &&key, Args&&... args)
3231
3232 Inserts a new element into the container. This new element
3233 is constructed in-place using \a args as the arguments for its
3234 construction.
3235
3236 If there is already an item with the same key in the hash, this
3237 function will simply create a new one. (This behavior is
3238 different from replace(), which overwrites the value of an
3239 existing item.)
3240
3241 Returns an iterator pointing to the new element.
3242
3243 \include qhash.cpp qhash-iterator-invalidation-func-desc
3244
3245 \sa insert
3246*/
3247
3248/*!
3249 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplaceReplace(const Key &key, Args&&... args)
3250 \fn template <class Key, class T> template <typename ...Args> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::emplaceReplace(Key &&key, Args&&... args)
3251
3252 Inserts a new element into the container. This new element
3253 is constructed in-place using \a args as the arguments for its
3254 construction.
3255
3256 If there is already an item with the same key in the hash, that item's
3257 value is replaced with a value constructed from \a args.
3258
3259 Returns an iterator pointing to the new element.
3260
3261 \include qhash.cpp qhash-iterator-invalidation-func-desc
3262
3263 \sa replace, emplace
3264*/
3265
3266/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::erase(const_iterator pos)
3267 \since 5.7
3268
3269 Removes the (key, value) pair associated with the iterator \a pos
3270 from the hash, and returns an iterator to the next item in the
3271 hash.
3272
3273 This function never causes QMultiHash to
3274 rehash its internal data structure. This means that it can safely
3275 be called while iterating, and won't affect the order of items in
3276 the hash. For example:
3277
3278 \snippet code/src_corelib_tools_qhash.cpp 15multihash
3279
3280 \include qhash.cpp qhash-iterator-invalidation-func-desc
3281
3282 \sa remove(), take(), find()
3283*/
3284
3285/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::unite(const QMultiHash &other)
3286 \since 5.13
3287
3288 Inserts all the items in the \a other hash into this hash
3289 and returns a reference to this hash.
3290
3291 \sa insert()
3292*/
3293
3294
3295/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::unite(const QHash<Key, T> &other)
3296 \since 6.0
3297
3298 Inserts all the items in the \a other hash into this hash
3299 and returns a reference to this hash.
3300
3301 \sa insert()
3302*/
3303
3304/*! \fn template <class Key, class T> QList<Key> QMultiHash<Key, T>::uniqueKeys() const
3305 \since 5.13
3306
3307 Returns a list containing all the keys in the map. Keys that occur multiple
3308 times in the map occur only once in the returned list.
3309
3310 \sa keys(), values()
3311*/
3312
3313/*! \fn template <class Key, class T> T QMultiHash<Key, T>::value(const Key &key) const
3314 \fn template <class Key, class T> T QMultiHash<Key, T>::value(const Key &key, const T &defaultValue) const
3315
3316 Returns the value associated with the \a key.
3317
3318 If the hash contains no item with the \a key, the function
3319 returns \a defaultValue, or a \l{default-constructed value} if this
3320 parameter has not been supplied.
3321
3322 If there are multiple
3323 items for the \a key in the hash, the value of the most recently
3324 inserted one is returned.
3325*/
3326
3327/*! \fn template <class Key, class T> QList<T> QMultiHash<Key, T>::values(const Key &key) const
3328 \overload
3329
3330 Returns a list of all the values associated with the \a key,
3331 from the most recently inserted to the least recently inserted.
3332
3333 \sa count(), insert()
3334*/
3335
3336/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::operator[](const Key &key)
3337
3338 Returns the value associated with the \a key as a modifiable reference.
3339
3340 If the hash contains no item with the \a key, the function inserts
3341 a \l{default-constructed value} into the hash with the \a key, and
3342 returns a reference to it.
3343
3344 If the hash contains multiple items with the \a key, this function returns
3345 a reference to the most recently inserted value.
3346
3347 \include qhash.cpp qhash-iterator-invalidation-func-desc
3348
3349 \sa insert(), value()
3350*/
3351
3352/*!
3353 \fn template <class Key, class T> bool QMultiHash<Key, T>::operator==(const QMultiHash &lhs, const QMultiHash &rhs)
3354
3355 Returns \c true if \a lhs multihash equals to the \a rhs multihash;
3356 otherwise returns \c false.
3357
3358 Two multihashes are considered equal if they contain the same (key, value)
3359 pairs.
3360
3361 This function requires the value type to implement \c {operator==()}.
3362
3363 \sa operator!=()
3364*/
3365
3366/*!
3367 \fn template <class Key, class T> bool QMultiHash<Key, T>::operator!=(const QMultiHash &lhs, const QMultiHash &rhs)
3368
3369 Returns \c true if \a lhs multihash is not equal to the \a rhs multihash;
3370 otherwise returns \c false.
3371
3372 Two multihashes are considered equal if they contain the same (key, value)
3373 pairs.
3374
3375 This function requires the value type to implement \c {operator==()}.
3376
3377 \sa operator==()
3378*/
3379
3380/*! \fn template <class Key, class T> QMultiHash &QMultiHash<Key, T>::operator+=(const QMultiHash &other)
3381
3382 Inserts all the items in the \a other hash into this hash
3383 and returns a reference to this hash.
3384
3385 \sa unite(), insert()
3386*/
3387
3388/*! \fn template <class Key, class T> QMultiHash QMultiHash<Key, T>::operator+(const QMultiHash &other) const
3389
3390 Returns a hash that contains all the items in this hash in
3391 addition to all the items in \a other. If a key is common to both
3392 hashes, the resulting hash will contain the key multiple times.
3393
3394 \sa operator+=()
3395*/
3396
3397/*!
3398 \fn template <class Key, class T> bool QMultiHash<Key, T>::contains(const Key &key, const T &value) const
3399 \since 4.3
3400
3401 Returns \c true if the hash contains an item with the \a key and
3402 \a value; otherwise returns \c false.
3403
3404 \sa count()
3405*/
3406
3407/*!
3408 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::remove(const Key &key)
3409 \since 4.3
3410
3411 Removes all the items that have the \a key from the hash.
3412 Returns the number of items removed.
3413
3414 \sa remove(const Key &key, const T &value)
3415*/
3416
3417/*!
3418 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::remove(const Key &key, const T &value)
3419 \since 4.3
3420
3421 Removes all the items that have the \a key and the value \a
3422 value from the hash. Returns the number of items removed.
3423
3424 \sa remove()
3425*/
3426
3427/*!
3428 \fn template <class Key, class T> void QMultiHash<Key, T>::clear()
3429 \since 4.3
3430
3431 Removes all items from the hash and frees up all memory used by it.
3432
3433 \sa remove()
3434*/
3435
3436/*! \fn template <class Key, class T> template <typename Predicate> qsizetype QMultiHash<Key, T>::removeIf(Predicate pred)
3437 \since 6.1
3438
3439 Removes all elements for which the predicate \a pred returns true
3440 from the multi hash.
3441
3442 The function supports predicates which take either an argument of
3443 type \c{QMultiHash<Key, T>::iterator}, or an argument of type
3444 \c{std::pair<const Key &, T &>}.
3445
3446 Returns the number of elements removed, if any.
3447
3448 \sa clear(), take()
3449*/
3450
3451/*! \fn template <class Key, class T> T QMultiHash<Key, T>::take(const Key &key)
3452
3453 Removes the item with the \a key from the hash and returns
3454 the value associated with it.
3455
3456 If the item does not exist in the hash, the function simply
3457 returns a \l{default-constructed value}. If there are multiple
3458 items for \a key in the hash, only the most recently inserted one
3459 is removed.
3460
3461 If you don't use the return value, remove() is more efficient.
3462
3463 \sa remove()
3464*/
3465
3466/*! \fn template <class Key, class T> QList<Key> QMultiHash<Key, T>::keys() const
3467
3468 Returns a list containing all the keys in the hash, in an
3469 arbitrary order. Keys that occur multiple times in the hash
3470 also occur multiple times in the list.
3471
3472 The order is guaranteed to be the same as that used by values().
3473
3474 This function creates a new list, in \l {linear time}. The time and memory
3475 use that entails can be avoided by iterating from \l keyBegin() to
3476 \l keyEnd().
3477
3478 \sa values(), key()
3479*/
3480
3481/*! \fn template <class Key, class T> QList<T> QMultiHash<Key, T>::values() const
3482
3483 Returns a list containing all the values in the hash, in an
3484 arbitrary order. If a key is associated with multiple values, all of
3485 its values will be in the list, and not just the most recently
3486 inserted one.
3487
3488 The order is guaranteed to be the same as that used by keys().
3489
3490 This function creates a new list, in \l {linear time}. The time and memory
3491 use that entails can be avoided by iterating from \l keyValueBegin() to
3492 \l keyValueEnd().
3493
3494 \sa keys(), value()
3495*/
3496
3497/*!
3498 \fn template <class Key, class T> Key QMultiHash<Key, T>::key(const T &value) const
3499 \fn template <class Key, class T> Key QMultiHash<Key, T>::key(const T &value, const Key &defaultKey) const
3500 \since 4.3
3501
3502 Returns the first key mapped to \a value. If the hash contains no item
3503 mapped to \a value, returns \a defaultKey, or a \l{default-constructed
3504 value}{default-constructed key} if this parameter has not been supplied.
3505
3506 This function can be slow (\l{linear time}), because QMultiHash's
3507 internal data structure is optimized for fast lookup by key, not
3508 by value.
3509*/
3510
3511/*!
3512 \fn template <class Key, class T> qsizetype QMultiHash<Key, T>::count(const Key &key, const T &value) const
3513 \since 4.3
3514
3515 Returns the number of items with the \a key and \a value.
3516
3517 \sa contains()
3518*/
3519
3520/*!
3521 \fn template <class Key, class T> typename QMultiHash<Key, T>::iterator QMultiHash<Key, T>::find(const Key &key, const T &value)
3522 \since 4.3
3523
3524 Returns an iterator pointing to the item with the \a key and \a value.
3525 If the hash contains no such item, the function returns end().
3526
3527 If the hash contains multiple items with the \a key and \a value, the
3528 iterator returned points to the most recently inserted item.
3529
3530 \include qhash.cpp qhash-iterator-invalidation-func-desc
3531*/
3532
3533/*!
3534 \fn template <class Key, class T> typename QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::find(const Key &key, const T &value) const
3535 \since 4.3
3536 \overload
3537
3538 \include qhash.cpp qhash-iterator-invalidation-func-desc
3539*/
3540
3541/*!
3542 \fn template <class Key, class T> typename QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constFind(const Key &key, const T &value) const
3543 \since 4.3
3544
3545 Returns an iterator pointing to the item with the \a key and the
3546 \a value in the hash.
3547
3548 If the hash contains no such item, the function returns
3549 constEnd().
3550
3551 \include qhash.cpp qhash-iterator-invalidation-func-desc
3552*/
3553
3554/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::begin()
3555
3556 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
3557 the hash.
3558
3559 \include qhash.cpp qhash-iterator-invalidation-func-desc
3560
3561 \sa constBegin(), end()
3562*/
3563
3564/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::begin() const
3565
3566 \overload
3567
3568 \include qhash.cpp qhash-iterator-invalidation-func-desc
3569*/
3570
3571/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::cbegin() const
3572 \since 5.0
3573
3574 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
3575 in the hash.
3576
3577 \include qhash.cpp qhash-iterator-invalidation-func-desc
3578
3579 \sa begin(), cend()
3580*/
3581
3582/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constBegin() const
3583
3584 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
3585 in the hash.
3586
3587 \include qhash.cpp qhash-iterator-invalidation-func-desc
3588
3589 \sa begin(), constEnd()
3590*/
3591
3592/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::keyBegin() const
3593 \since 5.6
3594
3595 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
3596 in the hash.
3597
3598 \include qhash.cpp qhash-iterator-invalidation-func-desc
3599
3600 \sa keyEnd()
3601*/
3602
3603/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::end()
3604
3605 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
3606 after the last item in the hash.
3607
3608 \include qhash.cpp qhash-iterator-invalidation-func-desc
3609
3610 \sa begin(), constEnd()
3611*/
3612
3613/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::end() const
3614
3615 \overload
3616*/
3617
3618/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::constEnd() const
3619
3620 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3621 item after the last item in the hash.
3622
3623 \include qhash.cpp qhash-iterator-invalidation-func-desc
3624
3625 \sa constBegin(), end()
3626*/
3627
3628/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::cend() const
3629 \since 5.0
3630
3631 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3632 item after the last item in the hash.
3633
3634 \include qhash.cpp qhash-iterator-invalidation-func-desc
3635
3636 \sa cbegin(), end()
3637*/
3638
3639/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::keyEnd() const
3640 \since 5.6
3641
3642 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3643 item after the last key in the hash.
3644
3645 \include qhash.cpp qhash-iterator-invalidation-func-desc
3646
3647 \sa keyBegin()
3648*/
3649
3650/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_value_iterator QMultiHash<Key, T>::keyValueBegin()
3651 \since 5.10
3652
3653 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3654 in the hash.
3655
3656 \include qhash.cpp qhash-iterator-invalidation-func-desc
3657
3658 \sa keyValueEnd()
3659*/
3660
3661/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_value_iterator QMultiHash<Key, T>::keyValueEnd()
3662 \since 5.10
3663
3664 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3665 entry after the last entry in the hash.
3666
3667 \include qhash.cpp qhash-iterator-invalidation-func-desc
3668
3669 \sa keyValueBegin()
3670*/
3671
3672/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::keyValueBegin() const
3673 \since 5.10
3674
3675 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3676 in the hash.
3677
3678 \include qhash.cpp qhash-iterator-invalidation-func-desc
3679
3680 \sa keyValueEnd()
3681*/
3682
3683/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::constKeyValueBegin() const
3684 \since 5.10
3685
3686 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first entry
3687 in the hash.
3688
3689 \include qhash.cpp qhash-iterator-invalidation-func-desc
3690
3691 \sa keyValueBegin()
3692*/
3693
3694/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::keyValueEnd() const
3695 \since 5.10
3696
3697 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3698 entry after the last entry in the hash.
3699
3700 \include qhash.cpp qhash-iterator-invalidation-func-desc
3701
3702 \sa keyValueBegin()
3703*/
3704
3705/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_key_value_iterator QMultiHash<Key, T>::constKeyValueEnd() const
3706 \since 5.10
3707
3708 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
3709 entry after the last entry in the hash.
3710
3711 \include qhash.cpp qhash-iterator-invalidation-func-desc
3712
3713 \sa constKeyValueBegin()
3714*/
3715
3716/*! \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() &
3717 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const &
3718 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() &&
3719 \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const &&
3720 \since 6.4
3721
3722 Returns a range object that allows iteration over this hash as
3723 key/value pairs. For instance, this range object can be used in a
3724 range-based for loop, in combination with a structured binding declaration:
3725
3726 \snippet code/src_corelib_tools_qhash.cpp 35
3727
3728 Note that both the key and the value obtained this way are
3729 references to the ones in the hash. Specifically, mutating the value
3730 will modify the hash itself.
3731
3732 \include qhash.cpp qhash-iterator-invalidation-func-desc
3733
3734 \sa QKeyValueIterator
3735*/
3736
3737/*! \class QMultiHash::iterator
3738 \inmodule QtCore
3739 \brief The QMultiHash::iterator class provides an STL-style non-const iterator for QMultiHash.
3740
3741 QMultiHash<Key, T>::iterator allows you to iterate over a QMultiHash
3742 and to modify the value (but not the key) associated
3743 with a particular key. If you want to iterate over a const QMultiHash,
3744 you should use QMultiHash::const_iterator. It is generally good
3745 practice to use QMultiHash::const_iterator on a non-const QMultiHash as
3746 well, unless you need to change the QMultiHash through the iterator.
3747 Const iterators are slightly faster, and can improve code
3748 readability.
3749
3750 The default QMultiHash::iterator constructor creates an uninitialized
3751 iterator. You must initialize it using a QMultiHash function like
3752 QMultiHash::begin(), QMultiHash::end(), or QMultiHash::find() before you can
3753 start iterating. Here's a typical loop that prints all the (key,
3754 value) pairs stored in a hash:
3755
3756 \snippet code/src_corelib_tools_qhash.cpp 17
3757
3758 Unlike QMap, which orders its items by key, QMultiHash stores its
3759 items in an arbitrary order.
3760
3761 Here's an example that increments every value stored in the QMultiHash
3762 by 2:
3763
3764 \snippet code/src_corelib_tools_qhash.cpp 18
3765
3766 To remove elements from a QMultiHash you can use erase_if(QMultiHash<Key, T> &map, Predicate pred):
3767
3768 \snippet code/src_corelib_tools_qhash.cpp 21
3769
3770 Multiple iterators can be used on the same hash. However, be aware
3771 that any modification performed directly on the QHash (inserting and
3772 removing items) can cause the iterators to become invalid.
3773
3774 Inserting items into the hash or calling methods such as QHash::reserve()
3775 or QHash::squeeze() can invalidate all iterators pointing into the hash.
3776 Iterators are guaranteed to stay valid only as long as the QHash doesn't have
3777 to grow/shrink its internal hash table.
3778 Using any iterator after a rehashing operation has occurred will lead to undefined behavior.
3779
3780 If you need to keep iterators over a long period of time, we recommend
3781 that you use QMultiMap rather than QHash.
3782
3783 \warning Iterators on implicitly shared containers do not work
3784 exactly like STL-iterators. You should avoid copying a container
3785 while iterators are active on that container. For more information,
3786 read \l{Implicit sharing iterator problem}.
3787
3788 \sa QMultiHash::const_iterator, QMultiHash::key_iterator, QMultiHash::key_value_iterator
3789*/
3790
3791/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator::iterator()
3792
3793 Constructs an uninitialized iterator.
3794
3795 Functions like key(), value(), and operator++() must not be
3796 called on an uninitialized iterator. Use operator=() to assign a
3797 value to it before using it.
3798
3799 \sa QMultiHash::begin(), QMultiHash::end()
3800*/
3801
3802/*! \fn template <class Key, class T> const Key &QMultiHash<Key, T>::iterator::key() const
3803
3804 Returns the current item's key as a const reference.
3805
3806 There is no direct way of changing an item's key through an
3807 iterator, although it can be done by calling QMultiHash::erase()
3808 followed by QMultiHash::insert().
3809
3810 \sa value()
3811*/
3812
3813/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::iterator::value() const
3814
3815 Returns a modifiable reference to the current item's value.
3816
3817 You can change the value of an item by using value() on
3818 the left side of an assignment, for example:
3819
3820 \snippet code/src_corelib_tools_qhash.cpp 22
3821
3822 \sa key(), operator*()
3823*/
3824
3825/*! \fn template <class Key, class T> T &QMultiHash<Key, T>::iterator::operator*() const
3826
3827 Returns a modifiable reference to the current item's value.
3828
3829 Same as value().
3830
3831 \sa key()
3832*/
3833
3834/*! \fn template <class Key, class T> T *QMultiHash<Key, T>::iterator::operator->() const
3835
3836 Returns a pointer to the current item's value.
3837
3838 \sa value()
3839*/
3840
3841/*!
3842 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator==(const iterator &other) const
3843 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator==(const const_iterator &other) const
3844
3845 Returns \c true if \a other points to the same item as this
3846 iterator; otherwise returns \c false.
3847
3848 \sa operator!=()
3849*/
3850
3851/*!
3852 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator!=(const iterator &other) const
3853 \fn template <class Key, class T> bool QMultiHash<Key, T>::iterator::operator!=(const const_iterator &other) const
3854
3855 Returns \c true if \a other points to a different item than this
3856 iterator; otherwise returns \c false.
3857
3858 \sa operator==()
3859*/
3860
3861/*!
3862 \fn template <class Key, class T> QMultiHash<Key, T>::iterator &QMultiHash<Key, T>::iterator::operator++()
3863
3864 The prefix ++ operator (\c{++i}) advances the iterator to the
3865 next item in the hash and returns an iterator to the new current
3866 item.
3867
3868 Calling this function on QMultiHash::end() leads to undefined results.
3869*/
3870
3871/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::iterator::operator++(int)
3872
3873 \overload
3874
3875 The postfix ++ operator (\c{i++}) advances the iterator to the
3876 next item in the hash and returns an iterator to the previously
3877 current item.
3878*/
3879
3880/*! \class QMultiHash::const_iterator
3881 \inmodule QtCore
3882 \brief The QMultiHash::const_iterator class provides an STL-style const iterator for QMultiHash.
3883
3884 QMultiHash<Key, T>::const_iterator allows you to iterate over a
3885 QMultiHash. If you want to modify the QMultiHash as you
3886 iterate over it, you must use QMultiHash::iterator instead. It is
3887 generally good practice to use QMultiHash::const_iterator on a
3888 non-const QMultiHash as well, unless you need to change the QMultiHash
3889 through the iterator. Const iterators are slightly faster, and
3890 can improve code readability.
3891
3892 The default QMultiHash::const_iterator constructor creates an
3893 uninitialized iterator. You must initialize it using a QMultiHash
3894 function like QMultiHash::cbegin(), QMultiHash::cend(), or
3895 QMultiHash::constFind() before you can start iterating. Here's a typical
3896 loop that prints all the (key, value) pairs stored in a hash:
3897
3898 \snippet code/src_corelib_tools_qhash.cpp 23
3899
3900 Unlike QMap, which orders its items by key, QMultiHash stores its
3901 items in an arbitrary order. The only guarantee is that items that
3902 share the same key (because they were inserted using
3903 a QMultiHash) will appear consecutively, from the most
3904 recently to the least recently inserted value.
3905
3906 Multiple iterators can be used on the same hash. However, be aware
3907 that any modification performed directly on the QMultiHash (inserting and
3908 removing items) can cause the iterators to become invalid.
3909
3910 Inserting items into the hash or calling methods such as QMultiHash::reserve()
3911 or QMultiHash::squeeze() can invalidate all iterators pointing into the hash.
3912 Iterators are guaranteed to stay valid only as long as the QMultiHash doesn't have
3913 to grow/shrink it's internal hash table.
3914 Using any iterator after a rehashing operation ahs occurred will lead to undefined behavior.
3915
3916 If you need to keep iterators over a long period of time, we recommend
3917 that you use QMultiMap rather than QMultiHash.
3918
3919 \warning Iterators on implicitly shared containers do not work
3920 exactly like STL-iterators. You should avoid copying a container
3921 while iterators are active on that container. For more information,
3922 read \l{Implicit sharing iterator problem}.
3923
3924 \sa QMultiHash::iterator, QMultiHash::key_iterator, QMultiHash::const_key_value_iterator
3925*/
3926
3927/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator::const_iterator()
3928
3929 Constructs an uninitialized iterator.
3930
3931 Functions like key(), value(), and operator++() must not be
3932 called on an uninitialized iterator. Use operator=() to assign a
3933 value to it before using it.
3934
3935 \sa QMultiHash::constBegin(), QMultiHash::constEnd()
3936*/
3937
3938/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator::const_iterator(const iterator &other)
3939
3940 Constructs a copy of \a other.
3941*/
3942
3943/*! \fn template <class Key, class T> const Key &QMultiHash<Key, T>::const_iterator::key() const
3944
3945 Returns the current item's key.
3946
3947 \sa value()
3948*/
3949
3950/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::const_iterator::value() const
3951
3952 Returns the current item's value.
3953
3954 \sa key(), operator*()
3955*/
3956
3957/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::const_iterator::operator*() const
3958
3959 Returns the current item's value.
3960
3961 Same as value().
3962
3963 \sa key()
3964*/
3965
3966/*! \fn template <class Key, class T> const T *QMultiHash<Key, T>::const_iterator::operator->() const
3967
3968 Returns a pointer to the current item's value.
3969
3970 \sa value()
3971*/
3972
3973/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::const_iterator::operator==(const const_iterator &other) const
3974
3975 Returns \c true if \a other points to the same item as this
3976 iterator; otherwise returns \c false.
3977
3978 \sa operator!=()
3979*/
3980
3981/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::const_iterator::operator!=(const const_iterator &other) const
3982
3983 Returns \c true if \a other points to a different item than this
3984 iterator; otherwise returns \c false.
3985
3986 \sa operator==()
3987*/
3988
3989/*!
3990 \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator &QMultiHash<Key, T>::const_iterator::operator++()
3991
3992 The prefix ++ operator (\c{++i}) advances the iterator to the
3993 next item in the hash and returns an iterator to the new current
3994 item.
3995
3996 Calling this function on QMultiHash::end() leads to undefined results.
3997*/
3998
3999/*! \fn template <class Key, class T> QMultiHash<Key, T>::const_iterator QMultiHash<Key, T>::const_iterator::operator++(int)
4000
4001 \overload
4002
4003 The postfix ++ operator (\c{i++}) advances the iterator to the
4004 next item in the hash and returns an iterator to the previously
4005 current item.
4006*/
4007
4008/*! \class QMultiHash::key_iterator
4009 \inmodule QtCore
4010 \since 5.6
4011 \brief The QMultiHash::key_iterator class provides an STL-style const iterator for QMultiHash keys.
4012
4013 QMultiHash::key_iterator is essentially the same as QMultiHash::const_iterator
4014 with the difference that operator*() and operator->() return a key
4015 instead of a value.
4016
4017 For most uses QMultiHash::iterator and QMultiHash::const_iterator should be used,
4018 you can easily access the key by calling QMultiHash::iterator::key():
4019
4020 \snippet code/src_corelib_tools_qhash.cpp 27
4021
4022 However, to have interoperability between QMultiHash's keys and STL-style
4023 algorithms we need an iterator that dereferences to a key instead
4024 of a value. With QMultiHash::key_iterator we can apply an algorithm to a
4025 range of keys without having to call QMultiHash::keys(), which is inefficient
4026 as it costs one QMultiHash iteration and memory allocation to create a temporary
4027 QList.
4028
4029 \snippet code/src_corelib_tools_qhash.cpp 28
4030
4031 QMultiHash::key_iterator is const, it's not possible to modify the key.
4032
4033 The default QMultiHash::key_iterator constructor creates an uninitialized
4034 iterator. You must initialize it using a QMultiHash function like
4035 QMultiHash::keyBegin() or QMultiHash::keyEnd().
4036
4037 \warning Iterators on implicitly shared containers do not work
4038 exactly like STL-iterators. You should avoid copying a container
4039 while iterators are active on that container. For more information,
4040 read \l{Implicit sharing iterator problem}.
4041
4042 \sa QMultiHash::const_iterator, QMultiHash::iterator
4043*/
4044
4045/*! \fn template <class Key, class T> const T &QMultiHash<Key, T>::key_iterator::operator*() const
4046
4047 Returns the current item's key.
4048*/
4049
4050/*! \fn template <class Key, class T> const T *QMultiHash<Key, T>::key_iterator::operator->() const
4051
4052 Returns a pointer to the current item's key.
4053*/
4054
4055/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::key_iterator::operator==(key_iterator other) const
4056
4057 Returns \c true if \a other points to the same item as this
4058 iterator; otherwise returns \c false.
4059
4060 \sa operator!=()
4061*/
4062
4063/*! \fn template <class Key, class T> bool QMultiHash<Key, T>::key_iterator::operator!=(key_iterator other) const
4064
4065 Returns \c true if \a other points to a different item than this
4066 iterator; otherwise returns \c false.
4067
4068 \sa operator==()
4069*/
4070
4071/*!
4072 \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator &QMultiHash<Key, T>::key_iterator::operator++()
4073
4074 The prefix ++ operator (\c{++i}) advances the iterator to the
4075 next item in the hash and returns an iterator to the new current
4076 item.
4077
4078 Calling this function on QMultiHash::keyEnd() leads to undefined results.
4079*/
4080
4081/*! \fn template <class Key, class T> QMultiHash<Key, T>::key_iterator QMultiHash<Key, T>::key_iterator::operator++(int)
4082
4083 \overload
4084
4085 The postfix ++ operator (\c{i++}) advances the iterator to the
4086 next item in the hash and returns an iterator to the previous
4087 item.
4088*/
4089
4090/*! \fn template <class Key, class T> const_iterator QMultiHash<Key, T>::key_iterator::base() const
4091 Returns the underlying const_iterator this key_iterator is based on.
4092*/
4093
4094/*! \typedef QMultiHash::const_key_value_iterator
4095 \inmodule QtCore
4096 \since 5.10
4097 \brief The QMultiHash::const_key_value_iterator typedef provides an STL-style const iterator for QMultiHash.
4098
4099 QMultiHash::const_key_value_iterator is essentially the same as QMultiHash::const_iterator
4100 with the difference that operator*() returns a key/value pair instead of a
4101 value.
4102
4103 \sa QKeyValueIterator
4104*/
4105
4106/*! \typedef QMultiHash::key_value_iterator
4107 \inmodule QtCore
4108 \since 5.10
4109 \brief The QMultiHash::key_value_iterator typedef provides an STL-style iterator for QMultiHash.
4110
4111 QMultiHash::key_value_iterator is essentially the same as QMultiHash::iterator
4112 with the difference that operator*() returns a key/value pair instead of a
4113 value.
4114
4115 \sa QKeyValueIterator
4116*/
4117
4118/*! \fn template <class Key, class T> QDataStream &operator<<(QDataStream &out, const QMultiHash<Key, T>& hash)
4119 \relates QMultiHash
4120
4121 Writes the hash \a hash to stream \a out.
4122
4123 This function requires the key and value types to implement \c
4124 operator<<().
4125
4126 \sa {Serializing Qt Data Types}
4127*/
4128
4129/*! \fn template <class Key, class T> QDataStream &operator>>(QDataStream &in, QMultiHash<Key, T> &hash)
4130 \relates QMultiHash
4131
4132 Reads a hash from stream \a in into \a hash.
4133
4134 This function requires the key and value types to implement \c
4135 operator>>().
4136
4137 \sa {Serializing Qt Data Types}
4138*/
4139
4140/*!
4141 \fn template <class Key, class T> size_t qHash(const QHash<Key, T> &key, size_t seed = 0)
4142 \since 5.8
4143 \qhasholdTS{QHash}{Key}{T}
4144*/
4145
4146/*!
4147 \fn template <class Key, class T> size_t qHash(const QMultiHash<Key, T> &key, size_t seed = 0)
4148 \since 5.8
4149 \qhasholdTS{QMultiHash}{Key}{T}
4150*/
4151
4152/*! \fn template <typename Key, typename T, typename Predicate> qsizetype erase_if(QHash<Key, T> &hash, Predicate pred)
4153 \relates QHash
4154 \since 6.1
4155
4156 Removes all elements for which the predicate \a pred returns true
4157 from the hash \a hash.
4158
4159 The function supports predicates which take either an argument of
4160 type \c{QHash<Key, T>::iterator}, or an argument of type
4161 \c{std::pair<const Key &, T &>}.
4162
4163 Returns the number of elements removed, if any.
4164*/
4165
4166/*! \fn template <typename Key, typename T, typename Predicate> qsizetype erase_if(QMultiHash<Key, T> &hash, Predicate pred)
4167 \relates QMultiHash
4168 \since 6.1
4169
4170 Removes all elements for which the predicate \a pred returns true
4171 from the multi hash \a hash.
4172
4173 The function supports predicates which take either an argument of
4174 type \c{QMultiHash<Key, T>::iterator}, or an argument of type
4175 \c{std::pair<const Key &, T &>}.
4176
4177 Returns the number of elements removed, if any.
4178*/
4179
4180/*! \macro QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD
4181 \relates QHash
4182 \since 6.11
4183
4184 Defining this macro disables the support for qHash overloads that only take
4185 one argument; in other words, for qHash overloads that do not also accept
4186 a seed. Support for the single-argument overloads of qHash is deprecated
4187 and will be removed in Qt 7.
4188
4189 \sa qHash
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:920