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

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

Issue 223373002: Create HeapLinkedHashSet and LinkedHashSet, ordered heap-friendly hash sets. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix gtest-related compile error on gcc by removing internal typedefs in iterators Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « Source/wtf/HashTable.h ('k') | Source/wtf/ListHashSet.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #ifndef WTF_LinkedHashSet_h
23 #define WTF_LinkedHashSet_h
24
25 #include "wtf/DefaultAllocator.h"
26 #include "wtf/HashSet.h"
27 #include "wtf/OwnPtr.h"
28 #include "wtf/PassOwnPtr.h"
29
30 namespace WTF {
31
32 // LinkedHashSet: Just like HashSet, this class provides a Set
33 // interface - a collection of unique objects with O(1) insertion,
34 // removal and test for containership. However, it also has an
35 // order - iterating it will always give back values in the order
36 // in which they are added.
37
38 // Unlike ListHashSet, but like most WTF collections, iteration is NOT safe
39 // against mutation of the LinkedHashSet.
40
41 template<typename Value, typename HashFunctions, typename HashTraits, typename A llocator> class LinkedHashSet;
42
43 template<typename LinkedHashSet> class LinkedHashSetIterator;
44 template<typename LinkedHashSet> class LinkedHashSetConstIterator;
45 template<typename LinkedHashSet> class LinkedHashSetReverseIterator;
46 template<typename LinkedHashSet> class LinkedHashSetConstReverseIterator;
47
48 template<typename Value, typename HashFunctions> struct LinkedHashSetTranslator;
49 template<typename Value> struct LinkedHashSetExtractor;
50 template<typename Value, typename ValueTraits> struct LinkedHashSetTraits;
51
52 class LinkedHashSetNodeBase {
53 public:
54 LinkedHashSetNodeBase() : m_prev(this), m_next(this) { }
55
56 void unlink()
57 {
58 if (!m_next)
59 return;
60 ASSERT(m_prev);
61 ASSERT(m_next->m_prev == this);
62 ASSERT(m_prev->m_next == this);
63 m_next->m_prev = m_prev;
64 m_prev->m_next = m_next;
65 }
66
67 ~LinkedHashSetNodeBase()
68 {
69 unlink();
70 }
71
72 void insertBefore(LinkedHashSetNodeBase& other)
73 {
74 other.m_next = this;
75 other.m_prev = m_prev;
76 m_prev->m_next = &other;
77 m_prev = &other;
78 ASSERT(other.m_next);
79 ASSERT(other.m_prev);
80 ASSERT(m_next);
81 ASSERT(m_prev);
82 }
83
84 void insertAfter(LinkedHashSetNodeBase& other)
85 {
86 other.m_prev = this;
87 other.m_next = m_next;
88 m_next->m_prev = &other;
89 m_next = &other;
90 ASSERT(other.m_next);
91 ASSERT(other.m_prev);
92 ASSERT(m_next);
93 ASSERT(m_prev);
94 }
95
96 LinkedHashSetNodeBase(LinkedHashSetNodeBase* prev, LinkedHashSetNodeBase* ne xt)
97 : m_prev(prev)
98 , m_next(next)
99 {
100 ASSERT((prev && next) || (!prev && !next));
101 }
102
103 LinkedHashSetNodeBase* m_prev;
104 LinkedHashSetNodeBase* m_next;
105
106 protected:
107 // If we take a copy of a node we can't copy the next and prev pointers,
108 // since they point to something that does not point at us. This is used
109 // inside the shouldExpand() "if" in HashTable::add.
110 LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other)
111 : m_prev(0)
112 , m_next(0) { }
113
114 private:
115 // Should not be used.
116 LinkedHashSetNodeBase& operator=(const LinkedHashSetNodeBase& other);
117 };
118
119 template<typename ValueArg>
120 class LinkedHashSetNode : public LinkedHashSetNodeBase {
121 public:
122 LinkedHashSetNode(const ValueArg& value, LinkedHashSetNodeBase* prev, Linked HashSetNodeBase* next)
123 : LinkedHashSetNodeBase(prev, next)
124 , m_value(value)
125 {
126 }
127
128 ValueArg m_value;
129
130 private:
131 // Not used.
132 LinkedHashSetNode(const LinkedHashSetNode&);
133 };
134
135 template<
136 typename ValueArg,
137 typename HashFunctions = typename DefaultHash<ValueArg>::Hash,
138 typename TraitsArg = HashTraits<ValueArg>,
139 typename Allocator = DefaultAllocator>
140 class LinkedHashSet {
141 WTF_USE_ALLOCATOR(LinkedHashSet);
142 private:
143 typedef ValueArg Value;
144 typedef TraitsArg Traits;
145 typedef LinkedHashSetNode<Value> Node;
146 typedef LinkedHashSetNodeBase NodeBase;
147 typedef LinkedHashSetTranslator<Value, HashFunctions> NodeHashFunctions;
148 typedef LinkedHashSetTraits<Value, Traits> NodeHashTraits;
149
150 typedef HashTable<Node, Node, IdentityExtractor,
151 NodeHashFunctions, NodeHashTraits, NodeHashTraits, Allocator> ImplType;
152
153 public:
154 typedef LinkedHashSetIterator<LinkedHashSet> iterator;
155 friend class LinkedHashSetIterator<LinkedHashSet>;
156 typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator;
157 friend class LinkedHashSetConstIterator<LinkedHashSet>;
158
159 typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator;
160 friend class LinkedHashSetReverseIterator<LinkedHashSet>;
161 typedef LinkedHashSetConstReverseIterator<LinkedHashSet> const_reverse_itera tor;
162 friend class LinkedHashSetConstReverseIterator<LinkedHashSet>;
163
164 struct AddResult {
165 AddResult(const typename ImplType::AddResult& hashTableAddResult)
166 : storedValue(&hashTableAddResult.storedValue->m_value)
167 , isNewEntry(hashTableAddResult.isNewEntry)
168 {
169 }
170
171 Value* storedValue;
172 bool isNewEntry;
173 };
174
175 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
176
177 LinkedHashSet();
178 LinkedHashSet(const LinkedHashSet&);
179 LinkedHashSet& operator=(const LinkedHashSet&);
180 ~LinkedHashSet();
181
182 static void finalize(void* pointer) { reinterpret_cast<LinkedHashSet*>(point er)->~LinkedHashSet(); }
183
184 void swap(LinkedHashSet&);
185
186 unsigned size() const { return m_impl.size(); }
187 unsigned capacity() const { return m_impl.capacity(); }
188 bool isEmpty() const { return m_impl.isEmpty(); }
189
190 iterator begin() { return makeIterator(firstNode()); }
191 iterator end() { return makeIterator(anchor()); }
192 const_iterator begin() const { return makeConstIterator(firstNode()); }
193 const_iterator end() const { return makeConstIterator(anchor()); }
194
195 reverse_iterator rbegin() { return makeReverseIterator(lastNode()); }
196 reverse_iterator rend() { return makeReverseIterator(anchor()); }
197 const_reverse_iterator rbegin() const { return makeConstReverseIterator(last Node()); }
198 const_reverse_iterator rend() const { return makeConstReverseIterator(anchor ()); }
199
200 Value& first();
201 const Value& first() const;
202 void removeFirst();
203
204 Value& last();
205 const Value& last() const;
206 void removeLast();
207
208 iterator find(ValuePeekInType);
209 const_iterator find(ValuePeekInType) const;
210 bool contains(ValuePeekInType) const;
211
212 // An alternate version of find() that finds the object by hashing and compa ring
213 // with some other type, to avoid the cost of type conversion.
214 // The HashTranslator interface is defined in HashSet.
215 template<typename HashTranslator, typename T> iterator find(const T&);
216 template<typename HashTranslator, typename T> const_iterator find(const T&) const;
217 template<typename HashTranslator, typename T> bool contains(const T&) const;
218
219 // The return value of add is a pair of a pointer to the stored value,
220 // and a bool that is true if an new entry was added.
221 AddResult add(ValuePeekInType);
222
223 // Same as add() except that the return value is an
224 // iterator. Useful in cases where it's needed to have the
225 // same return value as find() and where it's not possible to
226 // use a pointer to the storedValue.
227 iterator addReturnIterator(ValuePeekInType);
228
229 // Add the value to the end of the collection. If the value was already in
230 // the list, it is moved to the end.
231 AddResult appendOrMoveToLast(ValuePeekInType);
232
233 // Add the value to the beginning of the collection. If the value was alread y in
234 // the list, it is moved to the beginning.
235 AddResult prependOrMoveToFirst(ValuePeekInType);
236
237 AddResult insertBefore(ValuePeekInType beforeValue, ValuePeekInType newValue );
238 AddResult insertBefore(iterator it, ValuePeekInType newValue) { return m_imp l.template add<NodeHashFunctions>(newValue, it.node()); }
239
240 void remove(ValuePeekInType);
241 void remove(iterator);
242 void clear() { m_impl.clear(); }
243
244 void trace(typename Allocator::Visitor* visitor) { m_impl.trace(visitor); }
245
246 int64_t modifications() const { return m_impl.modifications(); }
247 void checkModifications(int64_t mods) const { m_impl.checkModifications(mods ); }
248
249 private:
250 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); }
251 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor) ; }
252 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); }
253 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_ancho r.m_next); }
254 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); }
255 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor .m_prev); }
256
257 iterator makeIterator(const Node* position) { return iterator(position, this ); }
258 const_iterator makeConstIterator(const Node* position) const { return const_ iterator(position, this); }
259 reverse_iterator makeReverseIterator(const Node* position) { return reverse_ iterator(position, this); }
260 const_reverse_iterator makeConstReverseIterator(const Node* position) const { return const_reverse_iterator(position, this); }
261
262 ImplType m_impl;
263 NodeBase m_anchor;
264 #ifndef ASSERT_ENABLED
265 uint64_t m_modifications;
266 #endif
267 };
268
269 template<typename Value, typename HashFunctions>
270 struct LinkedHashSetTranslator {
271 typedef LinkedHashSetNode<Value> Node;
272 typedef LinkedHashSetNodeBase NodeBase;
273 typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
274 static unsigned hash(const Node& node) { return HashFunctions::hash(node.m_v alue); }
275 static unsigned hash(const ValuePeekInType& key) { return HashFunctions::has h(key); }
276 static bool equal(const Node& a, const ValuePeekInType& b) { return HashFunc tions::equal(a.m_value, b); }
277 static bool equal(const Node& a, const Node& b) { return HashFunctions::equa l(a.m_value, b.m_value); }
278 static void translate(Node& location, ValuePeekInType key, NodeBase* anchor)
279 {
280 location.m_value = key;
281 anchor->insertBefore(location);
282 }
283
284 // Empty (or deleted) slots have the m_next pointer set to null, but we
285 // don't do anything to the other fields, which may contain junk.
286 // Therefore you can't compare a newly constructed empty value with a
287 // slot and get the right answer.
288 static const bool safeToCompareToEmptyOrDeleted = false;
289 };
290
291 template<typename Value>
292 struct LinkedHashSetExtractor {
293 static const Value& extract(const LinkedHashSetNode<Value>& node) { return n ode.m_value; }
294 };
295
296 template<typename Value, typename ValueTraitsArg>
297 struct LinkedHashSetTraits : public SimpleClassHashTraits<LinkedHashSetNode<Valu e> > {
298 typedef LinkedHashSetNode<Value> Node;
299 typedef ValueTraitsArg ValueTraits;
300
301 // The slot is empty when the m_next field is zero so it's safe to zero
302 // the backing.
303 static const bool emptyValueIsZero = true;
304
305 static const bool hasIsEmptyValueFunction = true;
306 static bool isEmptyValue(const Node& value) { return !value.m_next; }
307
308 static const int deletedValue = -1;
309
310 static void constructDeletedValue(Node& slot) { slot.m_next = reinterpret_ca st<Node*>(deletedValue); }
311 static bool isDeletedValue(const Node& slot) { return slot.m_next == reinter pret_cast<Node*>(deletedValue); }
312
313 // We always need to call destructors, that's how we get linked and
314 // unlinked from the chain.
315 static const bool needsDestruction = true;
316
317 // Whether we need to trace and do weak processing depends on the traits of
318 // the type inside the node.
319 template<typename U = void>
320 struct NeedsTracingLazily {
321 static const bool value = ValueTraits::template NeedsTracingLazily<>::va lue;
322 };
323 static const bool isWeak = ValueTraits::isWeak;
324 };
325
326 template<typename LinkedHashSetType>
327 class LinkedHashSetIterator {
328 private:
329 typedef typename LinkedHashSetType::Node Node;
330 typedef typename LinkedHashSetType::Traits Traits;
331
332 typedef typename LinkedHashSetType::Value& ReferenceType;
333 typedef typename LinkedHashSetType::Value* PointerType;
334
335 typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator;
336
337 Node* node() { return const_cast<Node*>(m_iterator.node()); }
338
339 protected:
340 LinkedHashSetIterator(const Node* position, LinkedHashSetType* m_container)
341 : m_iterator(position , m_container)
342 {
343 }
344
345 public:
346 // Default copy, assignment and destructor are OK.
347
348 PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
349 ReferenceType operator*() const { return *get(); }
350 PointerType operator->() const { return get(); }
351
352 LinkedHashSetIterator& operator++() { ++m_iterator; return *this; }
353 LinkedHashSetIterator& operator--() { --m_iterator; return *this; }
354
355 // Postfix ++ and -- intentionally omitted.
356
357 // Comparison.
358 bool operator==(const LinkedHashSetIterator& other) const { return m_iterato r == other.m_iterator; }
359 bool operator!=(const LinkedHashSetIterator& other) const { return m_iterato r != other.m_iterator; }
360
361 operator const_iterator() const { return m_iterator; }
362
363 protected:
364 const_iterator m_iterator;
365 template<typename T, typename U, typename V, typename W> friend class Linked HashSet;
366 };
367
368 template<typename LinkedHashSetType>
369 class LinkedHashSetConstIterator {
370 private:
371 typedef typename LinkedHashSetType::Node Node;
372 typedef typename LinkedHashSetType::Traits Traits;
373
374 typedef const typename LinkedHashSetType::Value& ReferenceType;
375 typedef const typename LinkedHashSetType::Value* PointerType;
376
377 const Node* node() const { return static_cast<const Node*>(m_position); }
378
379 protected:
380 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Link edHashSetType* container)
381 : m_position(position)
382 #ifdef ASSERT_ENABLED
383 , m_container(container)
384 , m_containerModifications(container->modifications())
385 #endif
386 {
387 }
388
389 public:
390 PointerType get() const
391 {
392 checkModifications();
393 return &static_cast<const Node*>(m_position)->m_value;
394 }
395 ReferenceType operator*() const { return *get(); }
396 PointerType operator->() const { return get(); }
397
398 LinkedHashSetConstIterator& operator++()
399 {
400 ASSERT(m_position);
401 checkModifications();
402 m_position = m_position->m_next;
403 return *this;
404 }
405
406 LinkedHashSetConstIterator& operator--()
407 {
408 ASSERT(m_position);
409 checkModifications();
410 m_position = m_position->m_prev;
411 return *this;
412 }
413
414 // Postfix ++ and -- intentionally omitted.
415
416 // Comparison.
417 bool operator==(const LinkedHashSetConstIterator& other) const
418 {
419 return m_position == other.m_position;
420 }
421 bool operator!=(const LinkedHashSetConstIterator& other) const
422 {
423 return m_position != other.m_position;
424 }
425
426 private:
427 const LinkedHashSetNodeBase* m_position;
428 #ifdef ASSERT_ENABLED
429 void checkModifications() const { m_container->checkModifications(m_containe rModifications); }
430 const LinkedHashSetType* m_container;
431 int64_t m_containerModifications;
432 #else
433 void checkModifications() const { }
434 #endif
435 template<typename T, typename U, typename V, typename W> friend class Linked HashSet;
436 friend class LinkedHashSetIterator<LinkedHashSetType>;
437 };
438
439 template<typename LinkedHashSetType>
440 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT ype> {
441 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass;
442 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_i terator;
443 typedef typename LinkedHashSetType::Node Node;
444
445 protected:
446 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* contai ner)
447 : Superclass(position, container) { }
448
449 public:
450 LinkedHashSetReverseIterator& operator++() { Superclass::operator--(); retur n *this; }
451 LinkedHashSetReverseIterator& operator--() { Superclass::operator++(); retur n *this; }
452
453 // Postfix ++ and -- intentionally omitted.
454
455 operator const_reverse_iterator() const { return *reinterpret_cast<const_rev erse_iterator*>(this); }
456
457 template<typename T, typename U, typename V, typename W> friend class Linked HashSet;
458 };
459
460 template<typename LinkedHashSetType>
461 class LinkedHashSetConstReverseIterator : public LinkedHashSetConstIterator<Link edHashSetType> {
462 typedef LinkedHashSetConstIterator<LinkedHashSetType> Superclass;
463 typedef typename LinkedHashSetType::Node Node;
464
465 public:
466 LinkedHashSetConstReverseIterator(const Node* position, const LinkedHashSetT ype* container)
467 : Superclass(position, container) { }
468
469 LinkedHashSetConstReverseIterator& operator++() { Superclass::operator--(); return *this; }
470 LinkedHashSetConstReverseIterator& operator--() { Superclass::operator++(); return *this; }
471
472 // Postfix ++ and -- intentionally omitted.
473
474 template<typename T, typename U, typename V, typename W> friend class Linked HashSet;
475 };
476
477 template<typename T, typename U, typename V, typename W>
478 inline LinkedHashSet<T, U, V, W>::LinkedHashSet() { }
479
480 template<typename T, typename U, typename V, typename W>
481 inline LinkedHashSet<T, U, V, W>::LinkedHashSet(const LinkedHashSet& other)
482 : m_anchor()
483 {
484 const_iterator end = other.end();
485 for (const_iterator it = other.begin(); it != end; ++it)
486 add(*it);
487 }
488
489 template<typename T, typename U, typename V, typename W>
490 inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=(const Lin kedHashSet& other)
491 {
492 LinkedHashSet tmp(other);
493 swap(tmp);
494 return *this;
495 }
496
497 template<typename T, typename U, typename V, typename W>
498 inline void LinkedHashSet<T, U, V, W>::swap(LinkedHashSet& other)
499 {
500 m_impl.swap(other.m_impl);
501 swap(m_anchor, other.m_anchor);
502 }
503
504 template<typename T, typename U, typename V, typename Allocator>
505 inline LinkedHashSet<T, U, V, Allocator>::~LinkedHashSet()
506 {
507 // The destructor of m_anchor will implicitly be called here, which will
508 // unlink the anchor from the collection.
509 }
510
511 template<typename T, typename U, typename V, typename W>
512 inline T& LinkedHashSet<T, U, V, W>::first()
513 {
514 ASSERT(!isEmpty());
515 return firstNode()->m_value;
516 }
517
518 template<typename T, typename U, typename V, typename W>
519 inline const T& LinkedHashSet<T, U, V, W>::first() const
520 {
521 ASSERT(!isEmpty());
522 return firstNode()->m_value;
523 }
524
525 template<typename T, typename U, typename V, typename W>
526 inline void LinkedHashSet<T, U, V, W>::removeFirst()
527 {
528 ASSERT(!isEmpty());
529 m_impl.remove(static_cast<Node*>(m_anchor.m_next));
530 }
531
532 template<typename T, typename U, typename V, typename W>
533 inline T& LinkedHashSet<T, U, V, W>::last()
534 {
535 ASSERT(!isEmpty());
536 return lastNode()->m_value;
537 }
538
539 template<typename T, typename U, typename V, typename W>
540 inline const T& LinkedHashSet<T, U, V, W>::last() const
541 {
542 ASSERT(!isEmpty());
543 return lastNode()->m_value;
544 }
545
546 template<typename T, typename U, typename V, typename W>
547 inline void LinkedHashSet<T, U, V, W>::removeLast()
548 {
549 ASSERT(!isEmpty());
550 m_impl.remove(static_cast<Node*>(m_anchor.m_prev));
551 }
552
553 template<typename T, typename U, typename V, typename W>
554 inline typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::f ind(ValuePeekInType value)
555 {
556 LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::NodeHashFu nctions, ValuePeekInType>(value);
557 if (!node)
558 return end();
559 return makeIterator(node);
560 }
561
562 template<typename T, typename U, typename V, typename W>
563 inline typename LinkedHashSet<T, U, V, W>::const_iterator LinkedHashSet<T, U, V, W>::find(ValuePeekInType value) const
564 {
565 const LinkedHashSet::Node* node = m_impl.template lookup<LinkedHashSet::Node HashFunctions, ValuePeekInType>(value);
566 if (!node)
567 return end();
568 return makeConstIterator(node);
569 }
570
571 template<typename Translator>
572 struct LinkedHashSetTranslatorAdapter {
573 template<typename T> static unsigned hash(const T& key) { return Translator: :hash(key); }
574 template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a.m_value, b); }
575 };
576
577 template<typename Value, typename U, typename V, typename W>
578 template<typename HashTranslator, typename T>
579 inline typename LinkedHashSet<Value, U, V, W>::iterator LinkedHashSet<Value, U, V, W>::find(const T& value)
580 {
581 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
582 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value);
583 if (!node)
584 return end();
585 return makeIterator(node);
586 }
587
588 template<typename Value, typename U, typename V, typename W>
589 template<typename HashTranslator, typename T>
590 inline typename LinkedHashSet<Value, U, V, W>::const_iterator LinkedHashSet<Valu e, U, V, W>::find(const T& value) const
591 {
592 typedef LinkedHashSetTranslatorAdapter<HashTranslator> TranslatedFunctions;
593 const LinkedHashSet::Node* node = m_impl.template lookup<TranslatedFunctions , const T&>(value);
594 if (!node)
595 return end();
596 return makeConstIterator(node);
597 }
598
599 template<typename Value, typename U, typename V, typename W>
600 template<typename HashTranslator, typename T>
601 inline bool LinkedHashSet<Value, U, V, W>::contains(const T& value) const
602 {
603 return m_impl.template contains<LinkedHashSetTranslatorAdapter<HashTranslato r> >(value);
604 }
605
606 template<typename T, typename U, typename V, typename W>
607 inline bool LinkedHashSet<T, U, V, W>::contains(ValuePeekInType value) const
608 {
609 return m_impl.template contains<NodeHashFunctions>(value);
610 }
611
612 template<typename Value, typename HashFunctions, typename Traits, typename Alloc ator>
613 typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult Linke dHashSet<Value, HashFunctions, Traits, Allocator>::add(ValuePeekInType value)
614 {
615 return m_impl.template add<NodeHashFunctions>(value, &m_anchor);
616 }
617
618 template<typename T, typename U, typename V, typename W>
619 typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::addRetur nIterator(ValuePeekInType value)
620 {
621 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor);
622 return makeIterator(result.storedValue);
623 }
624
625 template<typename T, typename U, typename V, typename W>
626 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::appendO rMoveToLast(ValuePeekInType value)
627 {
628 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, &m_anchor);
629 Node* node = result.storedValue;
630 if (!result.isNewEntry) {
631 node->unlink();
632 m_anchor.insertBefore(*node);
633 }
634 return result;
635 }
636
637 template<typename T, typename U, typename V, typename W>
638 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::prepend OrMoveToFirst(ValuePeekInType value)
639 {
640 typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions> (value, m_anchor.m_next);
641 Node* node = result.storedValue;
642 if (!result.isNewEntry) {
643 node->unlink();
644 m_anchor.insertAfter(*node);
645 }
646 return result;
647 }
648
649 template<typename T, typename U, typename V, typename W>
650 typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::insertB efore(ValuePeekInType beforeValue, ValuePeekInType newValue)
651 {
652 return insertBefore(find(beforeValue), newValue);
653 }
654
655 template<typename T, typename U, typename V, typename W>
656 inline void LinkedHashSet<T, U, V, W>::remove(iterator it)
657 {
658 if (it == end())
659 return;
660 m_impl.remove(it.node());
661 }
662
663 template<typename T, typename U, typename V, typename W>
664 inline void LinkedHashSet<T, U, V, W>::remove(ValuePeekInType value)
665 {
666 remove(find(value));
667 }
668
669 template<typename T>
670 struct IsWeak<LinkedHashSetNode<T> > {
671 static const bool value = IsWeak<T>::value;
672 };
673
674 inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b)
675 {
676 typedef LinkedHashSetNodeBase Base;
677 swap(a.m_next, b.m_next);
678 swap(a.m_prev, b.m_prev);
679 if (b.m_next) {
680 b.m_next->m_prev = &b;
681 b.m_prev->m_next = &b;
682 }
683 if (a.m_next) {
684 a.m_next->m_prev = &a;
685 a.m_prev->m_next = &a;
686 }
687 }
688
689 template<typename T>
690 inline void swap(LinkedHashSetNode<T>& a, LinkedHashSetNode<T>& b)
691 {
692 typedef LinkedHashSetNodeBase Base;
693
694 swap(static_cast<Base&>(a), static_cast<Base&>(b));
695 swap(a.m_value, b.m_value);
696 }
697
698 // Warning: After and while calling this you have a collection with deleted
699 // pointers. Consider using a smart pointer like OwnPtr and calling clear()
700 // instead.
701 template<typename ValueType, typename T, typename U>
702 void deleteAllValues(const LinkedHashSet<ValueType, T, U>& set)
703 {
704 typedef typename LinkedHashSet<ValueType, T, U>::const_iterator iterator;
705 iterator end = set.end();
706 for (iterator it = set.begin(); it != end; ++it)
707 delete *it;
708 }
709
710 }
711
712 using WTF::LinkedHashSet;
713
714 #endif /* WTF_LinkedHashSet_h */
OLDNEW
« no previous file with comments | « Source/wtf/HashTable.h ('k') | Source/wtf/ListHashSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698