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
26 // This specialization is a copy of HashMap for use with RefPtr keys, with overloaded functions
27 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
29 // FIXME: Find a way to do this with traits that doesn't require a copy of the HashMap template.
31 template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
32 class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
33 WTF_MAKE_FAST_ALLOCATED;
35 typedef KeyTraitsArg KeyTraits;
36 typedef MappedTraitsArg MappedTraits;
37 typedef KeyValuePairHashTraits<KeyTraits, MappedTraits> ValueTraits;
40 typedef typename KeyTraits::TraitType KeyType;
41 typedef T* RawKeyType;
42 typedef typename MappedTraits::TraitType MappedType;
43 typedef typename ValueTraits::TraitType ValueType;
46 typedef typename MappedTraits::PassInType MappedPassInType;
47 typedef typename MappedTraits::PassOutType MappedPassOutType;
48 typedef typename MappedTraits::PeekType MappedPeekType;
50 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedPassInReferenceType;
52 typedef HashArg HashFunctions;
54 typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor<ValueType>,
55 HashFunctions, ValueTraits, KeyTraits> HashTableType;
57 typedef HashMapTranslator<ValueTraits, HashFunctions>
61 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
62 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
63 typedef typename HashTableType::AddResult AddResult;
71 // iterators iterate over pairs of keys and values
74 const_iterator begin() const;
75 const_iterator end() const;
77 iterator find(const KeyType&);
78 iterator find(RawKeyType);
79 const_iterator find(const KeyType&) const;
80 const_iterator find(RawKeyType) const;
81 bool contains(const KeyType&) const;
82 bool contains(RawKeyType) const;
83 MappedPeekType get(const KeyType&) const;
84 MappedPeekType get(RawKeyType) const;
85 MappedPeekType inlineGet(RawKeyType) const;
87 // replaces value but not key if key is already present
88 // return value is a pair of the iterator to the key location,
89 // and a boolean that's true if a new value was actually added
90 AddResult set(const KeyType&, MappedPassInType);
91 AddResult set(RawKeyType, MappedPassInType);
93 // does nothing if key is already present
94 // return value is a pair of the iterator to the key location,
95 // and a boolean that's true if a new value was actually added
96 AddResult add(const KeyType&, MappedPassInType);
97 AddResult add(RawKeyType, MappedPassInType);
99 void remove(const KeyType&);
100 void remove(RawKeyType);
101 void remove(iterator);
104 MappedPassOutType take(const KeyType&); // efficient combination of get with remove
105 MappedPassOutType take(RawKeyType); // efficient combination of get with remove
108 AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
109 AddResult inlineAdd(RawKeyType, MappedPassInReferenceType);
111 HashTableType m_impl;
114 template<typename T, typename U, typename V, typename W, typename X>
115 inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other)
117 m_impl.swap(other.m_impl);
120 template<typename T, typename U, typename V, typename W, typename X>
121 inline int HashMap<RefPtr<T>, U, V, W, X>::size() const
123 return m_impl.size();
126 template<typename T, typename U, typename V, typename W, typename X>
127 inline int HashMap<RefPtr<T>, U, V, W, X>::capacity() const
129 return m_impl.capacity();
132 template<typename T, typename U, typename V, typename W, typename X>
133 inline bool HashMap<RefPtr<T>, U, V, W, X>::isEmpty() const
135 return m_impl.isEmpty();
138 template<typename T, typename U, typename V, typename W, typename X>
139 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::begin()
141 return m_impl.begin();
144 template<typename T, typename U, typename V, typename W, typename X>
145 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::end()
150 template<typename T, typename U, typename V, typename W, typename X>
151 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::begin() const
153 return m_impl.begin();
156 template<typename T, typename U, typename V, typename W, typename X>
157 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::end() const
162 template<typename T, typename U, typename V, typename W, typename X>
163 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key)
165 return m_impl.find(key);
168 template<typename T, typename U, typename V, typename W, typename X>
169 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key)
171 return m_impl.template find<Translator>(key);
174 template<typename T, typename U, typename V, typename W, typename X>
175 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const
177 return m_impl.find(key);
180 template<typename T, typename U, typename V, typename W, typename X>
181 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const
183 return m_impl.template find<Translator>(key);
186 template<typename T, typename U, typename V, typename W, typename X>
187 inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const
189 return m_impl.contains(key);
192 template<typename T, typename U, typename V, typename W, typename X>
193 inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const
195 return m_impl.template contains<Translator>(key);
198 template<typename T, typename U, typename V, typename W, typename X>
199 inline typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
200 HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(const KeyType& key, MappedPassInReferenceType mapped)
202 return m_impl.template add<Translator>(key, mapped);
205 template<typename T, typename U, typename V, typename W, typename X>
206 inline typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
207 HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(RawKeyType key, MappedPassInReferenceType mapped)
209 return m_impl.template add<Translator>(key, mapped);
212 template<typename T, typename U, typename V, typename W, typename X>
213 typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
214 HashMap<RefPtr<T>, U, V, W, X>::set(const KeyType& key, MappedPassInType mapped)
216 AddResult result = inlineAdd(key, mapped);
217 if (!result.isNewEntry) {
218 // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
219 MappedTraits::store(mapped, result.iterator->second);
224 template<typename T, typename U, typename V, typename W, typename X>
225 typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
226 HashMap<RefPtr<T>, U, V, W, X>::set(RawKeyType key, MappedPassInType mapped)
228 AddResult result = inlineAdd(key, mapped);
229 if (!result.isNewEntry) {
230 // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
231 MappedTraits::store(mapped, result.iterator->second);
236 template<typename T, typename U, typename V, typename W, typename X>
237 typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
238 HashMap<RefPtr<T>, U, V, W, X>::add(const KeyType& key, MappedPassInType mapped)
240 return inlineAdd(key, mapped);
243 template<typename T, typename U, typename V, typename W, typename X>
244 typename HashMap<RefPtr<T>, U, V, W, X>::AddResult
245 HashMap<RefPtr<T>, U, V, W, X>::add(RawKeyType key, MappedPassInType mapped)
247 return inlineAdd(key, mapped);
250 template<typename T, typename U, typename V, typename W, typename MappedTraits>
251 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
252 HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const
254 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
256 return MappedTraits::peek(MappedTraits::emptyValue());
257 return MappedTraits::peek(entry->second);
260 template<typename T, typename U, typename V, typename W, typename MappedTraits>
261 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
262 inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const
264 ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<Translator>(key);
266 return MappedTraits::peek(MappedTraits::emptyValue());
267 return MappedTraits::peek(entry->second);
270 template<typename T, typename U, typename V, typename W, typename MappedTraits>
271 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
272 HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
274 return inlineGet(key);
277 template<typename T, typename U, typename V, typename W, typename X>
278 inline void HashMap<RefPtr<T>, U, V, W, X>::remove(iterator it)
280 if (it.m_impl == m_impl.end())
282 m_impl.internalCheckTableConsistency();
283 m_impl.removeWithoutEntryConsistencyCheck(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>::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>::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>::clear()
304 template<typename T, typename U, typename V, typename W, typename MappedTraits>
305 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPassOutType
306 HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(const KeyType& key)
308 iterator it = find(key);
310 return MappedTraits::passOut(MappedTraits::emptyValue());
311 MappedPassOutType result = MappedTraits::passOut(it->second);
316 template<typename T, typename U, typename V, typename W, typename MappedTraits>
317 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPassOutType
318 HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(RawKeyType key)
320 iterator it = find(key);
322 return MappedTraits::passOut(MappedTraits::emptyValue());
323 MappedPassOutType result = MappedTraits::passOut(it->second);
330 #endif // RefPtrHashMap_h