xpcom/glue/nsHashKeys.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial