Bug 1685680 [wpt PR 27099] - Update wpt metadata, a=testonly
[gecko.git] / xpcom / ds / nsHashKeys.h
blobd26dc3c82694690ec072ac9bd7d800f012318cc0
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsTHashKeys_h__
8 #define nsTHashKeys_h__
10 #include "nsID.h"
11 #include "nsISupports.h"
12 #include "nsCOMPtr.h"
13 #include "PLDHashTable.h"
14 #include <new>
16 #include "nsString.h"
17 #include "nsCRTGlue.h"
18 #include "nsUnicharUtils.h"
19 #include "nsPointerHashKeys.h"
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
25 #include <utility>
27 #include "mozilla/HashFunctions.h"
29 namespace mozilla {
31 // These are defined analogously to the HashString overloads in mfbt.
33 inline uint32_t HashString(const nsAString& aStr) {
34 return HashString(aStr.BeginReading(), aStr.Length());
37 inline uint32_t HashString(const nsACString& aStr) {
38 return HashString(aStr.BeginReading(), aStr.Length());
41 } // namespace mozilla
43 /** @file nsHashKeys.h
44 * standard HashKey classes for nsBaseHashtable and relatives. Each of these
45 * classes follows the nsTHashtable::EntryType specification
47 * Lightweight keytypes provided here:
48 * nsStringHashKey
49 * nsCStringHashKey
50 * nsUint32HashKey
51 * nsUint64HashKey
52 * nsFloatHashKey
53 * IntPtrHashKey
54 * nsPtrHashKey
55 * nsClearingPtrHashKey
56 * nsVoidPtrHashKey
57 * nsClearingVoidPtrHashKey
58 * nsISupportsHashKey
59 * nsIDHashKey
60 * nsDepCharHashKey
61 * nsCharPtrHashKey
62 * nsUnicharPtrHashKey
63 * nsGenericHashKey
66 /**
67 * hashkey wrapper using nsAString KeyType
69 * @see nsTHashtable::EntryType for specification
71 class nsStringHashKey : public PLDHashEntryHdr {
72 public:
73 typedef const nsAString& KeyType;
74 typedef const nsAString* KeyTypePointer;
76 explicit nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) {}
77 nsStringHashKey(const nsStringHashKey&) = delete;
78 nsStringHashKey(nsStringHashKey&& aToMove)
79 : PLDHashEntryHdr(std::move(aToMove)), mStr(std::move(aToMove.mStr)) {}
80 ~nsStringHashKey() = default;
82 KeyType GetKey() const { return mStr; }
83 bool KeyEquals(const KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
85 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
86 static PLDHashNumber HashKey(const KeyTypePointer aKey) {
87 return mozilla::HashString(*aKey);
90 #ifdef MOZILLA_INTERNAL_API
91 // To avoid double-counting, only measure the string if it is unshared.
92 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
93 return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
95 #endif
97 enum { ALLOW_MEMMOVE = true };
99 private:
100 nsString mStr;
103 #ifdef MOZILLA_INTERNAL_API
106 * hashkey wrapper using nsAString KeyType
108 * This is internal-API only because nsCaseInsensitiveStringComparator is
109 * internal-only.
111 * @see nsTHashtable::EntryType for specification
113 class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr {
114 public:
115 typedef const nsAString& KeyType;
116 typedef const nsAString* KeyTypePointer;
118 explicit nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) {
119 // take it easy just deal HashKey
122 nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey&) =
123 delete;
124 nsStringCaseInsensitiveHashKey(nsStringCaseInsensitiveHashKey&& aToMove)
125 : PLDHashEntryHdr(std::move(aToMove)), mStr(std::move(aToMove.mStr)) {}
126 ~nsStringCaseInsensitiveHashKey() = default;
128 KeyType GetKey() const { return mStr; }
129 bool KeyEquals(const KeyTypePointer aKey) const {
130 return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator);
133 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
134 static PLDHashNumber HashKey(const KeyTypePointer aKey) {
135 nsAutoString tmKey(*aKey);
136 ToLowerCase(tmKey);
137 return mozilla::HashString(tmKey);
139 enum { ALLOW_MEMMOVE = true };
141 // To avoid double-counting, only measure the string if it is unshared.
142 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
143 return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
146 private:
147 const nsString mStr;
150 #endif
153 * hashkey wrapper using nsACString KeyType
155 * @see nsTHashtable::EntryType for specification
157 class nsCStringHashKey : public PLDHashEntryHdr {
158 public:
159 typedef const nsACString& KeyType;
160 typedef const nsACString* KeyTypePointer;
162 explicit nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) {}
163 nsCStringHashKey(nsCStringHashKey&& aOther)
164 : PLDHashEntryHdr(std::move(aOther)), mStr(std::move(aOther.mStr)) {}
165 ~nsCStringHashKey() = default;
167 KeyType GetKey() const { return mStr; }
168 bool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
170 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
171 static PLDHashNumber HashKey(KeyTypePointer aKey) {
172 return mozilla::HashString(*aKey);
175 #ifdef MOZILLA_INTERNAL_API
176 // To avoid double-counting, only measure the string if it is unshared.
177 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
178 return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
180 #endif
182 enum { ALLOW_MEMMOVE = true };
184 private:
185 const nsCString mStr;
189 * hashkey wrapper using uint32_t KeyType
191 * @see nsTHashtable::EntryType for specification
193 class nsUint32HashKey : public PLDHashEntryHdr {
194 public:
195 typedef const uint32_t& KeyType;
196 typedef const uint32_t* KeyTypePointer;
198 explicit nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) {}
199 nsUint32HashKey(nsUint32HashKey&& aOther)
200 : PLDHashEntryHdr(std::move(aOther)), mValue(std::move(aOther.mValue)) {}
201 ~nsUint32HashKey() = default;
203 KeyType GetKey() const { return mValue; }
204 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
206 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
207 static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; }
208 enum { ALLOW_MEMMOVE = true };
210 private:
211 const uint32_t mValue;
215 * hashkey wrapper using uint64_t KeyType
217 * @see nsTHashtable::EntryType for specification
219 class nsUint64HashKey : public PLDHashEntryHdr {
220 public:
221 typedef const uint64_t& KeyType;
222 typedef const uint64_t* KeyTypePointer;
224 explicit nsUint64HashKey(KeyTypePointer aKey) : mValue(*aKey) {}
225 nsUint64HashKey(nsUint64HashKey&& aOther)
226 : PLDHashEntryHdr(std::move(aOther)), mValue(std::move(aOther.mValue)) {}
227 ~nsUint64HashKey() = default;
229 KeyType GetKey() const { return mValue; }
230 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
232 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
233 static PLDHashNumber HashKey(KeyTypePointer aKey) {
234 return PLDHashNumber(*aKey);
236 enum { ALLOW_MEMMOVE = true };
238 private:
239 const uint64_t mValue;
243 * hashkey wrapper using float KeyType
245 * @see nsTHashtable::EntryType for specification
247 class nsFloatHashKey : public PLDHashEntryHdr {
248 public:
249 typedef const float& KeyType;
250 typedef const float* KeyTypePointer;
252 explicit nsFloatHashKey(KeyTypePointer aKey) : mValue(*aKey) {}
253 nsFloatHashKey(nsFloatHashKey&& aOther)
254 : PLDHashEntryHdr(std::move(aOther)), mValue(std::move(aOther.mValue)) {}
255 ~nsFloatHashKey() = default;
257 KeyType GetKey() const { return mValue; }
258 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
260 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
261 static PLDHashNumber HashKey(KeyTypePointer aKey) {
262 return *reinterpret_cast<const uint32_t*>(aKey);
264 enum { ALLOW_MEMMOVE = true };
266 private:
267 const float mValue;
271 * hashkey wrapper using intptr_t KeyType
273 * @see nsTHashtable::EntryType for specification
275 class IntPtrHashKey : public PLDHashEntryHdr {
276 public:
277 typedef const intptr_t& KeyType;
278 typedef const intptr_t* KeyTypePointer;
280 explicit IntPtrHashKey(KeyTypePointer aKey) : mValue(*aKey) {}
281 IntPtrHashKey(IntPtrHashKey&& aOther)
282 : PLDHashEntryHdr(std::move(aOther)), mValue(aOther.mValue) {}
283 ~IntPtrHashKey() = default;
285 KeyType GetKey() const { return mValue; }
286 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
288 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
289 static PLDHashNumber HashKey(KeyTypePointer aKey) {
290 return mozilla::HashGeneric(*aKey);
292 enum { ALLOW_MEMMOVE = true };
294 private:
295 const intptr_t mValue;
299 * hashkey wrapper using nsISupports* KeyType
301 * @see nsTHashtable::EntryType for specification
303 class nsISupportsHashKey : public PLDHashEntryHdr {
304 public:
305 typedef nsISupports* KeyType;
306 typedef const nsISupports* KeyTypePointer;
308 explicit nsISupportsHashKey(const nsISupports* aKey)
309 : mSupports(const_cast<nsISupports*>(aKey)) {}
310 nsISupportsHashKey(nsISupportsHashKey&& aOther)
311 : PLDHashEntryHdr(std::move(aOther)),
312 mSupports(std::move(aOther.mSupports)) {}
313 ~nsISupportsHashKey() = default;
315 KeyType GetKey() const { return mSupports; }
316 bool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; }
318 static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
319 static PLDHashNumber HashKey(KeyTypePointer aKey) {
320 return NS_PTR_TO_UINT32(aKey) >> 2;
322 enum { ALLOW_MEMMOVE = true };
324 private:
325 nsCOMPtr<nsISupports> mSupports;
329 * hashkey wrapper using refcounted * KeyType
331 * @see nsTHashtable::EntryType for specification
333 template <class T>
334 class nsRefPtrHashKey : public PLDHashEntryHdr {
335 public:
336 typedef T* KeyType;
337 typedef const T* KeyTypePointer;
339 explicit nsRefPtrHashKey(const T* aKey) : mKey(const_cast<T*>(aKey)) {}
340 nsRefPtrHashKey(nsRefPtrHashKey&& aOther)
341 : PLDHashEntryHdr(std::move(aOther)), mKey(std::move(aOther.mKey)) {}
342 ~nsRefPtrHashKey() = default;
344 KeyType GetKey() const { return mKey; }
345 bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
347 static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
348 static PLDHashNumber HashKey(KeyTypePointer aKey) {
349 return NS_PTR_TO_UINT32(aKey) >> 2;
351 enum { ALLOW_MEMMOVE = true };
353 private:
354 RefPtr<T> mKey;
357 template <class T>
358 inline void ImplCycleCollectionTraverse(
359 nsCycleCollectionTraversalCallback& aCallback, nsRefPtrHashKey<T>& aField,
360 const char* aName, uint32_t aFlags = 0) {
361 CycleCollectionNoteChild(aCallback, aField.GetKey(), aName, aFlags);
365 * hashkey wrapper using T* KeyType that sets key to nullptr upon
366 * destruction. Relevant only in cases where a memory pointer-scanner
367 * like valgrind might get confused about stale references.
369 * @see nsTHashtable::EntryType for specification
372 template <class T>
373 class nsClearingPtrHashKey : public nsPtrHashKey<T> {
374 public:
375 explicit nsClearingPtrHashKey(const T* aKey) : nsPtrHashKey<T>(aKey) {}
376 nsClearingPtrHashKey(nsClearingPtrHashKey&& aToMove)
377 : nsPtrHashKey<T>(std::move(aToMove)) {}
378 ~nsClearingPtrHashKey() { nsPtrHashKey<T>::mKey = nullptr; }
381 typedef nsClearingPtrHashKey<const void> nsClearingVoidPtrHashKey;
384 * hashkey wrapper using a function pointer KeyType
386 * @see nsTHashtable::EntryType for specification
388 template <class T>
389 class nsFuncPtrHashKey : public PLDHashEntryHdr {
390 public:
391 typedef T& KeyType;
392 typedef const T* KeyTypePointer;
394 explicit nsFuncPtrHashKey(const T* aKey) : mKey(*const_cast<T*>(aKey)) {}
395 nsFuncPtrHashKey(const nsFuncPtrHashKey<T>& aToCopy) : mKey(aToCopy.mKey) {}
396 ~nsFuncPtrHashKey() = default;
398 KeyType GetKey() const { return const_cast<T&>(mKey); }
399 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; }
401 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
402 static PLDHashNumber HashKey(KeyTypePointer aKey) {
403 return NS_PTR_TO_UINT32(*aKey) >> 2;
405 enum { ALLOW_MEMMOVE = true };
407 protected:
408 T mKey;
412 * hashkey wrapper using nsID KeyType
414 * @see nsTHashtable::EntryType for specification
416 class nsIDHashKey : public PLDHashEntryHdr {
417 public:
418 typedef const nsID& KeyType;
419 typedef const nsID* KeyTypePointer;
421 explicit nsIDHashKey(const nsID* aInID) : mID(*aInID) {}
422 nsIDHashKey(nsIDHashKey&& aOther)
423 : PLDHashEntryHdr(std::move(aOther)), mID(std::move(aOther.mID)) {}
424 ~nsIDHashKey() = default;
426 KeyType GetKey() const { return mID; }
427 bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); }
429 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
430 static PLDHashNumber HashKey(KeyTypePointer aKey) {
431 // Hash the nsID object's raw bytes.
432 return mozilla::HashBytes(aKey, sizeof(KeyType));
435 enum { ALLOW_MEMMOVE = true };
437 private:
438 nsID mID;
442 * hashkey wrapper using nsID* KeyType
444 * @see nsTHashtable::EntryType for specification
446 class nsIDPointerHashKey : public PLDHashEntryHdr {
447 public:
448 typedef const nsID* KeyType;
449 typedef const nsID* KeyTypePointer;
451 explicit nsIDPointerHashKey(const nsID* aInID) : mID(aInID) {}
452 nsIDPointerHashKey(nsIDPointerHashKey&& aOther)
453 : PLDHashEntryHdr(std::move(aOther)), mID(aOther.mID) {}
454 ~nsIDPointerHashKey() = default;
456 KeyType GetKey() const { return mID; }
457 bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(*mID); }
459 static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
460 static PLDHashNumber HashKey(KeyTypePointer aKey) {
461 // Hash the nsID object's raw bytes.
462 return mozilla::HashBytes(aKey, sizeof(*aKey));
465 enum { ALLOW_MEMMOVE = true };
467 private:
468 const nsID* mID;
472 * hashkey wrapper for "dependent" const char*; this class does not "own"
473 * its string pointer.
475 * This class must only be used if the strings have a lifetime longer than
476 * the hashtable they occupy. This normally occurs only for static
477 * strings or strings that have been arena-allocated.
479 * @see nsTHashtable::EntryType for specification
481 class nsDepCharHashKey : public PLDHashEntryHdr {
482 public:
483 typedef const char* KeyType;
484 typedef const char* KeyTypePointer;
486 explicit nsDepCharHashKey(const char* aKey) : mKey(aKey) {}
487 nsDepCharHashKey(nsDepCharHashKey&& aOther)
488 : PLDHashEntryHdr(std::move(aOther)), mKey(std::move(aOther.mKey)) {}
489 ~nsDepCharHashKey() = default;
491 const char* GetKey() const { return mKey; }
492 bool KeyEquals(const char* aKey) const { return !strcmp(mKey, aKey); }
494 static const char* KeyToPointer(const char* aKey) { return aKey; }
495 static PLDHashNumber HashKey(const char* aKey) {
496 return mozilla::HashString(aKey);
498 enum { ALLOW_MEMMOVE = true };
500 private:
501 const char* mKey;
505 * hashkey wrapper for const char*; at construction, this class duplicates
506 * a string pointed to by the pointer so that it doesn't matter whether or not
507 * the string lives longer than the hash table.
509 class nsCharPtrHashKey : public PLDHashEntryHdr {
510 public:
511 typedef const char* KeyType;
512 typedef const char* KeyTypePointer;
514 explicit nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) {}
516 nsCharPtrHashKey(const nsCharPtrHashKey&) = delete;
517 nsCharPtrHashKey(nsCharPtrHashKey&& aOther)
518 : PLDHashEntryHdr(std::move(aOther)), mKey(aOther.mKey) {
519 aOther.mKey = nullptr;
522 ~nsCharPtrHashKey() {
523 if (mKey) {
524 free(const_cast<char*>(mKey));
528 const char* GetKey() const { return mKey; }
529 bool KeyEquals(KeyTypePointer aKey) const { return !strcmp(mKey, aKey); }
531 static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
532 static PLDHashNumber HashKey(KeyTypePointer aKey) {
533 return mozilla::HashString(aKey);
536 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
537 return aMallocSizeOf(mKey);
540 enum { ALLOW_MEMMOVE = true };
542 private:
543 const char* mKey;
547 * hashkey wrapper for const char16_t*; at construction, this class duplicates
548 * a string pointed to by the pointer so that it doesn't matter whether or not
549 * the string lives longer than the hash table.
551 class nsUnicharPtrHashKey : public PLDHashEntryHdr {
552 public:
553 typedef const char16_t* KeyType;
554 typedef const char16_t* KeyTypePointer;
556 explicit nsUnicharPtrHashKey(const char16_t* aKey) : mKey(NS_xstrdup(aKey)) {}
557 nsUnicharPtrHashKey(const nsUnicharPtrHashKey& aToCopy) = delete;
558 nsUnicharPtrHashKey(nsUnicharPtrHashKey&& aOther)
559 : PLDHashEntryHdr(std::move(aOther)), mKey(aOther.mKey) {
560 aOther.mKey = nullptr;
563 ~nsUnicharPtrHashKey() {
564 if (mKey) {
565 free(const_cast<char16_t*>(mKey));
569 const char16_t* GetKey() const { return mKey; }
570 bool KeyEquals(KeyTypePointer aKey) const { return !NS_strcmp(mKey, aKey); }
572 static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
573 static PLDHashNumber HashKey(KeyTypePointer aKey) {
574 return mozilla::HashString(aKey);
577 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
578 return aMallocSizeOf(mKey);
581 enum { ALLOW_MEMMOVE = true };
583 private:
584 const char16_t* mKey;
587 namespace mozilla {
589 template <typename T>
590 PLDHashNumber Hash(const T& aValue) {
591 return aValue.Hash();
594 } // namespace mozilla
597 * Hashtable key class to use with objects for which Hash() and operator==()
598 * are defined.
600 template <typename T>
601 class nsGenericHashKey : public PLDHashEntryHdr {
602 public:
603 typedef const T& KeyType;
604 typedef const T* KeyTypePointer;
606 explicit nsGenericHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
607 nsGenericHashKey(const nsGenericHashKey&) = delete;
608 nsGenericHashKey(nsGenericHashKey&& aOther)
609 : PLDHashEntryHdr(std::move(aOther)), mKey(std::move(aOther.mKey)) {}
611 KeyType GetKey() const { return mKey; }
612 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; }
614 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
615 static PLDHashNumber HashKey(KeyTypePointer aKey) {
616 return ::mozilla::Hash(*aKey);
618 enum { ALLOW_MEMMOVE = true };
620 private:
621 T mKey;
624 #endif // nsTHashKeys_h__