summaryrefslogtreecommitdiffstats
path: root/library/cpp/containers
diff options
context:
space:
mode:
authortobo <[email protected]>2025-10-03 01:00:41 +0300
committertobo <[email protected]>2025-10-03 01:15:19 +0300
commit3845cf703c43a63764f37d7d6bd281193373147a (patch)
treeedb8c10533d994a3199fcb3d62f07e2790ae303a /library/cpp/containers
parentb1fa268eb661767da637df0c9e61f196884c1cd1 (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.h22
-rw-r--r--library/cpp/containers/compact_vector/compact_vector_ut.cpp74
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)