Change a couple of HashMap value types from OwnPtr to std::unique_ptr
[WebKit-https.git] / Source / WTF / wtf / RefPtrHashMap.h
1 /*
2  * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
3  *
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.
8  *
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.
13  *
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.
18  *
19  */
20
21 #ifndef RefPtrHashMap_h
22 #define RefPtrHashMap_h
23
24 namespace WTF {
25
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.
28     
29      // FIXME: Find a way to do this with traits that doesn't require a copy of the HashMap template.
30     
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;
34     private:
35         typedef KeyTraitsArg KeyTraits;
36         typedef MappedTraitsArg MappedTraits;
37         typedef KeyValuePairHashTraits<KeyTraits, MappedTraits> ValueTraits;
38
39     public:
40         typedef typename KeyTraits::TraitType KeyType;
41         typedef T* RawKeyType;
42         typedef typename MappedTraits::TraitType MappedType;
43         typedef typename ValueTraits::TraitType ValueType;
44
45     private:
46         typedef typename MappedTraits::PassInType MappedPassInType;
47         typedef typename MappedTraits::PassOutType MappedPassOutType;
48         typedef typename MappedTraits::PeekType MappedPeekType;
49
50         typedef typename std::add_lvalue_reference<MappedPassInType>::type MappedPassInReferenceType;
51         
52         typedef HashArg HashFunctions;
53
54         typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor<ValueType>,
55             HashFunctions, ValueTraits, KeyTraits> HashTableType;
56
57         typedef HashMapTranslator<ValueTraits, HashFunctions>
58             Translator;
59
60     public:
61         typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
62         typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
63         typedef typename HashTableType::AddResult AddResult;
64
65         void swap(HashMap&);
66
67         int size() const;
68         int capacity() const;
69         bool isEmpty() const;
70
71         // iterators iterate over pairs of keys and values
72         iterator begin();
73         iterator end();
74         const_iterator begin() const;
75         const_iterator end() const;
76
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;
86
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         template<typename V> AddResult set(const KeyType&, V&&);
91         template<typename V> AddResult set(RawKeyType, V&&);
92
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         template<typename V> AddResult add(const KeyType&, V&&);
97         template<typename V> AddResult add(RawKeyType, V&&);
98
99         bool remove(const KeyType&);
100         bool remove(RawKeyType);
101         bool remove(iterator);
102         void clear();
103
104         MappedPassOutType take(const KeyType&); // efficient combination of get with remove
105         MappedPassOutType take(RawKeyType); // efficient combination of get with remove
106
107     private:
108         template<typename V>
109         AddResult inlineAdd(const KeyType&, V&&);
110
111         template<typename V>
112         AddResult inlineAdd(RawKeyType, V&&);
113
114         HashTableType m_impl;
115     };
116     
117     template<typename T, typename U, typename V, typename W, typename X>
118     inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other)
119     {
120         m_impl.swap(other.m_impl); 
121     }
122
123     template<typename T, typename U, typename V, typename W, typename X>
124     inline int HashMap<RefPtr<T>, U, V, W, X>::size() const
125     {
126         return m_impl.size(); 
127     }
128
129     template<typename T, typename U, typename V, typename W, typename X>
130     inline int HashMap<RefPtr<T>, U, V, W, X>::capacity() const
131     { 
132         return m_impl.capacity(); 
133     }
134
135     template<typename T, typename U, typename V, typename W, typename X>
136     inline bool HashMap<RefPtr<T>, U, V, W, X>::isEmpty() const
137     {
138         return m_impl.isEmpty();
139     }
140
141     template<typename T, typename U, typename V, typename W, typename X>
142     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::begin()
143     {
144         return m_impl.begin();
145     }
146
147     template<typename T, typename U, typename V, typename W, typename X>
148     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::end()
149     {
150         return m_impl.end();
151     }
152
153     template<typename T, typename U, typename V, typename W, typename X>
154     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::begin() const
155     {
156         return m_impl.begin();
157     }
158
159     template<typename T, typename U, typename V, typename W, typename X>
160     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::end() const
161     {
162         return m_impl.end();
163     }
164
165     template<typename T, typename U, typename V, typename W, typename X>
166     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key)
167     {
168         return m_impl.find(key);
169     }
170
171     template<typename T, typename U, typename V, typename W, typename X>
172     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key)
173     {
174         return m_impl.template find<Translator>(key);
175     }
176
177     template<typename T, typename U, typename V, typename W, typename X>
178     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const
179     {
180         return m_impl.find(key);
181     }
182
183     template<typename T, typename U, typename V, typename W, typename X>
184     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const
185     {
186         return m_impl.template find<Translator>(key);
187     }
188
189     template<typename T, typename U, typename V, typename W, typename X>
190     inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const
191     {
192         return m_impl.contains(key);
193     }
194
195     template<typename T, typename U, typename V, typename W, typename X>
196     inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const
197     {
198         return m_impl.template contains<Translator>(key);
199     }
200
201     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
202     template<typename V>
203     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::inlineAdd(const KeyType& key, V&& mapped) -> AddResult
204     {
205         return m_impl.template add<Translator>(key, std::forward<V>(mapped));
206     }
207
208     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
209     template<typename V>
210     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::inlineAdd(RawKeyType key, V&& mapped) -> AddResult
211     {
212         return m_impl.template add<Translator>(key, std::forward<V>(mapped));
213     }
214
215     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
216     template<typename V>
217     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::set(const KeyType& key, V&& value) -> AddResult
218     {
219         AddResult result = inlineAdd(key, std::forward<V>(value));
220         if (!result.isNewEntry) {
221             // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
222             result.iterator->value = std::forward<V>(value);
223         }
224         return result;
225     }
226
227     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
228     template<typename V>
229     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::set(RawKeyType key, V&& value) -> AddResult
230     {
231         AddResult result = inlineAdd(key, std::forward<V>(value));
232         if (!result.isNewEntry) {
233             // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
234             result.iterator->value = std::forward<V>(value);
235         }
236         return result;
237     }
238
239     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
240     template<typename V>
241     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::add(const KeyType& key, V&& value) -> AddResult
242     {
243         return inlineAdd(key, std::forward<V>(value));
244     }
245
246     template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
247     template<typename V>
248     auto HashMap<RefPtr<KeyArg>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::add(RawKeyType key, V&& value) -> AddResult
249     {
250         return inlineAdd(key, std::forward<V>(value));
251     }
252
253     template<typename T, typename U, typename V, typename W, typename MappedTraits>
254     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
255     HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const
256     {
257         ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
258         if (!entry)
259             return MappedTraits::peek(MappedTraits::emptyValue());
260         return MappedTraits::peek(entry->value);
261     }
262
263     template<typename T, typename U, typename V, typename W, typename MappedTraits>
264     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
265     inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const
266     {
267         ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<Translator>(key);
268         if (!entry)
269             return MappedTraits::peek(MappedTraits::emptyValue());
270         return MappedTraits::peek(entry->value);
271     }
272
273     template<typename T, typename U, typename V, typename W, typename MappedTraits>
274     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPeekType
275     HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
276     {
277         return inlineGet(key);
278     }
279
280     template<typename T, typename U, typename V, typename W, typename X>
281     inline bool HashMap<RefPtr<T>, U, V, W, X>::remove(iterator it)
282     {
283         if (it.m_impl == m_impl.end())
284             return false;
285         m_impl.internalCheckTableConsistency();
286         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
287         return true;
288     }
289
290     template<typename T, typename U, typename V, typename W, typename X>
291     inline bool HashMap<RefPtr<T>, U, V, W, X>::remove(const KeyType& key)
292     {
293         return remove(find(key));
294     }
295
296     template<typename T, typename U, typename V, typename W, typename X>
297     inline bool HashMap<RefPtr<T>, U, V, W, X>::remove(RawKeyType key)
298     {
299         return remove(find(key));
300     }
301
302     template<typename T, typename U, typename V, typename W, typename X>
303     inline void HashMap<RefPtr<T>, U, V, W, X>::clear()
304     {
305         m_impl.clear();
306     }
307
308     template<typename T, typename U, typename V, typename W, typename MappedTraits>
309     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPassOutType
310     HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(const KeyType& key)
311     {
312         iterator it = find(key);
313         if (it == end())
314             return MappedTraits::passOut(MappedTraits::emptyValue());
315         MappedPassOutType result = MappedTraits::passOut(it->value);
316         remove(it);
317         return result;
318     }
319
320     template<typename T, typename U, typename V, typename W, typename MappedTraits>
321     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedPassOutType
322     HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(RawKeyType key)
323     {
324         iterator it = find(key);
325         if (it == end())
326             return MappedTraits::passOut(MappedTraits::emptyValue());
327         MappedPassOutType result = MappedTraits::passOut(it->value);
328         remove(it);
329         return result;
330     }
331
332 } // namespace WTF
333
334 #endif // RefPtrHashMap_h