/gecko_api/include/nsRefPtrHashtable.h
C Header | 197 lines | 85 code | 31 blank | 81 comment | 9 complexity | fccafcd76b4d7fbb1940ad20cf84e0e9 MD5 | raw file
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 4 * 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/ 9 * 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 13 * License. 14 * 15 * The Original Code is C++ hashtable templates. 16 * 17 * The Initial Developer of the Original Code is 18 * Benjamin Smedberg. 19 * Portions created by the Initial Developer are Copyright (C) 2002 20 * the Initial Developer. All Rights Reserved. 21 * 22 * Contributor(s): 23 * Neil Rashbrook <neil@parkwaycc.co.uk> 24 * 25 * Alternatively, the contents of this file may be used under the terms of 26 * either the GNU General Public License Version 2 or later (the "GPL"), or 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 * in which case the provisions of the GPL or the LGPL are applicable instead 29 * of those above. If you wish to allow use of your version of this file only 30 * under the terms of either the GPL or the LGPL, and not to allow others to 31 * use your version of this file under the terms of the MPL, indicate your 32 * decision by deleting the provisions above and replace them with the notice 33 * and other provisions required by the GPL or the LGPL. If you do not delete 34 * the provisions above, a recipient may use your version of this file under 35 * the terms of any one of the MPL, the GPL or the LGPL. 36 * 37 * ***** END LICENSE BLOCK ***** */ 38 39#ifndef nsRefPtrHashtable_h__ 40#define nsRefPtrHashtable_h__ 41 42#include "nsBaseHashtable.h" 43#include "nsHashKeys.h" 44#include "nsAutoPtr.h" 45 46/** 47 * templated hashtable class maps keys to reference pointers. 48 * See nsBaseHashtable for complete declaration. 49 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h 50 * for a complete specification. 51 * @param RefPtr the reference-type being wrapped 52 * @see nsDataHashtable, nsClassHashtable 53 */ 54template<class KeyClass, class RefPtr> 55class nsRefPtrHashtable : 56 public nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* > 57{ 58public: 59 typedef typename KeyClass::KeyType KeyType; 60 typedef RefPtr* UserDataType; 61 62 /** 63 * @copydoc nsBaseHashtable::Get 64 * @param pData This is an XPCOM getter, so pData is already_addrefed. 65 * If the key doesn't exist, pData will be set to nsnull. 66 */ 67 PRBool Get(KeyType aKey, UserDataType* pData) const; 68 69 /** 70 * Gets a weak reference to the hashtable entry. 71 * @param aFound If not nsnull, will be set to PR_TRUE if the entry is found, 72 * to PR_FALSE otherwise. 73 * @return The entry, or nsnull if not found. Do not release this pointer! 74 */ 75 RefPtr* GetWeak(KeyType aKey, PRBool* aFound = nsnull) const; 76}; 77 78/** 79 * Thread-safe version of nsRefPtrHashtable 80 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h 81 * for a complete specification. 82 * @param RefPtr the reference-type being wrapped 83 */ 84template<class KeyClass, class RefPtr> 85class nsRefPtrHashtableMT : 86 public nsBaseHashtableMT< KeyClass, nsRefPtr<RefPtr> , RefPtr* > 87{ 88public: 89 typedef typename KeyClass::KeyType KeyType; 90 typedef RefPtr* UserDataType; 91 92 /** 93 * @copydoc nsBaseHashtable::Get 94 * @param pData This is an XPCOM getter, so pData is already_addrefed. 95 * If the key doesn't exist, pData will be set to nsnull. 96 */ 97 PRBool Get(KeyType aKey, UserDataType* pData) const; 98 99 // GetWeak does not make sense on a multi-threaded hashtable, where another 100 // thread may remove the entry (and hence release it) as soon as GetWeak 101 // returns 102}; 103 104 105// 106// nsRefPtrHashtable definitions 107// 108 109template<class KeyClass, class RefPtr> 110PRBool 111nsRefPtrHashtable<KeyClass,RefPtr>::Get 112 (KeyType aKey, UserDataType* pRefPtr) const 113{ 114 typename nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent = 115 GetEntry(aKey); 116 117 if (ent) 118 { 119 if (pRefPtr) 120 { 121 *pRefPtr = ent->mData; 122 123 NS_IF_ADDREF(*pRefPtr); 124 } 125 126 return PR_TRUE; 127 } 128 129 // if the key doesn't exist, set *pRefPtr to null 130 // so that it is a valid XPCOM getter 131 if (pRefPtr) 132 *pRefPtr = nsnull; 133 134 return PR_FALSE; 135} 136 137template<class KeyClass, class RefPtr> 138RefPtr* 139nsRefPtrHashtable<KeyClass,RefPtr>::GetWeak 140 (KeyType aKey, PRBool* aFound) const 141{ 142 typename nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent = 143 GetEntry(aKey); 144 145 if (ent) 146 { 147 if (aFound) 148 *aFound = PR_TRUE; 149 150 return ent->mData; 151 } 152 153 // Key does not exist, return nsnull and set aFound to PR_FALSE 154 if (aFound) 155 *aFound = PR_FALSE; 156 return nsnull; 157} 158 159// 160// nsRefPtrHashtableMT definitions 161// 162 163template<class KeyClass, class RefPtr> 164PRBool 165nsRefPtrHashtableMT<KeyClass,RefPtr>::Get 166 (KeyType aKey, UserDataType* pRefPtr) const 167{ 168 PR_Lock(this->mLock); 169 170 typename nsBaseHashtableMT<KeyClass, nsRefPtr<RefPtr>, RefPtr*>::EntryType* ent = 171 GetEntry(aKey); 172 173 if (ent) 174 { 175 if (pRefPtr) 176 { 177 *pRefPtr = ent->mData; 178 179 NS_IF_ADDREF(*pRefPtr); 180 } 181 182 PR_Unlock(this->mLock); 183 184 return PR_TRUE; 185 } 186 187 // if the key doesn't exist, set *pRefPtr to null 188 // so that it is a valid XPCOM getter 189 if (pRefPtr) 190 *pRefPtr = nsnull; 191 192 PR_Unlock(this->mLock); 193 194 return PR_FALSE; 195} 196 197#endif // nsRefPtrHashtable_h__