| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
| 18 * | 18 * |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 #ifndef WTF_HashMap_h | 21 #ifndef WTF_HashMap_h |
| 22 #define WTF_HashMap_h | 22 #define WTF_HashMap_h |
| 23 | 23 |
| 24 #include "wtf/HashTable.h" | 24 #include "wtf/HashTable.h" |
| 25 #include "wtf/PartitionAllocator.h" | 25 #include "wtf/PartitionAllocator.h" |
| 26 | 26 |
| 27 namespace WTF { | 27 namespace WTF { |
| 28 | 28 |
| 29 template <typename KeyTraits, typename MappedTraits> struct HashMapValueTraits; | 29 template <typename KeyTraits, typename MappedTraits> |
| 30 struct HashMapValueTraits; |
| 30 | 31 |
| 31 template <typename T> struct ReferenceTypeMaker { | 32 template <typename T> |
| 32 typedef T& ReferenceType; | 33 struct ReferenceTypeMaker { |
| 34 typedef T& ReferenceType; |
| 33 }; | 35 }; |
| 34 template <typename T> struct ReferenceTypeMaker<T&> { | 36 template <typename T> |
| 35 typedef T& ReferenceType; | 37 struct ReferenceTypeMaker<T&> { |
| 38 typedef T& ReferenceType; |
| 36 }; | 39 }; |
| 37 | 40 |
| 38 struct KeyValuePairKeyExtractor { | 41 struct KeyValuePairKeyExtractor { |
| 39 template <typename T> | 42 template <typename T> |
| 40 static const typename T::KeyType& extract(const T& p) { return p.key; } | 43 static const typename T::KeyType& extract(const T& p) { return p.key; } |
| 41 }; | 44 }; |
| 42 | 45 |
| 43 // Note: empty or deleted key values are not allowed, using them may lead to | 46 // Note: empty or deleted key values are not allowed, using them may lead to |
| 44 // undefined behavior. For pointer keys this means that null pointers are not | 47 // undefined behavior. For pointer keys this means that null pointers are not |
| 45 // allowed unless you supply custom key traits. | 48 // allowed unless you supply custom key traits. |
| 46 template < | 49 template < |
| 47 typename KeyArg, | 50 typename KeyArg, |
| 48 typename MappedArg, | 51 typename MappedArg, |
| 49 typename HashArg = typename DefaultHash<KeyArg>::Hash, | 52 typename HashArg = typename DefaultHash<KeyArg>::Hash, |
| 50 typename KeyTraitsArg = HashTraits<KeyArg>, | 53 typename KeyTraitsArg = HashTraits<KeyArg>, |
| 51 typename MappedTraitsArg = HashTraits<MappedArg>, | 54 typename MappedTraitsArg = HashTraits<MappedArg>, |
| 52 typename Allocator = PartitionAllocator> | 55 typename Allocator = PartitionAllocator> |
| 53 class HashMap { | 56 class HashMap { |
| 54 WTF_USE_ALLOCATOR(HashMap, Allocator); | 57 WTF_USE_ALLOCATOR(HashMap, Allocator); |
| 55 private: | 58 |
| 56 typedef KeyTraitsArg KeyTraits; | 59 private: |
| 57 typedef MappedTraitsArg MappedTraits; | 60 typedef KeyTraitsArg KeyTraits; |
| 58 typedef HashMapValueTraits<KeyTraits, MappedTraits> ValueTraits; | 61 typedef MappedTraitsArg MappedTraits; |
| 59 | 62 typedef HashMapValueTraits<KeyTraits, MappedTraits> ValueTraits; |
| 60 public: | 63 |
| 61 typedef typename KeyTraits::TraitType KeyType; | 64 public: |
| 62 typedef const typename KeyTraits::PeekInType& KeyPeekInType; | 65 typedef typename KeyTraits::TraitType KeyType; |
| 63 typedef typename MappedTraits::TraitType MappedType; | 66 typedef const typename KeyTraits::PeekInType& KeyPeekInType; |
| 64 typedef typename ValueTraits::TraitType ValueType; | 67 typedef typename MappedTraits::TraitType MappedType; |
| 65 | 68 typedef typename ValueTraits::TraitType ValueType; |
| 66 private: | 69 |
| 67 typedef typename MappedTraits::PassInType MappedPassInType; | 70 private: |
| 68 typedef typename MappedTraits::PassOutType MappedPassOutType; | 71 typedef typename MappedTraits::PassInType MappedPassInType; |
| 69 typedef typename MappedTraits::PeekOutType MappedPeekType; | 72 typedef typename MappedTraits::PassOutType MappedPassOutType; |
| 70 | 73 typedef typename MappedTraits::PeekOutType MappedPeekType; |
| 71 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedP
assInReferenceType; | 74 |
| 72 | 75 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedPas
sInReferenceType; |
| 73 typedef HashArg HashFunctions; | 76 |
| 74 | 77 typedef HashArg HashFunctions; |
| 75 typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor, | 78 |
| 76 HashFunctions, ValueTraits, KeyTraits, Allocator> HashTableType; | 79 typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor, HashFunctions,
ValueTraits, KeyTraits, Allocator> HashTableType; |
| 77 | 80 |
| 78 class HashMapKeysProxy; | 81 class HashMapKeysProxy; |
| 79 class HashMapValuesProxy; | 82 class HashMapValuesProxy; |
| 80 | 83 |
| 81 public: | 84 public: |
| 82 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; | 85 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; |
| 83 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterat
or; | 86 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator
; |
| 84 typedef typename HashTableType::AddResult AddResult; | 87 typedef typename HashTableType::AddResult AddResult; |
| 85 | 88 |
| 86 public: | 89 public: |
| 87 void swap(HashMap& ref) | 90 void swap(HashMap& ref) { |
| 88 { | 91 m_impl.swap(ref.m_impl); |
| 89 m_impl.swap(ref.m_impl); | 92 } |
| 90 } | 93 |
| 91 | 94 void swap(typename Allocator::template OtherType<HashMap>::Type other) { |
| 92 void swap(typename Allocator::template OtherType<HashMap>::Type other) | 95 HashMap& ref = Allocator::getOther(other); |
| 93 { | 96 m_impl.swap(ref.m_impl); |
| 94 HashMap& ref = Allocator::getOther(other); | 97 } |
| 95 m_impl.swap(ref.m_impl); | 98 |
| 96 } | 99 unsigned size() const; |
| 97 | 100 unsigned capacity() const; |
| 98 unsigned size() const; | 101 void reserveCapacityForSize(unsigned size) { |
| 99 unsigned capacity() const; | 102 m_impl.reserveCapacityForSize(size); |
| 100 void reserveCapacityForSize(unsigned size) | 103 } |
| 101 { | 104 |
| 102 m_impl.reserveCapacityForSize(size); | 105 bool isEmpty() const; |
| 103 } | 106 |
| 104 | 107 // iterators iterate over pairs of keys and values |
| 105 bool isEmpty() const; | 108 iterator begin(); |
| 106 | 109 iterator end(); |
| 107 // iterators iterate over pairs of keys and values | 110 const_iterator begin() const; |
| 108 iterator begin(); | 111 const_iterator end() const; |
| 109 iterator end(); | 112 |
| 110 const_iterator begin() const; | 113 HashMapKeysProxy& keys() { return static_cast<HashMapKeysProxy&>(*this); } |
| 111 const_iterator end() const; | 114 const HashMapKeysProxy& keys() const { return static_cast<const HashMapKeysPro
xy&>(*this); } |
| 112 | 115 |
| 113 HashMapKeysProxy& keys() { return static_cast<HashMapKeysProxy&>(*this); } | 116 HashMapValuesProxy& values() { return static_cast<HashMapValuesProxy&>(*this);
} |
| 114 const HashMapKeysProxy& keys() const { return static_cast<const HashMapKeysP
roxy&>(*this); } | 117 const HashMapValuesProxy& values() const { return static_cast<const HashMapVal
uesProxy&>(*this); } |
| 115 | 118 |
| 116 HashMapValuesProxy& values() { return static_cast<HashMapValuesProxy&>(*this
); } | 119 iterator find(KeyPeekInType); |
| 117 const HashMapValuesProxy& values() const { return static_cast<const HashMapV
aluesProxy&>(*this); } | 120 const_iterator find(KeyPeekInType) const; |
| 118 | 121 bool contains(KeyPeekInType) const; |
| 119 iterator find(KeyPeekInType); | 122 MappedPeekType get(KeyPeekInType) const; |
| 120 const_iterator find(KeyPeekInType) const; | 123 |
| 121 bool contains(KeyPeekInType) const; | 124 // replaces value but not key if key is already present return value is a |
| 122 MappedPeekType get(KeyPeekInType) const; | 125 // pair of the iterator to the key location, and a boolean that's true if a |
| 123 | 126 // new value was actually added |
| 124 // replaces value but not key if key is already present return value is a | 127 AddResult set(KeyPeekInType, MappedPassInType); |
| 125 // pair of the iterator to the key location, and a boolean that's true if a | 128 |
| 126 // new value was actually added | 129 // does nothing if key is already present return value is a pair of the |
| 127 AddResult set(KeyPeekInType, MappedPassInType); | 130 // iterator to the key location, and a boolean that's true if a new value |
| 128 | 131 // was actually added |
| 129 // does nothing if key is already present return value is a pair of the | 132 AddResult add(KeyPeekInType, MappedPassInType); |
| 130 // iterator to the key location, and a boolean that's true if a new value | 133 |
| 131 // was actually added | 134 void remove(KeyPeekInType); |
| 132 AddResult add(KeyPeekInType, MappedPassInType); | 135 void remove(iterator); |
| 133 | 136 void clear(); |
| 134 void remove(KeyPeekInType); | 137 template <typename Collection> |
| 135 void remove(iterator); | 138 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRemo
ved); } |
| 136 void clear(); | 139 |
| 137 template <typename Collection> | 140 MappedPassOutType take(KeyPeekInType); // efficient combination of get with r
emove |
| 138 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRe
moved); } | 141 |
| 139 | 142 // An alternate version of find() that finds the object by hashing and |
| 140 MappedPassOutType take(KeyPeekInType); // efficient combination of get with
remove | 143 // comparing with some other type, to avoid the cost of type |
| 141 | 144 // conversion. HashTranslator must have the following function members: |
| 142 // An alternate version of find() that finds the object by hashing and | 145 // static unsigned hash(const T&); |
| 143 // comparing with some other type, to avoid the cost of type | 146 // static bool equal(const ValueType&, const T&); |
| 144 // conversion. HashTranslator must have the following function members: | 147 template <typename HashTranslator, typename T> |
| 145 // static unsigned hash(const T&); | 148 iterator find(const T&); |
| 146 // static bool equal(const ValueType&, const T&); | 149 template <typename HashTranslator, typename T> |
| 147 template <typename HashTranslator, typename T> iterator find(const T&); | 150 const_iterator find(const T&) const; |
| 148 template <typename HashTranslator, typename T> const_iterator find(const T&)
const; | 151 template <typename HashTranslator, typename T> |
| 149 template <typename HashTranslator, typename T> bool contains(const T&) const
; | 152 bool contains(const T&) const; |
| 150 | 153 |
| 151 // An alternate version of add() that finds the object by hashing and | 154 // An alternate version of add() that finds the object by hashing and |
| 152 // comparing with some other type, to avoid the cost of type conversion if | 155 // comparing with some other type, to avoid the cost of type conversion if |
| 153 // the object is already in the table. HashTranslator must have the | 156 // the object is already in the table. HashTranslator must have the |
| 154 // following function members: | 157 // following function members: |
| 155 // static unsigned hash(const T&); | 158 // static unsigned hash(const T&); |
| 156 // static bool equal(const ValueType&, const T&); | 159 // static bool equal(const ValueType&, const T&); |
| 157 // static translate(ValueType&, const T&, unsigned hashCode); | 160 // static translate(ValueType&, const T&, unsigned hashCode); |
| 158 template <typename HashTranslator, typename T> AddResult add(const T&, Mappe
dPassInType); | 161 template <typename HashTranslator, typename T> |
| 159 | 162 AddResult add(const T&, MappedPassInType); |
| 160 static bool isValidKey(KeyPeekInType); | 163 |
| 161 | 164 static bool isValidKey(KeyPeekInType); |
| 162 template <typename VisitorDispatcher> | 165 |
| 163 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 166 template <typename VisitorDispatcher> |
| 164 | 167 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } |
| 165 private: | 168 |
| 166 AddResult inlineAdd(KeyPeekInType, MappedPassInReferenceType); | 169 private: |
| 167 | 170 AddResult inlineAdd(KeyPeekInType, MappedPassInReferenceType); |
| 168 HashTableType m_impl; | 171 |
| 172 HashTableType m_impl; |
| 169 }; | 173 }; |
| 170 | 174 |
| 171 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTra
itsArg, typename MappedTraitsArg, typename Allocator> | 175 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTra
itsArg, typename MappedTraitsArg, typename Allocator> |
| 172 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapKeysProxy : | 176 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapKeysProxy : private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg
, MappedTraitsArg, Allocator> { |
| 173 private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> { | 177 public: |
| 174 public: | 178 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, All
ocator> HashMapType; |
| 175 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> HashMapType; | 179 typedef typename HashMapType::iterator::Keys iterator; |
| 176 typedef typename HashMapType::iterator::Keys iterator; | 180 typedef typename HashMapType::const_iterator::Keys const_iterator; |
| 177 typedef typename HashMapType::const_iterator::Keys const_iterator; | 181 |
| 178 | 182 iterator begin() { |
| 179 iterator begin() | 183 return HashMapType::begin().keys(); |
| 180 { | 184 } |
| 181 return HashMapType::begin().keys(); | 185 |
| 182 } | 186 iterator end() { |
| 183 | 187 return HashMapType::end().keys(); |
| 184 iterator end() | 188 } |
| 185 { | 189 |
| 186 return HashMapType::end().keys(); | 190 const_iterator begin() const { |
| 187 } | 191 return HashMapType::begin().keys(); |
| 188 | 192 } |
| 189 const_iterator begin() const | 193 |
| 190 { | 194 const_iterator end() const { |
| 191 return HashMapType::begin().keys(); | 195 return HashMapType::end().keys(); |
| 192 } | 196 } |
| 193 | 197 |
| 194 const_iterator end() const | 198 private: |
| 195 { | 199 friend class HashMap; |
| 196 return HashMapType::end().keys(); | 200 |
| 197 } | 201 // These are intentionally not implemented. |
| 198 | 202 HashMapKeysProxy(); |
| 199 private: | 203 HashMapKeysProxy(const HashMapKeysProxy&); |
| 200 friend class HashMap; | 204 HashMapKeysProxy& operator=(const HashMapKeysProxy&); |
| 201 | 205 ~HashMapKeysProxy(); |
| 202 // These are intentionally not implemented. | 206 }; |
| 203 HashMapKeysProxy(); | 207 |
| 204 HashMapKeysProxy(const HashMapKeysProxy&); | 208 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTra
itsArg, typename MappedTraitsArg, typename Allocator> |
| 205 HashMapKeysProxy& operator=(const HashMapKeysProxy&); | 209 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapValuesProxy : private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsA
rg, MappedTraitsArg, Allocator> { |
| 206 ~HashMapKeysProxy(); | 210 public: |
| 207 }; | 211 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, All
ocator> HashMapType; |
| 208 | 212 typedef typename HashMapType::iterator::Values iterator; |
| 209 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTr
aitsArg, typename MappedTraitsArg, typename Allocator> | 213 typedef typename HashMapType::const_iterator::Values const_iterator; |
| 210 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapValuesProxy : | 214 |
| 211 private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> { | 215 iterator begin() { |
| 212 public: | 216 return HashMapType::begin().values(); |
| 213 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> HashMapType; | 217 } |
| 214 typedef typename HashMapType::iterator::Values iterator; | 218 |
| 215 typedef typename HashMapType::const_iterator::Values const_iterator; | 219 iterator end() { |
| 216 | 220 return HashMapType::end().values(); |
| 217 iterator begin() | 221 } |
| 218 { | 222 |
| 219 return HashMapType::begin().values(); | 223 const_iterator begin() const { |
| 220 } | 224 return HashMapType::begin().values(); |
| 221 | 225 } |
| 222 iterator end() | 226 |
| 223 { | 227 const_iterator end() const { |
| 224 return HashMapType::end().values(); | 228 return HashMapType::end().values(); |
| 225 } | 229 } |
| 226 | 230 |
| 227 const_iterator begin() const | 231 private: |
| 228 { | 232 friend class HashMap; |
| 229 return HashMapType::begin().values(); | 233 |
| 230 } | 234 // These are intentionally not implemented. |
| 231 | 235 HashMapValuesProxy(); |
| 232 const_iterator end() const | 236 HashMapValuesProxy(const HashMapValuesProxy&); |
| 233 { | 237 HashMapValuesProxy& operator=(const HashMapValuesProxy&); |
| 234 return HashMapType::end().values(); | 238 ~HashMapValuesProxy(); |
| 235 } | |
| 236 | |
| 237 private: | |
| 238 friend class HashMap; | |
| 239 | |
| 240 // These are intentionally not implemented. | |
| 241 HashMapValuesProxy(); | |
| 242 HashMapValuesProxy(const HashMapValuesProxy&); | |
| 243 HashMapValuesProxy& operator=(const HashMapValuesProxy&); | |
| 244 ~HashMapValuesProxy(); | |
| 245 }; | 239 }; |
| 246 | 240 |
| 247 template <typename KeyTraits, typename MappedTraits> | 241 template <typename KeyTraits, typename MappedTraits> |
| 248 struct HashMapValueTraits : KeyValuePairHashTraits<KeyTraits, MappedTraits> { | 242 struct HashMapValueTraits : KeyValuePairHashTraits<KeyTraits, MappedTraits> { |
| 249 static const bool hasIsEmptyValueFunction = true; | 243 static const bool hasIsEmptyValueFunction = true; |
| 250 static bool isEmptyValue(const typename KeyValuePairHashTraits<KeyTraits, Ma
ppedTraits>::TraitType& value) | 244 static bool isEmptyValue(const typename KeyValuePairHashTraits<KeyTraits, Mapp
edTraits>::TraitType& value) { |
| 251 { | 245 return isHashTraitsEmptyValue<KeyTraits>(value.key); |
| 252 return isHashTraitsEmptyValue<KeyTraits>(value.key); | 246 } |
| 253 } | |
| 254 }; | 247 }; |
| 255 | 248 |
| 256 template <typename ValueTraits, typename HashFunctions> | 249 template <typename ValueTraits, typename HashFunctions> |
| 257 struct HashMapTranslator { | 250 struct HashMapTranslator { |
| 258 template <typename T> static unsigned hash(const T& key) { return HashFuncti
ons::hash(key); } | 251 template <typename T> |
| 259 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return HashFunctions::equal(a, b); } | 252 static unsigned hash(const T& key) { return HashFunctions::hash(key); } |
| 260 template <typename T, typename U, typename V> static void translate(T& locat
ion, const U& key, const V& mapped) | 253 template <typename T, typename U> |
| 261 { | 254 static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b);
} |
| 262 location.key = key; | 255 template <typename T, typename U, typename V> |
| 263 ValueTraits::ValueTraits::store(mapped, location.value); | 256 static void translate(T& location, const U& key, const V& mapped) { |
| 264 } | 257 location.key = key; |
| 258 ValueTraits::ValueTraits::store(mapped, location.value); |
| 259 } |
| 265 }; | 260 }; |
| 266 | 261 |
| 267 template <typename ValueTraits, typename Translator> | 262 template <typename ValueTraits, typename Translator> |
| 268 struct HashMapTranslatorAdapter { | 263 struct HashMapTranslatorAdapter { |
| 269 template <typename T> static unsigned hash(const T& key) { return Translator
::hash(key); } | 264 template <typename T> |
| 270 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return Translator::equal(a, b); } | 265 static unsigned hash(const T& key) { return Translator::hash(key); } |
| 271 template <typename T, typename U, typename V> static void translate(T& locat
ion, const U& key, const V& mapped, unsigned hashCode) | 266 template <typename T, typename U> |
| 272 { | 267 static bool equal(const T& a, const U& b) { return Translator::equal(a, b); } |
| 273 Translator::translate(location.key, key, hashCode); | 268 template <typename T, typename U, typename V> |
| 274 ValueTraits::ValueTraits::store(mapped, location.value); | 269 static void translate(T& location, const U& key, const V& mapped, unsigned has
hCode) { |
| 275 } | 270 Translator::translate(location.key, key, hashCode); |
| 276 }; | 271 ValueTraits::ValueTraits::store(mapped, location.value); |
| 277 | 272 } |
| 278 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 273 }; |
| 279 inline unsigned HashMap<T, U, V, W, X, Y>::size() const | 274 |
| 280 { | 275 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 281 return m_impl.size(); | 276 inline unsigned HashMap<T, U, V, W, X, Y>::size() const { |
| 282 } | 277 return m_impl.size(); |
| 283 | 278 } |
| 284 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 279 |
| 285 inline unsigned HashMap<T, U, V, W, X, Y>::capacity() const | 280 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 286 { | 281 inline unsigned HashMap<T, U, V, W, X, Y>::capacity() const { |
| 287 return m_impl.capacity(); | 282 return m_impl.capacity(); |
| 288 } | 283 } |
| 289 | 284 |
| 290 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 285 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 291 inline bool HashMap<T, U, V, W, X, Y>::isEmpty() const | 286 inline bool HashMap<T, U, V, W, X, Y>::isEmpty() const { |
| 292 { | 287 return m_impl.isEmpty(); |
| 293 return m_impl.isEmpty(); | 288 } |
| 294 } | 289 |
| 295 | 290 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 296 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 291 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::b
egin() { |
| 297 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::b
egin() | 292 return m_impl.begin(); |
| 298 { | 293 } |
| 299 return m_impl.begin(); | 294 |
| 300 } | 295 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 301 | 296 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::e
nd() { |
| 302 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 297 return m_impl.end(); |
| 303 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::e
nd() | 298 } |
| 304 { | 299 |
| 305 return m_impl.end(); | 300 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 306 } | 301 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::begin() const { |
| 307 | 302 return m_impl.begin(); |
| 308 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 303 } |
| 309 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::begin() const | 304 |
| 310 { | 305 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 311 return m_impl.begin(); | 306 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::end() const { |
| 312 } | 307 return m_impl.end(); |
| 313 | 308 } |
| 314 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 309 |
| 315 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::end() const | 310 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 316 { | 311 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::f
ind(KeyPeekInType key) { |
| 317 return m_impl.end(); | 312 return m_impl.find(key); |
| 318 } | 313 } |
| 319 | 314 |
| 320 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 315 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 321 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::f
ind(KeyPeekInType key) | 316 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::find(KeyPeekInType key) const { |
| 322 { | 317 return m_impl.find(key); |
| 323 return m_impl.find(key); | 318 } |
| 324 } | 319 |
| 325 | 320 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 326 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 321 inline bool HashMap<T, U, V, W, X, Y>::contains(KeyPeekInType key) const { |
| 327 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::find(KeyPeekInType key) const | 322 return m_impl.contains(key); |
| 328 { | |
| 329 return m_impl.find(key); | |
| 330 } | |
| 331 | |
| 332 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | |
| 333 inline bool HashMap<T, U, V, W, X, Y>::contains(KeyPeekInType key) const | |
| 334 { | |
| 335 return m_impl.contains(key); | |
| 336 } | 323 } |
| 337 | 324 |
| 338 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 325 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 339 template <typename HashTranslator, typename TYPE> | 326 template <typename HashTranslator, typename TYPE> |
| 340 inline typename HashMap<T, U, V, W, X, Y>::iterator | 327 inline typename HashMap<T, U, V, W, X, Y>::iterator |
| 341 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) | 328 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) { |
| 342 { | 329 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTranslat
or>>(value); |
| 343 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTransl
ator>>(value); | |
| 344 } | 330 } |
| 345 | 331 |
| 346 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 332 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 347 template <typename HashTranslator, typename TYPE> | 333 template <typename HashTranslator, typename TYPE> |
| 348 inline typename HashMap<T, U, V, W, X, Y>::const_iterator | 334 inline typename HashMap<T, U, V, W, X, Y>::const_iterator |
| 349 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) const | 335 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) const { |
| 350 { | 336 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTranslat
or>>(value); |
| 351 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTransl
ator>>(value); | |
| 352 } | 337 } |
| 353 | 338 |
| 354 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 339 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 355 template <typename HashTranslator, typename TYPE> | 340 template <typename HashTranslator, typename TYPE> |
| 356 inline bool | 341 inline bool |
| 357 HashMap<T, U, V, W, X, Y>::contains(const TYPE& value) const | 342 HashMap<T, U, V, W, X, Y>::contains(const TYPE& value) const { |
| 358 { | 343 return m_impl.template contains<HashMapTranslatorAdapter<ValueTraits, HashTran
slator>>(value); |
| 359 return m_impl.template contains<HashMapTranslatorAdapter<ValueTraits, HashTr
anslator>>(value); | |
| 360 } | 344 } |
| 361 | 345 |
| 362 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 346 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 363 typename HashMap<T, U, V, W, X, Y>::AddResult | 347 typename HashMap<T, U, V, W, X, Y>::AddResult |
| 364 HashMap<T, U, V, W, X, Y>::inlineAdd(KeyPeekInType key, MappedPassInReferenceTyp
e mapped) | 348 HashMap<T, U, V, W, X, Y>::inlineAdd(KeyPeekInType key, MappedPassInReferenceTyp
e mapped) { |
| 365 { | 349 return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>(key,
mapped); |
| 366 return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>(ke
y, mapped); | |
| 367 } | 350 } |
| 368 | 351 |
| 369 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 352 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 370 typename HashMap<T, U, V, W, X, Y>::AddResult | 353 typename HashMap<T, U, V, W, X, Y>::AddResult |
| 371 HashMap<T, U, V, W, X, Y>::set(KeyPeekInType key, MappedPassInType mapped) | 354 HashMap<T, U, V, W, X, Y>::set(KeyPeekInType key, MappedPassInType mapped) { |
| 372 { | 355 AddResult result = inlineAdd(key, mapped); |
| 373 AddResult result = inlineAdd(key, mapped); | 356 if (!result.isNewEntry) { |
| 374 if (!result.isNewEntry) { | 357 // The inlineAdd call above found an existing hash table entry; we need |
| 375 // The inlineAdd call above found an existing hash table entry; we need | 358 // to set the mapped value. |
| 376 // to set the mapped value. | 359 MappedTraits::store(mapped, result.storedValue->value); |
| 377 MappedTraits::store(mapped, result.storedValue->value); | 360 } |
| 378 } | 361 return result; |
| 379 return result; | |
| 380 } | 362 } |
| 381 | 363 |
| 382 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 364 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 383 template <typename HashTranslator, typename TYPE> | 365 template <typename HashTranslator, typename TYPE> |
| 384 typename HashMap<T, U, V, W, X, Y>::AddResult | 366 typename HashMap<T, U, V, W, X, Y>::AddResult |
| 385 HashMap<T, U, V, W, X, Y>::add(const TYPE& key, MappedPassInType value) | 367 HashMap<T, U, V, W, X, Y>::add(const TYPE& key, MappedPassInType value) { |
| 386 { | 368 return m_impl.template addPassingHashCode<HashMapTranslatorAdapter<ValueTraits
, HashTranslator>>(key, value); |
| 387 return m_impl.template addPassingHashCode<HashMapTranslatorAdapter<ValueTrai
ts, HashTranslator>>(key, value); | |
| 388 } | 369 } |
| 389 | 370 |
| 390 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 371 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 391 typename HashMap<T, U, V, W, X, Y>::AddResult | 372 typename HashMap<T, U, V, W, X, Y>::AddResult |
| 392 HashMap<T, U, V, W, X, Y>::add(KeyPeekInType key, MappedPassInType mapped) | 373 HashMap<T, U, V, W, X, Y>::add(KeyPeekInType key, MappedPassInType mapped) { |
| 393 { | 374 return inlineAdd(key, mapped); |
| 394 return inlineAdd(key, mapped); | |
| 395 } | 375 } |
| 396 | 376 |
| 397 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 377 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 398 typename HashMap<T, U, V, W, X, Y>::MappedPeekType | 378 typename HashMap<T, U, V, W, X, Y>::MappedPeekType |
| 399 HashMap<T, U, V, W, X, Y>::get(KeyPeekInType key) const | 379 HashMap<T, U, V, W, X, Y>::get(KeyPeekInType key) const { |
| 400 { | 380 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); |
| 401 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); | 381 if (!entry) |
| 402 if (!entry) | 382 return MappedTraits::peek(MappedTraits::emptyValue()); |
| 403 return MappedTraits::peek(MappedTraits::emptyValue()); | 383 return MappedTraits::peek(entry->value); |
| 404 return MappedTraits::peek(entry->value); | 384 } |
| 405 } | 385 |
| 406 | 386 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 407 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 387 inline void HashMap<T, U, V, W, X, Y>::remove(iterator it) { |
| 408 inline void HashMap<T, U, V, W, X, Y>::remove(iterator it) | 388 m_impl.remove(it.m_impl); |
| 409 { | 389 } |
| 410 m_impl.remove(it.m_impl); | 390 |
| 411 } | 391 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 412 | 392 inline void HashMap<T, U, V, W, X, Y>::remove(KeyPeekInType key) { |
| 413 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 393 remove(find(key)); |
| 414 inline void HashMap<T, U, V, W, X, Y>::remove(KeyPeekInType key) | 394 } |
| 415 { | 395 |
| 416 remove(find(key)); | 396 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 417 } | 397 inline void HashMap<T, U, V, W, X, Y>::clear() { |
| 418 | 398 m_impl.clear(); |
| 419 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | |
| 420 inline void HashMap<T, U, V, W, X, Y>::clear() | |
| 421 { | |
| 422 m_impl.clear(); | |
| 423 } | 399 } |
| 424 | 400 |
| 425 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 401 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 426 typename HashMap<T, U, V, W, X, Y>::MappedPassOutType | 402 typename HashMap<T, U, V, W, X, Y>::MappedPassOutType |
| 427 HashMap<T, U, V, W, X, Y>::take(KeyPeekInType key) | 403 HashMap<T, U, V, W, X, Y>::take(KeyPeekInType key) { |
| 428 { | 404 iterator it = find(key); |
| 429 iterator it = find(key); | 405 if (it == end()) |
| 430 if (it == end()) | 406 return MappedTraits::passOut(MappedTraits::emptyValue()); |
| 431 return MappedTraits::passOut(MappedTraits::emptyValue()); | 407 MappedPassOutType result = MappedTraits::passOut(it->value); |
| 432 MappedPassOutType result = MappedTraits::passOut(it->value); | 408 remove(it); |
| 433 remove(it); | 409 return result; |
| 434 return result; | 410 } |
| 435 } | 411 |
| 436 | 412 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 437 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 413 inline bool HashMap<T, U, V, W, X, Y>::isValidKey(KeyPeekInType key) { |
| 438 inline bool HashMap<T, U, V, W, X, Y>::isValidKey(KeyPeekInType key) | 414 if (KeyTraits::isDeletedValue(key)) |
| 439 { | 415 return false; |
| 440 if (KeyTraits::isDeletedValue(key)) | 416 |
| 441 return false; | 417 if (HashFunctions::safeToCompareToEmptyOrDeleted) { |
| 442 | 418 if (key == KeyTraits::emptyValue()) |
| 443 if (HashFunctions::safeToCompareToEmptyOrDeleted) { | 419 return false; |
| 444 if (key == KeyTraits::emptyValue()) | 420 } else { |
| 445 return false; | 421 if (isHashTraitsEmptyValue<KeyTraits>(key)) |
| 446 } else { | 422 return false; |
| 447 if (isHashTraitsEmptyValue<KeyTraits>(key)) | 423 } |
| 448 return false; | 424 |
| 449 } | 425 return true; |
| 450 | 426 } |
| 451 return true; | 427 |
| 452 } | 428 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 453 | 429 bool operator==(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V, W, X,
Y>& b) { |
| 454 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 430 if (a.size() != b.size()) |
| 455 bool operator==(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V, W, X,
Y>& b) | 431 return false; |
| 456 { | 432 |
| 457 if (a.size() != b.size()) | 433 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator const_iterator; |
| 458 return false; | 434 |
| 459 | 435 const_iterator aEnd = a.end(); |
| 460 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator const_iterator; | 436 const_iterator bEnd = b.end(); |
| 461 | 437 for (const_iterator it = a.begin(); it != aEnd; ++it) { |
| 462 const_iterator aEnd = a.end(); | 438 const_iterator bPos = b.find(it->key); |
| 463 const_iterator bEnd = b.end(); | 439 if (bPos == bEnd || it->value != bPos->value) |
| 464 for (const_iterator it = a.begin(); it != aEnd; ++it) { | 440 return false; |
| 465 const_iterator bPos = b.find(it->key); | 441 } |
| 466 if (bPos == bEnd || it->value != bPos->value) | 442 |
| 467 return false; | 443 return true; |
| 468 } | 444 } |
| 469 | 445 |
| 470 return true; | 446 template <typename T, typename U, typename V, typename W, typename X, typename Y
> |
| 471 } | 447 inline bool operator!=(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V
, W, X, Y>& b) { |
| 472 | 448 return !(a == b); |
| 473 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | |
| 474 inline bool operator!=(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V
, W, X, Y>& b) | |
| 475 { | |
| 476 return !(a == b); | |
| 477 } | 449 } |
| 478 | 450 |
| 479 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> | 451 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> |
| 480 inline void copyKeysToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& vec
tor) | 452 inline void copyKeysToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& vec
tor) { |
| 481 { | 453 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Keys iterator; |
| 482 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Keys iterator; | 454 |
| 483 | 455 vector.resize(collection.size()); |
| 484 vector.resize(collection.size()); | 456 |
| 485 | 457 iterator it = collection.begin().keys(); |
| 486 iterator it = collection.begin().keys(); | 458 iterator end = collection.end().keys(); |
| 487 iterator end = collection.end().keys(); | 459 for (unsigned i = 0; it != end; ++it, ++i) |
| 488 for (unsigned i = 0; it != end; ++it, ++i) | 460 vector[i] = *it; |
| 489 vector[i] = *it; | |
| 490 } | 461 } |
| 491 | 462 |
| 492 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> | 463 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> |
| 493 inline void copyValuesToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& v
ector) | 464 inline void copyValuesToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& v
ector) { |
| 494 { | 465 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Values iterator; |
| 495 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Values iterator; | 466 |
| 496 | 467 vector.resize(collection.size()); |
| 497 vector.resize(collection.size()); | 468 |
| 498 | 469 iterator it = collection.begin().values(); |
| 499 iterator it = collection.begin().values(); | 470 iterator end = collection.end().values(); |
| 500 iterator end = collection.end().values(); | 471 for (unsigned i = 0; it != end; ++it, ++i) |
| 501 for (unsigned i = 0; it != end; ++it, ++i) | 472 vector[i] = *it; |
| 502 vector[i] = *it; | |
| 503 } | 473 } |
| 504 | 474 |
| 505 #if !ENABLE(OILPAN) | 475 #if !ENABLE(OILPAN) |
| 506 template <typename T, typename U, typename V, typename W, typename X> | 476 template <typename T, typename U, typename V, typename W, typename X> |
| 507 struct NeedsTracing<HashMap<T, U, V, W, X>> { | 477 struct NeedsTracing<HashMap<T, U, V, W, X>> { |
| 508 static const bool value = false; | 478 static const bool value = false; |
| 509 }; | 479 }; |
| 510 #endif | 480 #endif |
| 511 | 481 |
| 512 } // namespace WTF | 482 } // namespace WTF |
| 513 | 483 |
| 514 using WTF::HashMap; | 484 using WTF::HashMap; |
| 515 | 485 |
| 516 #endif // WTF_HashMap_h | 486 #endif // WTF_HashMap_h |
| OLD | NEW |