OLD | NEW |
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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 | 272 |
273 void remove(ValuePeekInType); | 273 void remove(ValuePeekInType); |
274 void remove(iterator); | 274 void remove(iterator); |
275 void clear() { m_impl.clear(); } | 275 void clear() { m_impl.clear(); } |
276 template<typename Collection> | 276 template<typename Collection> |
277 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } | 277 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } |
278 | 278 |
279 template<typename VisitorDispatcher> | 279 template<typename VisitorDispatcher> |
280 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 280 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } |
281 | 281 |
282 int64_t modifications() const { return m_impl.modifications(); } | 282 #if ENABLE(ASSERT) |
283 void checkModifications(int64_t mods) const { m_impl.checkModifications(mods
); } | 283 void enterModificationForbiddenScope() { m_impl.enterModificationForbiddenSc
ope(); } |
| 284 void leaveModificationForbiddenScope() { m_impl.leaveModificationForbiddenSc
ope(); } |
| 285 #endif |
284 | 286 |
285 private: | 287 private: |
286 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } | 288 Node* anchor() { return reinterpret_cast<Node*>(&m_anchor); } |
287 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor)
; } | 289 const Node* anchor() const { return reinterpret_cast<const Node*>(&m_anchor)
; } |
288 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); } | 290 Node* firstNode() { return reinterpret_cast<Node*>(m_anchor.m_next); } |
289 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_ancho
r.m_next); } | 291 const Node* firstNode() const { return reinterpret_cast<const Node*>(m_ancho
r.m_next); } |
290 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); } | 292 Node* lastNode() { return reinterpret_cast<Node*>(m_anchor.m_prev); } |
291 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor
.m_prev); } | 293 const Node* lastNode() const { return reinterpret_cast<const Node*>(m_anchor
.m_prev); } |
292 | 294 |
293 iterator makeIterator(const Node* position) { return iterator(position, this
); } | 295 iterator makeIterator(const Node* position) { return iterator(position, this
); } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 411 |
410 typedef const typename LinkedHashSetType::Value& ReferenceType; | 412 typedef const typename LinkedHashSetType::Value& ReferenceType; |
411 typedef const typename LinkedHashSetType::Value* PointerType; | 413 typedef const typename LinkedHashSetType::Value* PointerType; |
412 | 414 |
413 const Node* getNode() const { return static_cast<const Node*>(m_position); } | 415 const Node* getNode() const { return static_cast<const Node*>(m_position); } |
414 | 416 |
415 protected: | 417 protected: |
416 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Link
edHashSetType* container) | 418 LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, const Link
edHashSetType* container) |
417 : m_position(position) | 419 : m_position(position) |
418 #if ENABLE(ASSERT) | 420 #if ENABLE(ASSERT) |
419 , m_container(container) | 421 , m_modificationForbiddenScope(position ? container : nullptr) |
420 , m_containerModifications(container->modifications()) | |
421 #endif | 422 #endif |
422 { | 423 { |
423 } | 424 } |
424 | 425 |
425 public: | 426 public: |
426 PointerType get() const | 427 PointerType get() const |
427 { | 428 { |
428 checkModifications(); | |
429 return &static_cast<const Node*>(m_position)->m_value; | 429 return &static_cast<const Node*>(m_position)->m_value; |
430 } | 430 } |
431 ReferenceType operator*() const { return *get(); } | 431 ReferenceType operator*() const { return *get(); } |
432 PointerType operator->() const { return get(); } | 432 PointerType operator->() const { return get(); } |
433 | 433 |
434 LinkedHashSetConstIterator& operator++() | 434 LinkedHashSetConstIterator& operator++() |
435 { | 435 { |
436 ASSERT(m_position); | 436 ASSERT(m_position); |
437 checkModifications(); | |
438 m_position = m_position->m_next; | 437 m_position = m_position->m_next; |
| 438 #if ENABLE(ASSERT) |
| 439 // If now at the end, leave the forbidden scope. Waiting until |
| 440 // the iterator goes out of (stack) scope disallows perfectly valid |
| 441 // code idioms. |
| 442 if (!m_position) |
| 443 m_modificationForbiddenScope.leaveScope(); |
| 444 #endif |
439 return *this; | 445 return *this; |
440 } | 446 } |
441 | 447 |
442 LinkedHashSetConstIterator& operator--() | 448 LinkedHashSetConstIterator& operator--() |
443 { | 449 { |
444 ASSERT(m_position); | 450 ASSERT(m_position); |
445 checkModifications(); | |
446 m_position = m_position->m_prev; | 451 m_position = m_position->m_prev; |
| 452 #if ENABLE(ASSERT) |
| 453 // If now at the end, leave the forbidden scope. Waiting until |
| 454 // the iterator goes out of (stack) scope disallows perfectly valid |
| 455 // code idioms. |
| 456 if (!m_position) |
| 457 m_modificationForbiddenScope.leaveScope(); |
| 458 #endif |
447 return *this; | 459 return *this; |
448 } | 460 } |
449 | 461 |
450 // Postfix ++ and -- intentionally omitted. | 462 // Postfix ++ and -- intentionally omitted. |
451 | 463 |
452 // Comparison. | 464 // Comparison. |
453 bool operator==(const LinkedHashSetConstIterator& other) const | 465 bool operator==(const LinkedHashSetConstIterator& other) const |
454 { | 466 { |
455 return m_position == other.m_position; | 467 return m_position == other.m_position; |
456 } | 468 } |
457 bool operator!=(const LinkedHashSetConstIterator& other) const | 469 bool operator!=(const LinkedHashSetConstIterator& other) const |
458 { | 470 { |
459 return m_position != other.m_position; | 471 return m_position != other.m_position; |
460 } | 472 } |
461 | 473 |
462 private: | 474 private: |
| 475 template<typename T, typename U, typename V, typename W> friend class Linked
HashSet; |
| 476 friend class LinkedHashSetIterator<LinkedHashSetType>; |
| 477 |
463 const LinkedHashSetNodeBase* m_position; | 478 const LinkedHashSetNodeBase* m_position; |
464 #if ENABLE(ASSERT) | 479 #if ENABLE(ASSERT) |
465 void checkModifications() const { m_container->checkModifications(m_containe
rModifications); } | 480 HashTableModificationForbiddenScope<LinkedHashSetType> m_modificationForbidd
enScope; |
466 const LinkedHashSetType* m_container; | |
467 int64_t m_containerModifications; | |
468 #else | |
469 void checkModifications() const { } | |
470 #endif | 481 #endif |
471 template<typename T, typename U, typename V, typename W> friend class Linked
HashSet; | |
472 friend class LinkedHashSetIterator<LinkedHashSetType>; | |
473 }; | 482 }; |
474 | 483 |
475 template<typename LinkedHashSetType> | 484 template<typename LinkedHashSetType> |
476 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT
ype> { | 485 class LinkedHashSetReverseIterator : public LinkedHashSetIterator<LinkedHashSetT
ype> { |
477 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass; | 486 typedef LinkedHashSetIterator<LinkedHashSetType> Superclass; |
478 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_i
terator; | 487 typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> const_reverse_i
terator; |
479 typedef typename LinkedHashSetType::Node Node; | 488 typedef typename LinkedHashSetType::Node Node; |
480 | 489 |
481 protected: | 490 protected: |
482 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* contai
ner) | 491 LinkedHashSetReverseIterator(const Node* position, LinkedHashSetType* contai
ner) |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 swap(static_cast<Base&>(a), static_cast<Base&>(b)); | 782 swap(static_cast<Base&>(a), static_cast<Base&>(b)); |
774 swap(a.m_value, b.m_value); | 783 swap(a.m_value, b.m_value); |
775 Allocator::leaveGCForbiddenScope(); | 784 Allocator::leaveGCForbiddenScope(); |
776 } | 785 } |
777 | 786 |
778 } // namespace WTF | 787 } // namespace WTF |
779 | 788 |
780 using WTF::LinkedHashSet; | 789 using WTF::LinkedHashSet; |
781 | 790 |
782 #endif /* WTF_LinkedHashSet_h */ | 791 #endif /* WTF_LinkedHashSet_h */ |
OLD | NEW |