diff --git a/mfbt/LinkedList.h b/mfbt/LinkedList.h index 2d450940db59..6e14aa162962 100644 --- a/mfbt/LinkedList.h +++ b/mfbt/LinkedList.h @@ -250,6 +250,30 @@ public: 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. diff --git a/mfbt/tests/TestLinkedList.cpp b/mfbt/tests/TestLinkedList.cpp index aa373ed2f371..0421668b97c5 100644 --- a/mfbt/tests/TestLinkedList.cpp +++ b/mfbt/tests/TestLinkedList.cpp @@ -156,6 +156,24 @@ TestMove() list3.clear(); } +static void +TestRemoveAndGet() +{ + LinkedList 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 { friend class mozilla::LinkedList; friend class mozilla::LinkedListElement; @@ -244,6 +262,7 @@ main() TestList(); TestPrivate(); TestMove(); + TestRemoveAndGet(); TestRefPtrList(); return 0; }