Bug 1113300 - Add a way to use SegmentedVector like a stack. r=froydnj

This commit is contained in:
Andrew McCreight 2015-05-07 09:11:00 +02:00
parent 2e3bab35a3
commit fb796b8e9b
2 changed files with 52 additions and 1 deletions

View File

@ -92,6 +92,13 @@ class SegmentedVector : private AllocPolicy
new (elem) T(mozilla::Forward<U>(aU));
}
void PopLast()
{
MOZ_ASSERT(mLength > 0);
(*this)[mLength - 1].~T();
mLength--;
}
uint32_t mLength;
// The union ensures that the elements are appropriately aligned.
@ -185,6 +192,32 @@ public:
}
}
T& GetLast()
{
MOZ_ASSERT(!IsEmpty());
Segment* last = mSegments.getLast();
return (*last)[last->Length() - 1];
}
const T& GetLast() const
{
MOZ_ASSERT(!IsEmpty());
Segment* last = mSegments.getLast();
return (*last)[last->Length() - 1];
}
void PopLast()
{
MOZ_ASSERT(!IsEmpty());
Segment* last = mSegments.getLast();
last->PopLast();
if (!last->Length()) {
mSegments.popLast();
last->~Segment();
this->free_(last);
}
}
// Use this class to iterate over a SegmentedVector, like so:
//
// for (auto iter = v.Iter(); !iter.Done(); iter.Next()) {

View File

@ -80,6 +80,22 @@ void TestBasics()
}
MOZ_RELEASE_ASSERT(n == 1000);
// Pop off all of the elements.
MOZ_RELEASE_ASSERT(v.Length() == 1000);
for (int len = (int)v.Length(); len > 0; len--) {
MOZ_RELEASE_ASSERT(v.GetLast() == len - 1);
v.PopLast();
}
MOZ_RELEASE_ASSERT(v.IsEmpty());
MOZ_RELEASE_ASSERT(v.Length() == 0);
// Fill the vector up again to prepare for the clear.
for (i = 0; i < 1000; i++) {
v.InfallibleAppend(mozilla::Move(i));
}
MOZ_RELEASE_ASSERT(!v.IsEmpty());
MOZ_RELEASE_ASSERT(v.Length() == 1000);
v.Clear();
MOZ_RELEASE_ASSERT(v.IsEmpty());
MOZ_RELEASE_ASSERT(v.Length() == 0);
@ -115,7 +131,9 @@ void TestConstructorsAndDestructors()
gDummy = v.Append(mozilla::Move(y)); // move constructor called
NonPOD z(1); // explicit constructor called
v.InfallibleAppend(mozilla::Move(z)); // move constructor called
v.Clear(); // destructor called 3 times
v.PopLast(); // destructor called 1 time
MOZ_RELEASE_ASSERT(gNumDtors == 1);
v.Clear(); // destructor called 2 times
MOZ_RELEASE_ASSERT(gNumDefaultCtors == 0);
MOZ_RELEASE_ASSERT(gNumExplicitCtors == 3);