forked from OSchip/llvm-project
ADT: Add SmallVectorImpl::truncate() to replace uses of set_size()
Add `SmallVectorImpl::truncate()`, a variant of `resize()` that cannot increase the size. - Compared to `resize()`, this has no code path for growing the allocation and can be better optimized. - Compared to `set_size()`, this formally calls destructors, and does not skip any constructors. - Compared to `pop_back_n()`, this takes the new desired size, which in many contexts is more intuitive than the number of elements to remove. The immediate motivation is to pair this with `resize_for_overwrite()` to remove uses of `set_size()`, which can then be made private. Differential Revision: https://reviews.llvm.org/D115383
This commit is contained in:
parent
1225c8a061
commit
ca451d3fa4
|
@ -593,7 +593,7 @@ private:
|
|||
return;
|
||||
|
||||
if (N < this->size()) {
|
||||
this->pop_back_n(this->size() - N);
|
||||
this->truncate(N);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -612,12 +612,19 @@ public:
|
|||
/// Like resize, but \ref T is POD, the new values won't be initialized.
|
||||
void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
|
||||
|
||||
/// Like resize, but requires that \p N is less than \a size().
|
||||
void truncate(size_type N) {
|
||||
assert(this->size() >= N && "Cannot increase size with truncate");
|
||||
this->destroy_range(this->begin() + N, this->end());
|
||||
this->set_size(N);
|
||||
}
|
||||
|
||||
void resize(size_type N, ValueParamT NV) {
|
||||
if (N == this->size())
|
||||
return;
|
||||
|
||||
if (N < this->size()) {
|
||||
this->pop_back_n(this->size() - N);
|
||||
this->truncate(N);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -632,8 +639,7 @@ public:
|
|||
|
||||
void pop_back_n(size_type NumItems) {
|
||||
assert(this->size() >= NumItems);
|
||||
this->destroy_range(this->end() - NumItems, this->end());
|
||||
this->set_size(this->size() - NumItems);
|
||||
truncate(this->size() - NumItems);
|
||||
}
|
||||
|
||||
LLVM_NODISCARD T pop_back_val() {
|
||||
|
|
|
@ -309,6 +309,32 @@ TYPED_TEST(SmallVectorTest, ResizeShrinkTest) {
|
|||
EXPECT_EQ(5, Constructable::getNumDestructorCalls());
|
||||
}
|
||||
|
||||
// Truncate test.
|
||||
TYPED_TEST(SmallVectorTest, TruncateTest) {
|
||||
SCOPED_TRACE("TruncateTest");
|
||||
|
||||
this->theVector.reserve(3);
|
||||
this->makeSequence(this->theVector, 1, 3);
|
||||
this->theVector.truncate(1);
|
||||
|
||||
this->assertValuesInOrder(this->theVector, 1u, 1);
|
||||
EXPECT_EQ(6, Constructable::getNumConstructorCalls());
|
||||
EXPECT_EQ(5, Constructable::getNumDestructorCalls());
|
||||
|
||||
#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
|
||||
EXPECT_DEATH(this->theVector.truncate(2), "Cannot increase size");
|
||||
#endif
|
||||
this->theVector.truncate(1);
|
||||
this->assertValuesInOrder(this->theVector, 1u, 1);
|
||||
EXPECT_EQ(6, Constructable::getNumConstructorCalls());
|
||||
EXPECT_EQ(5, Constructable::getNumDestructorCalls());
|
||||
|
||||
this->theVector.truncate(0);
|
||||
this->assertEmpty(this->theVector);
|
||||
EXPECT_EQ(6, Constructable::getNumConstructorCalls());
|
||||
EXPECT_EQ(6, Constructable::getNumDestructorCalls());
|
||||
}
|
||||
|
||||
// Resize bigger test.
|
||||
TYPED_TEST(SmallVectorTest, ResizeGrowTest) {
|
||||
SCOPED_TRACE("ResizeGrowTest");
|
||||
|
|
Loading…
Reference in New Issue