forked from OSchip/llvm-project
[ADT] Add resize_for_overwrite method to SmallVector.
Analagous to the std::make_(unqiue|shared)_for_overwrite added in c++20. If T is POD, and the container gets larger, any new values added wont be initialized. This is useful when using SmallVector as a buffer where its planned to overwrite any potential new values added. If T is not POD, `new (Storage) T` functions identically to `new (Storage) T()` so this will function identically to `resize(size_type)`. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D93532
This commit is contained in:
parent
be85b3e432
commit
5d10b8ad59
|
@ -460,7 +460,8 @@ public:
|
|||
this->Size = 0;
|
||||
}
|
||||
|
||||
void resize(size_type N) {
|
||||
private:
|
||||
template <bool ForOverwrite> void resizeImpl(size_type N) {
|
||||
if (N < this->size()) {
|
||||
this->destroy_range(this->begin()+N, this->end());
|
||||
this->set_size(N);
|
||||
|
@ -468,11 +469,20 @@ public:
|
|||
if (this->capacity() < N)
|
||||
this->grow(N);
|
||||
for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
|
||||
new (&*I) T();
|
||||
if (ForOverwrite)
|
||||
new (&*I) T;
|
||||
else
|
||||
new (&*I) T();
|
||||
this->set_size(N);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void resize(size_type N) { resizeImpl<false>(N); }
|
||||
|
||||
/// Like resize, but \ref T is POD, the new values won't be initialized.
|
||||
void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
|
||||
|
||||
void resize(size_type N, const T &NV) {
|
||||
if (N == this->size())
|
||||
return;
|
||||
|
|
|
@ -341,6 +341,31 @@ TYPED_TEST(SmallVectorTest, ResizeFillTest) {
|
|||
this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77);
|
||||
}
|
||||
|
||||
TEST(SmallVectorTest, ResizeForOverwrite) {
|
||||
{
|
||||
// Heap allocated storage.
|
||||
SmallVector<unsigned, 0> V;
|
||||
V.push_back(5);
|
||||
V.pop_back();
|
||||
V.resize_for_overwrite(V.size() + 1);
|
||||
EXPECT_EQ(5, V.back());
|
||||
V.pop_back();
|
||||
V.resize(V.size() + 1);
|
||||
EXPECT_EQ(0, V.back());
|
||||
}
|
||||
{
|
||||
// Inline storage.
|
||||
SmallVector<unsigned, 2> V;
|
||||
V.push_back(5);
|
||||
V.pop_back();
|
||||
V.resize_for_overwrite(V.size() + 1);
|
||||
EXPECT_EQ(5, V.back());
|
||||
V.pop_back();
|
||||
V.resize(V.size() + 1);
|
||||
EXPECT_EQ(0, V.back());
|
||||
}
|
||||
}
|
||||
|
||||
// Overflow past fixed size.
|
||||
TYPED_TEST(SmallVectorTest, OverflowTest) {
|
||||
SCOPED_TRACE("OverflowTest");
|
||||
|
|
Loading…
Reference in New Issue