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