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

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

Issue 1436153002: Apply clang-format with Chromium-style without column limit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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, typename HashFunctions, typename HashTraits, typename Allocator>
43 43 class LinkedHashSet;
44 template<typename LinkedHashSet> class LinkedHashSetIterator; 44
45 template<typename LinkedHashSet> class LinkedHashSetConstIterator; 45 template <typename LinkedHashSet>
46 template<typename LinkedHashSet> class LinkedHashSetReverseIterator; 46 class LinkedHashSetIterator;
47 template<typename LinkedHashSet> class LinkedHashSetConstReverseIterator; 47 template <typename LinkedHashSet>
48 48 class LinkedHashSetConstIterator;
49 template<typename Value, typename HashFunctions, typename Allocator> struct Link edHashSetTranslator; 49 template <typename LinkedHashSet>
50 template<typename Value, typename Allocator> struct LinkedHashSetExtractor; 50 class LinkedHashSetReverseIterator;
51 template<typename Value, typename ValueTraits, typename Allocator> struct Linked HashSetTraits; 51 template <typename LinkedHashSet>
52 class LinkedHashSetConstReverseIterator;
53
54 template <typename Value, typename HashFunctions, typename Allocator>
55 struct LinkedHashSetTranslator;
56 template <typename Value, typename Allocator>
57 struct LinkedHashSetExtractor;
58 template <typename Value, typename ValueTraits, typename Allocator>
59 struct LinkedHashSetTraits;
52 60
53 class LinkedHashSetNodeBase { 61 class LinkedHashSetNodeBase {
54 public: 62 public:
55 LinkedHashSetNodeBase() : m_prev(this), m_next(this) { } 63 LinkedHashSetNodeBase()
56 64 : m_prev(this), m_next(this) {}
57 NO_LAZY_SWEEP_SANITIZE_ADDRESS 65
58 void unlink() 66 NO_LAZY_SWEEP_SANITIZE_ADDRESS
59 { 67 void unlink() {
60 if (!m_next) 68 if (!m_next)
61 return; 69 return;
62 ASSERT(m_prev); 70 ASSERT(m_prev);
63 ASSERT(m_next->m_prev == this); 71 ASSERT(m_next->m_prev == this);
64 ASSERT(m_prev->m_next == this); 72 ASSERT(m_prev->m_next == this);
65 m_next->m_prev = m_prev; 73 m_next->m_prev = m_prev;
66 m_prev->m_next = m_next; 74 m_prev->m_next = m_next;
67 } 75 }
68 76
69 ~LinkedHashSetNodeBase() 77 ~LinkedHashSetNodeBase() {
70 { 78 unlink();
71 unlink(); 79 }
72 } 80
73 81 void insertBefore(LinkedHashSetNodeBase& other) {
74 void insertBefore(LinkedHashSetNodeBase& other) 82 other.m_next = this;
75 { 83 other.m_prev = m_prev;
76 other.m_next = this; 84 m_prev->m_next = &other;
77 other.m_prev = m_prev; 85 m_prev = &other;
78 m_prev->m_next = &other; 86 ASSERT(other.m_next);
79 m_prev = &other; 87 ASSERT(other.m_prev);
80 ASSERT(other.m_next); 88 ASSERT(m_next);
81 ASSERT(other.m_prev); 89 ASSERT(m_prev);
82 ASSERT(m_next); 90 }
83 ASSERT(m_prev); 91
84 } 92 void insertAfter(LinkedHashSetNodeBase& other) {
85 93 other.m_prev = this;
86 void insertAfter(LinkedHashSetNodeBase& other) 94 other.m_next = m_next;
87 { 95 m_next->m_prev = &other;
88 other.m_prev = this; 96 m_next = &other;
89 other.m_next = m_next; 97 ASSERT(other.m_next);
90 m_next->m_prev = &other; 98 ASSERT(other.m_prev);
91 m_next = &other; 99 ASSERT(m_next);
92 ASSERT(other.m_next); 100 ASSERT(m_prev);
93 ASSERT(other.m_prev); 101 }
94 ASSERT(m_next); 102
95 ASSERT(m_prev); 103 LinkedHashSetNodeBase(LinkedHashSetNodeBase* prev, LinkedHashSetNodeBase* next )
96 } 104 : m_prev(prev), m_next(next) {
97 105 ASSERT((prev && next) || (!prev && !next));
98 LinkedHashSetNodeBase(LinkedHashSetNodeBase* prev, LinkedHashSetNodeBase* ne xt) 106 }
99 : m_prev(prev) 107
100 , m_next(next) 108 LinkedHashSetNodeBase* m_prev;
101 { 109 LinkedHashSetNodeBase* m_next;
102 ASSERT((prev && next) || (!prev && !next)); 110
103 } 111 protected:
104 112 // If we take a copy of a node we can't copy the next and prev pointers,
105 LinkedHashSetNodeBase* m_prev; 113 // since they point to something that does not point at us. This is used
106 LinkedHashSetNodeBase* m_next; 114 // inside the shouldExpand() "if" in HashTable::add.
107 115 LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other)
108 protected: 116 : m_prev(0), m_next(0) {}
109 // If we take a copy of a node we can't copy the next and prev pointers, 117
110 // since they point to something that does not point at us. This is used 118 private:
111 // inside the shouldExpand() "if" in HashTable::add. 119 // Should not be used.
112 LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other) 120 LinkedHashSetNodeBase& operator=(const LinkedHashSetNodeBase& other);
113 : m_prev(0) 121 };
114 , m_next(0) { } 122
115 123 template <typename ValueArg, typename Allocator>
116 private:
117 // Should not be used.
118 LinkedHashSetNodeBase& operator=(const LinkedHashSetNodeBase& other);
119 };
120
121 template<typename ValueArg, typename Allocator>
122 class LinkedHashSetNode : public LinkedHashSetNodeBase { 124 class LinkedHashSetNode : public LinkedHashSetNodeBase {
123 public: 125 public:
124 LinkedHashSetNode(const ValueArg& value, LinkedHashSetNodeBase* prev, Linked HashSetNodeBase* next) 126 LinkedHashSetNode(const ValueArg& value, LinkedHashSetNodeBase* prev, LinkedHa shSetNodeBase* next)
125 : LinkedHashSetNodeBase(prev, next) 127 : LinkedHashSetNodeBase(prev, next), m_value(value) {
126 , m_value(value) 128 }
127 { 129
128 } 130 ValueArg m_value;
129 131
130 ValueArg m_value; 132 private:
131 133 // Not used.
132 private: 134 LinkedHashSetNode(const LinkedHashSetNode&);
133 // Not used. 135 };
134 LinkedHashSetNode(const LinkedHashSetNode&); 136
135 }; 137 template <
136
137 template<
138 typename ValueArg, 138 typename ValueArg,
139 typename HashFunctions = typename DefaultHash<ValueArg>::Hash, 139 typename HashFunctions = typename DefaultHash<ValueArg>::Hash,
140 typename TraitsArg = HashTraits<ValueArg>, 140 typename TraitsArg = HashTraits<ValueArg>,
141 typename Allocator = PartitionAllocator> 141 typename Allocator = PartitionAllocator>
142 class LinkedHashSet { 142 class LinkedHashSet {
143 WTF_USE_ALLOCATOR(LinkedHashSet, Allocator); 143 WTF_USE_ALLOCATOR(LinkedHashSet, Allocator);
144 private: 144
145 typedef ValueArg Value; 145 private:
146 typedef TraitsArg Traits; 146 typedef ValueArg Value;
147 typedef LinkedHashSetNode<Value, Allocator> Node; 147 typedef TraitsArg Traits;
148 typedef LinkedHashSetNodeBase NodeBase; 148 typedef LinkedHashSetNode<Value, Allocator> Node;
149 typedef LinkedHashSetTranslator<Value, HashFunctions, Allocator> NodeHashFun ctions; 149 typedef LinkedHashSetNodeBase NodeBase;
150 typedef LinkedHashSetTraits<Value, Traits, Allocator> NodeHashTraits; 150 typedef LinkedHashSetTranslator<Value, HashFunctions, Allocator> NodeHashFunct ions;
151 151 typedef LinkedHashSetTraits<Value, Traits, Allocator> NodeHashTraits;
152 typedef HashTable<Node, Node, IdentityExtractor, 152
153 NodeHashFunctions, NodeHashTraits, NodeHashTraits, Allocator> ImplType; 153 typedef HashTable<Node, Node, IdentityExtractor, NodeHashFunctions, NodeHashTr aits, NodeHashTraits, Allocator> ImplType;
154 154
155 public: 155 public:
156 typedef LinkedHashSetIterator<LinkedHashSet> iterator; 156 typedef LinkedHashSetIterator<LinkedHashSet> iterator;
157 friend class LinkedHashSetIterator<LinkedHashSet>; 157 friend class LinkedHashSetIterator<LinkedHashSet>;
158 typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator; 158 typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator;
159 friend class LinkedHashSetConstIterator<LinkedHashSet>; 159 friend class LinkedHashSetConstIterator<LinkedHashSet>;
160 160
161 typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator; 161 typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator;
162 friend class LinkedHashSetReverseIterator<LinkedHashSet>; 162 friend class LinkedHashSetReverseIterator<LinkedHashSet>;
163 typedef LinkedHashSetConstReverseIterator<LinkedHashSet> const_reverse_itera tor; 163 typedef LinkedHashSetConstReverseIterator<LinkedHashSet> const_reverse_iterato r;
164 friend class LinkedHashSetConstReverseIterator<LinkedHashSet>; 164 friend class LinkedHashSetConstReverseIterator<LinkedHashSet>;
165 165
166 struct AddResult { 166 struct AddResult {
167 AddResult(const typename ImplType::AddResult& hashTableAddResult) 167 AddResult(const typename ImplType::AddResult& hashTableAddResult)
168 : storedValue(&hashTableAddResult.storedValue->m_value) 168 : storedValue(&hashTableAddResult.storedValue->m_value), isNewEntry(hash TableAddResult.isNewEntry) {
169 , isNewEntry(hashTableAddResult.isNewEntry) 169 }
170 { 170
171 } 171 Value* storedValue;
172 172 bool isNewEntry;
173 Value* storedValue; 173 };
174 bool isNewEntry; 174
175 }; 175 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
176 176
177 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; 177 LinkedHashSet();
178 178 LinkedHashSet(const LinkedHashSet&);
179 LinkedHashSet(); 179 LinkedHashSet& operator=(const LinkedHashSet&);
180 LinkedHashSet(const LinkedHashSet&); 180
181 LinkedHashSet& operator=(const LinkedHashSet&); 181 // Needs finalization. The anchor needs to unlink itself from the chain.
182 182 ~LinkedHashSet();
183 // Needs finalization. The anchor needs to unlink itself from the chain. 183
184 ~LinkedHashSet(); 184 static void finalize(void* pointer) { reinterpret_cast<LinkedHashSet*>(pointer )->~LinkedHashSet(); }
185 185 void finalizeGarbageCollectedObject() { finalize(this); }
186 static void finalize(void* pointer) { reinterpret_cast<LinkedHashSet*>(point er)->~LinkedHashSet(); } 186
187 void finalizeGarbageCollectedObject() { finalize(this); } 187 void swap(LinkedHashSet&);
188 188
189 void swap(LinkedHashSet&); 189 unsigned size() const { return m_impl.size(); }
190 190 unsigned capacity() const { return m_impl.capacity(); }
191 unsigned size() const { return m_impl.size(); } 191 bool isEmpty() const { return m_impl.isEmpty(); }
192 unsigned capacity() const { return m_impl.capacity(); } 192
193 bool isEmpty() const { return m_impl.isEmpty(); } 193 iterator begin() { return makeIterator(firstNode()); }
194 194 iterator end() { return makeIterator(anchor()); }
195 iterator begin() { return makeIterator(firstNode()); } 195 const_iterator begin() const { return makeConstIterator(firstNode()); }
196 iterator end() { return makeIterator(anchor()); } 196 const_iterator end() const { return makeConstIterator(anchor()); }
197 const_iterator begin() const { return makeConstIterator(firstNode()); } 197
198 const_iterator end() const { return makeConstIterator(anchor()); } 198 reverse_iterator rbegin() { return makeReverseIterator(lastNode()); }
199 199 reverse_iterator rend() { return makeReverseIterator(anchor()); }
200 reverse_iterator rbegin() { return makeReverseIterator(lastNode()); } 200 const_reverse_iterator rbegin() const { return makeConstReverseIterator(lastNo de()); }
201 reverse_iterator rend() { return makeReverseIterator(anchor()); } 201 const_reverse_iterator rend() const { return makeConstReverseIterator(anchor() ); }
202 const_reverse_iterator rbegin() const { return makeConstReverseIterator(last Node()); } 202
203 const_reverse_iterator rend() const { return makeConstReverseIterator(anchor ()); } 203 Value& first();
204 204 const Value& first() const;
205 Value& first(); 205 void removeFirst();
206 const Value& first() const; 206
207 void removeFirst(); 207 Value& last();
208 208 const Value& last() const;
209 Value& last(); 209 void removeLast();
210 const Value& last() const; 210
211 void removeLast(); 211 iterator find(ValuePeekInType);
212 212 const_iterator find(ValuePeekInType) const;
213 iterator find(ValuePeekInType); 213 bool contains(ValuePeekInType) const;
214 const_iterator find(ValuePeekInType) const; 214
215 bool contains(ValuePeekInType) const; 215 // An alternate version of find() that finds the object by hashing and compari ng
216 216 // with some other type, to avoid the cost of type conversion.
217 // An alternate version of find() that finds the object by hashing and compa ring 217 // The HashTranslator interface is defined in HashSet.
218 // with some other type, to avoid the cost of type conversion. 218 template <typename HashTranslator, typename T>
219 // The HashTranslator interface is defined in HashSet. 219 iterator find(const T&);
220 template<typename HashTranslator, typename T> iterator find(const T&); 220 template <typename HashTranslator, typename T>
221 template<typename HashTranslator, typename T> const_iterator find(const T&) const; 221 const_iterator find(const T&) const;
222 template<typename HashTranslator, typename T> bool contains(const T&) const; 222 template <typename HashTranslator, typename T>
223 223 bool contains(const T&) const;
224 // The return value of add is a pair of a pointer to the stored value, 224
225 // and a bool that is true if an new entry was added. 225 // The return value of add is a pair of a pointer to the stored value,
226 AddResult add(ValuePeekInType); 226 // and a bool that is true if an new entry was added.
227 227 AddResult add(ValuePeekInType);
228 // Same as add() except that the return value is an 228
229 // iterator. Useful in cases where it's needed to have the 229 // Same as add() except that the return value is an
230 // same return value as find() and where it's not possible to 230 // iterator. Useful in cases where it's needed to have the
231 // use a pointer to the storedValue. 231 // same return value as find() and where it's not possible to
232 iterator addReturnIterator(ValuePeekInType); 232 // use a pointer to the storedValue.
233 233 iterator addReturnIterator(ValuePeekInType);
234 // Add the value to the end of the collection. If the value was already in 234
235 // the list, it is moved to the end. 235 // Add the value to the end of the collection. If the value was already in
236 AddResult appendOrMoveToLast(ValuePeekInType); 236 // the list, it is moved to the end.
237 237 AddResult appendOrMoveToLast(ValuePeekInType);
238 // Add the value to the beginning of the collection. If the value was alread y in 238
239 // the list, it is moved to the beginning. 239 // Add the value to the beginning of the collection. If the value was already in
240 AddResult prependOrMoveToFirst(ValuePeekInType); 240 // the list, it is moved to the beginning.
241 241 AddResult prependOrMoveToFirst(ValuePeekInType);
242 AddResult insertBefore(ValuePeekInType beforeValue, ValuePeekInType newValue ); 242
243 AddResult insertBefore(iterator it, ValuePeekInType newValue) { return m_imp l.template add<NodeHashFunctions>(newValue, it.node()); } 243 AddResult insertBefore(ValuePeekInType beforeValue, ValuePeekInType newValue);
244 244 AddResult insertBefore(iterator it, ValuePeekInType newValue) { return m_impl. template add<NodeHashFunctions>(newValue, it.node()); }
245 void remove(ValuePeekInType); 245
246 void remove(iterator); 246 void remove(ValuePeekInType);
247 void clear() { m_impl.clear(); } 247 void remove(iterator);
248 template<typename Collection> 248 void clear() { m_impl.clear(); }
249 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } 249 template <typename Collection>
250 250 void removeAll(const Collection& other) { WTF::removeAll(*this, other); }
251 template<typename VisitorDispatcher> 251
252 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } 252 template <typename VisitorDispatcher>
253 253 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); }
254 int64_t modifications() const { return m_impl.modifications(); } 254
255 void checkModifications(int64_t mods) const { m_impl.checkModifications(mods ); } 255 int64_t modifications() const { return m_impl.modifications(); }
256 256 void checkModifications(int64_t mods) const { m_impl.checkModifications(mods); }
257 private: 257
258 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } 258 private:
259 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor) ; } 259 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); }
260 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); } 260 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor); }
261 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_ancho r.m_next); } 261 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); }
262 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); } 262 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_anchor. m_next); }
263 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor .m_prev); } 263 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); }
264 264 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor.m _prev); }
265 iterator makeIterator(const Node* position) { return iterator(position, this ); } 265
266 const_iterator makeConstIterator(const Node* position) const { return const_ iterator(position, this); } 266 iterator makeIterator(const Node* position) { return iterator(position, this); }
267 reverse_iterator makeReverseIterator(const Node* position) { return reverse_ iterator(position, this); } 267 const_iterator makeConstIterator(const Node* position) const { return const_it erator(position, this); }
268 const_reverse_iterator makeConstReverseIterator(const Node* position) const { return const_reverse_iterator(position, this); } 268 reverse_iterator makeReverseIterator(const Node* position) { return reverse_it erator(position, this); }
269 269 const_reverse_iterator makeConstReverseIterator(const Node* position) const { return const_reverse_iterator(position, this); }
270 ImplType m_impl; 270
271 NodeBase m_anchor; 271 ImplType m_impl;
272 }; 272 NodeBase m_anchor;
273 273 };
274 template<typename Value, typename HashFunctions, typename Allocator> 274
275 template <typename Value, typename HashFunctions, typename Allocator>
275 struct LinkedHashSetTranslator { 276 struct LinkedHashSetTranslator {
276 typedef LinkedHashSetNode<Value, Allocator> Node; 277 typedef LinkedHashSetNode<Value, Allocator> Node;
277 typedef LinkedHashSetNodeBase NodeBase; 278 typedef LinkedHashSetNodeBase NodeBase;
278 typedef typename HashTraits<Value>::PeekInType ValuePeekInType; 279 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
279 static unsigned hash(const Node& node) { return HashFunctions::hash(node.m_v alue); } 280 static unsigned hash(const Node& node) { return HashFunctions::hash(node.m_val ue); }
280 static unsigned hash(const ValuePeekInType& key) { return HashFunctions::has h(key); } 281 static unsigned hash(const ValuePeekInType& key) { return HashFunctions::hash( key); }
281 static bool equal(const Node& a, const ValuePeekInType& b) { return HashFunc tions::equal(a.m_value, b); } 282 static bool equal(const Node& a, const ValuePeekInType& b) { return HashFuncti ons::equal(a.m_value, b); }
282 static bool equal(const Node& a, const Node& b) { return HashFunctions::equa l(a.m_value, b.m_value); } 283 static bool equal(const Node& a, const Node& b) { return HashFunctions::equal( a.m_value, b.m_value); }
283 static void translate(Node& location, ValuePeekInType key, NodeBase* anchor) 284 static void translate(Node& location, ValuePeekInType key, NodeBase* anchor) {
284 { 285 anchor->insertBefore(location);
285 anchor->insertBefore(location); 286 location.m_value = key;
286 location.m_value = key; 287 }
287 } 288
288 289 // Empty (or deleted) slots have the m_next pointer set to null, but we
289 // Empty (or deleted) slots have the m_next pointer set to null, but we 290 // don't do anything to the other fields, which may contain junk.
290 // don't do anything to the other fields, which may contain junk. 291 // Therefore you can't compare a newly constructed empty value with a
291 // Therefore you can't compare a newly constructed empty value with a 292 // slot and get the right answer.
292 // slot and get the right answer. 293 static const bool safeToCompareToEmptyOrDeleted = false;
293 static const bool safeToCompareToEmptyOrDeleted = false; 294 };
294 }; 295
295 296 template <typename Value, typename Allocator>
296 template<typename Value, typename Allocator>
297 struct LinkedHashSetExtractor { 297 struct LinkedHashSetExtractor {
298 static const Value& extract(const LinkedHashSetNode<Value, Allocator>& node) { return node.m_value; } 298 static const Value& extract(const LinkedHashSetNode<Value, Allocator>& node) { return node.m_value; }
299 }; 299 };
300 300
301 template<typename Value, typename ValueTraitsArg, typename Allocator> 301 template <typename Value, typename ValueTraitsArg, typename Allocator>
302 struct LinkedHashSetTraits : public SimpleClassHashTraits<LinkedHashSetNode<Valu e, Allocator>> { 302 struct LinkedHashSetTraits : public SimpleClassHashTraits<LinkedHashSetNode<Valu e, Allocator>> {
303 typedef LinkedHashSetNode<Value, Allocator> Node; 303 typedef LinkedHashSetNode<Value, Allocator> Node;
304 typedef ValueTraitsArg ValueTraits; 304 typedef ValueTraitsArg ValueTraits;
305 305
306 // The slot is empty when the m_next field is zero so it's safe to zero 306 // The slot is empty when the m_next field is zero so it's safe to zero
307 // the backing. 307 // the backing.
308 static const bool emptyValueIsZero = true; 308 static const bool emptyValueIsZero = true;
309 309
310 static const bool hasIsEmptyValueFunction = true; 310 static const bool hasIsEmptyValueFunction = true;
311 static bool isEmptyValue(const Node& node) { return !node.m_next; } 311 static bool isEmptyValue(const Node& node) { return !node.m_next; }
312 312
313 static const int deletedValue = -1; 313 static const int deletedValue = -1;
314 314
315 static void constructDeletedValue(Node& slot, bool) { slot.m_next = reinterp ret_cast<Node*>(deletedValue); } 315 static void constructDeletedValue(Node& slot, bool) { slot.m_next = reinterpre t_cast<Node*>(deletedValue); }
316 static bool isDeletedValue(const Node& slot) { return slot.m_next == reinter pret_cast<Node*>(deletedValue); } 316 static bool isDeletedValue(const Node& slot) { return slot.m_next == reinterpr et_cast<Node*>(deletedValue); }
317 317
318 // Whether we need to trace and do weak processing depends on the traits of 318 // Whether we need to trace and do weak processing depends on the traits of
319 // the type inside the node. 319 // the type inside the node.
320 template<typename U = void> 320 template <typename U = void>
321 struct NeedsTracingLazily { 321 struct NeedsTracingLazily {
322 static const bool value = ValueTraits::template NeedsTracingLazily<>::va lue; 322 static const bool value = ValueTraits::template NeedsTracingLazily<>::value;
323 }; 323 };
324 static const WeakHandlingFlag weakHandlingFlag = ValueTraits::weakHandlingFl ag; 324 static const WeakHandlingFlag weakHandlingFlag = ValueTraits::weakHandlingFlag ;
325 }; 325 };
326 326
327 template<typename LinkedHashSetType> 327 template <typename LinkedHashSetType>
328 class LinkedHashSetIterator { 328 class LinkedHashSetIterator {
329 private: 329 private:
330 typedef typename LinkedHashSetType::Node Node; 330 typedef typename LinkedHashSetType::Node Node;
331 typedef typename LinkedHashSetType::Traits Traits; 331 typedef typename LinkedHashSetType::Traits Traits;
332 332
333 typedef typename LinkedHashSetType::Value& ReferenceType; 333 typedef typename LinkedHashSetType::Value& ReferenceType;
334 typedef typename LinkedHashSetType::Value* PointerType; 334 typedef typename LinkedHashSetType::Value* PointerType;
335 335
336 typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator; 336 typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator;
337 337
338 Node* node() { return const_cast<Node*>(m_iterator.node()); } 338 Node* node() { return const_cast<Node*>(m_iterator.node()); }
339 339
340 protected: 340 protected:
341 LinkedHashSetIterator(const Node* position, LinkedHashSetType* m_container) 341 LinkedHashSetIterator(const Node* position, LinkedHashSetType* m_container)
342 : m_iterator(position , m_container) 342 : m_iterator(position, m_container) {
343 { 343 }
344 } 344
345 345 public:
346 public: 346 // Default copy, assignment and destructor are OK.
347 // Default copy, assignment and destructor are OK. 347
348 348 PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
349 PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } 349 ReferenceType operator*() const { return *get(); }
350 ReferenceType operator*() const { return *get(); } 350 PointerType operator->() const { return get(); }
351 PointerType operator->() const { return get(); } 351
352 352 LinkedHashSetIterator& operator++() {
353 LinkedHashSetIterator& operator++() { ++m_iterator; return *this; } 353 ++m_iterator;
354 LinkedHashSetIterator& operator--() { --m_iterator; return *this; } 354 return *this;
355 355 }
356 // Postfix ++ and -- intentionally omitted. 356 LinkedHashSetIterator& operator--() {
357 357 --m_iterator;
358 // Comparison. 358 return *this;
359 bool operator==(const LinkedHashSetIterator& other) const { return m_iterato r == other.m_iterator; } 359 }
360 bool operator!=(const LinkedHashSetIterator& other) const { return m_iterato r != other.m_iterator; } 360
361 361 // Postfix ++ and -- intentionally omitted.
362 operator const_iterator() const { return m_iterator; } 362
363 363 // Comparison.
364 protected: 364 bool operator==(const LinkedHashSetIterator& other) const { return m_iterator == other.m_iterator; }
365 const_iterator m_iterator; 365 bool operator!=(const LinkedHashSetIterator& other) const { return m_iterator != other.m_iterator; }
366 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 366
367 }; 367 operator const_iterator() const { return m_iterator; }
368 368
369 template<typename LinkedHashSetType> 369 protected:
370 const_iterator m_iterator;
371 template <typename T, typename U, typename V, typename W>
372 friend class LinkedHashSet;
373 };
374
375 template <typename LinkedHashSetType>
370 class LinkedHashSetConstIterator { 376 class LinkedHashSetConstIterator {
371 private: 377 private:
372 typedef typename LinkedHashSetType::Node Node; 378 typedef typename LinkedHashSetType::Node Node;
373 typedef typename LinkedHashSetType::Traits Traits; 379 typedef typename LinkedHashSetType::Traits Traits;
374 380
375 typedef const typename LinkedHashSetType::Value& ReferenceType; 381 typedef const typename LinkedHashSetType::Value& ReferenceType;
376 typedef const typename LinkedHashSetType::Value* PointerType; 382 typedef const typename LinkedHashSetType::Value* PointerType;
377 383
378 const Node* node() const { return static_cast<const Node*>(m_position); } 384 const Node* node() const { return static_cast<const Node*>(m_position); }
379 385
380 protected: 386 protected:
381 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Link edHashSetType* container) 387 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Linked HashSetType* container)
382 : m_position(position) 388 : m_position(position)
383 #if ENABLE(ASSERT) 389 #if ENABLE(ASSERT)
384 , m_container(container) 390 ,
385 , m_containerModifications(container->modifications()) 391 m_container(container),
392 m_containerModifications(container->modifications())
386 #endif 393 #endif
387 { 394 {
388 } 395 }
389 396
390 public: 397 public:
391 PointerType get() const 398 PointerType get() const {
392 { 399 checkModifications();
393 checkModifications(); 400 return &static_cast<const Node*>(m_position)->m_value;
394 return &static_cast<const Node*>(m_position)->m_value; 401 }
395 } 402 ReferenceType operator*() const { return *get(); }
396 ReferenceType operator*() const { return *get(); } 403 PointerType operator->() const { return get(); }
397 PointerType operator->() const { return get(); } 404
398 405 LinkedHashSetConstIterator& operator++() {
399 LinkedHashSetConstIterator& operator++() 406 ASSERT(m_position);
400 { 407 checkModifications();
401 ASSERT(m_position); 408 m_position = m_position->m_next;
402 checkModifications(); 409 return *this;
403 m_position = m_position->m_next; 410 }
404 return *this; 411
405 } 412 LinkedHashSetConstIterator& operator--() {
406 413 ASSERT(m_position);
407 LinkedHashSetConstIterator& operator--() 414 checkModifications();
408 { 415 m_position = m_position->m_prev;
409 ASSERT(m_position); 416 return *this;
410 checkModifications(); 417 }
411 m_position = m_position->m_prev; 418
412 return *this; 419 // Postfix ++ and -- intentionally omitted.
413 } 420
414 421 // Comparison.
415 // Postfix ++ and -- intentionally omitted. 422 bool operator==(const LinkedHashSetConstIterator& other) const {
416 423 return m_position == other.m_position;
417 // Comparison. 424 }
418 bool operator==(const LinkedHashSetConstIterator& other) const 425 bool operator!=(const LinkedHashSetConstIterator& other) const {
419 { 426 return m_position != other.m_position;
420 return m_position == other.m_position; 427 }
421 } 428
422 bool operator!=(const LinkedHashSetConstIterator& other) const 429 private:
423 { 430 const LinkedHashSetNodeBase* m_position;
424 return m_position != other.m_position;
425 }
426
427 private:
428 const LinkedHashSetNodeBase* m_position;
429 #if ENABLE(ASSERT) 431 #if ENABLE(ASSERT)
430 void checkModifications() const { m_container->checkModifications(m_containe rModifications); } 432 void checkModifications() const { m_container->checkModifications(m_containerM odifications); }
431 const LinkedHashSetType* m_container; 433 const LinkedHashSetType* m_container;
432 int64_t m_containerModifications; 434 int64_t m_containerModifications;
433 #else 435 #else
434 void checkModifications() const { } 436 void checkModifications() const {}
435 #endif 437 #endif
436 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 438 template <typename T, typename U, typename V, typename W>
437 friend class LinkedHashSetIterator<LinkedHashSetType>; 439 friend class LinkedHashSet;
438 }; 440 friend class LinkedHashSetIterator<LinkedHashSetType>;
439 441 };
440 template<typename LinkedHashSetType> 442
443 template <typename LinkedHashSetType>
441 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT ype> { 444 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT ype> {
442 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass; 445 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass;
443 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_i terator; 446 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_ite rator;
444 typedef typename LinkedHashSetType::Node Node; 447 typedef typename LinkedHashSetType::Node Node;
445 448
446 protected: 449 protected:
447 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* contai ner) 450 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* containe r)
448 : Superclass(position, container) { } 451 : Superclass(position, container) {}
449 452
450 public: 453 public:
451 LinkedHashSetReverseIterator& operator++() { Superclass::operator--(); retur n *this; } 454 LinkedHashSetReverseIterator& operator++() {
452 LinkedHashSetReverseIterator& operator--() { Superclass::operator++(); retur n *this; } 455 Superclass::operator--();
453 456 return *this;
454 // Postfix ++ and -- intentionally omitted. 457 }
455 458 LinkedHashSetReverseIterator& operator--() {
456 operator const_reverse_iterator() const { return *reinterpret_cast<const_rev erse_iterator*>(this); } 459 Superclass::operator++();
457 460 return *this;
458 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 461 }
459 }; 462
460 463 // Postfix ++ and -- intentionally omitted.
461 template<typename LinkedHashSetType> 464
465 operator const_reverse_iterator() const { return *reinterpret_cast<const_rever se_iterator*>(this); }
466
467 template <typename T, typename U, typename V, typename W>
468 friend class LinkedHashSet;
469 };
470
471 template <typename LinkedHashSetType>
462 class LinkedHashSetConstReverseIterator : public LinkedHashSetConstIterator<Link edHashSetType> { 472 class LinkedHashSetConstReverseIterator : public LinkedHashSetConstIterator<Link edHashSetType> {
463 typedef LinkedHashSetConstIterator<LinkedHashSetType> Superclass; 473 typedef LinkedHashSetConstIterator<LinkedHashSetType> Superclass;
464 typedef typename LinkedHashSetType::Node Node; 474 typedef typename LinkedHashSetType::Node Node;
465 475
466 public: 476 public:
467 LinkedHashSetConstReverseIterator(const Node* position, const LinkedHashSetT ype* container) 477 LinkedHashSetConstReverseIterator(const Node* position, const LinkedHashSetTyp e* container)
468 : Superclass(position, container) { } 478 : Superclass(position, container) {}
469 479
470 LinkedHashSetConstReverseIterator& operator++() { Superclass::operator--(); return *this; } 480 LinkedHashSetConstReverseIterator& operator++() {
471 LinkedHashSetConstReverseIterator& operator--() { Superclass::operator++(); return *this; } 481 Superclass::operator--();
472 482 return *this;
473 // Postfix ++ and -- intentionally omitted. 483 }
474 484 LinkedHashSetConstReverseIterator& operator--() {
475 template<typename T, typename U, typename V, typename W> friend class Linked HashSet; 485 Superclass::operator++();
476 }; 486 return *this;
477 487 }
478 template<typename T, typename U, typename V, typename W> 488
479 inline LinkedHashSet<T, U, V, W>::LinkedHashSet() { } 489 // Postfix ++ and -- intentionally omitted.
480 490
481 template<typename T, typename U, typename V, typename W> 491 template <typename T, typename U, typename V, typename W>
492 friend class LinkedHashSet;
493 };
494
495 template <typename T, typename U, typename V, typename W>
496 inline LinkedHashSet<T, U, V, W>::LinkedHashSet() {}
497
498 template <typename T, typename U, typename V, typename W>
482 inline LinkedHashSet<T, U, V, W>::LinkedHashSet(const LinkedHashSet& other) 499 inline LinkedHashSet<T, U, V, W>::LinkedHashSet(const LinkedHashSet& other)
483 : m_anchor() 500 : m_anchor() {
484 { 501 const_iterator end = other.end();
485 const_iterator end = other.end(); 502 for (const_iterator it = other.begin(); it != end; ++it)
486 for (const_iterator it = other.begin(); it != end; ++it) 503 add(*it);
487 add(*it); 504 }
488 } 505
489 506 template <typename T, typename U, typename V, typename W>
490 template<typename T, typename U, typename V, typename W> 507 inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=(const Lin kedHashSet& other) {
491 inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=(const Lin kedHashSet& other) 508 LinkedHashSet tmp(other);
492 { 509 swap(tmp);
493 LinkedHashSet tmp(other); 510 return *this;
494 swap(tmp); 511 }
495 return *this; 512
496 } 513 template <typename T, typename U, typename V, typename W>
497 514 inline void LinkedHashSet<T, U, V, W>::swap(LinkedHashSet& other) {
498 template<typename T, typename U, typename V, typename W> 515 m_impl.swap(other.m_impl);
499 inline void LinkedHashSet<T, U, V, W>::swap(LinkedHashSet& other) 516 swapAnchor(m_anchor, other.m_anchor);
500 { 517 }
501 m_impl.swap(other.m_impl); 518
502 swapAnchor(m_anchor, other.m_anchor); 519 template <typename T, typename U, typename V, typename Allocator>
503 } 520 inline LinkedHashSet<T, U, V, Allocator>::~LinkedHashSet() {
504 521 // The destructor of m_anchor will implicitly be called here, which will
505 template<typename T, typename U, typename V, typename Allocator> 522 // unlink the anchor from the collection.
506 inline LinkedHashSet<T, U, V, Allocator>::~LinkedHashSet() 523 }
507 { 524
508 // The destructor of m_anchor will implicitly be called here, which will 525 template <typename T, typename U, typename V, typename W>
509 // unlink the anchor from the collection. 526 inline T& LinkedHashSet<T, U, V, W>::first() {
510 } 527 ASSERT(!isEmpty());
511 528 return firstNode()->m_value;
512 template<typename T, typename U, typename V, typename W> 529 }
513 inline T& LinkedHashSet<T, U, V, W>::first() 530
514 { 531 template <typename T, typename U, typename V, typename W>
515 ASSERT(!isEmpty()); 532 inline const T& LinkedHashSet<T, U, V, W>::first() const {
516 return firstNode()->m_value; 533 ASSERT(!isEmpty());
517 } 534 return firstNode()->m_value;
518 535 }
519 template<typename T, typename U, typename V, typename W> 536
520 inline const T& LinkedHashSet<T, U, V, W>::first() const 537 template <typename T, typename U, typename V, typename W>
521 { 538 inline void LinkedHashSet<T, U, V, W>::removeFirst() {
522 ASSERT(!isEmpty()); 539 ASSERT(!isEmpty());
523 return firstNode()->m_value; 540 m_impl.remove(static_cast<Node*>(m_anchor.m_next));
524 } 541 }
525 542
526 template<typename T, typename U, typename V, typename W> 543 template <typename T, typename U, typename V, typename W>
527 inline void LinkedHashSet<T, U, V, W>::removeFirst() 544 inline T& LinkedHashSet<T, U, V, W>::last() {
528 { 545 ASSERT(!isEmpty());
529 ASSERT(!isEmpty()); 546 return lastNode()->m_value;
530 m_impl.remove(static_cast<Node*>(m_anchor.m_next)); 547 }
531 } 548
532 549 template <typename T, typename U, typename V, typename W>
533 template<typename T, typename U, typename V, typename W> 550 inline const T& LinkedHashSet<T, U, V, W>::last() const {
534 inline T& LinkedHashSet<T, U, V, W>::last() 551 ASSERT(!isEmpty());
535 { 552 return lastNode()->m_value;
536 ASSERT(!isEmpty()); 553 }
537 return lastNode()->m_value; 554
538 } 555 template <typename T, typename U, typename V, typename W>
539 556 inline void LinkedHashSet<T, U, V, W>::removeLast() {
540 template<typename T, typename U, typename V, typename W> 557 ASSERT(!isEmpty());
541 inline const T& LinkedHashSet<T, U, V, W>::last() const 558 m_impl.remove(static_cast<Node*>(m_anchor.m_prev));
542 { 559 }
543 ASSERT(!isEmpty()); 560
544 return lastNode()->m_value; 561 template <typename T, typename U, typename V, typename W>
545 } 562 inline typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::f ind(ValuePeekInType value) {
546 563 LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::NodeHashFunc tions, ValuePeekInType>(value);
547 template<typename T, typename U, typename V, typename W> 564 if (!node)
548 inline void LinkedHashSet<T, U, V, W>::removeLast() 565 return end();
549 { 566 return makeIterator(node);
550 ASSERT(!isEmpty()); 567 }
551 m_impl.remove(static_cast<Node*>(m_anchor.m_prev)); 568
552 } 569 template <typename T, typename U, typename V, typename W>
553 570 inline typename LinkedHashSet<T, U, V, W>::const_iterator LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) const {
554 template<typename T, typename U, typename V, typename W> 571 const LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::NodeHa shFunctions, ValuePeekInType>(value);
555 inline typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::f ind(ValuePeekInType value) 572 if (!node)
556 { 573 return end();
557 LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::NodeHashFu nctions, ValuePeekInType>(value); 574 return makeConstIterator(node);
558 if (!node) 575 }
559 return end(); 576
560 return makeIterator(node); 577 template <typename Translator>
561 }
562
563 template<typename T, typename U, typename V, typename W>
564 inline typename LinkedHashSet<T, U, V, W>::const_iterator LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) const
565 {
566 const LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::Node HashFunctions, ValuePeekInType>(value);
567 if (!node)
568 return end();
569 return makeConstIterator(node);
570 }
571
572 template<typename Translator>
573 struct LinkedHashSetTranslatorAdapter { 578 struct LinkedHashSetTranslatorAdapter {
574 template<typename T> static unsigned hash(const T& key) { return Translator: :hash(key); } 579 template <typename T>
575 template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a.m_value, b); } 580 static unsigned hash(const T& key) { return Translator::hash(key); }
576 }; 581 template <typename T, typename U>
577 582 static bool equal(const T& a, const U& b) { return Translator::equal(a.m_value , b); }
578 template<typename Value, typename U, typename V, typename W> 583 };
579 template<typename HashTranslator, typename T> 584
580 inline typename LinkedHashSet<Value, U, V, W>::iterator LinkedHashSet<Value, U, V, W>::find(const T& value) 585 template <typename Value, typename U, typename V, typename W>
581 { 586 template <typename HashTranslator, typename T>
582 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions; 587 inline typename LinkedHashSet<Value, U, V, W>::iterator LinkedHashSet<Value, U, V, W>::find(const T& value) {
583 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value); 588 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
584 if (!node) 589 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions, const T&>(value);
585 return end(); 590 if (!node)
586 return makeIterator(node); 591 return end();
587 } 592 return makeIterator(node);
588 593 }
589 template<typename Value, typename U, typename V, typename W> 594
590 template<typename HashTranslator, typename T> 595 template <typename Value, typename U, typename V, typename W>
591 inline typename LinkedHashSet<Value, U, V, W>::const_iterator LinkedHashSet<Valu e, U, V, W>::find(const T& value) const 596 template <typename HashTranslator, typename T>
592 { 597 inline typename LinkedHashSet<Value, U, V, W>::const_iterator LinkedHashSet<Valu e, U, V, W>::find(const T& value) const {
593 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions; 598 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
594 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value); 599 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions, const T&>(value);
595 if (!node) 600 if (!node)
596 return end(); 601 return end();
597 return makeConstIterator(node); 602 return makeConstIterator(node);
598 } 603 }
599 604
600 template<typename Value, typename U, typename V, typename W> 605 template <typename Value, typename U, typename V, typename W>
601 template<typename HashTranslator, typename T> 606 template <typename HashTranslator, typename T>
602 inline bool LinkedHashSet<Value, U, V, W>::contains(const T& value) const 607 inline bool LinkedHashSet<Value, U, V, W>::contains(const T& value) const {
603 { 608 return m_impl.template contains<LinkedHashSetTranslatorAdapter<HashTranslator> >(value);
604 return m_impl.template contains<LinkedHashSetTranslatorAdapter<HashTranslato r>>(value); 609 }
605 } 610
606 611 template <typename T, typename U, typename V, typename W>
607 template<typename T, typename U, typename V, typename W> 612 inline bool LinkedHashSet<T, U, V, W>::contains(ValuePeekInType value) const {
608 inline bool LinkedHashSet<T, U, V, W>::contains(ValuePeekInType value) const 613 return m_impl.template contains<NodeHashFunctions>(value);
609 { 614 }
610 return m_impl.template contains<NodeHashFunctions>(value); 615
611 } 616 template <typename Value, typename HashFunctions, typename Traits, typename Allo cator>
612 617 typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult Linke dHashSet<Value, HashFunctions, Traits, Allocator>::add(ValuePeekInType value) {
613 template<typename Value, typename HashFunctions, typename Traits, typename Alloc ator> 618 return m_impl.template add<NodeHashFunctions>(value, &m_anchor);
614 typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult Linke dHashSet<Value, HashFunctions, Traits, Allocator>::add(ValuePeekInType value) 619 }
615 { 620
616 return m_impl.template add<NodeHashFunctions>(value, &m_anchor); 621 template <typename T, typename U, typename V, typename W>
617 } 622 typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::addRetur nIterator(ValuePeekInType value) {
618 623 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>(v alue, &m_anchor);
619 template<typename T, typename U, typename V, typename W> 624 return makeIterator(result.storedValue);
620 typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::addRetur nIterator(ValuePeekInType value) 625 }
621 { 626
622 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor); 627 template <typename T, typename U, typename V, typename W>
623 return makeIterator(result.storedValue); 628 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::appendO rMoveToLast(ValuePeekInType value) {
624 } 629 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>(v alue, &m_anchor);
625 630 Node* node = result.storedValue;
626 template<typename T, typename U, typename V, typename W> 631 if (!result.isNewEntry) {
627 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::appendO rMoveToLast(ValuePeekInType value) 632 node->unlink();
628 { 633 m_anchor.insertBefore(*node);
629 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor); 634 }
630 Node* node = result.storedValue; 635 return result;
631 if (!result.isNewEntry) { 636 }
632 node->unlink(); 637
633 m_anchor.insertBefore(*node); 638 template <typename T, typename U, typename V, typename W>
634 } 639 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::prepend OrMoveToFirst(ValuePeekInType value) {
635 return result; 640 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>(v alue, m_anchor.m_next);
636 } 641 Node* node = result.storedValue;
637 642 if (!result.isNewEntry) {
638 template<typename T, typename U, typename V, typename W> 643 node->unlink();
639 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::prepend OrMoveToFirst(ValuePeekInType value) 644 m_anchor.insertAfter(*node);
640 { 645 }
641 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, m_anchor.m_next); 646 return result;
642 Node* node = result.storedValue; 647 }
643 if (!result.isNewEntry) { 648
644 node->unlink(); 649 template <typename T, typename U, typename V, typename W>
645 m_anchor.insertAfter(*node); 650 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::insertB efore(ValuePeekInType beforeValue, ValuePeekInType newValue) {
646 } 651 return insertBefore(find(beforeValue), newValue);
647 return result; 652 }
648 } 653
649 654 template <typename T, typename U, typename V, typename W>
650 template<typename T, typename U, typename V, typename W> 655 inline void LinkedHashSet<T, U, V, W>::remove(iterator it) {
651 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::insertB efore(ValuePeekInType beforeValue, ValuePeekInType newValue) 656 if (it == end())
652 { 657 return;
653 return insertBefore(find(beforeValue), newValue); 658 m_impl.remove(it.node());
654 } 659 }
655 660
656 template<typename T, typename U, typename V, typename W> 661 template <typename T, typename U, typename V, typename W>
657 inline void LinkedHashSet<T, U, V, W>::remove(iterator it) 662 inline void LinkedHashSet<T, U, V, W>::remove(ValuePeekInType value) {
658 { 663 remove(find(value));
659 if (it == end()) 664 }
660 return; 665
661 m_impl.remove(it.node()); 666 inline void swapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) {
662 } 667 ASSERT(a.m_prev && a.m_next && b.m_prev && b.m_next);
663 668 swap(a.m_prev, b.m_prev);
664 template<typename T, typename U, typename V, typename W> 669 swap(a.m_next, b.m_next);
665 inline void LinkedHashSet<T, U, V, W>::remove(ValuePeekInType value) 670 if (b.m_next == &a) {
666 { 671 ASSERT(b.m_prev == &a);
667 remove(find(value)); 672 b.m_next = &b;
668 } 673 b.m_prev = &b;
669 674 } else {
670 inline void swapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) 675 b.m_next->m_prev = &b;
671 { 676 b.m_prev->m_next = &b;
672 ASSERT(a.m_prev && a.m_next && b.m_prev && b.m_next); 677 }
673 swap(a.m_prev, b.m_prev); 678 if (a.m_next == &b) {
674 swap(a.m_next, b.m_next); 679 ASSERT(a.m_prev == &b);
675 if (b.m_next == &a) { 680 a.m_next = &a;
676 ASSERT(b.m_prev == &a); 681 a.m_prev = &a;
677 b.m_next = &b; 682 } else {
678 b.m_prev = &b; 683 a.m_next->m_prev = &a;
679 } else { 684 a.m_prev->m_next = &a;
680 b.m_next->m_prev = &b; 685 }
681 b.m_prev->m_next = &b; 686 }
682 } 687
683 if (a.m_next == &b) { 688 inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) {
684 ASSERT(a.m_prev == &b); 689 ASSERT(a.m_next != &a && b.m_next != &b);
685 a.m_next = &a; 690 swap(a.m_prev, b.m_prev);
686 a.m_prev = &a; 691 swap(a.m_next, b.m_next);
687 } else { 692 if (b.m_next) {
688 a.m_next->m_prev = &a; 693 b.m_next->m_prev = &b;
689 a.m_prev->m_next = &a; 694 b.m_prev->m_next = &b;
690 } 695 }
691 } 696 if (a.m_next) {
692 697 a.m_next->m_prev = &a;
693 inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) 698 a.m_prev->m_next = &a;
694 { 699 }
695 ASSERT(a.m_next != &a && b.m_next != &b); 700 }
696 swap(a.m_prev, b.m_prev); 701
697 swap(a.m_next, b.m_next); 702 template <typename T, typename Allocator>
698 if (b.m_next) { 703 inline void swap(LinkedHashSetNode<T, Allocator>& a, LinkedHashSetNode<T, Alloca tor>& b) {
699 b.m_next->m_prev = &b; 704 typedef LinkedHashSetNodeBase Base;
700 b.m_prev->m_next = &b; 705 // The key and value cannot be swapped atomically, and it would be
701 } 706 // wrong to have a GC when only one was swapped and the other still
702 if (a.m_next) { 707 // contained garbage (eg. from a previous use of the same slot).
703 a.m_next->m_prev = &a; 708 // Therefore we forbid a GC until both the key and the value are
704 a.m_prev->m_next = &a; 709 // swapped.
705 } 710 Allocator::enterGCForbiddenScope();
706 } 711 swap(static_cast<Base&>(a), static_cast<Base&>(b));
707 712 swap(a.m_value, b.m_value);
708 template<typename T, typename Allocator> 713 Allocator::leaveGCForbiddenScope();
709 inline void swap(LinkedHashSetNode<T, Allocator>& a, LinkedHashSetNode<T, Alloca tor>& b)
710 {
711 typedef LinkedHashSetNodeBase Base;
712 // The key and value cannot be swapped atomically, and it would be
713 // wrong to have a GC when only one was swapped and the other still
714 // contained garbage (eg. from a previous use of the same slot).
715 // Therefore we forbid a GC until both the key and the value are
716 // swapped.
717 Allocator::enterGCForbiddenScope();
718 swap(static_cast<Base&>(a), static_cast<Base&>(b));
719 swap(a.m_value, b.m_value);
720 Allocator::leaveGCForbiddenScope();
721 } 714 }
722 715
723 #if !ENABLE(OILPAN) 716 #if !ENABLE(OILPAN)
724 template<typename T, typename U, typename V> 717 template <typename T, typename U, typename V>
725 struct NeedsTracing<LinkedHashSet<T, U, V>> { 718 struct NeedsTracing<LinkedHashSet<T, U, V>> {
726 static const bool value = false; 719 static const bool value = false;
727 }; 720 };
728 #endif 721 #endif
729
730 } 722 }
731 723
732 using WTF::LinkedHashSet; 724 using WTF::LinkedHashSet;
733 725
734 #endif /* WTF_LinkedHashSet_h */ 726 #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