Bug 1473771 - Part 2: Make LinkedList::Iterator work when element type inherits from multiple LinkedListElement<T>s. r=Waldo
authorCameron McCormack <cam@mcc.id.au>
Fri, 06 Jul 2018 10:56:08 +1000
changeset 480523 f05677e4a0f7a59af36792423fb6fce87198529d
parent 480522 56cf99e809bd77e55af00736edbd1a2252c0b017
child 480524 1df83f663c81ecc7d737f640fe6371d08f3107c9
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1473771
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1473771 - Part 2: Make LinkedList::Iterator work when element type inherits from multiple LinkedListElement<T>s. r=Waldo MozReview-Commit-ID: 9dNTsSNyIYK
mfbt/LinkedList.h
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -406,37 +406,39 @@ template<typename T>
 class LinkedList
 {
 private:
   typedef typename detail::LinkedListElementTraits<T> Traits;
   typedef typename Traits::RawType RawType;
   typedef typename Traits::ConstRawType ConstRawType;
   typedef typename Traits::ClientType ClientType;
   typedef typename Traits::ConstClientType ConstClientType;
+  typedef LinkedListElement<T>* ElementType;
+  typedef const LinkedListElement<T>* ConstElementType;
 
   LinkedListElement<T> sentinel;
 
 public:
-  template <typename Type>
+  template <typename Type, typename Element>
   class Iterator {
     Type mCurrent;
 
   public:
     explicit Iterator(Type aCurrent) : mCurrent(aCurrent) {}
 
     Type operator *() const {
       return mCurrent;
     }
 
     const Iterator& operator++() {
-      mCurrent = mCurrent->getNext();
+      mCurrent = static_cast<Element>(mCurrent)->getNext();
       return *this;
     }
 
-    bool operator!=(const Iterator<Type>& aOther) const {
+    bool operator!=(const Iterator& aOther) const {
       return mCurrent != aOther.mCurrent;
     }
   };
 
   LinkedList() : sentinel(LinkedListElement<T>::NodeKind::Sentinel) { }
 
   LinkedList(LinkedList<T>&& aOther)
     : sentinel(std::move(aOther.sentinel))
@@ -531,27 +533,27 @@ public:
     }
   }
 
   /*
    * Allow range-based iteration:
    *
    *     for (MyElementType* elt : myList) { ... }
    */
-  Iterator<RawType> begin() {
-    return Iterator<RawType>(getFirst());
+  Iterator<RawType, ElementType> begin() {
+    return Iterator<RawType, ElementType>(getFirst());
   }
-  Iterator<ConstRawType> begin() const {
-    return Iterator<ConstRawType>(getFirst());
+  Iterator<ConstRawType, ConstElementType> begin() const {
+    return Iterator<ConstRawType, ConstElementType>(getFirst());
   }
-  Iterator<RawType> end() {
-    return Iterator<RawType>(nullptr);
+  Iterator<RawType, ElementType> end() {
+    return Iterator<RawType, ElementType>(nullptr);
   }
-  Iterator<ConstRawType> end() const {
-    return Iterator<ConstRawType>(nullptr);
+  Iterator<ConstRawType, ConstElementType> end() const {
+    return Iterator<ConstRawType, ConstElementType>(nullptr);
   }
 
   /*
    * Measures the memory consumption of the list excluding |this|.  Note that
    * it only measures the list elements themselves.  If the list elements
    * contain pointers to other memory blocks, those blocks must be measured
    * separately during a subsequent iteration over the list.
    */