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