diff options
| author | tobo <[email protected]> | 2025-10-03 01:00:41 +0300 |
|---|---|---|
| committer | tobo <[email protected]> | 2025-10-03 01:15:19 +0300 |
| commit | 3845cf703c43a63764f37d7d6bd281193373147a (patch) | |
| tree | edb8c10533d994a3199fcb3d62f07e2790ae303a /library/cpp/containers | |
| parent | b1fa268eb661767da637df0c9e61f196884c1cd1 (diff) | |
use std::move instead of copying in TCompactVector::Reserve() + ya style
commit_hash:3e1b1459766c0173831844249e9e4a3c564ae7ae
Diffstat (limited to 'library/cpp/containers')
| -rw-r--r-- | library/cpp/containers/compact_vector/compact_vector.h | 22 | ||||
| -rw-r--r-- | library/cpp/containers/compact_vector/compact_vector_ut.cpp | 74 |
2 files changed, 66 insertions, 30 deletions
diff --git a/library/cpp/containers/compact_vector/compact_vector.h b/library/cpp/containers/compact_vector/compact_vector.h index 238b336d1b8..f795b40eb41 100644 --- a/library/cpp/containers/compact_vector/compact_vector.h +++ b/library/cpp/containers/compact_vector/compact_vector.h @@ -4,6 +4,9 @@ #include <util/generic/yexception.h> #include <util/system/sys_alloc.h> +#include <algorithm> +#include <type_traits> + // vector that is 8 bytes when empty (TVector is 24 bytes) template <typename T> @@ -202,8 +205,13 @@ public: } else { TThis copy; copy.Reserve(newCapacity); - for (TConstIterator it = Begin(); it != End(); ++it) { - copy.PushBack(*it); + if constexpr (std::is_trivially_copyable_v<T>) { + std::copy_n(Ptr, Size(), copy.Ptr); + copy.Header()->Size = Size(); + } else { + for (auto& val : *this) { + copy.EmplaceBack(std::move(val)); + } } Swap(copy); } @@ -213,23 +221,23 @@ public: Reserve(newCapacity); } - size_t Size() const { + [[nodiscard]] size_t Size() const { return Ptr ? Header()->Size : 0; } - size_t size() const { + [[nodiscard]] size_t size() const { return Size(); } - bool Empty() const { + [[nodiscard]] bool Empty() const { return Size() == 0; } - bool empty() const { + [[nodiscard]] bool empty() const { return Empty(); } - size_t Capacity() const { + [[nodiscard]] size_t Capacity() const { return Ptr ? Header()->Capacity : 0; } diff --git a/library/cpp/containers/compact_vector/compact_vector_ut.cpp b/library/cpp/containers/compact_vector/compact_vector_ut.cpp index e576ac3a956..f9fd43d0c79 100644 --- a/library/cpp/containers/compact_vector/compact_vector_ut.cpp +++ b/library/cpp/containers/compact_vector/compact_vector_ut.cpp @@ -70,7 +70,7 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { } Y_UNIT_TEST(TestInitializerListConstructor) { - TCompactVector<ui32> vector = { 4, 8, 10, 3, 5}; + TCompactVector<ui32> vector = {4, 8, 10, 3, 5}; UNIT_ASSERT_VALUES_EQUAL(5u, vector.Size()); UNIT_ASSERT_VALUES_EQUAL(4u, vector[0]); @@ -81,7 +81,7 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { } Y_UNIT_TEST(TestIteratorConstructor) { - TVector<ui32> origVector = { 4, 8, 10, 3, 5}; + TVector<ui32> origVector = {4, 8, 10, 3, 5}; TCompactVector<ui32> vector(origVector.begin(), origVector.end()); UNIT_ASSERT_VALUES_EQUAL(5u, vector.Size()); @@ -93,10 +93,10 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { } Y_UNIT_TEST(TestInitializerListCopyOperator) { - TCompactVector<double> vector = { 4, 8, 10, 3, 5}; + TCompactVector<double> vector = {4, 8, 10, 3, 5}; UNIT_ASSERT_VALUES_EQUAL(5u, vector.Size()); - vector = { 11, 17, 23 }; + vector = {11, 17, 23}; UNIT_ASSERT_VALUES_EQUAL(3u, vector.Size()); UNIT_ASSERT_VALUES_EQUAL(11.0, vector[0]); @@ -105,7 +105,7 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { } Y_UNIT_TEST(TestMoveConstructor) { - TCompactVector<ui32> vector = { 4, 8, 10, 3, 5}; + TCompactVector<ui32> vector = {4, 8, 10, 3, 5}; auto it = vector.Begin(); TCompactVector<ui32> vector2(std::move(vector)); @@ -122,10 +122,9 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { Y_UNIT_TEST(TestReverseIterators) { TCompactVector<std::string> vector = { - "мама", - "мыла", - "раму" - }; + "мама", + "мыла", + "раму"}; TCompactVector<std::string> reverseVector(vector.rbegin(), vector.rend()); UNIT_ASSERT_VALUES_EQUAL(3u, reverseVector.Size()); @@ -137,11 +136,10 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { Y_UNIT_TEST(TestErase) { TCompactVector<std::string> vector = { - "мама", - "утром", - "мыла", - "раму" - }; + "мама", + "утром", + "мыла", + "раму"}; vector.erase(vector.begin() + 1); UNIT_ASSERT_VALUES_EQUAL(3u, vector.Size()); @@ -154,10 +152,9 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { Y_UNIT_TEST(TestCopyAssignmentOperator) { TCompactVector<std::string> vector; const TCompactVector<std::string> vector2 = { - "мама", - "мыла", - "раму" - }; + "мама", + "мыла", + "раму"}; vector = vector2; @@ -174,12 +171,43 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { Y_UNIT_TEST(TestComparison) { // UNIT_ASSERT_VALUES_EQUAL needs a specialization for Out(), so we just use bool assertions - TCompactVector<int> vector {1, 2, 3}; - TCompactVector<int> vector2 {1, 2}; - UNIT_ASSERT(vector != vector2); // diff size + TCompactVector<int> vector{1, 2, 3}; + TCompactVector<int> vector2{1, 2}; + UNIT_ASSERT(vector != vector2); // diff size vector2.emplace_back(4); - UNIT_ASSERT(vector != vector2); // diff values + UNIT_ASSERT(vector != vector2); // diff values vector2.back() = 3; UNIT_ASSERT(vector == vector2); } -} + + Y_UNIT_TEST(TestReserve) { + TCompactVector vector = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + UNIT_ASSERT_LT(vector.Capacity(), 100); + vector.reserve(100); + UNIT_ASSERT_GE(vector.Capacity(), 100); + + UNIT_ASSERT_VALUES_EQUAL(vector.size(), 10); + + for (size_t i = 0; i < 10; ++i) { + UNIT_ASSERT_VALUES_EQUAL(vector[i], i); + } + } + + Y_UNIT_TEST(TestReserveWithMovableType) { + TCompactVector<TVector<int>> vector; + vector.EmplaceBack(TVector({1, 2, 3})); + vector.EmplaceBack(TVector({2, 4, 5, 6, 7})); + + const int* ptr1 = vector[0].data(); + const int* ptr2 = vector[1].data(); + const size_t oldCapacity = vector.Capacity(); + + vector.Reserve(2 * oldCapacity); + + UNIT_ASSERT_GE(vector.Capacity(), 2 * oldCapacity); + + // check that values have been mooved, not copied + UNIT_ASSERT_VALUES_EQUAL(ptr1, vector[0].data()); + UNIT_ASSERT_VALUES_EQUAL(ptr2, vector[1].data()); + } +} // Y_UNIT_TEST_SUITE(TCompactVectorTest) |
