Bug 1562789 - SmallPointerArray should support moves, and have an IsEmpty() helper. r=froydnj
This also implicitly deletes its copy-assignment operator and copy-constructor, which is great since it's a huge footgun. Differential Revision: https://phabricator.services.mozilla.com/D36549
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#define mozilla_SmallPointerArray_h
|
#define mozilla_SmallPointerArray_h
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/PodOperations.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
// Array class for situations where a small number of NON-NULL elements (<= 2)
|
// Array class for situations where a small number of NON-NULL elements (<= 2)
|
||||||
// is expected, a large number of elements must be accomodated if necessary,
|
// is expected, a large number of elements must be accommodated if necessary,
|
||||||
// and the size of the class must be minimal. Typical vector implementations
|
// and the size of the class must be minimal. Typical vector implementations
|
||||||
// will fulfill the first two requirements by simply adding inline storage
|
// will fulfill the first two requirements by simply adding inline storage
|
||||||
// alongside the rest of their member variables. While this strategy works,
|
// alongside the rest of their member variables. While this strategy works,
|
||||||
@@ -49,6 +50,17 @@ class SmallPointerArray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallPointerArray(SmallPointerArray&& aOther) {
|
||||||
|
PodCopy(mArray, aOther.mArray, 2);
|
||||||
|
aOther.mArray[0].mValue = nullptr;
|
||||||
|
aOther.mArray[1].mVector = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallPointerArray& operator=(SmallPointerArray&& aOther) {
|
||||||
|
std::swap(mArray, aOther.mArray);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
if (first()) {
|
if (first()) {
|
||||||
first() = nullptr;
|
first() = nullptr;
|
||||||
@@ -160,6 +172,8 @@ class SmallPointerArray {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsEmpty() const { return Length() == 0; }
|
||||||
|
|
||||||
T* ElementAt(size_t aIndex) const {
|
T* ElementAt(size_t aIndex) const {
|
||||||
MOZ_ASSERT(aIndex < Length());
|
MOZ_ASSERT(aIndex < Length());
|
||||||
if (first()) {
|
if (first()) {
|
||||||
|
|||||||
@@ -192,8 +192,46 @@ void TestRangeBasedLoops() {
|
|||||||
MOZ_RELEASE_ASSERT(entries == 0);
|
MOZ_RELEASE_ASSERT(entries == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestMove() {
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
SmallPointerArray<void> testArray;
|
||||||
|
testArray.AppendElement(PTR1);
|
||||||
|
testArray.AppendElement(PTR2);
|
||||||
|
|
||||||
|
SmallPointerArray<void> moved = std::move(testArray);
|
||||||
|
|
||||||
|
MOZ_RELEASE_ASSERT(testArray.IsEmpty());
|
||||||
|
MOZ_RELEASE_ASSERT(moved.Length() == 2);
|
||||||
|
MOZ_RELEASE_ASSERT(moved[0] == PTR1);
|
||||||
|
MOZ_RELEASE_ASSERT(moved[1] == PTR2);
|
||||||
|
|
||||||
|
// Heap case.
|
||||||
|
moved.AppendElement(PTR3);
|
||||||
|
|
||||||
|
SmallPointerArray<void> another = std::move(moved);
|
||||||
|
|
||||||
|
MOZ_RELEASE_ASSERT(testArray.IsEmpty());
|
||||||
|
MOZ_RELEASE_ASSERT(moved.IsEmpty());
|
||||||
|
MOZ_RELEASE_ASSERT(another.Length() == 3);
|
||||||
|
MOZ_RELEASE_ASSERT(another[0] == PTR1);
|
||||||
|
MOZ_RELEASE_ASSERT(another[1] == PTR2);
|
||||||
|
MOZ_RELEASE_ASSERT(another[2] == PTR3);
|
||||||
|
|
||||||
|
// Move assignment.
|
||||||
|
testArray = std::move(another);
|
||||||
|
|
||||||
|
MOZ_RELEASE_ASSERT(moved.IsEmpty());
|
||||||
|
MOZ_RELEASE_ASSERT(another.IsEmpty());
|
||||||
|
MOZ_RELEASE_ASSERT(testArray.Length() == 3);
|
||||||
|
MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
|
||||||
|
MOZ_RELEASE_ASSERT(testArray[1] == PTR2);
|
||||||
|
MOZ_RELEASE_ASSERT(testArray[2] == PTR3);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
TestArrayManipulation();
|
TestArrayManipulation();
|
||||||
TestRangeBasedLoops();
|
TestRangeBasedLoops();
|
||||||
|
TestMove();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user