nsHashKeys.h 16 KB

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