| 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 | 30 struct HashMapValueTraits; |
| 31 template <typename T> struct ReferenceTypeMaker { | 31 |
| 32 STATIC_ONLY(ReferenceTypeMaker); | 32 template <typename T> |
| 33 typedef T& ReferenceType; | 33 struct ReferenceTypeMaker { |
| 34 }; | 34 STATIC_ONLY(ReferenceTypeMaker); |
| 35 template <typename T> struct ReferenceTypeMaker<T&> { | 35 typedef T& ReferenceType; |
| 36 STATIC_ONLY(ReferenceTypeMaker); | 36 }; |
| 37 typedef T& ReferenceType; | 37 template <typename T> |
| 38 struct ReferenceTypeMaker<T&> { |
| 39 STATIC_ONLY(ReferenceTypeMaker); |
| 40 typedef T& ReferenceType; |
| 38 }; | 41 }; |
| 39 | 42 |
| 40 struct KeyValuePairKeyExtractor { | 43 struct KeyValuePairKeyExtractor { |
| 41 STATIC_ONLY(KeyValuePairKeyExtractor); | 44 STATIC_ONLY(KeyValuePairKeyExtractor); |
| 42 template <typename T> | 45 template <typename T> |
| 43 static const typename T::KeyType& extract(const T& p) { return p.key; } | 46 static const typename T::KeyType& extract(const T& p) { |
| 47 return p.key; |
| 48 } |
| 44 }; | 49 }; |
| 45 | 50 |
| 46 // Note: empty or deleted key values are not allowed, using them may lead to | 51 // Note: empty or deleted key values are not allowed, using them may lead to |
| 47 // undefined behavior. For pointer keys this means that null pointers are not | 52 // undefined behavior. For pointer keys this means that null pointers are not |
| 48 // allowed unless you supply custom key traits. | 53 // allowed unless you supply custom key traits. |
| 49 template < | 54 template <typename KeyArg, |
| 50 typename KeyArg, | 55 typename MappedArg, |
| 51 typename MappedArg, | 56 typename HashArg = typename DefaultHash<KeyArg>::Hash, |
| 52 typename HashArg = typename DefaultHash<KeyArg>::Hash, | 57 typename KeyTraitsArg = HashTraits<KeyArg>, |
| 53 typename KeyTraitsArg = HashTraits<KeyArg>, | 58 typename MappedTraitsArg = HashTraits<MappedArg>, |
| 54 typename MappedTraitsArg = HashTraits<MappedArg>, | 59 typename Allocator = PartitionAllocator> |
| 55 typename Allocator = PartitionAllocator> | |
| 56 class HashMap { | 60 class HashMap { |
| 57 WTF_USE_ALLOCATOR(HashMap, Allocator); | 61 WTF_USE_ALLOCATOR(HashMap, Allocator); |
| 58 private: | 62 |
| 59 typedef KeyTraitsArg KeyTraits; | 63 private: |
| 60 typedef MappedTraitsArg MappedTraits; | 64 typedef KeyTraitsArg KeyTraits; |
| 61 typedef HashMapValueTraits<KeyTraits, MappedTraits> ValueTraits; | 65 typedef MappedTraitsArg MappedTraits; |
| 62 | 66 typedef HashMapValueTraits<KeyTraits, MappedTraits> ValueTraits; |
| 63 public: | 67 |
| 64 typedef typename KeyTraits::TraitType KeyType; | 68 public: |
| 65 typedef const typename KeyTraits::PeekInType& KeyPeekInType; | 69 typedef typename KeyTraits::TraitType KeyType; |
| 66 typedef typename MappedTraits::TraitType MappedType; | 70 typedef const typename KeyTraits::PeekInType& KeyPeekInType; |
| 67 typedef typename ValueTraits::TraitType ValueType; | 71 typedef typename MappedTraits::TraitType MappedType; |
| 68 | 72 typedef typename ValueTraits::TraitType ValueType; |
| 69 private: | 73 |
| 70 typedef typename MappedTraits::PassInType MappedPassInType; | 74 private: |
| 71 typedef typename MappedTraits::PassOutType MappedPassOutType; | 75 typedef typename MappedTraits::PassInType MappedPassInType; |
| 72 typedef typename MappedTraits::PeekOutType MappedPeekType; | 76 typedef typename MappedTraits::PassOutType MappedPassOutType; |
| 73 | 77 typedef typename MappedTraits::PeekOutType MappedPeekType; |
| 74 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedP
assInReferenceType; | 78 |
| 75 | 79 typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType |
| 76 typedef HashArg HashFunctions; | 80 MappedPassInReferenceType; |
| 77 | 81 |
| 78 typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor, | 82 typedef HashArg HashFunctions; |
| 79 HashFunctions, ValueTraits, KeyTraits, Allocator> HashTableType; | 83 |
| 80 | 84 typedef HashTable<KeyType, |
| 81 class HashMapKeysProxy; | 85 ValueType, |
| 82 class HashMapValuesProxy; | 86 KeyValuePairKeyExtractor, |
| 83 | 87 HashFunctions, |
| 84 public: | 88 ValueTraits, |
| 85 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; | 89 KeyTraits, |
| 86 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterat
or; | 90 Allocator> |
| 87 typedef typename HashTableType::AddResult AddResult; | 91 HashTableType; |
| 88 | 92 |
| 89 public: | 93 class HashMapKeysProxy; |
| 90 void swap(HashMap& ref) | 94 class HashMapValuesProxy; |
| 91 { | 95 |
| 92 m_impl.swap(ref.m_impl); | 96 public: |
| 93 } | 97 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; |
| 94 | 98 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> |
| 95 void swap(typename Allocator::template OtherType<HashMap>::Type other) | 99 const_iterator; |
| 96 { | 100 typedef typename HashTableType::AddResult AddResult; |
| 97 HashMap& ref = Allocator::getOther(other); | 101 |
| 98 m_impl.swap(ref.m_impl); | 102 public: |
| 99 } | 103 void swap(HashMap& ref) { m_impl.swap(ref.m_impl); } |
| 100 | 104 |
| 101 unsigned size() const; | 105 void swap(typename Allocator::template OtherType<HashMap>::Type other) { |
| 102 unsigned capacity() const; | 106 HashMap& ref = Allocator::getOther(other); |
| 103 void reserveCapacityForSize(unsigned size) | 107 m_impl.swap(ref.m_impl); |
| 104 { | 108 } |
| 105 m_impl.reserveCapacityForSize(size); | 109 |
| 106 } | 110 unsigned size() const; |
| 107 | 111 unsigned capacity() const; |
| 108 bool isEmpty() const; | 112 void reserveCapacityForSize(unsigned size) { |
| 109 | 113 m_impl.reserveCapacityForSize(size); |
| 110 // iterators iterate over pairs of keys and values | 114 } |
| 111 iterator begin(); | 115 |
| 112 iterator end(); | 116 bool isEmpty() const; |
| 113 const_iterator begin() const; | 117 |
| 114 const_iterator end() const; | 118 // iterators iterate over pairs of keys and values |
| 115 | 119 iterator begin(); |
| 116 HashMapKeysProxy& keys() { return static_cast<HashMapKeysProxy&>(*this); } | 120 iterator end(); |
| 117 const HashMapKeysProxy& keys() const { return static_cast<const HashMapKeysP
roxy&>(*this); } | 121 const_iterator begin() const; |
| 118 | 122 const_iterator end() const; |
| 119 HashMapValuesProxy& values() { return static_cast<HashMapValuesProxy&>(*this
); } | 123 |
| 120 const HashMapValuesProxy& values() const { return static_cast<const HashMapV
aluesProxy&>(*this); } | 124 HashMapKeysProxy& keys() { return static_cast<HashMapKeysProxy&>(*this); } |
| 121 | 125 const HashMapKeysProxy& keys() const { |
| 122 iterator find(KeyPeekInType); | 126 return static_cast<const HashMapKeysProxy&>(*this); |
| 123 const_iterator find(KeyPeekInType) const; | 127 } |
| 124 bool contains(KeyPeekInType) const; | 128 |
| 125 MappedPeekType get(KeyPeekInType) const; | 129 HashMapValuesProxy& values() { |
| 126 | 130 return static_cast<HashMapValuesProxy&>(*this); |
| 127 // replaces value but not key if key is already present return value is a | 131 } |
| 128 // pair of the iterator to the key location, and a boolean that's true if a | 132 const HashMapValuesProxy& values() const { |
| 129 // new value was actually added | 133 return static_cast<const HashMapValuesProxy&>(*this); |
| 130 AddResult set(KeyPeekInType, MappedPassInType); | 134 } |
| 131 | 135 |
| 132 // does nothing if key is already present return value is a pair of the | 136 iterator find(KeyPeekInType); |
| 133 // iterator to the key location, and a boolean that's true if a new value | 137 const_iterator find(KeyPeekInType) const; |
| 134 // was actually added | 138 bool contains(KeyPeekInType) const; |
| 135 AddResult add(KeyPeekInType, MappedPassInType); | 139 MappedPeekType get(KeyPeekInType) const; |
| 136 | 140 |
| 137 void remove(KeyPeekInType); | 141 // replaces value but not key if key is already present return value is a |
| 138 void remove(iterator); | 142 // pair of the iterator to the key location, and a boolean that's true if a |
| 139 void clear(); | 143 // new value was actually added |
| 140 template <typename Collection> | 144 AddResult set(KeyPeekInType, MappedPassInType); |
| 141 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRe
moved); } | 145 |
| 142 | 146 // does nothing if key is already present return value is a pair of the |
| 143 MappedPassOutType take(KeyPeekInType); // efficient combination of get with
remove | 147 // iterator to the key location, and a boolean that's true if a new value |
| 144 | 148 // was actually added |
| 145 // An alternate version of find() that finds the object by hashing and | 149 AddResult add(KeyPeekInType, MappedPassInType); |
| 146 // comparing with some other type, to avoid the cost of type | 150 |
| 147 // conversion. HashTranslator must have the following function members: | 151 void remove(KeyPeekInType); |
| 148 // static unsigned hash(const T&); | 152 void remove(iterator); |
| 149 // static bool equal(const ValueType&, const T&); | 153 void clear(); |
| 150 template <typename HashTranslator, typename T> iterator find(const T&); | 154 template <typename Collection> |
| 151 template <typename HashTranslator, typename T> const_iterator find(const T&)
const; | 155 void removeAll(const Collection& toBeRemoved) { |
| 152 template <typename HashTranslator, typename T> bool contains(const T&) const
; | 156 WTF::removeAll(*this, toBeRemoved); |
| 153 | 157 } |
| 154 // An alternate version of add() that finds the object by hashing and | 158 |
| 155 // comparing with some other type, to avoid the cost of type conversion if | 159 MappedPassOutType take( |
| 156 // the object is already in the table. HashTranslator must have the | 160 KeyPeekInType); // efficient combination of get with remove |
| 157 // following function members: | 161 |
| 158 // static unsigned hash(const T&); | 162 // An alternate version of find() that finds the object by hashing and |
| 159 // static bool equal(const ValueType&, const T&); | 163 // comparing with some other type, to avoid the cost of type |
| 160 // static translate(ValueType&, const T&, unsigned hashCode); | 164 // conversion. HashTranslator must have the following function members: |
| 161 template <typename HashTranslator, typename T> AddResult add(const T&, Mappe
dPassInType); | 165 // static unsigned hash(const T&); |
| 162 | 166 // static bool equal(const ValueType&, const T&); |
| 163 static bool isValidKey(KeyPeekInType); | 167 template <typename HashTranslator, typename T> |
| 164 | 168 iterator find(const T&); |
| 165 template <typename VisitorDispatcher> | 169 template <typename HashTranslator, typename T> |
| 166 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 170 const_iterator find(const T&) const; |
| 167 | 171 template <typename HashTranslator, typename T> |
| 168 private: | 172 bool contains(const T&) const; |
| 169 AddResult inlineAdd(KeyPeekInType, MappedPassInReferenceType); | 173 |
| 170 | 174 // An alternate version of add() that finds the object by hashing and |
| 171 HashTableType m_impl; | 175 // comparing with some other type, to avoid the cost of type conversion if |
| 172 }; | 176 // the object is already in the table. HashTranslator must have the |
| 173 | 177 // following function members: |
| 174 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTra
itsArg, typename MappedTraitsArg, typename Allocator> | 178 // static unsigned hash(const T&); |
| 175 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapKeysProxy : | 179 // static bool equal(const ValueType&, const T&); |
| 176 private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> { | 180 // static translate(ValueType&, const T&, unsigned hashCode); |
| 177 DISALLOW_NEW(); | 181 template <typename HashTranslator, typename T> |
| 178 public: | 182 AddResult add(const T&, MappedPassInType); |
| 179 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> HashMapType; | 183 |
| 180 typedef typename HashMapType::iterator::Keys iterator; | 184 static bool isValidKey(KeyPeekInType); |
| 181 typedef typename HashMapType::const_iterator::Keys const_iterator; | 185 |
| 182 | 186 template <typename VisitorDispatcher> |
| 183 iterator begin() | 187 void trace(VisitorDispatcher visitor) { |
| 184 { | 188 m_impl.trace(visitor); |
| 185 return HashMapType::begin().keys(); | 189 } |
| 186 } | 190 |
| 187 | 191 private: |
| 188 iterator end() | 192 AddResult inlineAdd(KeyPeekInType, MappedPassInReferenceType); |
| 189 { | 193 |
| 190 return HashMapType::end().keys(); | 194 HashTableType m_impl; |
| 191 } | 195 }; |
| 192 | 196 |
| 193 const_iterator begin() const | 197 template <typename KeyArg, |
| 194 { | 198 typename MappedArg, |
| 195 return HashMapType::begin().keys(); | 199 typename HashArg, |
| 196 } | 200 typename KeyTraitsArg, |
| 197 | 201 typename MappedTraitsArg, |
| 198 const_iterator end() const | 202 typename Allocator> |
| 199 { | 203 class HashMap<KeyArg, |
| 200 return HashMapType::end().keys(); | 204 MappedArg, |
| 201 } | 205 HashArg, |
| 202 | 206 KeyTraitsArg, |
| 203 private: | 207 MappedTraitsArg, |
| 204 friend class HashMap; | 208 Allocator>::HashMapKeysProxy : private HashMap<KeyArg, |
| 205 | 209 MappedArg, |
| 206 // These are intentionally not implemented. | 210 HashArg, |
| 207 HashMapKeysProxy(); | 211 KeyTraitsArg, |
| 208 HashMapKeysProxy(const HashMapKeysProxy&); | 212 MappedTraitsArg, |
| 209 HashMapKeysProxy& operator=(const HashMapKeysProxy&); | 213 Allocator> { |
| 210 ~HashMapKeysProxy(); | 214 DISALLOW_NEW(); |
| 211 }; | 215 |
| 212 | 216 public: |
| 213 template <typename KeyArg, typename MappedArg, typename HashArg, typename KeyTr
aitsArg, typename MappedTraitsArg, typename Allocator> | 217 typedef HashMap<KeyArg, |
| 214 class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, Allocat
or>::HashMapValuesProxy : | 218 MappedArg, |
| 215 private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> { | 219 HashArg, |
| 216 DISALLOW_NEW(); | 220 KeyTraitsArg, |
| 217 public: | 221 MappedTraitsArg, |
| 218 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, A
llocator> HashMapType; | 222 Allocator> |
| 219 typedef typename HashMapType::iterator::Values iterator; | 223 HashMapType; |
| 220 typedef typename HashMapType::const_iterator::Values const_iterator; | 224 typedef typename HashMapType::iterator::Keys iterator; |
| 221 | 225 typedef typename HashMapType::const_iterator::Keys const_iterator; |
| 222 iterator begin() | 226 |
| 223 { | 227 iterator begin() { return HashMapType::begin().keys(); } |
| 224 return HashMapType::begin().values(); | 228 |
| 225 } | 229 iterator end() { return HashMapType::end().keys(); } |
| 226 | 230 |
| 227 iterator end() | 231 const_iterator begin() const { return HashMapType::begin().keys(); } |
| 228 { | 232 |
| 229 return HashMapType::end().values(); | 233 const_iterator end() const { return HashMapType::end().keys(); } |
| 230 } | 234 |
| 231 | 235 private: |
| 232 const_iterator begin() const | 236 friend class HashMap; |
| 233 { | 237 |
| 234 return HashMapType::begin().values(); | 238 // These are intentionally not implemented. |
| 235 } | 239 HashMapKeysProxy(); |
| 236 | 240 HashMapKeysProxy(const HashMapKeysProxy&); |
| 237 const_iterator end() const | 241 HashMapKeysProxy& operator=(const HashMapKeysProxy&); |
| 238 { | 242 ~HashMapKeysProxy(); |
| 239 return HashMapType::end().values(); | 243 }; |
| 240 } | 244 |
| 241 | 245 template <typename KeyArg, |
| 242 private: | 246 typename MappedArg, |
| 243 friend class HashMap; | 247 typename HashArg, |
| 244 | 248 typename KeyTraitsArg, |
| 245 // These are intentionally not implemented. | 249 typename MappedTraitsArg, |
| 246 HashMapValuesProxy(); | 250 typename Allocator> |
| 247 HashMapValuesProxy(const HashMapValuesProxy&); | 251 class HashMap<KeyArg, |
| 248 HashMapValuesProxy& operator=(const HashMapValuesProxy&); | 252 MappedArg, |
| 249 ~HashMapValuesProxy(); | 253 HashArg, |
| 254 KeyTraitsArg, |
| 255 MappedTraitsArg, |
| 256 Allocator>::HashMapValuesProxy : private HashMap<KeyArg, |
| 257 MappedArg, |
| 258 HashArg, |
| 259 KeyTraitsArg, |
| 260 MappedTraitsArg, |
| 261 Allocator> { |
| 262 DISALLOW_NEW(); |
| 263 |
| 264 public: |
| 265 typedef HashMap<KeyArg, |
| 266 MappedArg, |
| 267 HashArg, |
| 268 KeyTraitsArg, |
| 269 MappedTraitsArg, |
| 270 Allocator> |
| 271 HashMapType; |
| 272 typedef typename HashMapType::iterator::Values iterator; |
| 273 typedef typename HashMapType::const_iterator::Values const_iterator; |
| 274 |
| 275 iterator begin() { return HashMapType::begin().values(); } |
| 276 |
| 277 iterator end() { return HashMapType::end().values(); } |
| 278 |
| 279 const_iterator begin() const { return HashMapType::begin().values(); } |
| 280 |
| 281 const_iterator end() const { return HashMapType::end().values(); } |
| 282 |
| 283 private: |
| 284 friend class HashMap; |
| 285 |
| 286 // These are intentionally not implemented. |
| 287 HashMapValuesProxy(); |
| 288 HashMapValuesProxy(const HashMapValuesProxy&); |
| 289 HashMapValuesProxy& operator=(const HashMapValuesProxy&); |
| 290 ~HashMapValuesProxy(); |
| 250 }; | 291 }; |
| 251 | 292 |
| 252 template <typename KeyTraits, typename MappedTraits> | 293 template <typename KeyTraits, typename MappedTraits> |
| 253 struct HashMapValueTraits : KeyValuePairHashTraits<KeyTraits, MappedTraits> { | 294 struct HashMapValueTraits : KeyValuePairHashTraits<KeyTraits, MappedTraits> { |
| 254 STATIC_ONLY(HashMapValueTraits); | 295 STATIC_ONLY(HashMapValueTraits); |
| 255 static const bool hasIsEmptyValueFunction = true; | 296 static const bool hasIsEmptyValueFunction = true; |
| 256 static bool isEmptyValue(const typename KeyValuePairHashTraits<KeyTraits, Ma
ppedTraits>::TraitType& value) | 297 static bool isEmptyValue( |
| 257 { | 298 const typename KeyValuePairHashTraits<KeyTraits, MappedTraits>::TraitType& |
| 258 return isHashTraitsEmptyValue<KeyTraits>(value.key); | 299 value) { |
| 259 } | 300 return isHashTraitsEmptyValue<KeyTraits>(value.key); |
| 301 } |
| 260 }; | 302 }; |
| 261 | 303 |
| 262 template <typename ValueTraits, typename HashFunctions> | 304 template <typename ValueTraits, typename HashFunctions> |
| 263 struct HashMapTranslator { | 305 struct HashMapTranslator { |
| 264 STATIC_ONLY(HashMapTranslator); | 306 STATIC_ONLY(HashMapTranslator); |
| 265 template <typename T> static unsigned hash(const T& key) { return HashFuncti
ons::hash(key); } | 307 template <typename T> |
| 266 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return HashFunctions::equal(a, b); } | 308 static unsigned hash(const T& key) { |
| 267 template <typename T, typename U, typename V> static void translate(T& locat
ion, const U& key, const V& mapped) | 309 return HashFunctions::hash(key); |
| 268 { | 310 } |
| 269 location.key = key; | 311 template <typename T, typename U> |
| 270 ValueTraits::ValueTraits::store(mapped, location.value); | 312 static bool equal(const T& a, const U& b) { |
| 271 } | 313 return HashFunctions::equal(a, b); |
| 314 } |
| 315 template <typename T, typename U, typename V> |
| 316 static void translate(T& location, const U& key, const V& mapped) { |
| 317 location.key = key; |
| 318 ValueTraits::ValueTraits::store(mapped, location.value); |
| 319 } |
| 272 }; | 320 }; |
| 273 | 321 |
| 274 template <typename ValueTraits, typename Translator> | 322 template <typename ValueTraits, typename Translator> |
| 275 struct HashMapTranslatorAdapter { | 323 struct HashMapTranslatorAdapter { |
| 276 STATIC_ONLY(HashMapTranslatorAdapter); | 324 STATIC_ONLY(HashMapTranslatorAdapter); |
| 277 template <typename T> static unsigned hash(const T& key) { return Translator
::hash(key); } | 325 template <typename T> |
| 278 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return Translator::equal(a, b); } | 326 static unsigned hash(const T& key) { |
| 279 template <typename T, typename U, typename V> static void translate(T& locat
ion, const U& key, const V& mapped, unsigned hashCode) | 327 return Translator::hash(key); |
| 280 { | 328 } |
| 281 Translator::translate(location.key, key, hashCode); | 329 template <typename T, typename U> |
| 282 ValueTraits::ValueTraits::store(mapped, location.value); | 330 static bool equal(const T& a, const U& b) { |
| 283 } | 331 return Translator::equal(a, b); |
| 284 }; | 332 } |
| 285 | 333 template <typename T, typename U, typename V> |
| 286 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 334 static void translate(T& location, |
| 287 inline unsigned HashMap<T, U, V, W, X, Y>::size() const | 335 const U& key, |
| 288 { | 336 const V& mapped, |
| 289 return m_impl.size(); | 337 unsigned hashCode) { |
| 290 } | 338 Translator::translate(location.key, key, hashCode); |
| 291 | 339 ValueTraits::ValueTraits::store(mapped, location.value); |
| 292 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 340 } |
| 293 inline unsigned HashMap<T, U, V, W, X, Y>::capacity() const | 341 }; |
| 294 { | 342 |
| 295 return m_impl.capacity(); | 343 template <typename T, |
| 296 } | 344 typename U, |
| 297 | 345 typename V, |
| 298 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 346 typename W, |
| 299 inline bool HashMap<T, U, V, W, X, Y>::isEmpty() const | 347 typename X, |
| 300 { | 348 typename Y> |
| 301 return m_impl.isEmpty(); | 349 inline unsigned HashMap<T, U, V, W, X, Y>::size() const { |
| 302 } | 350 return m_impl.size(); |
| 303 | 351 } |
| 304 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 352 |
| 305 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::b
egin() | 353 template <typename T, |
| 306 { | 354 typename U, |
| 307 return m_impl.begin(); | 355 typename V, |
| 308 } | 356 typename W, |
| 309 | 357 typename X, |
| 310 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 358 typename Y> |
| 311 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::e
nd() | 359 inline unsigned HashMap<T, U, V, W, X, Y>::capacity() const { |
| 312 { | 360 return m_impl.capacity(); |
| 313 return m_impl.end(); | 361 } |
| 314 } | 362 |
| 315 | 363 template <typename T, |
| 316 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 364 typename U, |
| 317 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::begin() const | 365 typename V, |
| 318 { | 366 typename W, |
| 319 return m_impl.begin(); | 367 typename X, |
| 320 } | 368 typename Y> |
| 321 | 369 inline bool HashMap<T, U, V, W, X, Y>::isEmpty() const { |
| 322 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 370 return m_impl.isEmpty(); |
| 323 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::end() const | 371 } |
| 324 { | 372 |
| 325 return m_impl.end(); | 373 template <typename T, |
| 326 } | 374 typename U, |
| 327 | 375 typename V, |
| 328 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 376 typename W, |
| 329 inline typename HashMap<T, U, V, W, X, Y>::iterator HashMap<T, U, V, W, X, Y>::f
ind(KeyPeekInType key) | 377 typename X, |
| 330 { | 378 typename Y> |
| 331 return m_impl.find(key); | 379 inline typename HashMap<T, U, V, W, X, Y>::iterator |
| 332 } | 380 HashMap<T, U, V, W, X, Y>::begin() { |
| 333 | 381 return m_impl.begin(); |
| 334 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 382 } |
| 335 inline typename HashMap<T, U, V, W, X, Y>::const_iterator HashMap<T, U, V, W, X,
Y>::find(KeyPeekInType key) const | 383 |
| 336 { | 384 template <typename T, |
| 337 return m_impl.find(key); | 385 typename U, |
| 338 } | 386 typename V, |
| 339 | 387 typename W, |
| 340 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 388 typename X, |
| 341 inline bool HashMap<T, U, V, W, X, Y>::contains(KeyPeekInType key) const | 389 typename Y> |
| 342 { | 390 inline typename HashMap<T, U, V, W, X, Y>::iterator |
| 343 return m_impl.contains(key); | 391 HashMap<T, U, V, W, X, Y>::end() { |
| 344 } | 392 return m_impl.end(); |
| 345 | 393 } |
| 346 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 394 |
| 395 template <typename T, |
| 396 typename U, |
| 397 typename V, |
| 398 typename W, |
| 399 typename X, |
| 400 typename Y> |
| 401 inline typename HashMap<T, U, V, W, X, Y>::const_iterator |
| 402 HashMap<T, U, V, W, X, Y>::begin() const { |
| 403 return m_impl.begin(); |
| 404 } |
| 405 |
| 406 template <typename T, |
| 407 typename U, |
| 408 typename V, |
| 409 typename W, |
| 410 typename X, |
| 411 typename Y> |
| 412 inline typename HashMap<T, U, V, W, X, Y>::const_iterator |
| 413 HashMap<T, U, V, W, X, Y>::end() const { |
| 414 return m_impl.end(); |
| 415 } |
| 416 |
| 417 template <typename T, |
| 418 typename U, |
| 419 typename V, |
| 420 typename W, |
| 421 typename X, |
| 422 typename Y> |
| 423 inline typename HashMap<T, U, V, W, X, Y>::iterator |
| 424 HashMap<T, U, V, W, X, Y>::find(KeyPeekInType key) { |
| 425 return m_impl.find(key); |
| 426 } |
| 427 |
| 428 template <typename T, |
| 429 typename U, |
| 430 typename V, |
| 431 typename W, |
| 432 typename X, |
| 433 typename Y> |
| 434 inline typename HashMap<T, U, V, W, X, Y>::const_iterator |
| 435 HashMap<T, U, V, W, X, Y>::find(KeyPeekInType key) const { |
| 436 return m_impl.find(key); |
| 437 } |
| 438 |
| 439 template <typename T, |
| 440 typename U, |
| 441 typename V, |
| 442 typename W, |
| 443 typename X, |
| 444 typename Y> |
| 445 inline bool HashMap<T, U, V, W, X, Y>::contains(KeyPeekInType key) const { |
| 446 return m_impl.contains(key); |
| 447 } |
| 448 |
| 449 template <typename T, |
| 450 typename U, |
| 451 typename V, |
| 452 typename W, |
| 453 typename X, |
| 454 typename Y> |
| 347 template <typename HashTranslator, typename TYPE> | 455 template <typename HashTranslator, typename TYPE> |
| 348 inline typename HashMap<T, U, V, W, X, Y>::iterator | 456 inline typename HashMap<T, U, V, W, X, Y>::iterator |
| 349 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) | 457 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) { |
| 350 { | 458 return m_impl |
| 351 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTransl
ator>>(value); | 459 .template find<HashMapTranslatorAdapter<ValueTraits, HashTranslator>>( |
| 352 } | 460 value); |
| 353 | 461 } |
| 354 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 462 |
| 463 template <typename T, |
| 464 typename U, |
| 465 typename V, |
| 466 typename W, |
| 467 typename X, |
| 468 typename Y> |
| 355 template <typename HashTranslator, typename TYPE> | 469 template <typename HashTranslator, typename TYPE> |
| 356 inline typename HashMap<T, U, V, W, X, Y>::const_iterator | 470 inline typename HashMap<T, U, V, W, X, Y>::const_iterator |
| 357 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) const | 471 HashMap<T, U, V, W, X, Y>::find(const TYPE& value) const { |
| 358 { | 472 return m_impl |
| 359 return m_impl.template find<HashMapTranslatorAdapter<ValueTraits, HashTransl
ator>>(value); | 473 .template find<HashMapTranslatorAdapter<ValueTraits, HashTranslator>>( |
| 360 } | 474 value); |
| 361 | 475 } |
| 362 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 476 |
| 477 template <typename T, |
| 478 typename U, |
| 479 typename V, |
| 480 typename W, |
| 481 typename X, |
| 482 typename Y> |
| 363 template <typename HashTranslator, typename TYPE> | 483 template <typename HashTranslator, typename TYPE> |
| 364 inline bool | 484 inline bool HashMap<T, U, V, W, X, Y>::contains(const TYPE& value) const { |
| 365 HashMap<T, U, V, W, X, Y>::contains(const TYPE& value) const | 485 return m_impl |
| 366 { | 486 .template contains<HashMapTranslatorAdapter<ValueTraits, HashTranslator>>( |
| 367 return m_impl.template contains<HashMapTranslatorAdapter<ValueTraits, HashTr
anslator>>(value); | 487 value); |
| 368 } | 488 } |
| 369 | 489 |
| 370 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 490 template <typename T, |
| 491 typename U, |
| 492 typename V, |
| 493 typename W, |
| 494 typename X, |
| 495 typename Y> |
| 371 typename HashMap<T, U, V, W, X, Y>::AddResult | 496 typename HashMap<T, U, V, W, X, Y>::AddResult |
| 372 HashMap<T, U, V, W, X, Y>::inlineAdd(KeyPeekInType key, MappedPassInReferenceTyp
e mapped) | 497 HashMap<T, U, V, W, X, Y>::inlineAdd(KeyPeekInType key, |
| 373 { | 498 MappedPassInReferenceType mapped) { |
| 374 return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>(ke
y, mapped); | 499 return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>( |
| 375 } | 500 key, mapped); |
| 376 | 501 } |
| 377 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 502 |
| 378 typename HashMap<T, U, V, W, X, Y>::AddResult | 503 template <typename T, |
| 379 HashMap<T, U, V, W, X, Y>::set(KeyPeekInType key, MappedPassInType mapped) | 504 typename U, |
| 380 { | 505 typename V, |
| 381 AddResult result = inlineAdd(key, mapped); | 506 typename W, |
| 382 if (!result.isNewEntry) { | 507 typename X, |
| 383 // The inlineAdd call above found an existing hash table entry; we need | 508 typename Y> |
| 384 // to set the mapped value. | 509 typename HashMap<T, U, V, W, X, Y>::AddResult HashMap<T, U, V, W, X, Y>::set( |
| 385 MappedTraits::store(mapped, result.storedValue->value); | 510 KeyPeekInType key, |
| 386 } | 511 MappedPassInType mapped) { |
| 387 return result; | 512 AddResult result = inlineAdd(key, mapped); |
| 388 } | 513 if (!result.isNewEntry) { |
| 389 | 514 // The inlineAdd call above found an existing hash table entry; we need |
| 390 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 515 // to set the mapped value. |
| 516 MappedTraits::store(mapped, result.storedValue->value); |
| 517 } |
| 518 return result; |
| 519 } |
| 520 |
| 521 template <typename T, |
| 522 typename U, |
| 523 typename V, |
| 524 typename W, |
| 525 typename X, |
| 526 typename Y> |
| 391 template <typename HashTranslator, typename TYPE> | 527 template <typename HashTranslator, typename TYPE> |
| 392 typename HashMap<T, U, V, W, X, Y>::AddResult | 528 typename HashMap<T, U, V, W, X, Y>::AddResult HashMap<T, U, V, W, X, Y>::add( |
| 393 HashMap<T, U, V, W, X, Y>::add(const TYPE& key, MappedPassInType value) | 529 const TYPE& key, |
| 394 { | 530 MappedPassInType value) { |
| 395 return m_impl.template addPassingHashCode<HashMapTranslatorAdapter<ValueTrai
ts, HashTranslator>>(key, value); | 531 return m_impl.template addPassingHashCode< |
| 396 } | 532 HashMapTranslatorAdapter<ValueTraits, HashTranslator>>(key, value); |
| 397 | 533 } |
| 398 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 534 |
| 399 typename HashMap<T, U, V, W, X, Y>::AddResult | 535 template <typename T, |
| 400 HashMap<T, U, V, W, X, Y>::add(KeyPeekInType key, MappedPassInType mapped) | 536 typename U, |
| 401 { | 537 typename V, |
| 402 return inlineAdd(key, mapped); | 538 typename W, |
| 403 } | 539 typename X, |
| 404 | 540 typename Y> |
| 405 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 541 typename HashMap<T, U, V, W, X, Y>::AddResult HashMap<T, U, V, W, X, Y>::add( |
| 542 KeyPeekInType key, |
| 543 MappedPassInType mapped) { |
| 544 return inlineAdd(key, mapped); |
| 545 } |
| 546 |
| 547 template <typename T, |
| 548 typename U, |
| 549 typename V, |
| 550 typename W, |
| 551 typename X, |
| 552 typename Y> |
| 406 typename HashMap<T, U, V, W, X, Y>::MappedPeekType | 553 typename HashMap<T, U, V, W, X, Y>::MappedPeekType |
| 407 HashMap<T, U, V, W, X, Y>::get(KeyPeekInType key) const | 554 HashMap<T, U, V, W, X, Y>::get(KeyPeekInType key) const { |
| 408 { | 555 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); |
| 409 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); | 556 if (!entry) |
| 410 if (!entry) | 557 return MappedTraits::peek(MappedTraits::emptyValue()); |
| 411 return MappedTraits::peek(MappedTraits::emptyValue()); | 558 return MappedTraits::peek(entry->value); |
| 412 return MappedTraits::peek(entry->value); | 559 } |
| 413 } | 560 |
| 414 | 561 template <typename T, |
| 415 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 562 typename U, |
| 416 inline void HashMap<T, U, V, W, X, Y>::remove(iterator it) | 563 typename V, |
| 417 { | 564 typename W, |
| 418 m_impl.remove(it.m_impl); | 565 typename X, |
| 419 } | 566 typename Y> |
| 420 | 567 inline void HashMap<T, U, V, W, X, Y>::remove(iterator it) { |
| 421 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 568 m_impl.remove(it.m_impl); |
| 422 inline void HashMap<T, U, V, W, X, Y>::remove(KeyPeekInType key) | 569 } |
| 423 { | 570 |
| 424 remove(find(key)); | 571 template <typename T, |
| 425 } | 572 typename U, |
| 426 | 573 typename V, |
| 427 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 574 typename W, |
| 428 inline void HashMap<T, U, V, W, X, Y>::clear() | 575 typename X, |
| 429 { | 576 typename Y> |
| 430 m_impl.clear(); | 577 inline void HashMap<T, U, V, W, X, Y>::remove(KeyPeekInType key) { |
| 431 } | 578 remove(find(key)); |
| 432 | 579 } |
| 433 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 580 |
| 581 template <typename T, |
| 582 typename U, |
| 583 typename V, |
| 584 typename W, |
| 585 typename X, |
| 586 typename Y> |
| 587 inline void HashMap<T, U, V, W, X, Y>::clear() { |
| 588 m_impl.clear(); |
| 589 } |
| 590 |
| 591 template <typename T, |
| 592 typename U, |
| 593 typename V, |
| 594 typename W, |
| 595 typename X, |
| 596 typename Y> |
| 434 typename HashMap<T, U, V, W, X, Y>::MappedPassOutType | 597 typename HashMap<T, U, V, W, X, Y>::MappedPassOutType |
| 435 HashMap<T, U, V, W, X, Y>::take(KeyPeekInType key) | 598 HashMap<T, U, V, W, X, Y>::take(KeyPeekInType key) { |
| 436 { | 599 iterator it = find(key); |
| 437 iterator it = find(key); | 600 if (it == end()) |
| 438 if (it == end()) | 601 return MappedTraits::passOut(MappedTraits::emptyValue()); |
| 439 return MappedTraits::passOut(MappedTraits::emptyValue()); | 602 MappedPassOutType result = MappedTraits::passOut(it->value); |
| 440 MappedPassOutType result = MappedTraits::passOut(it->value); | 603 remove(it); |
| 441 remove(it); | 604 return result; |
| 442 return result; | 605 } |
| 443 } | 606 |
| 444 | 607 template <typename T, |
| 445 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 608 typename U, |
| 446 inline bool HashMap<T, U, V, W, X, Y>::isValidKey(KeyPeekInType key) | 609 typename V, |
| 447 { | 610 typename W, |
| 448 if (KeyTraits::isDeletedValue(key)) | 611 typename X, |
| 449 return false; | 612 typename Y> |
| 450 | 613 inline bool HashMap<T, U, V, W, X, Y>::isValidKey(KeyPeekInType key) { |
| 451 if (HashFunctions::safeToCompareToEmptyOrDeleted) { | 614 if (KeyTraits::isDeletedValue(key)) |
| 452 if (key == KeyTraits::emptyValue()) | 615 return false; |
| 453 return false; | 616 |
| 454 } else { | 617 if (HashFunctions::safeToCompareToEmptyOrDeleted) { |
| 455 if (isHashTraitsEmptyValue<KeyTraits>(key)) | 618 if (key == KeyTraits::emptyValue()) |
| 456 return false; | 619 return false; |
| 457 } | 620 } else { |
| 458 | 621 if (isHashTraitsEmptyValue<KeyTraits>(key)) |
| 459 return true; | 622 return false; |
| 460 } | 623 } |
| 461 | 624 |
| 462 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 625 return true; |
| 463 bool operator==(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V, W, X,
Y>& b) | 626 } |
| 464 { | 627 |
| 465 if (a.size() != b.size()) | 628 template <typename T, |
| 466 return false; | 629 typename U, |
| 467 | 630 typename V, |
| 468 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator const_iterator; | 631 typename W, |
| 469 | 632 typename X, |
| 470 const_iterator aEnd = a.end(); | 633 typename Y> |
| 471 const_iterator bEnd = b.end(); | 634 bool operator==(const HashMap<T, U, V, W, X, Y>& a, |
| 472 for (const_iterator it = a.begin(); it != aEnd; ++it) { | 635 const HashMap<T, U, V, W, X, Y>& b) { |
| 473 const_iterator bPos = b.find(it->key); | 636 if (a.size() != b.size()) |
| 474 if (bPos == bEnd || it->value != bPos->value) | 637 return false; |
| 475 return false; | 638 |
| 476 } | 639 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator const_iterator; |
| 477 | 640 |
| 478 return true; | 641 const_iterator aEnd = a.end(); |
| 479 } | 642 const_iterator bEnd = b.end(); |
| 480 | 643 for (const_iterator it = a.begin(); it != aEnd; ++it) { |
| 481 template <typename T, typename U, typename V, typename W, typename X, typename Y
> | 644 const_iterator bPos = b.find(it->key); |
| 482 inline bool operator!=(const HashMap<T, U, V, W, X, Y>& a, const HashMap<T, U, V
, W, X, Y>& b) | 645 if (bPos == bEnd || it->value != bPos->value) |
| 483 { | 646 return false; |
| 484 return !(a == b); | 647 } |
| 485 } | 648 |
| 486 | 649 return true; |
| 487 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> | 650 } |
| 488 inline void copyKeysToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& vec
tor) | 651 |
| 489 { | 652 template <typename T, |
| 490 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Keys iterator; | 653 typename U, |
| 491 | 654 typename V, |
| 492 vector.resize(collection.size()); | 655 typename W, |
| 493 | 656 typename X, |
| 494 iterator it = collection.begin().keys(); | 657 typename Y> |
| 495 iterator end = collection.end().keys(); | 658 inline bool operator!=(const HashMap<T, U, V, W, X, Y>& a, |
| 496 for (unsigned i = 0; it != end; ++it, ++i) | 659 const HashMap<T, U, V, W, X, Y>& b) { |
| 497 vector[i] = *it; | 660 return !(a == b); |
| 498 } | 661 } |
| 499 | 662 |
| 500 template <typename T, typename U, typename V, typename W, typename X, typename Y
, typename Z> | 663 template <typename T, |
| 501 inline void copyValuesToVector(const HashMap<T, U, V, W, X, Y>& collection, Z& v
ector) | 664 typename U, |
| 502 { | 665 typename V, |
| 503 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Values iterator; | 666 typename W, |
| 504 | 667 typename X, |
| 505 vector.resize(collection.size()); | 668 typename Y, |
| 506 | 669 typename Z> |
| 507 iterator it = collection.begin().values(); | 670 inline void copyKeysToVector(const HashMap<T, U, V, W, X, Y>& collection, |
| 508 iterator end = collection.end().values(); | 671 Z& vector) { |
| 509 for (unsigned i = 0; it != end; ++it, ++i) | 672 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Keys iterator; |
| 510 vector[i] = *it; | 673 |
| 674 vector.resize(collection.size()); |
| 675 |
| 676 iterator it = collection.begin().keys(); |
| 677 iterator end = collection.end().keys(); |
| 678 for (unsigned i = 0; it != end; ++it, ++i) |
| 679 vector[i] = *it; |
| 680 } |
| 681 |
| 682 template <typename T, |
| 683 typename U, |
| 684 typename V, |
| 685 typename W, |
| 686 typename X, |
| 687 typename Y, |
| 688 typename Z> |
| 689 inline void copyValuesToVector(const HashMap<T, U, V, W, X, Y>& collection, |
| 690 Z& vector) { |
| 691 typedef typename HashMap<T, U, V, W, X, Y>::const_iterator::Values iterator; |
| 692 |
| 693 vector.resize(collection.size()); |
| 694 |
| 695 iterator it = collection.begin().values(); |
| 696 iterator end = collection.end().values(); |
| 697 for (unsigned i = 0; it != end; ++it, ++i) |
| 698 vector[i] = *it; |
| 511 } | 699 } |
| 512 | 700 |
| 513 #if !ENABLE(OILPAN) | 701 #if !ENABLE(OILPAN) |
| 514 template <typename T, typename U, typename V, typename W, typename X> | 702 template <typename T, typename U, typename V, typename W, typename X> |
| 515 struct NeedsTracing<HashMap<T, U, V, W, X>> { | 703 struct NeedsTracing<HashMap<T, U, V, W, X>> { |
| 516 STATIC_ONLY(NeedsTracing); | 704 STATIC_ONLY(NeedsTracing); |
| 517 static const bool value = false; | 705 static const bool value = false; |
| 518 }; | 706 }; |
| 519 #endif | 707 #endif |
| 520 | 708 |
| 521 } // namespace WTF | 709 } // namespace WTF |
| 522 | 710 |
| 523 using WTF::HashMap; | 711 using WTF::HashMap; |
| 524 | 712 |
| 525 #endif // WTF_HashMap_h | 713 #endif // WTF_HashMap_h |
| OLD | NEW |