[WK2] Small Caps font variant issue for Italic fonts
[framework/web/webkit-efl.git] / Source / WTF / wtf / HashMap.h
1 /*
2  * Copyright (C) 2005, 2006, 2007, 2008, 2011 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 WTF_HashMap_h
22 #define WTF_HashMap_h
23
24 #include <wtf/HashTable.h>
25
26 namespace WTF {
27
28     template<typename KeyTraits, typename MappedTraits> struct HashMapValueTraits;
29
30     template<typename T> struct ReferenceTypeMaker {
31         typedef T& ReferenceType;
32     };
33     template<typename T> struct ReferenceTypeMaker<T&> {
34         typedef T& ReferenceType;
35     };
36
37     template<typename T> struct KeyValuePairKeyExtractor {
38         static const typename T::KeyType& extract(const T& p) { return p.first; }
39     };
40
41     template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
42         typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> >
43     class HashMap {
44         WTF_MAKE_FAST_ALLOCATED;
45     private:
46         typedef KeyTraitsArg KeyTraits;
47         typedef MappedTraitsArg MappedTraits;
48         typedef HashMapValueTraits<KeyTraits, MappedTraits> ValueTraits;
49
50     public:
51         typedef typename KeyTraits::TraitType KeyType;
52         typedef typename MappedTraits::TraitType MappedType;
53         typedef typename ValueTraits::TraitType ValueType;
54
55     private:
56         typedef typename MappedTraits::PassInType MappedPassInType;
57         typedef typename MappedTraits::PassOutType MappedPassOutType;
58         typedef typename MappedTraits::PeekType MappedPeekType;
59
60         typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedPassInReferenceType;
61
62         typedef HashArg HashFunctions;
63
64         typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor<ValueType>,
65             HashFunctions, ValueTraits, KeyTraits> HashTableType;
66
67         class HashMapKeysProxy;
68         class HashMapValuesProxy;
69
70     public:
71         typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
72         typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
73         typedef typename HashTableType::AddResult AddResult;
74
75     public:
76         void swap(HashMap&);
77
78         int size() const;
79         int capacity() const;
80         bool isEmpty() const;
81
82         // iterators iterate over pairs of keys and values
83         iterator begin();
84         iterator end();
85         const_iterator begin() const;
86         const_iterator end() const;
87
88         HashMapKeysProxy& keys() { return static_cast<HashMapKeysProxy&>(*this); }
89         const HashMapKeysProxy& keys() const { return static_cast<const HashMapKeysProxy&>(*this); }
90
91         HashMapValuesProxy& values() { return static_cast<HashMapValuesProxy&>(*this); }
92         const HashMapValuesProxy& values() const { return static_cast<const HashMapValuesProxy&>(*this); }
93
94         iterator find(const KeyType&);
95         const_iterator find(const KeyType&) const;
96         bool contains(const KeyType&) const;
97         MappedPeekType get(const KeyType&) const;
98
99         // replaces value but not key if key is already present
100         // return value is a pair of the iterator to the key location, 
101         // and a boolean that's true if a new value was actually added
102         AddResult set(const KeyType&, MappedPassInType);
103
104         // does nothing if key is already present
105         // return value is a pair of the iterator to the key location, 
106         // and a boolean that's true if a new value was actually added
107         AddResult add(const KeyType&, MappedPassInType);
108
109         void remove(const KeyType&);
110         void remove(iterator);
111         void clear();
112
113         MappedPassOutType take(const KeyType&); // efficient combination of get with remove
114
115         // An alternate version of find() that finds the object by hashing and comparing
116         // with some other type, to avoid the cost of type conversion. HashTranslator
117         // must have the following function members:
118         //   static unsigned hash(const T&);
119         //   static bool equal(const ValueType&, const T&);
120         template<typename T, typename HashTranslator> iterator find(const T&);
121         template<typename T, typename HashTranslator> const_iterator find(const T&) const;
122         template<typename T, typename HashTranslator> bool contains(const T&) const;
123
124         // An alternate version of add() that finds the object by hashing and comparing
125         // with some other type, to avoid the cost of type conversion if the object is already
126         // in the table. HashTranslator must have the following function members:
127         //   static unsigned hash(const T&);
128         //   static bool equal(const ValueType&, const T&);
129         //   static translate(ValueType&, const T&, unsigned hashCode);
130         template<typename T, typename HashTranslator> AddResult add(const T&, MappedPassInType);
131
132         void checkConsistency() const;
133
134     private:
135         AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
136
137         class HashMapKeysProxy : private HashMap {
138         public:
139             typedef typename HashMap::iterator::Keys iterator;
140             typedef typename HashMap::const_iterator::Keys const_iterator;
141             
142             iterator begin()
143             {
144                 return HashMap::begin().keys();
145             }
146             
147             iterator end()
148             {
149                 return HashMap::end().keys();
150             }
151
152             const_iterator begin() const
153             {
154                 return HashMap::begin().keys();
155             }
156             
157             const_iterator end() const
158             {
159                 return HashMap::end().keys();
160             }
161
162         private:
163             friend class HashMap;
164
165             // These are intentionally not implemented.
166             HashMapKeysProxy();
167             HashMapKeysProxy(const HashMapKeysProxy&);
168             HashMapKeysProxy& operator=(const HashMapKeysProxy&);
169             ~HashMapKeysProxy();
170         };
171
172         class HashMapValuesProxy : private HashMap {
173         public:
174             typedef typename HashMap::iterator::Values iterator;
175             typedef typename HashMap::const_iterator::Values const_iterator;
176             
177             iterator begin()
178             {
179                 return HashMap::begin().values();
180             }
181             
182             iterator end()
183             {
184                 return HashMap::end().values();
185             }
186
187             const_iterator begin() const
188             {
189                 return HashMap::begin().values();
190             }
191             
192             const_iterator end() const
193             {
194                 return HashMap::end().values();
195             }
196
197         private:
198             friend class HashMap;
199
200             // These are intentionally not implemented.
201             HashMapValuesProxy();
202             HashMapValuesProxy(const HashMapValuesProxy&);
203             HashMapValuesProxy& operator=(const HashMapValuesProxy&);
204             ~HashMapValuesProxy();
205         };
206
207         HashTableType m_impl;
208     };
209
210     template<typename KeyTraits, typename MappedTraits> struct HashMapValueTraits : KeyValuePairHashTraits<KeyTraits, MappedTraits> {
211         static const bool hasIsEmptyValueFunction = true;
212         static bool isEmptyValue(const typename KeyValuePairHashTraits<KeyTraits, MappedTraits>::TraitType& value)
213         {
214             return isHashTraitsEmptyValue<KeyTraits>(value.first);
215         }
216     };
217
218     template<typename ValueTraits, typename HashFunctions>
219     struct HashMapTranslator {
220         template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); }
221         template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }
222         template<typename T, typename U, typename V> static void translate(T& location, const U& key, const V& mapped)
223         {
224             location.first = key;
225             ValueTraits::ValueTraits::store(mapped, location.second);
226         }
227     };
228
229     template<typename ValueTraits, typename Translator>
230     struct HashMapTranslatorAdapter {
231         template<typename T> static unsigned hash(const T& key) { return Translator::hash(key); }
232         template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a, b); }
233         template<typename T, typename U, typename V> static void translate(T& location, const U& key, const V& mapped, unsigned hashCode)
234         {
235             Translator::translate(location.first, key, hashCode);
236             ValueTraits::ValueTraits::store(mapped, location.second);
237         }
238     };
239
240     template<typename T, typename U, typename V, typename W, typename X>
241     inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
242     {
243         m_impl.swap(other.m_impl); 
244     }
245
246     template<typename T, typename U, typename V, typename W, typename X>
247     inline int HashMap<T, U, V, W, X>::size() const
248     {
249         return m_impl.size(); 
250     }
251
252     template<typename T, typename U, typename V, typename W, typename X>
253     inline int HashMap<T, U, V, W, X>::capacity() const
254     { 
255         return m_impl.capacity(); 
256     }
257
258     template<typename T, typename U, typename V, typename W, typename X>
259     inline bool HashMap<T, U, V, W, X>::isEmpty() const
260     {
261         return m_impl.isEmpty();
262     }
263
264     template<typename T, typename U, typename V, typename W, typename X>
265     inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin()
266     {
267         return m_impl.begin();
268     }
269
270     template<typename T, typename U, typename V, typename W, typename X>
271     inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end()
272     {
273         return m_impl.end();
274     }
275
276     template<typename T, typename U, typename V, typename W, typename X>
277     inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const
278     {
279         return m_impl.begin();
280     }
281
282     template<typename T, typename U, typename V, typename W, typename X>
283     inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const
284     {
285         return m_impl.end();
286     }
287
288     template<typename T, typename U, typename V, typename W, typename X>
289     inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key)
290     {
291         return m_impl.find(key);
292     }
293
294     template<typename T, typename U, typename V, typename W, typename X>
295     inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const
296     {
297         return m_impl.find(key);
298     }
299
300     template<typename T, typename U, typename V, typename W, typename X>
301     inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const
302     {
303         return m_impl.contains(key);
304     }
305
306     template<typename T, typename U, typename V, typename W, typename X>
307     template<typename TYPE, typename HashTranslator>
308     inline typename HashMap<T, U, V, W, X>::iterator
309     HashMap<T, U, V, W, X>::find(const TYPE& value)
310     {
311         return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTranslator> >(value);
312     }
313
314     template<typename T, typename U, typename V, typename W, typename X>
315     template<typename TYPE, typename HashTranslator>
316     inline typename HashMap<T, U, V, W, X>::const_iterator 
317     HashMap<T, U, V, W, X>::find(const TYPE& value) const
318     {
319         return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTranslator> >(value);
320     }
321
322     template<typename T, typename U, typename V, typename W, typename X>
323     template<typename TYPE, typename HashTranslator>
324     inline bool
325     HashMap<T, U, V, W, X>::contains(const TYPE& value) const
326     {
327         return m_impl.template contains<HashMapTranslatorAdapter<ValueTraits, HashTranslator> >(value);
328     }
329
330     template<typename T, typename U, typename V, typename W, typename X>
331     typename HashMap<T, U, V, W, X>::AddResult
332     HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, MappedPassInReferenceType mapped) 
333     {
334         return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions> >(key, mapped);
335     }
336
337     template<typename T, typename U, typename V, typename W, typename X>
338     typename HashMap<T, U, V, W, X>::AddResult
339     HashMap<T, U, V, W, X>::set(const KeyType& key, MappedPassInType mapped) 
340     {
341         AddResult result = inlineAdd(key, mapped);
342         if (!result.isNewEntry) {
343             // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
344             MappedTraits::store(mapped, result.iterator->second);
345         }
346         return result;
347     }
348
349     template<typename T, typename U, typename V, typename W, typename X>
350     template<typename TYPE, typename HashTranslator>
351     typename HashMap<T, U, V, W, X>::AddResult
352     HashMap<T, U, V, W, X>::add(const TYPE& key, MappedPassInType value)
353     {
354         return m_impl.template addPassingHashCode<HashMapTranslatorAdapter<ValueTraits, HashTranslator> >(key, value);
355     }
356
357     template<typename T, typename U, typename V, typename W, typename X>
358     typename HashMap<T, U, V, W, X>::AddResult
359     HashMap<T, U, V, W, X>::add(const KeyType& key, MappedPassInType mapped)
360     {
361         return inlineAdd(key, mapped);
362     }
363
364     template<typename T, typename U, typename V, typename W, typename MappedTraits>
365     typename HashMap<T, U, V, W, MappedTraits>::MappedPeekType
366     HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const
367     {
368         ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
369         if (!entry)
370             return MappedTraits::peek(MappedTraits::emptyValue());
371         return MappedTraits::peek(entry->second);
372     }
373
374     template<typename T, typename U, typename V, typename W, typename X>
375     inline void HashMap<T, U, V, W, X>::remove(iterator it)
376     {
377         if (it.m_impl == m_impl.end())
378             return;
379         m_impl.internalCheckTableConsistency();
380         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
381     }
382
383     template<typename T, typename U, typename V, typename W, typename X>
384     inline void HashMap<T, U, V, W, X>::remove(const KeyType& key)
385     {
386         remove(find(key));
387     }
388
389     template<typename T, typename U, typename V, typename W, typename X>
390     inline void HashMap<T, U, V, W, X>::clear()
391     {
392         m_impl.clear();
393     }
394
395     template<typename T, typename U, typename V, typename W, typename MappedTraits>
396     typename HashMap<T, U, V, W, MappedTraits>::MappedPassOutType
397     HashMap<T, U, V, W, MappedTraits>::take(const KeyType& key)
398     {
399         iterator it = find(key);
400         if (it == end())
401             return MappedTraits::passOut(MappedTraits::emptyValue());
402         MappedPassOutType result = MappedTraits::passOut(it->second);
403         remove(it);
404         return result;
405     }
406
407     template<typename T, typename U, typename V, typename W, typename X>
408     inline void HashMap<T, U, V, W, X>::checkConsistency() const
409     {
410         m_impl.checkTableConsistency();
411     }
412
413     template<typename T, typename U, typename V, typename W, typename X>
414     bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
415     {
416         if (a.size() != b.size())
417             return false;
418
419         typedef typename HashMap<T, U, V, W, X>::const_iterator const_iterator;
420
421         const_iterator end = a.end();
422         const_iterator notFound = b.end();
423         for (const_iterator it = a.begin(); it != end; ++it) {
424             const_iterator bPos = b.find(it->first);
425             if (bPos == notFound || it->second != bPos->second)
426                 return false;
427         }
428
429         return true;
430     }
431
432     template<typename T, typename U, typename V, typename W, typename X>
433     inline bool operator!=(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
434     {
435         return !(a == b);
436     }
437
438     template<typename HashTableType>
439     void deleteAllPairSeconds(HashTableType& collection)
440     {
441         typedef typename HashTableType::const_iterator iterator;
442         iterator end = collection.end();
443         for (iterator it = collection.begin(); it != end; ++it)
444             delete it->second;
445     }
446
447     template<typename T, typename U, typename V, typename W, typename X>
448     inline void deleteAllValues(const HashMap<T, U, V, W, X>& collection)
449     {
450         deleteAllPairSeconds(collection);
451     }
452
453     template<typename HashTableType>
454     void deleteAllPairFirsts(HashTableType& collection)
455     {
456         typedef typename HashTableType::const_iterator iterator;
457         iterator end = collection.end();
458         for (iterator it = collection.begin(); it != end; ++it)
459             delete it->first;
460     }
461
462     template<typename T, typename U, typename V, typename W, typename X>
463     inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection)
464     {
465         deleteAllPairFirsts(collection);
466     }
467     
468     template<typename T, typename U, typename V, typename W, typename X, typename Y>
469     inline void copyKeysToVector(const HashMap<T, U, V, W, X>& collection, Y& vector)
470     {
471         typedef typename HashMap<T, U, V, W, X>::const_iterator::Keys iterator;
472         
473         vector.resize(collection.size());
474         
475         iterator it = collection.begin().keys();
476         iterator end = collection.end().keys();
477         for (unsigned i = 0; it != end; ++it, ++i)
478             vector[i] = *it;
479     }  
480
481     template<typename T, typename U, typename V, typename W, typename X, typename Y>
482     inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Y& vector)
483     {
484         typedef typename HashMap<T, U, V, W, X>::const_iterator::Values iterator;
485         
486         vector.resize(collection.size());
487         
488         iterator it = collection.begin().values();
489         iterator end = collection.end().values();
490         for (unsigned i = 0; it != end; ++it, ++i)
491             vector[i] = *it;
492     }   
493
494 } // namespace WTF
495
496 using WTF::HashMap;
497
498 #include <wtf/RefPtrHashMap.h>
499
500 #endif /* WTF_HashMap_h */