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