1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/glue/nsHashKeys.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,614 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsTHashKeys_h__ 1.10 +#define nsTHashKeys_h__ 1.11 + 1.12 +#include "nsID.h" 1.13 +#include "nsISupports.h" 1.14 +#include "nsIHashable.h" 1.15 +#include "nsAutoPtr.h" 1.16 +#include "nsCOMPtr.h" 1.17 +#include "pldhash.h" 1.18 +#include <new> 1.19 + 1.20 +#include "nsStringGlue.h" 1.21 +#include "nsCRTGlue.h" 1.22 +#include "nsUnicharUtils.h" 1.23 + 1.24 +#include <stdlib.h> 1.25 +#include <string.h> 1.26 + 1.27 +#include "mozilla/HashFunctions.h" 1.28 +#include "mozilla/Move.h" 1.29 + 1.30 +namespace mozilla { 1.31 + 1.32 +// These are defined analogously to the HashString overloads in mfbt. 1.33 + 1.34 +inline uint32_t 1.35 +HashString(const nsAString& aStr) 1.36 +{ 1.37 + return HashString(aStr.BeginReading(), aStr.Length()); 1.38 +} 1.39 + 1.40 +inline uint32_t 1.41 +HashString(const nsACString& aStr) 1.42 +{ 1.43 + return HashString(aStr.BeginReading(), aStr.Length()); 1.44 +} 1.45 + 1.46 +} // namespace mozilla 1.47 + 1.48 +/** @file nsHashKeys.h 1.49 + * standard HashKey classes for nsBaseHashtable and relatives. Each of these 1.50 + * classes follows the nsTHashtable::EntryType specification 1.51 + * 1.52 + * Lightweight keytypes provided here: 1.53 + * nsStringHashKey 1.54 + * nsCStringHashKey 1.55 + * nsUint32HashKey 1.56 + * nsUint64HashKey 1.57 + * nsFloatHashKey 1.58 + * nsPtrHashkey 1.59 + * nsClearingPtrHashKey 1.60 + * nsVoidPtrHashKey 1.61 + * nsClearingVoidPtrHashKey 1.62 + * nsISupportsHashKey 1.63 + * nsIDHashKey 1.64 + * nsDepCharHashKey 1.65 + * nsCharPtrHashKey 1.66 + * nsUnicharPtrHashKey 1.67 + * nsHashableHashKey 1.68 + * nsGenericHashKey 1.69 + */ 1.70 + 1.71 +/** 1.72 + * hashkey wrapper using nsAString KeyType 1.73 + * 1.74 + * @see nsTHashtable::EntryType for specification 1.75 + */ 1.76 +class nsStringHashKey : public PLDHashEntryHdr 1.77 +{ 1.78 +public: 1.79 + typedef const nsAString& KeyType; 1.80 + typedef const nsAString* KeyTypePointer; 1.81 + 1.82 + nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) { } 1.83 + nsStringHashKey(const nsStringHashKey& toCopy) : mStr(toCopy.mStr) { } 1.84 + ~nsStringHashKey() { } 1.85 + 1.86 + KeyType GetKey() const { return mStr; } 1.87 + bool KeyEquals(const KeyTypePointer aKey) const 1.88 + { 1.89 + return mStr.Equals(*aKey); 1.90 + } 1.91 + 1.92 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.93 + static PLDHashNumber HashKey(const KeyTypePointer aKey) 1.94 + { 1.95 + return mozilla::HashString(*aKey); 1.96 + } 1.97 + enum { ALLOW_MEMMOVE = true }; 1.98 + 1.99 +private: 1.100 + const nsString mStr; 1.101 +}; 1.102 + 1.103 +#ifdef MOZILLA_INTERNAL_API 1.104 + 1.105 +/** 1.106 + * hashkey wrapper using nsAString KeyType 1.107 + * 1.108 + * This is internal-API only because nsCaseInsensitiveStringComparator is 1.109 + * internal-only. 1.110 + * 1.111 + * @see nsTHashtable::EntryType for specification 1.112 + */ 1.113 +class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr 1.114 +{ 1.115 +public: 1.116 + typedef const nsAString& KeyType; 1.117 + typedef const nsAString* KeyTypePointer; 1.118 + 1.119 + nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey 1.120 + nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { } 1.121 + ~nsStringCaseInsensitiveHashKey() { } 1.122 + 1.123 + KeyType GetKey() const { return mStr; } 1.124 + bool KeyEquals(const KeyTypePointer aKey) const 1.125 + { 1.126 + return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator()); 1.127 + } 1.128 + 1.129 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.130 + static PLDHashNumber HashKey(const KeyTypePointer aKey) 1.131 + { 1.132 + nsAutoString tmKey(*aKey); 1.133 + ToLowerCase(tmKey); 1.134 + return mozilla::HashString(tmKey); 1.135 + } 1.136 + enum { ALLOW_MEMMOVE = true }; 1.137 + 1.138 +private: 1.139 + const nsString mStr; 1.140 +}; 1.141 + 1.142 +#endif 1.143 + 1.144 +/** 1.145 + * hashkey wrapper using nsACString KeyType 1.146 + * 1.147 + * @see nsTHashtable::EntryType for specification 1.148 + */ 1.149 +class nsCStringHashKey : public PLDHashEntryHdr 1.150 +{ 1.151 +public: 1.152 + typedef const nsACString& KeyType; 1.153 + typedef const nsACString* KeyTypePointer; 1.154 + 1.155 + nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) { } 1.156 + nsCStringHashKey(const nsCStringHashKey& toCopy) : mStr(toCopy.mStr) { } 1.157 + ~nsCStringHashKey() { } 1.158 + 1.159 + KeyType GetKey() const { return mStr; } 1.160 + 1.161 + bool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); } 1.162 + 1.163 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.164 + static PLDHashNumber HashKey(KeyTypePointer aKey) 1.165 + { 1.166 + return mozilla::HashString(*aKey); 1.167 + } 1.168 + enum { ALLOW_MEMMOVE = true }; 1.169 + 1.170 +private: 1.171 + const nsCString mStr; 1.172 +}; 1.173 + 1.174 +/** 1.175 + * hashkey wrapper using uint32_t KeyType 1.176 + * 1.177 + * @see nsTHashtable::EntryType for specification 1.178 + */ 1.179 +class nsUint32HashKey : public PLDHashEntryHdr 1.180 +{ 1.181 +public: 1.182 + typedef const uint32_t& KeyType; 1.183 + typedef const uint32_t* KeyTypePointer; 1.184 + 1.185 + nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) { } 1.186 + nsUint32HashKey(const nsUint32HashKey& toCopy) : mValue(toCopy.mValue) { } 1.187 + ~nsUint32HashKey() { } 1.188 + 1.189 + KeyType GetKey() const { return mValue; } 1.190 + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } 1.191 + 1.192 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.193 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } 1.194 + enum { ALLOW_MEMMOVE = true }; 1.195 + 1.196 +private: 1.197 + const uint32_t mValue; 1.198 +}; 1.199 + 1.200 +/** 1.201 + * hashkey wrapper using uint64_t KeyType 1.202 + * 1.203 + * @see nsTHashtable::EntryType for specification 1.204 + */ 1.205 +class nsUint64HashKey : public PLDHashEntryHdr 1.206 +{ 1.207 +public: 1.208 + typedef const uint64_t& KeyType; 1.209 + typedef const uint64_t* KeyTypePointer; 1.210 + 1.211 + nsUint64HashKey(KeyTypePointer aKey) : mValue(*aKey) { } 1.212 + nsUint64HashKey(const nsUint64HashKey& toCopy) : mValue(toCopy.mValue) { } 1.213 + ~nsUint64HashKey() { } 1.214 + 1.215 + KeyType GetKey() const { return mValue; } 1.216 + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } 1.217 + 1.218 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.219 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return PLDHashNumber(*aKey); } 1.220 + enum { ALLOW_MEMMOVE = true }; 1.221 + 1.222 +private: 1.223 + const uint64_t mValue; 1.224 +}; 1.225 + 1.226 +/** 1.227 + * hashkey wrapper using float KeyType 1.228 + * 1.229 + * @see nsTHashtable::EntryType for specification 1.230 + */ 1.231 +class nsFloatHashKey : public PLDHashEntryHdr 1.232 +{ 1.233 +public: 1.234 + typedef const float& KeyType; 1.235 + typedef const float* KeyTypePointer; 1.236 + 1.237 + nsFloatHashKey(KeyTypePointer aKey) : mValue(*aKey) { } 1.238 + nsFloatHashKey(const nsFloatHashKey& toCopy) : mValue(toCopy.mValue) { } 1.239 + ~nsFloatHashKey() { } 1.240 + 1.241 + KeyType GetKey() const { return mValue; } 1.242 + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } 1.243 + 1.244 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.245 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return *reinterpret_cast<const uint32_t*>(aKey); } 1.246 + enum { ALLOW_MEMMOVE = true }; 1.247 + 1.248 +private: 1.249 + const float mValue; 1.250 +}; 1.251 + 1.252 +/** 1.253 + * hashkey wrapper using nsISupports* KeyType 1.254 + * 1.255 + * @see nsTHashtable::EntryType for specification 1.256 + */ 1.257 +class nsISupportsHashKey : public PLDHashEntryHdr 1.258 +{ 1.259 +public: 1.260 + typedef nsISupports* KeyType; 1.261 + typedef const nsISupports* KeyTypePointer; 1.262 + 1.263 + nsISupportsHashKey(const nsISupports* key) : 1.264 + mSupports(const_cast<nsISupports*>(key)) { } 1.265 + nsISupportsHashKey(const nsISupportsHashKey& toCopy) : 1.266 + mSupports(toCopy.mSupports) { } 1.267 + ~nsISupportsHashKey() { } 1.268 + 1.269 + KeyType GetKey() const { return mSupports; } 1.270 + 1.271 + bool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; } 1.272 + 1.273 + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } 1.274 + static PLDHashNumber HashKey(KeyTypePointer aKey) 1.275 + { 1.276 + return NS_PTR_TO_INT32(aKey) >>2; 1.277 + } 1.278 + enum { ALLOW_MEMMOVE = true }; 1.279 + 1.280 +private: 1.281 + nsCOMPtr<nsISupports> mSupports; 1.282 +}; 1.283 + 1.284 +/** 1.285 + * hashkey wrapper using refcounted * KeyType 1.286 + * 1.287 + * @see nsTHashtable::EntryType for specification 1.288 + */ 1.289 +template<class T> 1.290 +class nsRefPtrHashKey : public PLDHashEntryHdr 1.291 +{ 1.292 +public: 1.293 + typedef T* KeyType; 1.294 + typedef const T* KeyTypePointer; 1.295 + 1.296 + nsRefPtrHashKey(const T* key) : 1.297 + mKey(const_cast<T*>(key)) { } 1.298 + nsRefPtrHashKey(const nsRefPtrHashKey& toCopy) : 1.299 + mKey(toCopy.mKey) { } 1.300 + ~nsRefPtrHashKey() { } 1.301 + 1.302 + KeyType GetKey() const { return mKey; } 1.303 + 1.304 + bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; } 1.305 + 1.306 + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } 1.307 + static PLDHashNumber HashKey(KeyTypePointer aKey) 1.308 + { 1.309 + return NS_PTR_TO_INT32(aKey) >>2; 1.310 + } 1.311 + enum { ALLOW_MEMMOVE = true }; 1.312 + 1.313 +private: 1.314 + nsRefPtr<T> mKey; 1.315 +}; 1.316 + 1.317 +template <class T> 1.318 +inline void 1.319 +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, 1.320 + nsRefPtrHashKey<T>& aField, 1.321 + const char* aName, 1.322 + uint32_t aFlags = 0) 1.323 +{ 1.324 + CycleCollectionNoteChild(aCallback, aField.GetKey(), aName, aFlags); 1.325 +} 1.326 + 1.327 +/** 1.328 + * hashkey wrapper using T* KeyType 1.329 + * 1.330 + * @see nsTHashtable::EntryType for specification 1.331 + */ 1.332 +template<class T> 1.333 +class nsPtrHashKey : public PLDHashEntryHdr 1.334 +{ 1.335 + public: 1.336 + typedef T *KeyType; 1.337 + typedef const T *KeyTypePointer; 1.338 + 1.339 + nsPtrHashKey(const T *key) : mKey(const_cast<T*>(key)) {} 1.340 + nsPtrHashKey(const nsPtrHashKey<T> &toCopy) : mKey(toCopy.mKey) {} 1.341 + ~nsPtrHashKey() {} 1.342 + 1.343 + KeyType GetKey() const { return mKey; } 1.344 + 1.345 + bool KeyEquals(KeyTypePointer key) const { return key == mKey; } 1.346 + 1.347 + static KeyTypePointer KeyToPointer(KeyType key) { return key; } 1.348 + static PLDHashNumber HashKey(KeyTypePointer key) 1.349 + { 1.350 + return NS_PTR_TO_INT32(key) >> 2; 1.351 + } 1.352 + enum { ALLOW_MEMMOVE = true }; 1.353 + 1.354 + protected: 1.355 + T *mKey; 1.356 +}; 1.357 + 1.358 +/** 1.359 + * hashkey wrapper using T* KeyType that sets key to nullptr upon 1.360 + * destruction. Relevant only in cases where a memory pointer-scanner 1.361 + * like valgrind might get confused about stale references. 1.362 + * 1.363 + * @see nsTHashtable::EntryType for specification 1.364 + */ 1.365 + 1.366 +template<class T> 1.367 +class nsClearingPtrHashKey : public nsPtrHashKey<T> 1.368 +{ 1.369 + public: 1.370 + nsClearingPtrHashKey(const T *key) : nsPtrHashKey<T>(key) {} 1.371 + nsClearingPtrHashKey(const nsClearingPtrHashKey<T> &toCopy) : 1.372 + nsPtrHashKey<T>(toCopy) {} 1.373 + ~nsClearingPtrHashKey() { nsPtrHashKey<T>::mKey = nullptr; } 1.374 +}; 1.375 + 1.376 +typedef nsPtrHashKey<const void> nsVoidPtrHashKey; 1.377 +typedef nsClearingPtrHashKey<const void> nsClearingVoidPtrHashKey; 1.378 + 1.379 +/** 1.380 + * hashkey wrapper using a function pointer KeyType 1.381 + * 1.382 + * @see nsTHashtable::EntryType for specification 1.383 + */ 1.384 +template<class T> 1.385 +class nsFuncPtrHashKey : public PLDHashEntryHdr 1.386 +{ 1.387 + public: 1.388 + typedef T &KeyType; 1.389 + typedef const T *KeyTypePointer; 1.390 + 1.391 + nsFuncPtrHashKey(const T *key) : mKey(*const_cast<T*>(key)) {} 1.392 + nsFuncPtrHashKey(const nsFuncPtrHashKey<T> &toCopy) : mKey(toCopy.mKey) {} 1.393 + ~nsFuncPtrHashKey() {} 1.394 + 1.395 + KeyType GetKey() const { return const_cast<T&>(mKey); } 1.396 + 1.397 + bool KeyEquals(KeyTypePointer key) const { return *key == mKey; } 1.398 + 1.399 + static KeyTypePointer KeyToPointer(KeyType key) { return &key; } 1.400 + static PLDHashNumber HashKey(KeyTypePointer key) 1.401 + { 1.402 + return NS_PTR_TO_INT32(*key) >> 2; 1.403 + } 1.404 + enum { ALLOW_MEMMOVE = true }; 1.405 + 1.406 + protected: 1.407 + T mKey; 1.408 +}; 1.409 + 1.410 +/** 1.411 + * hashkey wrapper using nsID KeyType 1.412 + * 1.413 + * @see nsTHashtable::EntryType for specification 1.414 + */ 1.415 +class nsIDHashKey : public PLDHashEntryHdr 1.416 +{ 1.417 +public: 1.418 + typedef const nsID& KeyType; 1.419 + typedef const nsID* KeyTypePointer; 1.420 + 1.421 + nsIDHashKey(const nsID* inID) : mID(*inID) { } 1.422 + nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { } 1.423 + ~nsIDHashKey() { } 1.424 + 1.425 + KeyType GetKey() const { return mID; } 1.426 + 1.427 + bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); } 1.428 + 1.429 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.430 + static PLDHashNumber HashKey(KeyTypePointer aKey) 1.431 + { 1.432 + // Hash the nsID object's raw bytes. 1.433 + return mozilla::HashBytes(aKey, sizeof(KeyType)); 1.434 + } 1.435 + 1.436 + enum { ALLOW_MEMMOVE = true }; 1.437 + 1.438 +private: 1.439 + const nsID mID; 1.440 +}; 1.441 + 1.442 +/** 1.443 + * hashkey wrapper for "dependent" const char*; this class does not "own" 1.444 + * its string pointer. 1.445 + * 1.446 + * This class must only be used if the strings have a lifetime longer than 1.447 + * the hashtable they occupy. This normally occurs only for static 1.448 + * strings or strings that have been arena-allocated. 1.449 + * 1.450 + * @see nsTHashtable::EntryType for specification 1.451 + */ 1.452 +class nsDepCharHashKey : public PLDHashEntryHdr 1.453 +{ 1.454 +public: 1.455 + typedef const char* KeyType; 1.456 + typedef const char* KeyTypePointer; 1.457 + 1.458 + nsDepCharHashKey(const char* aKey) { mKey = aKey; } 1.459 + nsDepCharHashKey(const nsDepCharHashKey& toCopy) { mKey = toCopy.mKey; } 1.460 + ~nsDepCharHashKey() { } 1.461 + 1.462 + const char* GetKey() const { return mKey; } 1.463 + bool KeyEquals(const char* aKey) const 1.464 + { 1.465 + return !strcmp(mKey, aKey); 1.466 + } 1.467 + 1.468 + static const char* KeyToPointer(const char* aKey) { return aKey; } 1.469 + static PLDHashNumber HashKey(const char* aKey) { return mozilla::HashString(aKey); } 1.470 + enum { ALLOW_MEMMOVE = true }; 1.471 + 1.472 +private: 1.473 + const char* mKey; 1.474 +}; 1.475 + 1.476 +/** 1.477 + * hashkey wrapper for const char*; at construction, this class duplicates 1.478 + * a string pointed to by the pointer so that it doesn't matter whether or not 1.479 + * the string lives longer than the hash table. 1.480 + */ 1.481 +class nsCharPtrHashKey : public PLDHashEntryHdr 1.482 +{ 1.483 +public: 1.484 + typedef const char* KeyType; 1.485 + typedef const char* KeyTypePointer; 1.486 + 1.487 + nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { } 1.488 + nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { } 1.489 + 1.490 + nsCharPtrHashKey(nsCharPtrHashKey&& other) 1.491 + : mKey(other.mKey) 1.492 + { 1.493 + other.mKey = nullptr; 1.494 + } 1.495 + 1.496 + ~nsCharPtrHashKey() { if (mKey) free(const_cast<char *>(mKey)); } 1.497 + 1.498 + const char* GetKey() const { return mKey; } 1.499 + bool KeyEquals(KeyTypePointer aKey) const 1.500 + { 1.501 + return !strcmp(mKey, aKey); 1.502 + } 1.503 + 1.504 + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } 1.505 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); } 1.506 + 1.507 + enum { ALLOW_MEMMOVE = true }; 1.508 + 1.509 +private: 1.510 + const char* mKey; 1.511 +}; 1.512 + 1.513 +/** 1.514 + * hashkey wrapper for const char16_t*; at construction, this class duplicates 1.515 + * a string pointed to by the pointer so that it doesn't matter whether or not 1.516 + * the string lives longer than the hash table. 1.517 + */ 1.518 +class nsUnicharPtrHashKey : public PLDHashEntryHdr 1.519 +{ 1.520 +public: 1.521 + typedef const char16_t* KeyType; 1.522 + typedef const char16_t* KeyTypePointer; 1.523 + 1.524 + nsUnicharPtrHashKey(const char16_t* aKey) : mKey(NS_strdup(aKey)) { } 1.525 + nsUnicharPtrHashKey(const nsUnicharPtrHashKey& toCopy) : mKey(NS_strdup(toCopy.mKey)) { } 1.526 + 1.527 + nsUnicharPtrHashKey(nsUnicharPtrHashKey&& other) 1.528 + : mKey(other.mKey) 1.529 + { 1.530 + other.mKey = nullptr; 1.531 + } 1.532 + 1.533 + ~nsUnicharPtrHashKey() { if (mKey) NS_Free(const_cast<char16_t *>(mKey)); } 1.534 + 1.535 + const char16_t* GetKey() const { return mKey; } 1.536 + bool KeyEquals(KeyTypePointer aKey) const 1.537 + { 1.538 + return !NS_strcmp(mKey, aKey); 1.539 + } 1.540 + 1.541 + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } 1.542 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); } 1.543 + 1.544 + enum { ALLOW_MEMMOVE = true }; 1.545 + 1.546 +private: 1.547 + const char16_t* mKey; 1.548 +}; 1.549 + 1.550 +/** 1.551 + * Hashtable key class to use with objects that support nsIHashable 1.552 + */ 1.553 +class nsHashableHashKey : public PLDHashEntryHdr 1.554 +{ 1.555 +public: 1.556 + typedef nsIHashable* KeyType; 1.557 + typedef const nsIHashable* KeyTypePointer; 1.558 + 1.559 + nsHashableHashKey(const nsIHashable* aKey) : 1.560 + mKey(const_cast<nsIHashable*>(aKey)) { } 1.561 + nsHashableHashKey(const nsHashableHashKey& toCopy) : 1.562 + mKey(toCopy.mKey) { } 1.563 + ~nsHashableHashKey() { } 1.564 + 1.565 + nsIHashable* GetKey() const { return mKey; } 1.566 + 1.567 + bool KeyEquals(const nsIHashable* aKey) const { 1.568 + bool eq; 1.569 + if (NS_SUCCEEDED(mKey->Equals(const_cast<nsIHashable*>(aKey), &eq))) { 1.570 + return eq; 1.571 + } 1.572 + return false; 1.573 + } 1.574 + 1.575 + static const nsIHashable* KeyToPointer(nsIHashable* aKey) { return aKey; } 1.576 + static PLDHashNumber HashKey(const nsIHashable* aKey) { 1.577 + uint32_t code = 8888; // magic number if GetHashCode fails :-( 1.578 +#ifdef DEBUG 1.579 + nsresult rv = 1.580 +#endif 1.581 + const_cast<nsIHashable*>(aKey)->GetHashCode(&code); 1.582 + NS_ASSERTION(NS_SUCCEEDED(rv), "GetHashCode should not throw!"); 1.583 + return code; 1.584 + } 1.585 + 1.586 + enum { ALLOW_MEMMOVE = true }; 1.587 + 1.588 +private: 1.589 + nsCOMPtr<nsIHashable> mKey; 1.590 +}; 1.591 + 1.592 +/** 1.593 + * Hashtable key class to use with objects for which Hash() and operator==() 1.594 + * are defined. 1.595 + */ 1.596 +template <typename T> 1.597 +class nsGenericHashKey : public PLDHashEntryHdr 1.598 +{ 1.599 +public: 1.600 + typedef const T& KeyType; 1.601 + typedef const T* KeyTypePointer; 1.602 + 1.603 + nsGenericHashKey(KeyTypePointer aKey) : mKey(*aKey) { } 1.604 + nsGenericHashKey(const nsGenericHashKey<T>& aOther) : mKey(aOther.mKey) { } 1.605 + 1.606 + KeyType GetKey() const { return mKey; } 1.607 + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; } 1.608 + 1.609 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.610 + static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); } 1.611 + enum { ALLOW_MEMMOVE = true }; 1.612 + 1.613 +private: 1.614 + T mKey; 1.615 +}; 1.616 + 1.617 +#endif // nsTHashKeys_h__