Bug 1310547 - Add removeAndGetNext/Previous methods to LinkedList (r=froydnj)
authorBill McCloskey <billm@mozilla.com>
Mon, 24 Oct 2016 12:49:21 -0700
changeset 320261 b30dfbf5fe2a
parent 320260 815e8f226bb9
child 320262 f1d9568cc12f
push id20754
push usercbook@mozilla.com
push dateMon, 31 Oct 2016 15:58:35 +0000
treeherderfx-team@b1b66b1780c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1310547
milestone52.0a1
Bug 1310547 - Add removeAndGetNext/Previous methods to LinkedList (r=froydnj)
mfbt/LinkedList.h
mfbt/tests/TestLinkedList.cpp
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -246,16 +246,40 @@ public:
     mNext->mPrev = mPrev;
     mNext = this;
     mPrev = this;
 
     Traits::exitList(this);
   }
 
   /*
+   * Remove this element from the list containing it.  Returns a pointer to the
+   * element that follows this element (before it was removed).  This method
+   * asserts if the element does not belong to a list.
+   */
+  ClientType removeAndGetNext()
+  {
+    ClientType r = getNext();
+    remove();
+    return r;
+  }
+
+  /*
+   * Remove this element from the list containing it.  Returns a pointer to the
+   * previous element in the containing list (before the removal).  This method
+   * asserts if the element does not belong to a list.
+   */
+  ClientType removeAndGetPrevious()
+  {
+    ClientType r = getPrevious();
+    remove();
+    return r;
+  }
+
+  /*
    * Identical to remove(), but also asserts in debug builds that this element
    * is in aList.
    */
   void removeFrom(const LinkedList<T>& aList)
   {
     aList.assertContains(asT());
     remove();
   }
--- a/mfbt/tests/TestLinkedList.cpp
+++ b/mfbt/tests/TestLinkedList.cpp
@@ -151,16 +151,34 @@ TestMove()
   LinkedList<SomeClass> list3;
   list3 = Move(list2);
   { unsigned int check[] { 1, 2 }; CheckListValues(list3, check); }
   MOZ_RELEASE_ASSERT(list2.isEmpty());
 
   list3.clear();
 }
 
+static void
+TestRemoveAndGet()
+{
+  LinkedList<SomeClass> list;
+
+  SomeClass one(1), two(2), three(3);
+  list.insertBack(&one);
+  list.insertBack(&two);
+  list.insertBack(&three);
+  { unsigned int check[] { 1, 2, 3 }; CheckListValues(list, check); }
+
+  MOZ_RELEASE_ASSERT(two.removeAndGetNext() == &three);
+  { unsigned int check[] { 1, 3 }; CheckListValues(list, check); }
+
+  MOZ_RELEASE_ASSERT(three.removeAndGetPrevious() == &one);
+  { unsigned int check[] { 1 }; CheckListValues(list, check); }
+}
+
 struct PrivateClass : private LinkedListElement<PrivateClass> {
   friend class mozilla::LinkedList<PrivateClass>;
   friend class mozilla::LinkedListElement<PrivateClass>;
 };
 
 static void
 TestPrivate()
 {
@@ -239,11 +257,12 @@ TestRefPtrList()
 }
 
 int
 main()
 {
   TestList();
   TestPrivate();
   TestMove();
+  TestRemoveAndGet();
   TestRefPtrList();
   return 0;
 }