Coverage Report

Created: 2018-09-25 14:53

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