Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: third_party/WebKit/Source/wtf/LinkedHashSet.h

Issue 1611343002: wtf reformat test Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pydent Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> 3 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com>
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 21 matching lines...) Expand all
32 32
33 // LinkedHashSet: Just like HashSet, this class provides a Set 33 // LinkedHashSet: Just like HashSet, this class provides a Set
34 // interface - a collection of unique objects with O(1) insertion, 34 // interface - a collection of unique objects with O(1) insertion,
35 // removal and test for containership. However, it also has an 35 // removal and test for containership. However, it also has an
36 // order - iterating it will always give back values in the order 36 // order - iterating it will always give back values in the order
37 // in which they are added. 37 // in which they are added.
38 38
39 // Unlike ListHashSet, but like most WTF collections, iteration is NOT safe 39 // Unlike ListHashSet, but like most WTF collections, iteration is NOT safe
40 // against mutation of the LinkedHashSet. 40 // against mutation of the LinkedHashSet.
41 41
42 template<typename Value, typename HashFunctions, typename HashTraits, typename A llocator> class LinkedHashSet; 42 template <typename Value,
43 43 typename HashFunctions,
44 template<typename LinkedHashSet> class LinkedHashSetIterator; 44 typename HashTraits,
45 template<typename LinkedHashSet> class LinkedHashSetConstIterator; 45 typename Allocator>
46 template<typename LinkedHashSet> class LinkedHashSetReverseIterator; 46 class LinkedHashSet;
47 template<typename LinkedHashSet> class LinkedHashSetConstReverseIterator; 47
48 48 template <typename LinkedHashSet>
49 template<typename Value, typename HashFunctions, typename Allocator> struct Link edHashSetTranslator; 49 class LinkedHashSetIterator;
50 template<typename Value, typename Allocator> struct LinkedHashSetExtractor; 50 template <typename LinkedHashSet>
51 template<typename Value, typename ValueTraits, typename Allocator> struct Linked HashSetTraits; 51 class LinkedHashSetConstIterator;
52 template <typename LinkedHashSet>
53 class LinkedHashSetReverseIterator;
54 template <typename LinkedHashSet>
55 class LinkedHashSetConstReverseIterator;
56
57 template <typename Value, typename HashFunctions, typename Allocator>
58 struct LinkedHashSetTranslator;
59 template <typename Value, typename Allocator>
60 struct LinkedHashSetExtractor;
61 template <typename Value, typename ValueTraits, typename Allocator>
62 struct LinkedHashSetTraits;
52 63
53 class LinkedHashSetNodeBase { 64 class LinkedHashSetNodeBase {
54 DISALLOW_NEW(); 65 DISALLOW_NEW();
55 public: 66
56 LinkedHashSetNodeBase() : m_prev(this), m_next(this) { } 67 public:
57 68 LinkedHashSetNodeBase() : m_prev(this), m_next(this) {}
58 NO_LAZY_SWEEP_SANITIZE_ADDRESS 69
59 void unlink() 70 NO_LAZY_SWEEP_SANITIZE_ADDRESS
60 { 71 void unlink() {
61 if (!m_next) 72 if (!m_next)
62 return; 73 return;
63 ASSERT(m_prev); 74 ASSERT(m_prev);
64 ASSERT(m_next->m_prev == this); 75 ASSERT(m_next->m_prev == this);
65 ASSERT(m_prev->m_next == this); 76 ASSERT(m_prev->m_next == this);
66 m_next->m_prev = m_prev; 77 m_next->m_prev = m_prev;
67 m_prev->m_next = m_next; 78 m_prev->m_next = m_next;
68 } 79 }
69 80
70 ~LinkedHashSetNodeBase() 81 ~LinkedHashSetNodeBase() { unlink(); }
71 { 82
72 unlink(); 83 void insertBefore(LinkedHashSetNodeBase& other) {
73 } 84 other.m_next = this;
74 85 other.m_prev = m_prev;
75 void insertBefore(LinkedHashSetNodeBase& other) 86 m_prev->m_next = &other;
76 { 87 m_prev = &other;
77 other.m_next = this; 88 ASSERT(other.m_next);
78 other.m_prev = m_prev; 89 ASSERT(other.m_prev);
79 m_prev->m_next = &other; 90 ASSERT(m_next);
80 m_prev = &other; 91 ASSERT(m_prev);
81 ASSERT(other.m_next); 92 }
82 ASSERT(other.m_prev); 93
83 ASSERT(m_next); 94 void insertAfter(LinkedHashSetNodeBase& other) {
84 ASSERT(m_prev); 95 other.m_prev = this;
85 } 96 other.m_next = m_next;
86 97 m_next->m_prev = &other;
87 void insertAfter(LinkedHashSetNodeBase& other) 98 m_next = &other;
88 { 99 ASSERT(other.m_next);
89 other.m_prev = this; 100 ASSERT(other.m_prev);
90 other.m_next = m_next; 101 ASSERT(m_next);
91 m_next->m_prev = &other; 102 ASSERT(m_prev);
92 m_next = &other; 103 }
93 ASSERT(other.m_next); 104
94 ASSERT(other.m_prev); 105 LinkedHashSetNodeBase(LinkedHashSetNodeBase* prev,
95 ASSERT(m_next); 106 LinkedHashSetNodeBase* next)
96 ASSERT(m_prev); 107 : m_prev(prev), m_next(next) {
97 } 108 ASSERT((prev && next) || (!prev && !next));
98 109 }
99 LinkedHashSetNodeBase(LinkedHashSetNodeBase* prev, LinkedHashSetNodeBase* ne xt) 110
100 : m_prev(prev) 111 LinkedHashSetNodeBase* m_prev;
101 , m_next(next) 112 LinkedHashSetNodeBase* m_next;
102 { 113
103 ASSERT((prev && next) || (!prev && !next)); 114 protected:
104 } 115 // If we take a copy of a node we can't copy the next and prev pointers,
105 116 // since they point to something that does not point at us. This is used
106 LinkedHashSetNodeBase* m_prev; 117 // inside the shouldExpand() "if" in HashTable::add.
107 LinkedHashSetNodeBase* m_next; 118 LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other)
108 119 : m_prev(0), m_next(0) {}
109 protected: 120
110 // If we take a copy of a node we can't copy the next and prev pointers, 121 private:
111 // since they point to something that does not point at us. This is used 122 // Should not be used.
112 // inside the shouldExpand() "if" in HashTable::add. 123 LinkedHashSetNodeBase& operator=(const LinkedHashSetNodeBase& other);
113 LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other) 124 };
114 : m_prev(0) 125
115 , m_next(0) { } 126 template <typename ValueArg, typename Allocator>
116
117 private:
118 // Should not be used.
119 LinkedHashSetNodeBase& operator=(const LinkedHashSetNodeBase& other);
120 };
121
122 template<typename ValueArg, typename Allocator>
123 class LinkedHashSetNode : public LinkedHashSetNodeBase { 127 class LinkedHashSetNode : public LinkedHashSetNodeBase {
124 DISALLOW_NEW(); 128 DISALLOW_NEW();
125 public: 129
126 LinkedHashSetNode(const ValueArg& value, LinkedHashSetNodeBase* prev, Linked HashSetNodeBase* next) 130 public:
127 : LinkedHashSetNodeBase(prev, next) 131 LinkedHashSetNode(const ValueArg& value,
128 , m_value(value) 132 LinkedHashSetNodeBase* prev,
129 { 133 LinkedHashSetNodeBase* next)
130 } 134 : LinkedHashSetNodeBase(prev, next), m_value(value) {}
131 135
132 ValueArg m_value; 136 ValueArg m_value;
133 137
134 private: 138 private:
135 // Not used. 139 // Not used.
136 LinkedHashSetNode(const LinkedHashSetNode&); 140 LinkedHashSetNode(const LinkedHashSetNode&);
137 }; 141 };
138 142
139 template< 143 template <typename ValueArg,
140 typename ValueArg, 144 typename HashFunctions = typename DefaultHash<ValueArg>::Hash,
141 typename HashFunctions = typename DefaultHash<ValueArg>::Hash, 145 typename TraitsArg = HashTraits<ValueArg>,
142 typename TraitsArg = HashTraits<ValueArg>, 146 typename Allocator = PartitionAllocator>
143 typename Allocator = PartitionAllocator>
144 class LinkedHashSet { 147 class LinkedHashSet {
145 WTF_USE_ALLOCATOR(LinkedHashSet, Allocator); 148 WTF_USE_ALLOCATOR(LinkedHashSet, Allocator);
146 private: 149
147 typedef ValueArg Value; 150 private:
148 typedef TraitsArg Traits; 151 typedef ValueArg Value;
149 typedef LinkedHashSetNode<Value, Allocator> Node; 152 typedef TraitsArg Traits;
150 typedef LinkedHashSetNodeBase NodeBase; 153 typedef LinkedHashSetNode<Value, Allocator> Node;
151 typedef LinkedHashSetTranslator<Value, HashFunctions, Allocator> NodeHashFun ctions; 154 typedef LinkedHashSetNodeBase NodeBase;
152 typedef LinkedHashSetTraits<Value, Traits, Allocator> NodeHashTraits; 155 typedef LinkedHashSetTranslator<Value, HashFunctions, Allocator>
153 156 NodeHashFunctions;
154 typedef HashTable<Node, Node, IdentityExtractor, 157 typedef LinkedHashSetTraits<Value, Traits, Allocator> NodeHashTraits;
155 NodeHashFunctions, NodeHashTraits, NodeHashTraits, Allocator> ImplType; 158
156 159 typedef HashTable<Node,
157 public: 160 Node,
158 typedef LinkedHashSetIterator<LinkedHashSet> iterator; 161 IdentityExtractor,
159 friend class LinkedHashSetIterator<LinkedHashSet>; 162 NodeHashFunctions,
160 typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator; 163 NodeHashTraits,
161 friend class LinkedHashSetConstIterator<LinkedHashSet>; 164 NodeHashTraits,
162 165 Allocator>
163 typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator; 166 ImplType;
164 friend class LinkedHashSetReverseIterator<LinkedHashSet>; 167
165 typedef LinkedHashSetConstReverseIterator<LinkedHashSet> const_reverse_itera tor; 168 public:
166 friend class LinkedHashSetConstReverseIterator<LinkedHashSet>; 169 typedef LinkedHashSetIterator<LinkedHashSet> iterator;
167 170 friend class LinkedHashSetIterator<LinkedHashSet>;
168 struct AddResult final { 171 typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator;
169 STACK_ALLOCATED(); 172 friend class LinkedHashSetConstIterator<LinkedHashSet>;
170 AddResult(const typename ImplType::AddResult& hashTableAddResult) 173
171 : storedValue(&hashTableAddResult.storedValue->m_value) 174 typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator;
172 , isNewEntry(hashTableAddResult.isNewEntry) 175 friend class LinkedHashSetReverseIterator<LinkedHashSet>;
173 { 176 typedef LinkedHashSetConstReverseIterator<LinkedHashSet>
174 } 177 const_reverse_iterator;
175 178 friend class LinkedHashSetConstReverseIterator<LinkedHashSet>;
176 Value* storedValue; 179
177 bool isNewEntry; 180 struct AddResult final {
178 }; 181 STACK_ALLOCATED();
179 182 AddResult(const typename ImplType::AddResult& hashTableAddResult)
180 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; 183 : storedValue(&hashTableAddResult.storedValue->m_value),
181 184 isNewEntry(hashTableAddResult.isNewEntry) {}
182 LinkedHashSet(); 185
183 LinkedHashSet(const LinkedHashSet&); 186 Value* storedValue;
184 LinkedHashSet& operator=(const LinkedHashSet&); 187 bool isNewEntry;
185 188 };
186 // Needs finalization. The anchor needs to unlink itself from the chain. 189
187 ~LinkedHashSet(); 190 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
188 191
189 static void finalize(void* pointer) { reinterpret_cast<LinkedHashSet*>(point er)->~LinkedHashSet(); } 192 LinkedHashSet();
190 void finalizeGarbageCollectedObject() { finalize(this); } 193 LinkedHashSet(const LinkedHashSet&);
191 194 LinkedHashSet& operator=(const LinkedHashSet&);
192 void swap(LinkedHashSet&); 195
193 196 // Needs finalization. The anchor needs to unlink itself from the chain.
194 unsigned size() const { return m_impl.size(); } 197 ~LinkedHashSet();
195 unsigned capacity() const { return m_impl.capacity(); } 198
196 bool isEmpty() const { return m_impl.isEmpty(); } 199 static void finalize(void* pointer) {
197 200 reinterpret_cast<LinkedHashSet*>(pointer)->~LinkedHashSet();
198 iterator begin() { return makeIterator(firstNode()); } 201 }
199 iterator end() { return makeIterator(anchor()); } 202 void finalizeGarbageCollectedObject() { finalize(this); }
200 const_iterator begin() const { return makeConstIterator(firstNode()); } 203
201 const_iterator end() const { return makeConstIterator(anchor()); } 204 void swap(LinkedHashSet&);
202 205
203 reverse_iterator rbegin() { return makeReverseIterator(lastNode()); } 206 unsigned size() const { return m_impl.size(); }
204 reverse_iterator rend() { return makeReverseIterator(anchor()); } 207 unsigned capacity() const { return m_impl.capacity(); }
205 const_reverse_iterator rbegin() const { return makeConstReverseIterator(last Node()); } 208 bool isEmpty() const { return m_impl.isEmpty(); }
206 const_reverse_iterator rend() const { return makeConstReverseIterator(anchor ()); } 209
207 210 iterator begin() { return makeIterator(firstNode()); }
208 Value& first(); 211 iterator end() { return makeIterator(anchor()); }
209 const Value& first() const; 212 const_iterator begin() const { return makeConstIterator(firstNode()); }
210 void removeFirst(); 213 const_iterator end() const { return makeConstIterator(anchor()); }
211 214
212 Value& last(); 215 reverse_iterator rbegin() { return makeReverseIterator(lastNode()); }
213 const Value& last() const; 216 reverse_iterator rend() { return makeReverseIterator(anchor()); }
214 void removeLast(); 217 const_reverse_iterator rbegin() const {
215 218 return makeConstReverseIterator(lastNode());
216 iterator find(ValuePeekInType); 219 }
217 const_iterator find(ValuePeekInType) const; 220 const_reverse_iterator rend() const {
218 bool contains(ValuePeekInType) const; 221 return makeConstReverseIterator(anchor());
219 222 }
220 // An alternate version of find() that finds the object by hashing and compa ring 223
221 // with some other type, to avoid the cost of type conversion. 224 Value& first();
222 // The HashTranslator interface is defined in HashSet. 225 const Value& first() const;
223 template<typename HashTranslator, typename T> iterator find(const T&); 226 void removeFirst();
224 template<typename HashTranslator, typename T> const_iterator find(const T&) const; 227
225 template<typename HashTranslator, typename T> bool contains(const T&) const; 228 Value& last();
226 229 const Value& last() const;
227 // The return value of add is a pair of a pointer to the stored value, 230 void removeLast();
228 // and a bool that is true if an new entry was added. 231
229 AddResult add(ValuePeekInType); 232 iterator find(ValuePeekInType);
230 233 const_iterator find(ValuePeekInType) const;
231 // Same as add() except that the return value is an 234 bool contains(ValuePeekInType) const;
232 // iterator. Useful in cases where it's needed to have the 235
233 // same return value as find() and where it's not possible to 236 // An alternate version of find() that finds the object by hashing and compari ng
234 // use a pointer to the storedValue. 237 // with some other type, to avoid the cost of type conversion.
235 iterator addReturnIterator(ValuePeekInType); 238 // The HashTranslator interface is defined in HashSet.
236 239 template <typename HashTranslator, typename T>
237 // Add the value to the end of the collection. If the value was already in 240 iterator find(const T&);
238 // the list, it is moved to the end. 241 template <typename HashTranslator, typename T>
239 AddResult appendOrMoveToLast(ValuePeekInType); 242 const_iterator find(const T&) const;
240 243 template <typename HashTranslator, typename T>
241 // Add the value to the beginning of the collection. If the value was alread y in 244 bool contains(const T&) const;
242 // the list, it is moved to the beginning. 245
243 AddResult prependOrMoveToFirst(ValuePeekInType); 246 // The return value of add is a pair of a pointer to the stored value,
244 247 // and a bool that is true if an new entry was added.
245 AddResult insertBefore(ValuePeekInType beforeValue, ValuePeekInType newValue ); 248 AddResult add(ValuePeekInType);
246 AddResult insertBefore(iterator it, ValuePeekInType newValue) { return m_imp l.template add<NodeHashFunctions>(newValue, it.node()); } 249
247 250 // Same as add() except that the return value is an
248 void remove(ValuePeekInType); 251 // iterator. Useful in cases where it's needed to have the
249 void remove(iterator); 252 // same return value as find() and where it's not possible to
250 void clear() { m_impl.clear(); } 253 // use a pointer to the storedValue.
251 template<typename Collection> 254 iterator addReturnIterator(ValuePeekInType);
252 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } 255
253 256 // Add the value to the end of the collection. If the value was already in
254 template<typename VisitorDispatcher> 257 // the list, it is moved to the end.
255 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } 258 AddResult appendOrMoveToLast(ValuePeekInType);
256 259
257 int64_t modifications() const { return m_impl.modifications(); } 260 // Add the value to the beginning of the collection. If the value was already in
258 void checkModifications(int64_t mods) const { m_impl.checkModifications(mods ); } 261 // the list, it is moved to the beginning.
259 262 AddResult prependOrMoveToFirst(ValuePeekInType);
260 private: 263
261 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } 264 AddResult insertBefore(ValuePeekInType beforeValue, ValuePeekInType newValue);
262 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor) ; } 265 AddResult insertBefore(iterator it, ValuePeekInType newValue) {
263 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); } 266 return m_impl.template add<NodeHashFunctions>(newValue, it.node());
264 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_ancho r.m_next); } 267 }
265 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); } 268
266 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor .m_prev); } 269 void remove(ValuePeekInType);
267 270 void remove(iterator);
268 iterator makeIterator(const Node* position) { return iterator(position, this ); } 271 void clear() { m_impl.clear(); }
269 const_iterator makeConstIterator(const Node* position) const { return const_ iterator(position, this); } 272 template <typename Collection>
270 reverse_iterator makeReverseIterator(const Node* position) { return reverse_ iterator(position, this); } 273 void removeAll(const Collection& other) {
271 const_reverse_iterator makeConstReverseIterator(const Node* position) const { return const_reverse_iterator(position, this); } 274 WTF::removeAll(*this, other);
272 275 }
273 ImplType m_impl; 276
274 NodeBase m_anchor; 277 template <typename VisitorDispatcher>
275 }; 278 void trace(VisitorDispatcher visitor) {
276 279 m_impl.trace(visitor);
277 template<typename Value, typename HashFunctions, typename Allocator> 280 }
281
282 int64_t modifications() const { return m_impl.modifications(); }
283 void checkModifications(int64_t mods) const {
284 m_impl.checkModifications(mods);
285 }
286
287 private:
288 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); }
289 const Node* anchor() const {
290 return reinterpret_cast<const Node*>(&m_anchor);
291 }
292 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); }
293 const Node* firstNode() const {
294 return reinterpret_cast<const Node*>(m_anchor.m_next);
295 }
296 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); }
297 const Node* lastNode() const {
298 return reinterpret_cast<const Node*>(m_anchor.m_prev);
299 }
300
301 iterator makeIterator(const Node* position) {
302 return iterator(position, this);
303 }
304 const_iterator makeConstIterator(const Node* position) const {
305 return const_iterator(position, this);
306 }
307 reverse_iterator makeReverseIterator(const Node* position) {
308 return reverse_iterator(position, this);
309 }
310 const_reverse_iterator makeConstReverseIterator(const Node* position) const {
311 return const_reverse_iterator(position, this);
312 }
313
314 ImplType m_impl;
315 NodeBase m_anchor;
316 };
317
318 template <typename Value, typename HashFunctions, typename Allocator>
278 struct LinkedHashSetTranslator { 319 struct LinkedHashSetTranslator {
279 STATIC_ONLY(LinkedHashSetTranslator); 320 STATIC_ONLY(LinkedHashSetTranslator);
280 typedef LinkedHashSetNode<Value, Allocator> Node; 321 typedef LinkedHashSetNode<Value, Allocator> Node;
281 typedef LinkedHashSetNodeBase NodeBase; 322 typedef LinkedHashSetNodeBase NodeBase;
282 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; 323 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
283 static unsigned hash(const Node& node) { return HashFunctions::hash(node.m_v alue); } 324 static unsigned hash(const Node& node) {
284 static unsigned hash(const ValuePeekInType& key) { return HashFunctions::has h(key); } 325 return HashFunctions::hash(node.m_value);
285 static bool equal(const Node& a, const ValuePeekInType& b) { return HashFunc tions::equal(a.m_value, b); } 326 }
286 static bool equal(const Node& a, const Node& b) { return HashFunctions::equa l(a.m_value, b.m_value); } 327 static unsigned hash(const ValuePeekInType& key) {
287 static void translate(Node& location, ValuePeekInType key, NodeBase* anchor) 328 return HashFunctions::hash(key);
288 { 329 }
289 anchor->insertBefore(location); 330 static bool equal(const Node& a, const ValuePeekInType& b) {
290 location.m_value = key; 331 return HashFunctions::equal(a.m_value, b);
291 } 332 }
292 333 static bool equal(const Node& a, const Node& b) {
293 // Empty (or deleted) slots have the m_next pointer set to null, but we 334 return HashFunctions::equal(a.m_value, b.m_value);
294 // don't do anything to the other fields, which may contain junk. 335 }
295 // Therefore you can't compare a newly constructed empty value with a 336 static void translate(Node& location, ValuePeekInType key, NodeBase* anchor) {
296 // slot and get the right answer. 337 anchor->insertBefore(location);
297 static const bool safeToCompareToEmptyOrDeleted = false; 338 location.m_value = key;
298 }; 339 }
299 340
300 template<typename Value, typename Allocator> 341 // Empty (or deleted) slots have the m_next pointer set to null, but we
342 // don't do anything to the other fields, which may contain junk.
343 // Therefore you can't compare a newly constructed empty value with a
344 // slot and get the right answer.
345 static const bool safeToCompareToEmptyOrDeleted = false;
346 };
347
348 template <typename Value, typename Allocator>
301 struct LinkedHashSetExtractor { 349 struct LinkedHashSetExtractor {
302 STATIC_ONLY(LinkedHashSetExtractor); 350 STATIC_ONLY(LinkedHashSetExtractor);
303 static const Value& extract(const LinkedHashSetNode<Value, Allocator>& node) { return node.m_value; } 351 static const Value& extract(const LinkedHashSetNode<Value, Allocator>& node) {
304 }; 352 return node.m_value;
305 353 }
306 template<typename Value, typename ValueTraitsArg, typename Allocator> 354 };
307 struct LinkedHashSetTraits : public SimpleClassHashTraits<LinkedHashSetNode<Valu e, Allocator>> { 355
308 STATIC_ONLY(LinkedHashSetTraits); 356 template <typename Value, typename ValueTraitsArg, typename Allocator>
309 typedef LinkedHashSetNode<Value, Allocator> Node; 357 struct LinkedHashSetTraits
310 typedef ValueTraitsArg ValueTraits; 358 : public SimpleClassHashTraits<LinkedHashSetNode<Value, Allocator>> {
311 359 STATIC_ONLY(LinkedHashSetTraits);
312 // The slot is empty when the m_next field is zero so it's safe to zero 360 typedef LinkedHashSetNode<Value, Allocator> Node;
313 // the backing. 361 typedef ValueTraitsArg ValueTraits;
314 static const bool emptyValueIsZero = true; 362
315 363 // The slot is empty when the m_next field is zero so it's safe to zero
316 static const bool hasIsEmptyValueFunction = true; 364 // the backing.
317 static bool isEmptyValue(const Node& node) { return !node.m_next; } 365 static const bool emptyValueIsZero = true;
318 366
319 static const int deletedValue = -1; 367 static const bool hasIsEmptyValueFunction = true;
320 368 static bool isEmptyValue(const Node& node) { return !node.m_next; }
321 static void constructDeletedValue(Node& slot, bool) { slot.m_next = reinterp ret_cast<Node*>(deletedValue); } 369
322 static bool isDeletedValue(const Node& slot) { return slot.m_next == reinter pret_cast<Node*>(deletedValue); } 370 static const int deletedValue = -1;
323 371
324 // Whether we need to trace and do weak processing depends on the traits of 372 static void constructDeletedValue(Node& slot, bool) {
325 // the type inside the node. 373 slot.m_next = reinterpret_cast<Node*>(deletedValue);
326 template<typename U = void> 374 }
327 struct NeedsTracingLazily { 375 static bool isDeletedValue(const Node& slot) {
328 STATIC_ONLY(NeedsTracingLazily); 376 return slot.m_next == reinterpret_cast<Node*>(deletedValue);
329 static const bool value = ValueTraits::template NeedsTracingLazily<>::va lue; 377 }
330 }; 378
331 static const WeakHandlingFlag weakHandlingFlag = ValueTraits::weakHandlingFl ag; 379 // Whether we need to trace and do weak processing depends on the traits of
332 }; 380 // the type inside the node.
333 381 template <typename U = void>
334 template<typename LinkedHashSetType> 382 struct NeedsTracingLazily {
383 STATIC_ONLY(NeedsTracingLazily);
384 static const bool value = ValueTraits::template NeedsTracingLazily<>::value;
385 };
386 static const WeakHandlingFlag weakHandlingFlag =
387 ValueTraits::weakHandlingFlag;
388 };
389
390 template <typename LinkedHashSetType>
335 class LinkedHashSetIterator { 391 class LinkedHashSetIterator {
336 DISALLOW_NEW(); 392 DISALLOW_NEW();
337 private: 393
338 typedef typename LinkedHashSetType::Node Node; 394 private:
339 typedef typename LinkedHashSetType::Traits Traits; 395 typedef typename LinkedHashSetType::Node Node;
340 396 typedef typename LinkedHashSetType::Traits Traits;
341 typedef typename LinkedHashSetType::Value& ReferenceType; 397
342 typedef typename LinkedHashSetType::Value* PointerType; 398 typedef typename LinkedHashSetType::Value& ReferenceType;
343 399 typedef typename LinkedHashSetType::Value* PointerType;
344 typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator; 400
345 401 typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator;
346 Node* node() { return const_cast<Node*>(m_iterator.node()); } 402
347 403 Node* node() { return const_cast<Node*>(m_iterator.node()); }
348 protected: 404
349 LinkedHashSetIterator(const Node* position, LinkedHashSetType* m_container) 405 protected:
350 : m_iterator(position , m_container) 406 LinkedHashSetIterator(const Node* position, LinkedHashSetType* m_container)
351 { 407 : m_iterator(position, m_container) {}
352 } 408
353 409 public:
354 public: 410 // Default copy, assignment and destructor are OK.
355 // Default copy, assignment and destructor are OK. 411
356 412 PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
357 PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } 413 ReferenceType operator*() const { return *get(); }
358 ReferenceType operator*() const { return *get(); } 414 PointerType operator->() const { return get(); }
359 PointerType operator->() const { return get(); } 415
360 416 LinkedHashSetIterator& operator++() {
361 LinkedHashSetIterator& operator++() { ++m_iterator; return *this; } 417 ++m_iterator;
362 LinkedHashSetIterator& operator--() { --m_iterator; return *this; } 418 return *this;
363 419 }
364 // Postfix ++ and -- intentionally omitted. 420 LinkedHashSetIterator& operator--() {
365 421 --m_iterator;
366 // Comparison. 422 return *this;
367 bool operator==(const LinkedHashSetIterator& other) const { return m_iterato r == other.m_iterator; } 423 }
368 bool operator!=(const LinkedHashSetIterator& other) const { return m_iterato r != other.m_iterator; } 424
369 425 // Postfix ++ and -- intentionally omitted.
370 operator const_iterator() const { return m_iterator; } 426
371 427 // Comparison.
372 protected: 428 bool operator==(const LinkedHashSetIterator& other) const {
373 const_iterator m_iterator; 429 return m_iterator == other.m_iterator;
374 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 430 }
375 }; 431 bool operator!=(const LinkedHashSetIterator& other) const {
376 432 return m_iterator != other.m_iterator;
377 template<typename LinkedHashSetType> 433 }
434
435 operator const_iterator() const { return m_iterator; }
436
437 protected:
438 const_iterator m_iterator;
439 template <typename T, typename U, typename V, typename W>
440 friend class LinkedHashSet;
441 };
442
443 template <typename LinkedHashSetType>
378 class LinkedHashSetConstIterator { 444 class LinkedHashSetConstIterator {
379 DISALLOW_NEW(); 445 DISALLOW_NEW();
380 private: 446
381 typedef typename LinkedHashSetType::Node Node; 447 private:
382 typedef typename LinkedHashSetType::Traits Traits; 448 typedef typename LinkedHashSetType::Node Node;
383 449 typedef typename LinkedHashSetType::Traits Traits;
384 typedef const typename LinkedHashSetType::Value& ReferenceType; 450
385 typedef const typename LinkedHashSetType::Value* PointerType; 451 typedef const typename LinkedHashSetType::Value& ReferenceType;
386 452 typedef const typename LinkedHashSetType::Value* PointerType;
387 const Node* node() const { return static_cast<const Node*>(m_position); } 453
388 454 const Node* node() const { return static_cast<const Node*>(m_position); }
389 protected: 455
390 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Link edHashSetType* container) 456 protected:
391 : m_position(position) 457 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position,
458 const LinkedHashSetType* container)
459 : m_position(position)
392 #if ENABLE(ASSERT) 460 #if ENABLE(ASSERT)
393 , m_container(container) 461 ,
394 , m_containerModifications(container->modifications()) 462 m_container(container),
463 m_containerModifications(container->modifications())
395 #endif 464 #endif
396 { 465 {
397 } 466 }
398 467
399 public: 468 public:
400 PointerType get() const 469 PointerType get() const {
401 { 470 checkModifications();
402 checkModifications(); 471 return &static_cast<const Node*>(m_position)->m_value;
403 return &static_cast<const Node*>(m_position)->m_value; 472 }
404 } 473 ReferenceType operator*() const { return *get(); }
405 ReferenceType operator*() const { return *get(); } 474 PointerType operator->() const { return get(); }
406 PointerType operator->() const { return get(); } 475
407 476 LinkedHashSetConstIterator& operator++() {
408 LinkedHashSetConstIterator& operator++() 477 ASSERT(m_position);
409 { 478 checkModifications();
410 ASSERT(m_position); 479 m_position = m_position->m_next;
411 checkModifications(); 480 return *this;
412 m_position = m_position->m_next; 481 }
413 return *this; 482
414 } 483 LinkedHashSetConstIterator& operator--() {
415 484 ASSERT(m_position);
416 LinkedHashSetConstIterator& operator--() 485 checkModifications();
417 { 486 m_position = m_position->m_prev;
418 ASSERT(m_position); 487 return *this;
419 checkModifications(); 488 }
420 m_position = m_position->m_prev; 489
421 return *this; 490 // Postfix ++ and -- intentionally omitted.
422 } 491
423 492 // Comparison.
424 // Postfix ++ and -- intentionally omitted. 493 bool operator==(const LinkedHashSetConstIterator& other) const {
425 494 return m_position == other.m_position;
426 // Comparison. 495 }
427 bool operator==(const LinkedHashSetConstIterator& other) const 496 bool operator!=(const LinkedHashSetConstIterator& other) const {
428 { 497 return m_position != other.m_position;
429 return m_position == other.m_position; 498 }
430 } 499
431 bool operator!=(const LinkedHashSetConstIterator& other) const 500 private:
432 { 501 const LinkedHashSetNodeBase* m_position;
433 return m_position != other.m_position;
434 }
435
436 private:
437 const LinkedHashSetNodeBase* m_position;
438 #if ENABLE(ASSERT) 502 #if ENABLE(ASSERT)
439 void checkModifications() const { m_container->checkModifications(m_containe rModifications); } 503 void checkModifications() const {
440 const LinkedHashSetType* m_container; 504 m_container->checkModifications(m_containerModifications);
441 int64_t m_containerModifications; 505 }
506 const LinkedHashSetType* m_container;
507 int64_t m_containerModifications;
442 #else 508 #else
443 void checkModifications() const { } 509 void checkModifications() const {}
444 #endif 510 #endif
445 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 511 template <typename T, typename U, typename V, typename W>
446 friend class LinkedHashSetIterator<LinkedHashSetType>; 512 friend class LinkedHashSet;
447 }; 513 friend class LinkedHashSetIterator<LinkedHashSetType>;
448 514 };
449 template<typename LinkedHashSetType> 515
450 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT ype> { 516 template <typename LinkedHashSetType>
451 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass; 517 class LinkedHashSetReverseIterator
452 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_i terator; 518 : public LinkedHashSetIterator<LinkedHashSetType> {
453 typedef typename LinkedHashSetType::Node Node; 519 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass;
454 520 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType>
455 protected: 521 const_reverse_iterator;
456 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* contai ner) 522 typedef typename LinkedHashSetType::Node Node;
457 : Superclass(position, container) { } 523
458 524 protected:
459 public: 525 LinkedHashSetReverseIterator(const Node* position,
460 LinkedHashSetReverseIterator& operator++() { Superclass::operator--(); retur n *this; } 526 LinkedHashSetType* container)
461 LinkedHashSetReverseIterator& operator--() { Superclass::operator++(); retur n *this; } 527 : Superclass(position, container) {}
462 528
463 // Postfix ++ and -- intentionally omitted. 529 public:
464 530 LinkedHashSetReverseIterator& operator++() {
465 operator const_reverse_iterator() const { return *reinterpret_cast<const_rev erse_iterator*>(this); } 531 Superclass::operator--();
466 532 return *this;
467 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 533 }
468 }; 534 LinkedHashSetReverseIterator& operator--() {
469 535 Superclass::operator++();
470 template<typename LinkedHashSetType> 536 return *this;
471 class LinkedHashSetConstReverseIterator : public LinkedHashSetConstIterator<Link edHashSetType> { 537 }
472 typedef LinkedHashSetConstIterator<LinkedHashSetType> Superclass; 538
473 typedef typename LinkedHashSetType::Node Node; 539 // Postfix ++ and -- intentionally omitted.
474 540
475 public: 541 operator const_reverse_iterator() const {
476 LinkedHashSetConstReverseIterator(const Node* position, const LinkedHashSetT ype* container) 542 return *reinterpret_cast<const_reverse_iterator*>(this);
477 : Superclass(position, container) { } 543 }
478 544
479 LinkedHashSetConstReverseIterator& operator++() { Superclass::operator--(); return *this; } 545 template <typename T, typename U, typename V, typename W>
480 LinkedHashSetConstReverseIterator& operator--() { Superclass::operator++(); return *this; } 546 friend class LinkedHashSet;
481 547 };
482 // Postfix ++ and -- intentionally omitted. 548
483 549 template <typename LinkedHashSetType>
484 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 550 class LinkedHashSetConstReverseIterator
485 }; 551 : public LinkedHashSetConstIterator<LinkedHashSetType> {
486 552 typedef LinkedHashSetConstIterator<LinkedHashSetType> Superclass;
487 template<typename T, typename U, typename V, typename W> 553 typedef typename LinkedHashSetType::Node Node;
488 inline LinkedHashSet<T, U, V, W>::LinkedHashSet() { } 554
489 555 public:
490 template<typename T, typename U, typename V, typename W> 556 LinkedHashSetConstReverseIterator(const Node* position,
557 const LinkedHashSetType* container)
558 : Superclass(position, container) {}
559
560 LinkedHashSetConstReverseIterator& operator++() {
561 Superclass::operator--();
562 return *this;
563 }
564 LinkedHashSetConstReverseIterator& operator--() {
565 Superclass::operator++();
566 return *this;
567 }
568
569 // Postfix ++ and -- intentionally omitted.
570
571 template <typename T, typename U, typename V, typename W>
572 friend class LinkedHashSet;
573 };
574
575 template <typename T, typename U, typename V, typename W>
576 inline LinkedHashSet<T, U, V, W>::LinkedHashSet() {}
577
578 template <typename T, typename U, typename V, typename W>
491 inline LinkedHashSet<T, U, V, W>::LinkedHashSet(const LinkedHashSet& other) 579 inline LinkedHashSet<T, U, V, W>::LinkedHashSet(const LinkedHashSet& other)
492 : m_anchor() 580 : m_anchor() {
493 { 581 const_iterator end = other.end();
494 const_iterator end = other.end(); 582 for (const_iterator it = other.begin(); it != end; ++it)
495 for (const_iterator it = other.begin(); it != end; ++it) 583 add(*it);
496 add(*it); 584 }
497 } 585
498 586 template <typename T, typename U, typename V, typename W>
499 template<typename T, typename U, typename V, typename W> 587 inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=(
500 inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=(const Lin kedHashSet& other) 588 const LinkedHashSet& other) {
501 { 589 LinkedHashSet tmp(other);
502 LinkedHashSet tmp(other); 590 swap(tmp);
503 swap(tmp); 591 return *this;
504 return *this; 592 }
505 } 593
506 594 template <typename T, typename U, typename V, typename W>
507 template<typename T, typename U, typename V, typename W> 595 inline void LinkedHashSet<T, U, V, W>::swap(LinkedHashSet& other) {
508 inline void LinkedHashSet<T, U, V, W>::swap(LinkedHashSet& other) 596 m_impl.swap(other.m_impl);
509 { 597 swapAnchor(m_anchor, other.m_anchor);
510 m_impl.swap(other.m_impl); 598 }
511 swapAnchor(m_anchor, other.m_anchor); 599
512 } 600 template <typename T, typename U, typename V, typename Allocator>
513 601 inline LinkedHashSet<T, U, V, Allocator>::~LinkedHashSet() {
514 template<typename T, typename U, typename V, typename Allocator> 602 // The destructor of m_anchor will implicitly be called here, which will
515 inline LinkedHashSet<T, U, V, Allocator>::~LinkedHashSet() 603 // unlink the anchor from the collection.
516 { 604 }
517 // The destructor of m_anchor will implicitly be called here, which will 605
518 // unlink the anchor from the collection. 606 template <typename T, typename U, typename V, typename W>
519 } 607 inline T& LinkedHashSet<T, U, V, W>::first() {
520 608 ASSERT(!isEmpty());
521 template<typename T, typename U, typename V, typename W> 609 return firstNode()->m_value;
522 inline T& LinkedHashSet<T, U, V, W>::first() 610 }
523 { 611
524 ASSERT(!isEmpty()); 612 template <typename T, typename U, typename V, typename W>
525 return firstNode()->m_value; 613 inline const T& LinkedHashSet<T, U, V, W>::first() const {
526 } 614 ASSERT(!isEmpty());
527 615 return firstNode()->m_value;
528 template<typename T, typename U, typename V, typename W> 616 }
529 inline const T& LinkedHashSet<T, U, V, W>::first() const 617
530 { 618 template <typename T, typename U, typename V, typename W>
531 ASSERT(!isEmpty()); 619 inline void LinkedHashSet<T, U, V, W>::removeFirst() {
532 return firstNode()->m_value; 620 ASSERT(!isEmpty());
533 } 621 m_impl.remove(static_cast<Node*>(m_anchor.m_next));
534 622 }
535 template<typename T, typename U, typename V, typename W> 623
536 inline void LinkedHashSet<T, U, V, W>::removeFirst() 624 template <typename T, typename U, typename V, typename W>
537 { 625 inline T& LinkedHashSet<T, U, V, W>::last() {
538 ASSERT(!isEmpty()); 626 ASSERT(!isEmpty());
539 m_impl.remove(static_cast<Node*>(m_anchor.m_next)); 627 return lastNode()->m_value;
540 } 628 }
541 629
542 template<typename T, typename U, typename V, typename W> 630 template <typename T, typename U, typename V, typename W>
543 inline T& LinkedHashSet<T, U, V, W>::last() 631 inline const T& LinkedHashSet<T, U, V, W>::last() const {
544 { 632 ASSERT(!isEmpty());
545 ASSERT(!isEmpty()); 633 return lastNode()->m_value;
546 return lastNode()->m_value; 634 }
547 } 635
548 636 template <typename T, typename U, typename V, typename W>
549 template<typename T, typename U, typename V, typename W> 637 inline void LinkedHashSet<T, U, V, W>::removeLast() {
550 inline const T& LinkedHashSet<T, U, V, W>::last() const 638 ASSERT(!isEmpty());
551 { 639 m_impl.remove(static_cast<Node*>(m_anchor.m_prev));
552 ASSERT(!isEmpty()); 640 }
553 return lastNode()->m_value; 641
554 } 642 template <typename T, typename U, typename V, typename W>
555 643 inline typename LinkedHashSet<T, U, V, W>::iterator
556 template<typename T, typename U, typename V, typename W> 644 LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) {
557 inline void LinkedHashSet<T, U, V, W>::removeLast() 645 LinkedHashSet::Node* node =
558 { 646 m_impl.template lookup<LinkedHashSet::NodeHashFunctions, ValuePeekInType>(
559 ASSERT(!isEmpty()); 647 value);
560 m_impl.remove(static_cast<Node*>(m_anchor.m_prev)); 648 if (!node)
561 } 649 return end();
562 650 return makeIterator(node);
563 template<typename T, typename U, typename V, typename W> 651 }
564 inline typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::f ind(ValuePeekInType value) 652
565 { 653 template <typename T, typename U, typename V, typename W>
566 LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::NodeHashFu nctions, ValuePeekInType>(value); 654 inline typename LinkedHashSet<T, U, V, W>::const_iterator
567 if (!node) 655 LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) const {
568 return end(); 656 const LinkedHashSet::Node* node =
569 return makeIterator(node); 657 m_impl.template lookup<LinkedHashSet::NodeHashFunctions, ValuePeekInType>(
570 } 658 value);
571 659 if (!node)
572 template<typename T, typename U, typename V, typename W> 660 return end();
573 inline typename LinkedHashSet<T, U, V, W>::const_iterator LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) const 661 return makeConstIterator(node);
574 { 662 }
575 const LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::Node HashFunctions, ValuePeekInType>(value); 663
576 if (!node) 664 template <typename Translator>
577 return end();
578 return makeConstIterator(node);
579 }
580
581 template<typename Translator>
582 struct LinkedHashSetTranslatorAdapter { 665 struct LinkedHashSetTranslatorAdapter {
583 STATIC_ONLY(LinkedHashSetTranslatorAdapter); 666 STATIC_ONLY(LinkedHashSetTranslatorAdapter);
584 template<typename T> static unsigned hash(const T& key) { return Translator: :hash(key); } 667 template <typename T>
585 template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a.m_value, b); } 668 static unsigned hash(const T& key) {
586 }; 669 return Translator::hash(key);
587 670 }
588 template<typename Value, typename U, typename V, typename W> 671 template <typename T, typename U>
589 template<typename HashTranslator, typename T> 672 static bool equal(const T& a, const U& b) {
590 inline typename LinkedHashSet<Value, U, V, W>::iterator LinkedHashSet<Value, U, V, W>::find(const T& value) 673 return Translator::equal(a.m_value, b);
591 { 674 }
592 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions; 675 };
593 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value); 676
594 if (!node) 677 template <typename Value, typename U, typename V, typename W>
595 return end(); 678 template <typename HashTranslator, typename T>
596 return makeIterator(node); 679 inline typename LinkedHashSet<Value, U, V, W>::iterator
597 } 680 LinkedHashSet<Value, U, V, W>::find(const T& value) {
598 681 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
599 template<typename Value, typename U, typename V, typename W> 682 const LinkedHashSet::Node* node =
600 template<typename HashTranslator, typename T> 683 m_impl.template lookup<TranslatedFunctions, const T&>(value);
601 inline typename LinkedHashSet<Value, U, V, W>::const_iterator LinkedHashSet<Valu e, U, V, W>::find(const T& value) const 684 if (!node)
602 { 685 return end();
603 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions; 686 return makeIterator(node);
604 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value); 687 }
605 if (!node) 688
606 return end(); 689 template <typename Value, typename U, typename V, typename W>
607 return makeConstIterator(node); 690 template <typename HashTranslator, typename T>
608 } 691 inline typename LinkedHashSet<Value, U, V, W>::const_iterator
609 692 LinkedHashSet<Value, U, V, W>::find(const T& value) const {
610 template<typename Value, typename U, typename V, typename W> 693 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
611 template<typename HashTranslator, typename T> 694 const LinkedHashSet::Node* node =
612 inline bool LinkedHashSet<Value, U, V, W>::contains(const T& value) const 695 m_impl.template lookup<TranslatedFunctions, const T&>(value);
613 { 696 if (!node)
614 return m_impl.template contains<LinkedHashSetTranslatorAdapter<HashTranslato r>>(value); 697 return end();
615 } 698 return makeConstIterator(node);
616 699 }
617 template<typename T, typename U, typename V, typename W> 700
618 inline bool LinkedHashSet<T, U, V, W>::contains(ValuePeekInType value) const 701 template <typename Value, typename U, typename V, typename W>
619 { 702 template <typename HashTranslator, typename T>
620 return m_impl.template contains<NodeHashFunctions>(value); 703 inline bool LinkedHashSet<Value, U, V, W>::contains(const T& value) const {
621 } 704 return m_impl
622 705 .template contains<LinkedHashSetTranslatorAdapter<HashTranslator>>(value);
623 template<typename Value, typename HashFunctions, typename Traits, typename Alloc ator> 706 }
624 typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult Linke dHashSet<Value, HashFunctions, Traits, Allocator>::add(ValuePeekInType value) 707
625 { 708 template <typename T, typename U, typename V, typename W>
626 return m_impl.template add<NodeHashFunctions>(value, &m_anchor); 709 inline bool LinkedHashSet<T, U, V, W>::contains(ValuePeekInType value) const {
627 } 710 return m_impl.template contains<NodeHashFunctions>(value);
628 711 }
629 template<typename T, typename U, typename V, typename W> 712
630 typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::addRetur nIterator(ValuePeekInType value) 713 template <typename Value,
631 { 714 typename HashFunctions,
632 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor); 715 typename Traits,
633 return makeIterator(result.storedValue); 716 typename Allocator>
634 } 717 typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult
635 718 LinkedHashSet<Value, HashFunctions, Traits, Allocator>::add(
636 template<typename T, typename U, typename V, typename W> 719 ValuePeekInType value) {
637 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::appendO rMoveToLast(ValuePeekInType value) 720 return m_impl.template add<NodeHashFunctions>(value, &m_anchor);
638 { 721 }
639 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor); 722
640 Node* node = result.storedValue; 723 template <typename T, typename U, typename V, typename W>
641 if (!result.isNewEntry) { 724 typename LinkedHashSet<T, U, V, W>::iterator
642 node->unlink(); 725 LinkedHashSet<T, U, V, W>::addReturnIterator(ValuePeekInType value) {
643 m_anchor.insertBefore(*node); 726 typename ImplType::AddResult result =
644 } 727 m_impl.template add<NodeHashFunctions>(value, &m_anchor);
645 return result; 728 return makeIterator(result.storedValue);
646 } 729 }
647 730
648 template<typename T, typename U, typename V, typename W> 731 template <typename T, typename U, typename V, typename W>
649 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::prepend OrMoveToFirst(ValuePeekInType value) 732 typename LinkedHashSet<T, U, V, W>::AddResult
650 { 733 LinkedHashSet<T, U, V, W>::appendOrMoveToLast(ValuePeekInType value) {
651 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, m_anchor.m_next); 734 typename ImplType::AddResult result =
652 Node* node = result.storedValue; 735 m_impl.template add<NodeHashFunctions>(value, &m_anchor);
653 if (!result.isNewEntry) { 736 Node* node = result.storedValue;
654 node->unlink(); 737 if (!result.isNewEntry) {
655 m_anchor.insertAfter(*node); 738 node->unlink();
656 } 739 m_anchor.insertBefore(*node);
657 return result; 740 }
658 } 741 return result;
659 742 }
660 template<typename T, typename U, typename V, typename W> 743
661 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::insertB efore(ValuePeekInType beforeValue, ValuePeekInType newValue) 744 template <typename T, typename U, typename V, typename W>
662 { 745 typename LinkedHashSet<T, U, V, W>::AddResult
663 return insertBefore(find(beforeValue), newValue); 746 LinkedHashSet<T, U, V, W>::prependOrMoveToFirst(ValuePeekInType value) {
664 } 747 typename ImplType::AddResult result =
665 748 m_impl.template add<NodeHashFunctions>(value, m_anchor.m_next);
666 template<typename T, typename U, typename V, typename W> 749 Node* node = result.storedValue;
667 inline void LinkedHashSet<T, U, V, W>::remove(iterator it) 750 if (!result.isNewEntry) {
668 { 751 node->unlink();
669 if (it == end()) 752 m_anchor.insertAfter(*node);
670 return; 753 }
671 m_impl.remove(it.node()); 754 return result;
672 } 755 }
673 756
674 template<typename T, typename U, typename V, typename W> 757 template <typename T, typename U, typename V, typename W>
675 inline void LinkedHashSet<T, U, V, W>::remove(ValuePeekInType value) 758 typename LinkedHashSet<T, U, V, W>::AddResult
676 { 759 LinkedHashSet<T, U, V, W>::insertBefore(ValuePeekInType beforeValue,
677 remove(find(value)); 760 ValuePeekInType newValue) {
678 } 761 return insertBefore(find(beforeValue), newValue);
679 762 }
680 inline void swapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) 763
681 { 764 template <typename T, typename U, typename V, typename W>
682 ASSERT(a.m_prev && a.m_next && b.m_prev && b.m_next); 765 inline void LinkedHashSet<T, U, V, W>::remove(iterator it) {
683 swap(a.m_prev, b.m_prev); 766 if (it == end())
684 swap(a.m_next, b.m_next); 767 return;
685 if (b.m_next == &a) { 768 m_impl.remove(it.node());
686 ASSERT(b.m_prev == &a); 769 }
687 b.m_next = &b; 770
688 b.m_prev = &b; 771 template <typename T, typename U, typename V, typename W>
689 } else { 772 inline void LinkedHashSet<T, U, V, W>::remove(ValuePeekInType value) {
690 b.m_next->m_prev = &b; 773 remove(find(value));
691 b.m_prev->m_next = &b; 774 }
692 } 775
693 if (a.m_next == &b) { 776 inline void swapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) {
694 ASSERT(a.m_prev == &b); 777 ASSERT(a.m_prev && a.m_next && b.m_prev && b.m_next);
695 a.m_next = &a; 778 swap(a.m_prev, b.m_prev);
696 a.m_prev = &a; 779 swap(a.m_next, b.m_next);
697 } else { 780 if (b.m_next == &a) {
698 a.m_next->m_prev = &a; 781 ASSERT(b.m_prev == &a);
699 a.m_prev->m_next = &a; 782 b.m_next = &b;
700 } 783 b.m_prev = &b;
701 } 784 } else {
702 785 b.m_next->m_prev = &b;
703 inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) 786 b.m_prev->m_next = &b;
704 { 787 }
705 ASSERT(a.m_next != &a && b.m_next != &b); 788 if (a.m_next == &b) {
706 swap(a.m_prev, b.m_prev); 789 ASSERT(a.m_prev == &b);
707 swap(a.m_next, b.m_next); 790 a.m_next = &a;
708 if (b.m_next) { 791 a.m_prev = &a;
709 b.m_next->m_prev = &b; 792 } else {
710 b.m_prev->m_next = &b; 793 a.m_next->m_prev = &a;
711 } 794 a.m_prev->m_next = &a;
712 if (a.m_next) { 795 }
713 a.m_next->m_prev = &a; 796 }
714 a.m_prev->m_next = &a; 797
715 } 798 inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) {
716 } 799 ASSERT(a.m_next != &a && b.m_next != &b);
717 800 swap(a.m_prev, b.m_prev);
718 template<typename T, typename Allocator> 801 swap(a.m_next, b.m_next);
719 inline void swap(LinkedHashSetNode<T, Allocator>& a, LinkedHashSetNode<T, Alloca tor>& b) 802 if (b.m_next) {
720 { 803 b.m_next->m_prev = &b;
721 typedef LinkedHashSetNodeBase Base; 804 b.m_prev->m_next = &b;
722 // The key and value cannot be swapped atomically, and it would be 805 }
723 // wrong to have a GC when only one was swapped and the other still 806 if (a.m_next) {
724 // contained garbage (eg. from a previous use of the same slot). 807 a.m_next->m_prev = &a;
725 // Therefore we forbid a GC until both the key and the value are 808 a.m_prev->m_next = &a;
726 // swapped. 809 }
727 Allocator::enterGCForbiddenScope(); 810 }
728 swap(static_cast<Base&>(a), static_cast<Base&>(b)); 811
729 swap(a.m_value, b.m_value); 812 template <typename T, typename Allocator>
730 Allocator::leaveGCForbiddenScope(); 813 inline void swap(LinkedHashSetNode<T, Allocator>& a,
814 LinkedHashSetNode<T, Allocator>& b) {
815 typedef LinkedHashSetNodeBase Base;
816 // The key and value cannot be swapped atomically, and it would be
817 // wrong to have a GC when only one was swapped and the other still
818 // contained garbage (eg. from a previous use of the same slot).
819 // Therefore we forbid a GC until both the key and the value are
820 // swapped.
821 Allocator::enterGCForbiddenScope();
822 swap(static_cast<Base&>(a), static_cast<Base&>(b));
823 swap(a.m_value, b.m_value);
824 Allocator::leaveGCForbiddenScope();
731 } 825 }
732 826
733 #if !ENABLE(OILPAN) 827 #if !ENABLE(OILPAN)
734 template<typename T, typename U, typename V> 828 template <typename T, typename U, typename V>
735 struct NeedsTracing<LinkedHashSet<T, U, V>> { 829 struct NeedsTracing<LinkedHashSet<T, U, V>> {
736 STATIC_ONLY(NeedsTracing); 830 STATIC_ONLY(NeedsTracing);
737 static const bool value = false; 831 static const bool value = false;
738 }; 832 };
739 #endif 833 #endif
740
741 } 834 }
742 835
743 using WTF::LinkedHashSet; 836 using WTF::LinkedHashSet;
744 837
745 #endif /* WTF_LinkedHashSet_h */ 838 #endif /* WTF_LinkedHashSet_h */
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/LeakAnnotations.h ('k') | third_party/WebKit/Source/wtf/LinkedStack.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698