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