diff --git a/base/base_tests/buffer_vector_test.cpp b/base/base_tests/buffer_vector_test.cpp index 789e1ff7a2..2436ecc353 100644 --- a/base/base_tests/buffer_vector_test.cpp +++ b/base/base_tests/buffer_vector_test.cpp @@ -22,12 +22,29 @@ UNIT_TEST(BufferVector_PushBack_And_Realloc) using ElementT = std::vector; ElementT element({1, 2, 3}); - buffer_vector v; - v.append(2, element); + size_t constexpr kFixedSize = 2; + { + buffer_vector v; + v.append(kFixedSize, element); - v.push_back(v[0]); - TEST_EQUAL(v.size(), 3, ()); - TEST_EQUAL(v[2], element, ()); + v.push_back(v[0]); + TEST_EQUAL(v.size(), kFixedSize + 1, ()); + + for (auto const & e : v) + TEST_EQUAL(e, element, ()); + } + + { + buffer_vector v; + v.append(kFixedSize, element); + + v.emplace_back(3, v[0][1]); + TEST_EQUAL(v.size(), kFixedSize + 1, ()); + + for (size_t i = 0; i < kFixedSize; ++i) + TEST_EQUAL(v[i], element, ()); + TEST_EQUAL(v[kFixedSize], ElementT({2, 2, 2}), ()); + } } UNIT_TEST(BufferVectorBounds) @@ -364,7 +381,7 @@ UNIT_TEST(BufferVector_EraseIf) TEST_EQUAL(v[0], 2, ()); TEST_EQUAL(v[1], 4, ()); - v.erase_if([] (int x) { return true; }); + v.erase_if([] (int) { return true; }); TEST_EQUAL(v.size(), 0, ()); } diff --git a/base/buffer_vector.hpp b/base/buffer_vector.hpp index a758166924..b721fc9b32 100644 --- a/base/buffer_vector.hpp +++ b/base/buffer_vector.hpp @@ -279,22 +279,18 @@ public: /// By value to be consistent with m_vec.push_back(m_vec[0]). void push_back(T t) { - if (IsDynamic()) + if (!IsDynamic()) { - m_dynamic.push_back(t); - return; + if (m_size < N) + { + Swap(m_static[m_size++], t); + return; + } + else + SwitchToDynamic(N + 1); } - if (m_size < N) - { - Swap(m_static[m_size++], t); - } - else - { - SwitchToDynamic(N + 1); - m_dynamic.push_back(std::move(t)); - ASSERT_EQUAL(m_dynamic.size(), N + 1, ()); - } + m_dynamic.push_back(std::move(t)); } void pop_back() @@ -315,19 +311,20 @@ public: if (IsDynamic()) { m_dynamic.emplace_back(std::forward(args)...); - return; - } - - if (m_size < N) - { - value_type v(std::forward(args)...); - Swap(v, m_static[m_size++]); } else { - SwitchToDynamic(N + 1); - m_dynamic.emplace_back(std::forward(args)...); - ASSERT_EQUAL(m_dynamic.size(), N + 1, ()); + // Construct value first in case of reallocation and m_vec.emplace_back(m_vec[0]). + value_type v(std::forward(args)...); + if (m_size < N) + { + Swap(v, m_static[m_size++]); + } + else + { + SwitchToDynamic(N + 1); + m_dynamic.push_back(std::move(v)); + } } }