From 1a886ad52ce02f8a51125134686563753f794e77 Mon Sep 17 00:00:00 2001 From: Ole Erik Peistorpet Date: Thu, 14 Sep 2023 16:45:27 +0200 Subject: [PATCH] Fixed: shrink_to_fit lost elements when relocation was non-trivial Caused by wrong return value from _detail::Relocate --- auxi/impl_algo.h | 2 +- unit_test/dynarray_mutate_gtest.cpp | 38 ++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/auxi/impl_algo.h b/auxi/impl_algo.h index f2f9b93e..410fbbb7 100644 --- a/auxi/impl_algo.h +++ b/auxi/impl_algo.h @@ -118,7 +118,7 @@ namespace _detail ::new(static_cast(dest + i)) T( std::move(src[i]) ); src[i].~T(); } - return dest; + return dest + n; } #undef OEL_CHECK_NULL_MEMCPY diff --git a/unit_test/dynarray_mutate_gtest.cpp b/unit_test/dynarray_mutate_gtest.cpp index 56f5af70..6af1f3bd 100644 --- a/unit_test/dynarray_mutate_gtest.cpp +++ b/unit_test/dynarray_mutate_gtest.cpp @@ -682,15 +682,19 @@ void testEraseOne() EXPECT_EQ(1, static_cast(d.front())); } -TEST_F(dynarrayTest, eraseSingle) +TEST_F(dynarrayTest, eraseSingleInt) { testEraseOne(); +} - TrivialRelocat::clearCount(); +TEST_F(dynarrayTest, eraseSingleTrivialReloc) +{ testEraseOne(); EXPECT_EQ(TrivialRelocat::nConstructions, TrivialRelocat::nDestruct); +} - MoveOnly::clearCount(); +TEST_F(dynarrayTest, eraseSingle) +{ testEraseOne(); EXPECT_EQ(MoveOnly::nConstructions, MoveOnly::nDestruct); } @@ -712,15 +716,19 @@ void testErase() EXPECT_EQ(s, static_cast(d.back())); } -TEST_F(dynarrayTest, eraseRange) +TEST_F(dynarrayTest, eraseRangeInt) { testErase(); +} - TrivialRelocat::clearCount(); +TEST_F(dynarrayTest, eraseRangeTrivialReloc) +{ testErase(); EXPECT_EQ(TrivialRelocat::nConstructions, TrivialRelocat::nDestruct); +} - MoveOnly::clearCount(); +TEST_F(dynarrayTest, eraseRange) +{ testErase(); EXPECT_EQ(MoveOnly::nConstructions, MoveOnly::nDestruct); } @@ -777,9 +785,27 @@ void testEraseUnstable() TEST_F(dynarrayTest, eraseUnstable) { testEraseUnstable(); +} + +TEST_F(dynarrayTest, eraseUnstableTrivialReloc) +{ testEraseUnstable(); } +TEST_F(dynarrayTest, shrinkToFit) +{ + { + dynarray d(oel::reserve, 9); + d.emplace_back(-5); + + d.shrink_to_fit(); + + EXPECT_GT(9u, d.capacity()); + EXPECT_EQ(1u, d.size()); + } + EXPECT_EQ(MoveOnly::nConstructions, MoveOnly::nDestruct); +} + TEST_F(dynarrayTest, overAligned) { static unsigned int const testAlignment = 64;