2 * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #ifndef RefPtrHashMap_h
22 #define RefPtrHashMap_h
24 #include "wtf/DefaultAllocator.h"
28 // This specialization is a copy of HashMap for use with RefPtr keys, with overloaded functions
29 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
31 // FIXME: Find a way to do this with traits that doesn't require a copy of the HashMap template.
33 template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
34 class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, DefaultAllocator> {
36 typedef KeyTraitsArg KeyTraits;
37 typedef MappedTraitsArg MappedTraits;
38 typedef KeyValuePairHashTraits<KeyTraits, MappedTraits> ValueTraits;
41 typedef typename KeyTraits::TraitType KeyType;
42 typedef T* RawKeyType;
43 typedef typename MappedTraits::TraitType MappedType;
44 typedef typename ValueTraits::TraitType ValueType;
47 typedef typename MappedTraits::PassInType MappedPassInType;
48 typedef typename MappedTraits::PassOutType MappedPassOutType;
49 typedef typename MappedTraits::PeekOutType MappedPeekType;
51 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedPassInReferenceType;
53 typedef HashArg HashFunctions;
55 typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor,
56 HashFunctions, ValueTraits, KeyTraits, DefaultAllocator> HashTableType;
58 typedef HashMapTranslator<ValueTraits, HashFunctions>
62 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
63 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
64 typedef typename HashTableType::AddResult AddResult;
68 unsigned size() const;
69 unsigned capacity() const;
72 // iterators iterate over pairs of keys and values
75 const_iterator begin() const;
76 const_iterator end() const;
78 iterator find(const KeyType&);
79 iterator find(RawKeyType);
80 const_iterator find(const KeyType&) const;
81 const_iterator find(RawKeyType) const;
82 bool contains(const KeyType&) const;
83 bool contains(RawKeyType) const;
84 MappedPeekType get(const KeyType&) const;
85 MappedPeekType get(RawKeyType) const;
86 MappedPeekType inlineGet(RawKeyType) const;
88 // replaces value but not key if key is already present
89 // return value is a pair of the iterator to the key location,
90 // and a boolean that's true if a new value was actually added
91 AddResult set(const KeyType&, MappedPassInType);
92 AddResult set(RawKeyType, MappedPassInType);
94 // does nothing if key is already present
95 // return value is a pair of the iterator to the key location,
96 // and a boolean that's true if a new value was actually added
97 AddResult add(const KeyType&, MappedPassInType);
98 AddResult add(RawKeyType, MappedPassInType);
100 void remove(const KeyType&);
101 void remove(RawKeyType);
102 void remove(iterator);
105 MappedPassOutType take(const KeyType&); // efficient combination of get with remove
106 MappedPassOutType take(RawKeyType); // efficient combination of get with remove
109 AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
110 AddResult inlineAdd(RawKeyType, MappedPassInReferenceType);
112 HashTableType m_impl;
115 template<typename T, typename U, typename V, typename W, typename X>
116 inline void HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::swap(HashMap& other)
118 m_impl.swap(other.m_impl);
121 template<typename T, typename U, typename V, typename W, typename X>
122 inline unsigned HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::size() const
124 return m_impl.size();
127 template<typename T, typename U, typename V, typename W, typename X>
128 inline unsigned HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::capacity() const
130 return m_impl.capacity();
133 template<typename T, typename U, typename V, typename W, typename X>
134 inline bool HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::isEmpty() const
136 return m_impl.isEmpty();
139 template<typename T, typename U, typename V, typename W, typename X>
140 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::begin()
142 return m_impl.begin();
145 template<typename T, typename U, typename V, typename W, typename X>
146 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::end()
151 template<typename T, typename U, typename V, typename W, typename X>
152 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::const_iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::begin() const
154 return m_impl.begin();
157 template<typename T, typename U, typename V, typename W, typename X>
158 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::const_iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::end() const
163 template<typename T, typename U, typename V, typename W, typename X>
164 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::find(const KeyType& key)
166 return m_impl.find(key);
169 template<typename T, typename U, typename V, typename W, typename X>
170 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::find(RawKeyType key)
172 return m_impl.template find<Translator>(key);
175 template<typename T, typename U, typename V, typename W, typename X>
176 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::const_iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::find(const KeyType& key) const
178 return m_impl.find(key);
181 template<typename T, typename U, typename V, typename W, typename X>
182 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::const_iterator HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::find(RawKeyType key) const
184 return m_impl.template find<Translator>(key);
187 template<typename T, typename U, typename V, typename W, typename X>
188 inline bool HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::contains(const KeyType& key) const
190 return m_impl.contains(key);
193 template<typename T, typename U, typename V, typename W, typename X>
194 inline bool HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::contains(RawKeyType key) const
196 return m_impl.template contains<Translator>(key);
199 template<typename T, typename U, typename V, typename W, typename X>
200 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
201 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::inlineAdd(const KeyType& key, MappedPassInReferenceType mapped)
203 return m_impl.template add<Translator>(key, mapped);
206 template<typename T, typename U, typename V, typename W, typename X>
207 inline typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
208 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::inlineAdd(RawKeyType key, MappedPassInReferenceType mapped)
210 return m_impl.template add<Translator>(key, mapped);
213 template<typename T, typename U, typename V, typename W, typename X>
214 typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
215 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::set(const KeyType& key, MappedPassInType mapped)
217 AddResult result = inlineAdd(key, mapped);
218 if (!result.isNewEntry) {
219 // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
220 MappedTraits::store(mapped, result.storedValue->value);
225 template<typename T, typename U, typename V, typename W, typename X>
226 typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
227 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::set(RawKeyType key, MappedPassInType mapped)
229 AddResult result = inlineAdd(key, mapped);
230 if (!result.isNewEntry) {
231 // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
232 MappedTraits::store(mapped, result.storedValue->value);
237 template<typename T, typename U, typename V, typename W, typename X>
238 typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
239 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::add(const KeyType& key, MappedPassInType mapped)
241 return inlineAdd(key, mapped);
244 template<typename T, typename U, typename V, typename W, typename X>
245 typename HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::AddResult
246 HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::add(RawKeyType key, MappedPassInType mapped)
248 return inlineAdd(key, mapped);
251 template<typename T, typename U, typename V, typename W, typename MappedTraits>
252 typename HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::MappedPeekType
253 HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::get(const KeyType& key) const
255 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
257 return MappedTraits::peek(MappedTraits::emptyValue());
258 return MappedTraits::peek(entry->value);
261 template<typename T, typename U, typename V, typename W, typename MappedTraits>
262 typename HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::MappedPeekType
263 inline HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::inlineGet(RawKeyType key) const
265 ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<Translator>(key);
267 return MappedTraits::peek(MappedTraits::emptyValue());
268 return MappedTraits::peek(entry->value);
271 template<typename T, typename U, typename V, typename W, typename MappedTraits>
272 typename HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::MappedPeekType
273 HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::get(RawKeyType key) const
275 return inlineGet(key);
278 template<typename T, typename U, typename V, typename W, typename X>
279 inline void HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::remove(iterator it)
281 if (it.m_impl == m_impl.end())
283 m_impl.remove(it.m_impl);
286 template<typename T, typename U, typename V, typename W, typename X>
287 inline void HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::remove(const KeyType& key)
292 template<typename T, typename U, typename V, typename W, typename X>
293 inline void HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::remove(RawKeyType key)
298 template<typename T, typename U, typename V, typename W, typename X>
299 inline void HashMap<RefPtr<T>, U, V, W, X, DefaultAllocator>::clear()
304 template<typename T, typename U, typename V, typename W, typename MappedTraits>
305 typename HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::MappedPassOutType
306 HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::take(const KeyType& key)
308 iterator it = find(key);
310 return MappedTraits::passOut(MappedTraits::emptyValue());
311 MappedPassOutType result = MappedTraits::passOut(it->value);
316 template<typename T, typename U, typename V, typename W, typename MappedTraits>
317 typename HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::MappedPassOutType
318 HashMap<RefPtr<T>, U, V, W, MappedTraits, DefaultAllocator>::take(RawKeyType key)
320 iterator it = find(key);
322 return MappedTraits::passOut(MappedTraits::emptyValue());
323 MappedPassOutType result = MappedTraits::passOut(it->value);
330 #endif // RefPtrHashMap_h