Line data Source code
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/. */
6 :
7 : #ifndef nsTHashKeys_h__
8 : #define nsTHashKeys_h__
9 :
10 : #include "nsID.h"
11 : #include "nsISupports.h"
12 : #include "nsIHashable.h"
13 : #include "nsAutoPtr.h"
14 : #include "nsCOMPtr.h"
15 : #include "PLDHashTable.h"
16 : #include <new>
17 :
18 : #include "nsStringGlue.h"
19 : #include "nsCRTGlue.h"
20 : #include "nsUnicharUtils.h"
21 : #include "nsPointerHashKeys.h"
22 :
23 : #include <stdlib.h>
24 : #include <string.h>
25 :
26 : #include "mozilla/HashFunctions.h"
27 : #include "mozilla/Move.h"
28 :
29 : namespace mozilla {
30 :
31 : // These are defined analogously to the HashString overloads in mfbt.
32 :
33 : inline uint32_t
34 30822 : HashString(const nsAString& aStr)
35 : {
36 30822 : return HashString(aStr.BeginReading(), aStr.Length());
37 : }
38 :
39 : inline uint32_t
40 30588 : HashString(const nsACString& aStr)
41 : {
42 30588 : return HashString(aStr.BeginReading(), aStr.Length());
43 : }
44 :
45 : } // namespace mozilla
46 :
47 : /** @file nsHashKeys.h
48 : * standard HashKey classes for nsBaseHashtable and relatives. Each of these
49 : * classes follows the nsTHashtable::EntryType specification
50 : *
51 : * Lightweight keytypes provided here:
52 : * nsStringHashKey
53 : * nsCStringHashKey
54 : * nsUint32HashKey
55 : * nsUint64HashKey
56 : * nsFloatHashKey
57 : * nsPtrHashKey
58 : * nsClearingPtrHashKey
59 : * nsVoidPtrHashKey
60 : * nsClearingVoidPtrHashKey
61 : * nsISupportsHashKey
62 : * nsIDHashKey
63 : * nsDepCharHashKey
64 : * nsCharPtrHashKey
65 : * nsUnicharPtrHashKey
66 : * nsHashableHashKey
67 : * nsGenericHashKey
68 : */
69 :
70 : /**
71 : * hashkey wrapper using nsAString KeyType
72 : *
73 : * @see nsTHashtable::EntryType for specification
74 : */
75 : class nsStringHashKey : public PLDHashEntryHdr
76 : {
77 : public:
78 : typedef const nsAString& KeyType;
79 : typedef const nsAString* KeyTypePointer;
80 :
81 5878 : explicit nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) {}
82 0 : nsStringHashKey(const nsStringHashKey& aToCopy) : mStr(aToCopy.mStr) {}
83 1059 : ~nsStringHashKey() {}
84 :
85 285 : KeyType GetKey() const { return mStr; }
86 8571 : bool KeyEquals(const KeyTypePointer aKey) const
87 : {
88 8571 : return mStr.Equals(*aKey);
89 : }
90 :
91 16941 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
92 16727 : static PLDHashNumber HashKey(const KeyTypePointer aKey)
93 : {
94 16727 : return mozilla::HashString(*aKey);
95 : }
96 :
97 : #ifdef MOZILLA_INTERNAL_API
98 : // To avoid double-counting, only measure the string if it is unshared.
99 0 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
100 : {
101 0 : return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
102 : }
103 : #endif
104 :
105 : enum { ALLOW_MEMMOVE = true };
106 :
107 : private:
108 : const nsString mStr;
109 : };
110 :
111 : #ifdef MOZILLA_INTERNAL_API
112 :
113 : /**
114 : * hashkey wrapper using nsAString KeyType
115 : *
116 : * This is internal-API only because nsCaseInsensitiveStringComparator is
117 : * internal-only.
118 : *
119 : * @see nsTHashtable::EntryType for specification
120 : */
121 : class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr
122 : {
123 : public:
124 : typedef const nsAString& KeyType;
125 : typedef const nsAString* KeyTypePointer;
126 :
127 0 : explicit nsStringCaseInsensitiveHashKey(KeyTypePointer aStr)
128 0 : : mStr(*aStr)
129 : {
130 : // take it easy just deal HashKey
131 0 : }
132 : nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& aToCopy)
133 : : mStr(aToCopy.mStr)
134 : {
135 : }
136 0 : ~nsStringCaseInsensitiveHashKey() {}
137 :
138 : KeyType GetKey() const { return mStr; }
139 0 : bool KeyEquals(const KeyTypePointer aKey) const
140 : {
141 0 : return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator());
142 : }
143 :
144 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
145 0 : static PLDHashNumber HashKey(const KeyTypePointer aKey)
146 : {
147 0 : nsAutoString tmKey(*aKey);
148 0 : ToLowerCase(tmKey);
149 0 : return mozilla::HashString(tmKey);
150 : }
151 : enum { ALLOW_MEMMOVE = true };
152 :
153 : // To avoid double-counting, only measure the string if it is unshared.
154 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
155 : {
156 : return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
157 : }
158 :
159 : private:
160 : const nsString mStr;
161 : };
162 :
163 : #endif
164 :
165 : /**
166 : * hashkey wrapper using nsACString KeyType
167 : *
168 : * @see nsTHashtable::EntryType for specification
169 : */
170 : class nsCStringHashKey : public PLDHashEntryHdr
171 : {
172 : public:
173 : typedef const nsACString& KeyType;
174 : typedef const nsACString* KeyTypePointer;
175 :
176 6036 : explicit nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) {}
177 0 : nsCStringHashKey(const nsCStringHashKey& aToCopy) : mStr(aToCopy.mStr) {}
178 225 : ~nsCStringHashKey() {}
179 :
180 2685 : KeyType GetKey() const { return mStr; }
181 14837 : bool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
182 :
183 22660 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
184 22471 : static PLDHashNumber HashKey(KeyTypePointer aKey)
185 : {
186 22471 : return mozilla::HashString(*aKey);
187 : }
188 :
189 : #ifdef MOZILLA_INTERNAL_API
190 : // To avoid double-counting, only measure the string if it is unshared.
191 0 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
192 : {
193 0 : return GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
194 : }
195 : #endif
196 :
197 : enum { ALLOW_MEMMOVE = true };
198 :
199 : private:
200 : const nsCString mStr;
201 : };
202 :
203 : /**
204 : * hashkey wrapper using uint32_t KeyType
205 : *
206 : * @see nsTHashtable::EntryType for specification
207 : */
208 : class nsUint32HashKey : public PLDHashEntryHdr
209 : {
210 : public:
211 : typedef const uint32_t& KeyType;
212 : typedef const uint32_t* KeyTypePointer;
213 :
214 576 : explicit nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) {}
215 0 : nsUint32HashKey(const nsUint32HashKey& aToCopy) : mValue(aToCopy.mValue) {}
216 27 : ~nsUint32HashKey() {}
217 :
218 268 : KeyType GetKey() const { return mValue; }
219 921 : bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
220 :
221 1906 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
222 1757 : static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; }
223 : enum { ALLOW_MEMMOVE = true };
224 :
225 : private:
226 : const uint32_t mValue;
227 : };
228 :
229 : /**
230 : * hashkey wrapper using uint64_t KeyType
231 : *
232 : * @see nsTHashtable::EntryType for specification
233 : */
234 : class nsUint64HashKey : public PLDHashEntryHdr
235 : {
236 : public:
237 : typedef const uint64_t& KeyType;
238 : typedef const uint64_t* KeyTypePointer;
239 :
240 153 : explicit nsUint64HashKey(KeyTypePointer aKey) : mValue(*aKey) {}
241 0 : nsUint64HashKey(const nsUint64HashKey& aToCopy) : mValue(aToCopy.mValue) {}
242 70 : ~nsUint64HashKey() {}
243 :
244 0 : KeyType GetKey() const { return mValue; }
245 457 : bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
246 :
247 1773 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
248 1222 : static PLDHashNumber HashKey(KeyTypePointer aKey)
249 : {
250 1222 : return PLDHashNumber(*aKey);
251 : }
252 : enum { ALLOW_MEMMOVE = true };
253 :
254 : private:
255 : const uint64_t mValue;
256 : };
257 :
258 : /**
259 : * hashkey wrapper using float KeyType
260 : *
261 : * @see nsTHashtable::EntryType for specification
262 : */
263 : class nsFloatHashKey : public PLDHashEntryHdr
264 : {
265 : public:
266 : typedef const float& KeyType;
267 : typedef const float* KeyTypePointer;
268 :
269 0 : explicit nsFloatHashKey(KeyTypePointer aKey) : mValue(*aKey) {}
270 : nsFloatHashKey(const nsFloatHashKey& aToCopy) : mValue(aToCopy.mValue) {}
271 0 : ~nsFloatHashKey() {}
272 :
273 : KeyType GetKey() const { return mValue; }
274 0 : bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
275 :
276 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
277 0 : static PLDHashNumber HashKey(KeyTypePointer aKey)
278 : {
279 0 : return *reinterpret_cast<const uint32_t*>(aKey);
280 : }
281 : enum { ALLOW_MEMMOVE = true };
282 :
283 : private:
284 : const float mValue;
285 : };
286 :
287 : /**
288 : * hashkey wrapper using nsISupports* KeyType
289 : *
290 : * @see nsTHashtable::EntryType for specification
291 : */
292 : class nsISupportsHashKey : public PLDHashEntryHdr
293 : {
294 : public:
295 : typedef nsISupports* KeyType;
296 : typedef const nsISupports* KeyTypePointer;
297 :
298 1293 : explicit nsISupportsHashKey(const nsISupports* aKey)
299 1293 : : mSupports(const_cast<nsISupports*>(aKey))
300 : {
301 1293 : }
302 : nsISupportsHashKey(const nsISupportsHashKey& aToCopy)
303 : : mSupports(aToCopy.mSupports)
304 : {
305 : }
306 167 : ~nsISupportsHashKey() {}
307 :
308 69 : KeyType GetKey() const { return mSupports; }
309 2448 : bool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; }
310 :
311 5596 : static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
312 5481 : static PLDHashNumber HashKey(KeyTypePointer aKey)
313 : {
314 5481 : return NS_PTR_TO_UINT32(aKey) >> 2;
315 : }
316 : enum { ALLOW_MEMMOVE = true };
317 :
318 : private:
319 : nsCOMPtr<nsISupports> mSupports;
320 : };
321 :
322 : /**
323 : * hashkey wrapper using refcounted * KeyType
324 : *
325 : * @see nsTHashtable::EntryType for specification
326 : */
327 : template<class T>
328 : class nsRefPtrHashKey : public PLDHashEntryHdr
329 : {
330 : public:
331 : typedef T* KeyType;
332 : typedef const T* KeyTypePointer;
333 :
334 854 : explicit nsRefPtrHashKey(const T* aKey) : mKey(const_cast<T*>(aKey)) {}
335 6 : nsRefPtrHashKey(const nsRefPtrHashKey& aToCopy) : mKey(aToCopy.mKey) {}
336 362 : ~nsRefPtrHashKey() {}
337 :
338 2825 : KeyType GetKey() const { return mKey; }
339 571 : bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
340 :
341 1684 : static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
342 1661 : static PLDHashNumber HashKey(KeyTypePointer aKey)
343 : {
344 1661 : return NS_PTR_TO_UINT32(aKey) >> 2;
345 : }
346 : enum { ALLOW_MEMMOVE = true };
347 :
348 : private:
349 : RefPtr<T> mKey;
350 : };
351 :
352 : template<class T>
353 : inline void
354 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
355 : nsRefPtrHashKey<T>& aField,
356 : const char* aName,
357 : uint32_t aFlags = 0)
358 : {
359 0 : CycleCollectionNoteChild(aCallback, aField.GetKey(), aName, aFlags);
360 0 : }
361 :
362 : /**
363 : * hashkey wrapper using T* KeyType that sets key to nullptr upon
364 : * destruction. Relevant only in cases where a memory pointer-scanner
365 : * like valgrind might get confused about stale references.
366 : *
367 : * @see nsTHashtable::EntryType for specification
368 : */
369 :
370 : template<class T>
371 : class nsClearingPtrHashKey : public nsPtrHashKey<T>
372 : {
373 : public:
374 0 : explicit nsClearingPtrHashKey(const T* aKey) : nsPtrHashKey<T>(aKey) {}
375 : nsClearingPtrHashKey(const nsClearingPtrHashKey<T>& aToCopy)
376 : : nsPtrHashKey<T>(aToCopy)
377 : {
378 : }
379 0 : ~nsClearingPtrHashKey() { nsPtrHashKey<T>::mKey = nullptr; }
380 : };
381 :
382 : typedef nsClearingPtrHashKey<const void> nsClearingVoidPtrHashKey;
383 :
384 : /**
385 : * hashkey wrapper using a function pointer KeyType
386 : *
387 : * @see nsTHashtable::EntryType for specification
388 : */
389 : template<class T>
390 : class nsFuncPtrHashKey : public PLDHashEntryHdr
391 : {
392 : public:
393 : typedef T& KeyType;
394 : typedef const T* KeyTypePointer;
395 :
396 1 : explicit nsFuncPtrHashKey(const T* aKey) : mKey(*const_cast<T*>(aKey)) {}
397 : nsFuncPtrHashKey(const nsFuncPtrHashKey<T>& aToCopy) : mKey(aToCopy.mKey) {}
398 0 : ~nsFuncPtrHashKey() {}
399 :
400 0 : KeyType GetKey() const { return const_cast<T&>(mKey); }
401 57 : bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; }
402 :
403 58 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
404 58 : static PLDHashNumber HashKey(KeyTypePointer aKey)
405 : {
406 58 : return NS_PTR_TO_UINT32(*aKey) >> 2;
407 : }
408 : enum { ALLOW_MEMMOVE = true };
409 :
410 : protected:
411 : T mKey;
412 : };
413 :
414 : /**
415 : * hashkey wrapper using nsID KeyType
416 : *
417 : * @see nsTHashtable::EntryType for specification
418 : */
419 : class nsIDHashKey : public PLDHashEntryHdr
420 : {
421 : public:
422 : typedef const nsID& KeyType;
423 : typedef const nsID* KeyTypePointer;
424 :
425 5944 : explicit nsIDHashKey(const nsID* aInID) : mID(*aInID) {}
426 0 : nsIDHashKey(const nsIDHashKey& aToCopy) : mID(aToCopy.mID) {}
427 0 : ~nsIDHashKey() {}
428 :
429 0 : KeyType GetKey() const { return mID; }
430 4808 : bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); }
431 :
432 15987 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
433 15984 : static PLDHashNumber HashKey(KeyTypePointer aKey)
434 : {
435 : // Hash the nsID object's raw bytes.
436 15984 : return mozilla::HashBytes(aKey, sizeof(KeyType));
437 : }
438 :
439 : enum { ALLOW_MEMMOVE = true };
440 :
441 : private:
442 : const nsID mID;
443 : };
444 :
445 : /**
446 : * hashkey wrapper for "dependent" const char*; this class does not "own"
447 : * its string pointer.
448 : *
449 : * This class must only be used if the strings have a lifetime longer than
450 : * the hashtable they occupy. This normally occurs only for static
451 : * strings or strings that have been arena-allocated.
452 : *
453 : * @see nsTHashtable::EntryType for specification
454 : */
455 : class nsDepCharHashKey : public PLDHashEntryHdr
456 : {
457 : public:
458 : typedef const char* KeyType;
459 : typedef const char* KeyTypePointer;
460 :
461 9768 : explicit nsDepCharHashKey(const char* aKey) : mKey(aKey) {}
462 : nsDepCharHashKey(const nsDepCharHashKey& aToCopy) : mKey(aToCopy.mKey) {}
463 3 : ~nsDepCharHashKey() {}
464 :
465 77 : const char* GetKey() const { return mKey; }
466 1649 : bool KeyEquals(const char* aKey) const { return !strcmp(mKey, aKey); }
467 :
468 12065 : static const char* KeyToPointer(const char* aKey) { return aKey; }
469 11962 : static PLDHashNumber HashKey(const char* aKey)
470 : {
471 11962 : return mozilla::HashString(aKey);
472 : }
473 : enum { ALLOW_MEMMOVE = true };
474 :
475 : private:
476 : const char* mKey;
477 : };
478 :
479 : /**
480 : * hashkey wrapper for const char*; at construction, this class duplicates
481 : * a string pointed to by the pointer so that it doesn't matter whether or not
482 : * the string lives longer than the hash table.
483 : */
484 : class nsCharPtrHashKey : public PLDHashEntryHdr
485 : {
486 : public:
487 : typedef const char* KeyType;
488 : typedef const char* KeyTypePointer;
489 :
490 693 : explicit nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) {}
491 : nsCharPtrHashKey(const nsCharPtrHashKey& aToCopy)
492 : : mKey(strdup(aToCopy.mKey))
493 : {
494 : }
495 :
496 : nsCharPtrHashKey(nsCharPtrHashKey&& aOther)
497 : : mKey(aOther.mKey)
498 : {
499 : aOther.mKey = nullptr;
500 : }
501 :
502 123 : ~nsCharPtrHashKey()
503 123 : {
504 123 : if (mKey) {
505 123 : free(const_cast<char*>(mKey));
506 : }
507 123 : }
508 :
509 0 : const char* GetKey() const { return mKey; }
510 1194 : bool KeyEquals(KeyTypePointer aKey) const { return !strcmp(mKey, aKey); }
511 :
512 2628 : static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
513 2625 : static PLDHashNumber HashKey(KeyTypePointer aKey)
514 : {
515 2625 : return mozilla::HashString(aKey);
516 : }
517 :
518 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
519 : {
520 : return aMallocSizeOf(mKey);
521 : }
522 :
523 : enum { ALLOW_MEMMOVE = true };
524 :
525 : private:
526 : const char* mKey;
527 : };
528 :
529 : /**
530 : * hashkey wrapper for const char16_t*; at construction, this class duplicates
531 : * a string pointed to by the pointer so that it doesn't matter whether or not
532 : * the string lives longer than the hash table.
533 : */
534 : class nsUnicharPtrHashKey : public PLDHashEntryHdr
535 : {
536 : public:
537 : typedef const char16_t* KeyType;
538 : typedef const char16_t* KeyTypePointer;
539 :
540 0 : explicit nsUnicharPtrHashKey(const char16_t* aKey) : mKey(NS_strdup(aKey)) {}
541 : nsUnicharPtrHashKey(const nsUnicharPtrHashKey& aToCopy)
542 : : mKey(NS_strdup(aToCopy.mKey))
543 : {
544 : }
545 :
546 : nsUnicharPtrHashKey(nsUnicharPtrHashKey&& aOther)
547 : : mKey(aOther.mKey)
548 : {
549 : aOther.mKey = nullptr;
550 : }
551 :
552 0 : ~nsUnicharPtrHashKey()
553 0 : {
554 0 : if (mKey) {
555 0 : NS_Free(const_cast<char16_t*>(mKey));
556 : }
557 0 : }
558 :
559 0 : const char16_t* GetKey() const { return mKey; }
560 0 : bool KeyEquals(KeyTypePointer aKey) const { return !NS_strcmp(mKey, aKey); }
561 :
562 0 : static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
563 0 : static PLDHashNumber HashKey(KeyTypePointer aKey)
564 : {
565 0 : return mozilla::HashString(aKey);
566 : }
567 :
568 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
569 : {
570 : return aMallocSizeOf(mKey);
571 : }
572 :
573 : enum { ALLOW_MEMMOVE = true };
574 :
575 : private:
576 : const char16_t* mKey;
577 : };
578 :
579 : /**
580 : * Hashtable key class to use with objects that support nsIHashable
581 : */
582 : class nsHashableHashKey : public PLDHashEntryHdr
583 : {
584 : public:
585 : typedef nsIHashable* KeyType;
586 : typedef const nsIHashable* KeyTypePointer;
587 :
588 : explicit nsHashableHashKey(const nsIHashable* aKey)
589 : : mKey(const_cast<nsIHashable*>(aKey))
590 : {
591 : }
592 : nsHashableHashKey(const nsHashableHashKey& aToCopy) : mKey(aToCopy.mKey) {}
593 : ~nsHashableHashKey() {}
594 :
595 : nsIHashable* GetKey() const { return mKey; }
596 :
597 : bool KeyEquals(const nsIHashable* aKey) const
598 : {
599 : bool eq;
600 : if (NS_SUCCEEDED(mKey->Equals(const_cast<nsIHashable*>(aKey), &eq))) {
601 : return eq;
602 : }
603 : return false;
604 : }
605 :
606 : static const nsIHashable* KeyToPointer(nsIHashable* aKey) { return aKey; }
607 : static PLDHashNumber HashKey(const nsIHashable* aKey)
608 : {
609 : uint32_t code = 8888; // magic number if GetHashCode fails :-(
610 : #ifdef DEBUG
611 : nsresult rv =
612 : #endif
613 : const_cast<nsIHashable*>(aKey)->GetHashCode(&code);
614 : NS_ASSERTION(NS_SUCCEEDED(rv), "GetHashCode should not throw!");
615 : return code;
616 : }
617 :
618 : enum { ALLOW_MEMMOVE = true };
619 :
620 : private:
621 : nsCOMPtr<nsIHashable> mKey;
622 : };
623 :
624 : namespace mozilla {
625 :
626 : template <typename T>
627 : PLDHashNumber
628 382 : Hash(const T& aValue)
629 : {
630 382 : return aValue.Hash();
631 : }
632 :
633 : } // namespace mozilla
634 :
635 : /**
636 : * Hashtable key class to use with objects for which Hash() and operator==()
637 : * are defined.
638 : */
639 : template<typename T>
640 15 : class nsGenericHashKey : public PLDHashEntryHdr
641 : {
642 : public:
643 : typedef const T& KeyType;
644 : typedef const T* KeyTypePointer;
645 :
646 87 : explicit nsGenericHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
647 : nsGenericHashKey(const nsGenericHashKey<T>& aOther) : mKey(aOther.mKey) {}
648 :
649 0 : KeyType GetKey() const { return mKey; }
650 217 : bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; }
651 :
652 450 : static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
653 382 : static PLDHashNumber HashKey(KeyTypePointer aKey) { return ::mozilla::Hash(*aKey); }
654 : enum { ALLOW_MEMMOVE = true };
655 :
656 : private:
657 : T mKey;
658 : };
659 :
660 : #endif // nsTHashKeys_h__
|