Bug 803688 - Remove LinkedListElements from their list when they're destructed, and assert that a LinkedList is empty when it's destructed. r=waldo, a=tef+
authorJustin Lebar <justin.lebar@gmail.com>
Wed, 24 Oct 2012 12:40:35 -0400
changeset 118581 819504e273514a22897014ad03f3410b406e3850
parent 118580 71e44bcc920be1134f1d6c4d0d0bdb7186612777
child 118582 d67c4bd5feb7b5ef49494865b2b6b9797c8930e6
push id29
push userryanvm@gmail.com
push dateTue, 26 Feb 2013 14:38:03 +0000
reviewerswaldo, tef
bugs803688
milestone18.0
Bug 803688 - Remove LinkedListElements from their list when they're destructed, and assert that a LinkedList is empty when it's destructed. r=waldo, a=tef+
mfbt/LinkedList.h
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -8,16 +8,20 @@
 /*
  * The classes LinkedList<T> and LinkedListElement<T> together form a
  * convenient, type-safe doubly-linked list implementation.
  *
  * The class T which will be inserted into the linked list must inherit from
  * LinkedListElement<T>.  A given object may be in only one linked list at a
  * time.
  *
+ * A LinkedListElement automatically removes itself from the list upon
+ * destruction, and a LinkedList will fatally assert in debug builds if it's
+ * non-empty when it's destructed.
+ *
  * For example, you might use LinkedList in a simple observer list class as
  * follows.
  *
  *   class Observer : public LinkedListElement<Observer>
  *   {
  *     public:
  *       void observe(char* topic) { ... }
  *   };
@@ -99,16 +103,21 @@ class LinkedListElement
   private:
     LinkedListElement* next;
     LinkedListElement* prev;
     const bool isSentinel;
 
   public:
     LinkedListElement() : next(this), prev(this), isSentinel(false) { }
 
+    ~LinkedListElement() {
+      if (!isSentinel && isInList())
+        remove();
+    }
+
     /*
      * Get the next element in the list, or NULL if this is the last element in
      * the list.
      */
     T* getNext() {
       return next->asT();
     }
     const T* getNext() const {
@@ -173,18 +182,17 @@ class LinkedListElement
       NODE_KIND_NORMAL,
       NODE_KIND_SENTINEL
     };
 
     LinkedListElement(NodeKind nodeKind)
       : next(this),
         prev(this),
         isSentinel(nodeKind == NODE_KIND_SENTINEL)
-    {
-    }
+    { }
 
     /*
      * Return |this| cast to T* if we're a normal node, or return NULL if we're
      * a sentinel node.
      */
     T* asT() {
       if (isSentinel)
         return NULL;