Bug 906912 - Add move constructors to mozilla::LinkedList and mozilla::LinkedListElement. r=waldo
authorJustin Lebar <justin.lebar@gmail.com>
Thu, 29 Aug 2013 11:54:14 -0700
changeset 157970 3f307f37b77a321b9deeb4f26e20d78494ea38d0
parent 157969 bb557a5557c2d70b2d73f2002855e70ed16870f6
child 157971 7c79b89c492a161b2f6f7e643c29e30fb4b4fa96
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs906912
milestone26.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 906912 - Add move constructors to mozilla::LinkedList and mozilla::LinkedListElement. r=waldo
mfbt/LinkedList.h
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -53,16 +53,17 @@
  *
  */
 
 #ifndef mozilla_LinkedList_h
 #define mozilla_LinkedList_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/Move.h"
 #include "mozilla/NullPtr.h"
 
 #ifdef __cplusplus
 
 namespace mozilla {
 
 template<typename T>
 class LinkedList;
@@ -111,16 +112,46 @@ class LinkedListElement
 
   public:
     LinkedListElement()
       : next(MOZ_THIS_IN_INITIALIZER_LIST()),
         prev(MOZ_THIS_IN_INITIALIZER_LIST()),
         isSentinel(false)
     { }
 
+    LinkedListElement(LinkedListElement<T>&& other)
+      : isSentinel(other.isSentinel)
+    {
+      if (!other.isInList()) {
+        next = this;
+        prev = this;
+        return;
+      }
+
+      MOZ_ASSERT(other.next->prev == &other);
+      MOZ_ASSERT(other.prev->next == &other);
+
+      /*
+       * Initialize |this| with |other|'s prev/next pointers, and adjust those
+       * element to point to this one.
+       */
+      next = other.next;
+      prev = other.prev;
+
+      next->prev = this;
+      prev->next = this;
+
+      /*
+       * Adjust |other| so it doesn't think it's in a list.  This makes it
+       * safely destructable.
+       */
+      other.next = &other;
+      other.prev = &other;
+    }
+
     ~LinkedListElement() {
       if (!isSentinel && isInList())
         remove();
     }
 
     /*
      * Get the next element in the list, or nullptr if this is the last element
      * in the list.
@@ -260,16 +291,20 @@ template<typename T>
 class LinkedList
 {
   private:
     LinkedListElement<T> sentinel;
 
   public:
     LinkedList() : sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL) { }
 
+    LinkedList(LinkedList<T>&& other)
+      : sentinel(mozilla::Move(other.sentinel))
+    { }
+
     ~LinkedList() {
       MOZ_ASSERT(isEmpty());
     }
 
     /*
      * Add elem to the front of the list.
      */
     void insertFront(T* elem) {