1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is C++ hashtable templates.
17 * The Initial Developer of the Original Code is
19 * Portions created by the Initial Developer are Copyright (C) 2002
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsTHashKeys_h__
39 #define nsTHashKeys_h__
42 #include "nsISupports.h"
43 #include "nsIHashable.h"
48 #include "nsStringGlue.h"
49 #include "nsCRTGlue.h"
54 /** @file nsHashKeys.h
55 * standard HashKey classes for nsBaseHashtable and relatives. Each of these
56 * classes follows the nsTHashtable::EntryType specification
58 * Lightweight keytypes provided here:
64 * nsClearingPtrHashKey
66 * nsClearingVoidPtrHashKey
75 NS_COM_GLUE PRUint32
HashString(const nsAString
& aStr
);
76 NS_COM_GLUE PRUint32
HashString(const nsACString
& aStr
);
77 NS_COM_GLUE PRUint32
HashString(const char* aKey
);
78 NS_COM_GLUE PRUint32
HashString(const PRUnichar
* aKey
);
81 * hashkey wrapper using nsAString KeyType
83 * @see nsTHashtable::EntryType for specification
85 class nsStringHashKey
: public PLDHashEntryHdr
88 typedef const nsAString
& KeyType
;
89 typedef const nsAString
* KeyTypePointer
;
91 nsStringHashKey(KeyTypePointer aStr
) : mStr(*aStr
) { }
92 nsStringHashKey(const nsStringHashKey
& toCopy
) : mStr(toCopy
.mStr
) { }
93 ~nsStringHashKey() { }
95 KeyType
GetKey() const { return mStr
; }
96 PRBool
KeyEquals(const KeyTypePointer aKey
) const
98 return mStr
.Equals(*aKey
);
101 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
102 static PLDHashNumber
HashKey(const KeyTypePointer aKey
)
104 return HashString(*aKey
);
106 enum { ALLOW_MEMMOVE
= PR_TRUE
};
113 * hashkey wrapper using nsACString KeyType
115 * @see nsTHashtable::EntryType for specification
117 class nsCStringHashKey
: public PLDHashEntryHdr
120 typedef const nsACString
& KeyType
;
121 typedef const nsACString
* KeyTypePointer
;
123 nsCStringHashKey(const nsACString
* aStr
) : mStr(*aStr
) { }
124 nsCStringHashKey(const nsCStringHashKey
& toCopy
) : mStr(toCopy
.mStr
) { }
125 ~nsCStringHashKey() { }
127 KeyType
GetKey() const { return mStr
; }
129 PRBool
KeyEquals(KeyTypePointer aKey
) const { return mStr
.Equals(*aKey
); }
131 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
132 static PLDHashNumber
HashKey(KeyTypePointer aKey
)
134 return HashString(*aKey
);
136 enum { ALLOW_MEMMOVE
= PR_TRUE
};
139 const nsCString mStr
;
143 * hashkey wrapper using PRUint32 KeyType
145 * @see nsTHashtable::EntryType for specification
147 class nsUint32HashKey
: public PLDHashEntryHdr
150 typedef const PRUint32
& KeyType
;
151 typedef const PRUint32
* KeyTypePointer
;
153 nsUint32HashKey(KeyTypePointer aKey
) : mValue(*aKey
) { }
154 nsUint32HashKey(const nsUint32HashKey
& toCopy
) : mValue(toCopy
.mValue
) { }
155 ~nsUint32HashKey() { }
157 KeyType
GetKey() const { return mValue
; }
158 PRBool
KeyEquals(KeyTypePointer aKey
) const { return *aKey
== mValue
; }
160 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
161 static PLDHashNumber
HashKey(KeyTypePointer aKey
) { return *aKey
; }
162 enum { ALLOW_MEMMOVE
= PR_TRUE
};
165 const PRUint32 mValue
;
169 * hashkey wrapper using PRUint64 KeyType
171 * @see nsTHashtable::EntryType for specification
173 class nsUint64HashKey
: public PLDHashEntryHdr
176 typedef const PRUint64
& KeyType
;
177 typedef const PRUint64
* KeyTypePointer
;
179 nsUint64HashKey(KeyTypePointer aKey
) : mValue(*aKey
) { }
180 nsUint64HashKey(const nsUint64HashKey
& toCopy
) : mValue(toCopy
.mValue
) { }
181 ~nsUint64HashKey() { }
183 KeyType
GetKey() const { return mValue
; }
184 PRBool
KeyEquals(KeyTypePointer aKey
) const { return *aKey
== mValue
; }
186 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
187 static PLDHashNumber
HashKey(KeyTypePointer aKey
) { return PLDHashNumber(*aKey
); }
188 enum { ALLOW_MEMMOVE
= PR_TRUE
};
191 const PRUint64 mValue
;
195 * hashkey wrapper using nsISupports* KeyType
197 * @see nsTHashtable::EntryType for specification
199 class nsISupportsHashKey
: public PLDHashEntryHdr
202 typedef nsISupports
* KeyType
;
203 typedef const nsISupports
* KeyTypePointer
;
205 nsISupportsHashKey(const nsISupports
* key
) :
206 mSupports(const_cast<nsISupports
*>(key
)) { }
207 nsISupportsHashKey(const nsISupportsHashKey
& toCopy
) :
208 mSupports(toCopy
.mSupports
) { }
209 ~nsISupportsHashKey() { }
211 KeyType
GetKey() const { return mSupports
; }
213 PRBool
KeyEquals(KeyTypePointer aKey
) const { return aKey
== mSupports
; }
215 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return aKey
; }
216 static PLDHashNumber
HashKey(KeyTypePointer aKey
)
218 return NS_PTR_TO_INT32(aKey
) >>2;
220 enum { ALLOW_MEMMOVE
= PR_TRUE
};
223 nsCOMPtr
<nsISupports
> mSupports
;
227 * hashkey wrapper using T* KeyType
229 * @see nsTHashtable::EntryType for specification
232 class nsPtrHashKey
: public PLDHashEntryHdr
236 typedef const T
*KeyTypePointer
;
238 nsPtrHashKey(const T
*key
) : mKey(const_cast<T
*>(key
)) {}
239 nsPtrHashKey(const nsPtrHashKey
<T
> &toCopy
) : mKey(toCopy
.mKey
) {}
242 KeyType
GetKey() const { return mKey
; }
244 PRBool
KeyEquals(KeyTypePointer key
) const { return key
== mKey
; }
246 static KeyTypePointer
KeyToPointer(KeyType key
) { return key
; }
247 static PLDHashNumber
HashKey(KeyTypePointer key
)
249 return NS_PTR_TO_INT32(key
) >> 2;
251 enum { ALLOW_MEMMOVE
= PR_TRUE
};
258 * hashkey wrapper using T* KeyType that sets key to NULL upon
259 * destruction. Relevant only in cases where a memory pointer-scanner
260 * like valgrind might get confused about stale references.
262 * @see nsTHashtable::EntryType for specification
266 class nsClearingPtrHashKey
: public nsPtrHashKey
<T
>
269 nsClearingPtrHashKey(const T
*key
) : nsPtrHashKey
<T
>(key
) {}
270 nsClearingPtrHashKey(const nsClearingPtrHashKey
<T
> &toCopy
) :
271 nsPtrHashKey
<T
>(toCopy
) {}
272 ~nsClearingPtrHashKey() { nsPtrHashKey
<T
>::mKey
= nsnull
; }
275 typedef nsPtrHashKey
<const void> nsVoidPtrHashKey
;
276 typedef nsClearingPtrHashKey
<const void> nsClearingVoidPtrHashKey
;
279 * hashkey wrapper using nsID KeyType
281 * @see nsTHashtable::EntryType for specification
283 class nsIDHashKey
: public PLDHashEntryHdr
286 typedef const nsID
& KeyType
;
287 typedef const nsID
* KeyTypePointer
;
289 nsIDHashKey(const nsID
* inID
) : mID(*inID
) { }
290 nsIDHashKey(const nsIDHashKey
& toCopy
) : mID(toCopy
.mID
) { }
293 KeyType
GetKey() const { return mID
; }
295 PRBool
KeyEquals(KeyTypePointer aKey
) const { return aKey
->Equals(mID
); }
297 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
298 static PLDHashNumber
HashKey(KeyTypePointer aKey
);
299 enum { ALLOW_MEMMOVE
= PR_TRUE
};
306 * hashkey wrapper for "dependent" const char*; this class does not "own"
307 * its string pointer.
309 * This class must only be used if the strings have a lifetime longer than
310 * the hashtable they occupy. This normally occurs only for static
311 * strings or strings that have been arena-allocated.
313 * @see nsTHashtable::EntryType for specification
315 class nsDepCharHashKey
: public PLDHashEntryHdr
318 typedef const char* KeyType
;
319 typedef const char* KeyTypePointer
;
321 nsDepCharHashKey(const char* aKey
) { mKey
= aKey
; }
322 nsDepCharHashKey(const nsDepCharHashKey
& toCopy
) { mKey
= toCopy
.mKey
; }
323 ~nsDepCharHashKey() { }
325 const char* GetKey() const { return mKey
; }
326 PRBool
KeyEquals(const char* aKey
) const
328 return !strcmp(mKey
, aKey
);
331 static const char* KeyToPointer(const char* aKey
) { return aKey
; }
332 static PLDHashNumber
HashKey(const char* aKey
) { return HashString(aKey
); }
333 enum { ALLOW_MEMMOVE
= PR_TRUE
};
340 * hashkey wrapper for const char*; at construction, this class duplicates
341 * a string pointed to by the pointer so that it doesn't matter whether or not
342 * the string lives longer than the hash table.
344 class nsCharPtrHashKey
: public PLDHashEntryHdr
347 typedef const char* KeyType
;
348 typedef const char* KeyTypePointer
;
350 nsCharPtrHashKey(const char* aKey
) : mKey(strdup(aKey
)) { }
351 nsCharPtrHashKey(const nsCharPtrHashKey
& toCopy
) : mKey(strdup(toCopy
.mKey
)) { }
352 ~nsCharPtrHashKey() { if (mKey
) free(const_cast<char *>(mKey
)); }
354 const char* GetKey() const { return mKey
; }
355 PRBool
KeyEquals(KeyTypePointer aKey
) const
357 return !strcmp(mKey
, aKey
);
360 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return aKey
; }
361 static PLDHashNumber
HashKey(KeyTypePointer aKey
) { return HashString(aKey
); }
363 enum { ALLOW_MEMMOVE
= PR_TRUE
};
370 * hashkey wrapper for const PRUnichar*; at construction, this class duplicates
371 * a string pointed to by the pointer so that it doesn't matter whether or not
372 * the string lives longer than the hash table.
374 class nsUnicharPtrHashKey
: public PLDHashEntryHdr
377 typedef const PRUnichar
* KeyType
;
378 typedef const PRUnichar
* KeyTypePointer
;
380 nsUnicharPtrHashKey(const PRUnichar
* aKey
) : mKey(NS_strdup(aKey
)) { }
381 nsUnicharPtrHashKey(const nsUnicharPtrHashKey
& toCopy
) : mKey(NS_strdup(toCopy
.mKey
)) { }
382 ~nsUnicharPtrHashKey() { if (mKey
) NS_Free(const_cast<PRUnichar
*>(mKey
)); }
384 const PRUnichar
* GetKey() const { return mKey
; }
385 PRBool
KeyEquals(KeyTypePointer aKey
) const
387 return !NS_strcmp(mKey
, aKey
);
390 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return aKey
; }
391 static PLDHashNumber
HashKey(KeyTypePointer aKey
) { return HashString(aKey
); }
393 enum { ALLOW_MEMMOVE
= PR_TRUE
};
396 const PRUnichar
* mKey
;
400 * Hashtable key class to use with objects that support nsIHashable
402 class nsHashableHashKey
: public PLDHashEntryHdr
405 typedef nsIHashable
* KeyType
;
406 typedef const nsIHashable
* KeyTypePointer
;
408 nsHashableHashKey(const nsIHashable
* aKey
) :
409 mKey(const_cast<nsIHashable
*>(aKey
)) { }
410 nsHashableHashKey(const nsHashableHashKey
& toCopy
) :
411 mKey(toCopy
.mKey
) { }
412 ~nsHashableHashKey() { }
414 nsIHashable
* GetKey() const { return mKey
; }
416 PRBool
KeyEquals(const nsIHashable
* aKey
) const {
418 if (NS_SUCCEEDED(mKey
->Equals(const_cast<nsIHashable
*>(aKey
), &eq
))) {
424 static const nsIHashable
* KeyToPointer(nsIHashable
* aKey
) { return aKey
; }
425 static PLDHashNumber
HashKey(const nsIHashable
* aKey
) {
426 PRUint32 code
= 8888; // magic number if GetHashCode fails :-(
430 const_cast<nsIHashable
*>(aKey
)->GetHashCode(&code
);
431 NS_ASSERTION(NS_SUCCEEDED(rv
), "GetHashCode should not throw!");
435 enum { ALLOW_MEMMOVE
= PR_TRUE
};
438 nsCOMPtr
<nsIHashable
> mKey
;
441 #endif // nsTHashKeys_h__