mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1665462 - Add moving Vector::appendAll(Vector&&) overload. r=jwalden
Differential Revision: https://phabricator.services.mozilla.com/D90522
This commit is contained in:
parent
d87f6fb19c
commit
29d19d608b
@ -120,6 +120,11 @@ class GCVector {
|
||||
MOZ_MUST_USE bool appendAll(const U& aU) {
|
||||
return vector.append(aU.begin(), aU.end());
|
||||
}
|
||||
template <typename T2, size_t MinInlineCapacity2, typename AllocPolicy2>
|
||||
MOZ_MUST_USE bool appendAll(
|
||||
GCVector<T2, MinInlineCapacity2, AllocPolicy2>&& aU) {
|
||||
return vector.appendAll(aU.begin(), aU.end());
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool appendN(const T& val, size_t count) {
|
||||
return vector.appendN(val, count);
|
||||
@ -264,7 +269,7 @@ class MutableWrappedPtrOperations<JS::GCVector<T, Capacity, AllocPolicy>,
|
||||
vec().infallibleEmplaceBack(std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename U>
|
||||
MOZ_MUST_USE bool appendAll(const U& aU) {
|
||||
MOZ_MUST_USE bool appendAll(U&& aU) {
|
||||
return vec().appendAll(aU);
|
||||
}
|
||||
MOZ_MUST_USE bool appendN(const T& aT, size_t aN) {
|
||||
|
@ -423,6 +423,8 @@ class MOZ_NON_PARAM Vector final : private AllocPolicy {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool internalEnsureCapacity(size_t aNeeded);
|
||||
|
||||
/* Append operations guaranteed to succeed due to pre-reserved space. */
|
||||
template <typename U>
|
||||
void internalAppend(U&& aU);
|
||||
@ -431,6 +433,8 @@ class MOZ_NON_PARAM Vector final : private AllocPolicy {
|
||||
void internalAppendN(const T& aT, size_t aN);
|
||||
template <typename U>
|
||||
void internalAppend(const U* aBegin, size_t aLength);
|
||||
template <typename U>
|
||||
void internalMoveAppend(U* aBegin, size_t aLength);
|
||||
|
||||
public:
|
||||
static const size_t sMaxInlineStorage = MinInlineCapacity;
|
||||
@ -667,11 +671,15 @@ class MOZ_NON_PARAM Vector final : private AllocPolicy {
|
||||
|
||||
template <typename U, size_t O, class BP>
|
||||
MOZ_MUST_USE bool appendAll(const Vector<U, O, BP>& aU);
|
||||
template <typename U, size_t O, class BP>
|
||||
MOZ_MUST_USE bool appendAll(Vector<U, O, BP>&& aU);
|
||||
MOZ_MUST_USE bool appendN(const T& aT, size_t aN);
|
||||
template <typename U>
|
||||
MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd);
|
||||
template <typename U>
|
||||
MOZ_MUST_USE bool append(const U* aBegin, size_t aLength);
|
||||
template <typename U>
|
||||
MOZ_MUST_USE bool moveAppend(U* aBegin, U* aEnd);
|
||||
|
||||
/*
|
||||
* Guaranteed-infallible append operations for use upon vectors whose
|
||||
@ -1347,11 +1355,8 @@ void Vector<T, N, AP>::eraseIfEqual(const U& aU) {
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::append(const U* aInsBegin,
|
||||
const U* aInsEnd) {
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd);
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::internalEnsureCapacity(
|
||||
size_t aNeeded) {
|
||||
if (mLength + aNeeded > mTail.mCapacity) {
|
||||
if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) {
|
||||
return false;
|
||||
@ -1364,7 +1369,19 @@ MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::append(const U* aInsBegin,
|
||||
mTail.mReserved = mLength + aNeeded;
|
||||
}
|
||||
#endif
|
||||
internalAppend(aInsBegin, aNeeded);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::append(const U* aInsBegin,
|
||||
const U* aInsEnd) {
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
const size_t needed = PointerRangeSize(aInsBegin, aInsEnd);
|
||||
if (!internalEnsureCapacity(needed)) {
|
||||
return false;
|
||||
}
|
||||
internalAppend(aInsBegin, needed);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1378,6 +1395,28 @@ MOZ_ALWAYS_INLINE void Vector<T, N, AP>::internalAppend(const U* aInsBegin,
|
||||
mLength += aInsLength;
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::moveAppend(U* aInsBegin, U* aInsEnd) {
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
const size_t needed = PointerRangeSize(aInsBegin, aInsEnd);
|
||||
if (!internalEnsureCapacity(needed)) {
|
||||
return false;
|
||||
}
|
||||
internalMoveAppend(aInsBegin, needed);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U>
|
||||
MOZ_ALWAYS_INLINE void Vector<T, N, AP>::internalMoveAppend(U* aInsBegin,
|
||||
size_t aInsLength) {
|
||||
MOZ_ASSERT(mLength + aInsLength <= mTail.mReserved);
|
||||
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
|
||||
Impl::moveConstruct(endNoCheck(), aInsBegin, aInsBegin + aInsLength);
|
||||
mLength += aInsLength;
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::append(U&& aU) {
|
||||
@ -1405,6 +1444,22 @@ MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::appendAll(
|
||||
return append(aOther.begin(), aOther.length());
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <typename U, size_t O, class BP>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::appendAll(Vector<U, O, BP>&& aOther) {
|
||||
if (empty() && capacity() < aOther.length()) {
|
||||
*this = std::move(aOther);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (moveAppend(aOther.begin(), aOther.end())) {
|
||||
aOther.clearAndFree();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, size_t N, class AP>
|
||||
template <class U>
|
||||
MOZ_ALWAYS_INLINE bool Vector<T, N, AP>::append(const U* aInsBegin,
|
||||
|
@ -6,9 +6,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/IntegerRange.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
using mozilla::IntegerRange;
|
||||
using mozilla::MakeUnique;
|
||||
using mozilla::UniquePtr;
|
||||
using mozilla::Vector;
|
||||
@ -25,6 +27,7 @@ struct mozilla::detail::VectorTesting {
|
||||
static void testInsert();
|
||||
static void testErase();
|
||||
static void testShrinkStorageToFit();
|
||||
static void testAppend();
|
||||
};
|
||||
|
||||
void mozilla::detail::VectorTesting::testReserved() {
|
||||
@ -662,6 +665,26 @@ void mozilla::detail::VectorTesting::testShrinkStorageToFit() {
|
||||
}
|
||||
}
|
||||
|
||||
void mozilla::detail::VectorTesting::testAppend() {
|
||||
// Test moving append/appendAll with a move-only type
|
||||
Vector<UniquePtr<int>> bv;
|
||||
for (const int val : IntegerRange<int>(0, 3)) {
|
||||
MOZ_RELEASE_ASSERT(bv.append(MakeUnique<int>(val)));
|
||||
}
|
||||
|
||||
Vector<UniquePtr<int>> otherbv;
|
||||
for (const int val : IntegerRange<int>(3, 8)) {
|
||||
MOZ_RELEASE_ASSERT(otherbv.append(MakeUnique<int>(val)));
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(bv.appendAll(std::move(otherbv)));
|
||||
|
||||
MOZ_RELEASE_ASSERT(otherbv.length() == 0);
|
||||
MOZ_RELEASE_ASSERT(bv.length() == 8);
|
||||
for (const int val : IntegerRange<int>(0, 8)) {
|
||||
MOZ_RELEASE_ASSERT(*bv[val] == val);
|
||||
}
|
||||
}
|
||||
|
||||
// Declare but leave (permanently) incomplete.
|
||||
struct Incomplete;
|
||||
|
||||
@ -777,5 +800,6 @@ int main() {
|
||||
VectorTesting::testInsert();
|
||||
VectorTesting::testErase();
|
||||
VectorTesting::testShrinkStorageToFit();
|
||||
VectorTesting::testAppend();
|
||||
TestVectorBeginNonNull();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user