Bug 1473771 - Part 2: Make LinkedList::Iterator work when element type inherits from multiple LinkedListElement<T>s. r=Waldo draft
authorCameron McCormack <cam@mcc.id.au>
Fri, 06 Jul 2018 10:56:08 +1000
changeset 815243 cb919d0e6b762fc6e80ffab915135550d61c4d5d
parent 815242 26129bbc410747c87df132c5c84ebb2a41eb9457
child 815244 8467a30a89b6111361fee5e53f62fd6b5be041bb
push id115472
push userbmo:cam@mcc.id.au
push dateFri, 06 Jul 2018 23:29:01 +0000
reviewersWaldo
bugs1473771
milestone63.0a1
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.
    */