Bug 1113300 - Add a way to pop the last element off a SegmentedVector. r=froydnj
authorAndrew McCreight <continuation@gmail.com>
Mon, 22 Dec 2014 19:01:17 -0500
changeset 341295 f393b1cd149b22423a40b0bdcec1cf608ccfa108
parent 341294 59414d1f5dc7b8d3f9eaa4233b8f914e1fe5f17c
child 341296 578adac81d4f7580e4724ab7d5b2940d0cc26395
push id46474
push useramccreight@mozilla.com
push dateTue, 23 Dec 2014 00:01:30 +0000
treeherdertry@55f22e1178fb [default view] [failures only]
reviewersfroydnj
bugs1113300
milestone37.0a1
Bug 1113300 - Add a way to pop the last element off a SegmentedVector. r=froydnj
mfbt/SegmentedVector.h
--- a/mfbt/SegmentedVector.h
+++ b/mfbt/SegmentedVector.h
@@ -92,16 +92,25 @@ class SegmentedVector : private AllocPol
       MOZ_ASSERT(mLength < SegmentCapacity);
 #endif
       // Pre-increment mLength so that the bounds-check in operator[] passes.
       mLength++;
       T* elem = &(*this)[mLength - 1];
       new (elem) T(mozilla::Forward<U>(aU));
     }
 
+    T PopLast()
+    {
+      MOZ_ASSERT(mLength > 0);
+      T lastElement(Move((*this)[mLength - 1]));
+      (*this)[mLength - 1].~T();
+      mLength--;
+      return lastElement;
+    }
+
     uint32_t mLength;
 
     // The union ensures that the elements are appropriately aligned.
     union Storage
     {
       char mBuf[sizeof(T) * SegmentCapacity];
       mozilla::AlignedElem<MOZ_ALIGNOF(T)> mAlign;
     } mStorage;
@@ -185,16 +194,29 @@ public:
   {
     Segment* segment;
     while ((segment = mSegments.popFirst())) {
       segment->~Segment();
       this->free_(segment);
     }
   }
 
+  T PopLast()
+  {
+    MOZ_ASSERT(!IsEmpty());
+    Segment* lastSegment = mSegments.getLast();
+    T lastElement(lastSegment->PopLast());
+    if (lastSegment->Length() == 0) {
+      mSegments.popLast();
+      lastSegment->~Segment();
+      this->free_(lastSegment);
+    }
+    return lastElement;
+  }
+
   // Use this class to iterate over a SegmentedVector, like so:
   //
   //  for (auto iter = v.Iter(); !iter.Done(); iter.Next()) {
   //    MyElem& elem = iter.Get();
   //    f(elem);
   //  }
   //
   class IterImpl