aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp22
-rw-r--r--libs/kstd/kstd/ring_buffer.tests.cpp32
2 files changed, 42 insertions, 12 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp
index 8741c6db..66d870dd 100644
--- a/libs/kstd/kstd/ring_buffer.hpp
+++ b/libs/kstd/kstd/ring_buffer.hpp
@@ -11,6 +11,7 @@
#include <memory>
#include <ranges>
#include <type_traits>
+#include <utility>
namespace kstd
{
@@ -190,8 +191,11 @@ namespace kstd
: m_size{other.m_size}
, m_read_index{}
{
- std::ranges::for_each(std::views::iota(0uz, other.size()),
- [&](auto const i) { m_storage.construct(i, std::move(other[i])); });
+ std::ranges::for_each(std::views::iota(0uz, other.size()), [&](auto const i) {
+ m_storage.construct(i, std::move(other[i]));
+ std::destroy_at(other.element_at(i));
+ });
+ other.m_size = 0;
}
//! Destroy this ring buffer.
@@ -268,12 +272,18 @@ namespace kstd
}
auto const to_move_assign = std::min(m_size, other.m_size);
- std::ranges::move(std::views::take(other, to_move_assign), std::ranges::begin(*this));
+ std::ranges::for_each(std::views::enumerate(std::views::take(other, to_move_assign)), [&](auto const & entry) {
+ auto & [i, element] = entry;
+ (*this)[i] = std::move(element);
+ std::destroy_at(other.element_at(i));
+ });
if (to_move_assign < other.m_size)
{
- std::ranges::for_each(std::views::iota(to_move_assign, other.m_size),
- [&](auto const i) { std::construct_at(element_at(i), std::move(other[i])); });
+ std::ranges::for_each(std::views::iota(to_move_assign, other.m_size), [&](auto const i) {
+ std::construct_at(element_at(i), std::move(other[i]));
+ std::destroy_at(other.element_at(i));
+ });
}
else if (to_move_assign < m_size)
{
@@ -281,7 +291,7 @@ namespace kstd
[](auto & element) { std::destroy_at(&element); });
}
- m_size = other.m_size;
+ m_size = std::exchange(other.m_size, 0);
return *this;
}
diff --git a/libs/kstd/kstd/ring_buffer.tests.cpp b/libs/kstd/kstd/ring_buffer.tests.cpp
index 163d537c..d22633d6 100644
--- a/libs/kstd/kstd/ring_buffer.tests.cpp
+++ b/libs/kstd/kstd/ring_buffer.tests.cpp
@@ -331,6 +331,11 @@ SCENARIO("Ring Buffer initialization and construction", "[kstd][ring_buffer]")
{
REQUIRE(std::ranges::equal(moved, copy));
}
+
+ THEN("the moved-from buffer is empty")
+ {
+ REQUIRE(buffer.empty());
+ }
}
}
}
@@ -416,14 +421,19 @@ SCENARIO("Ring Buffer assignment", "[kstd][ring_buffer]")
kstd::tests::static_copy_move_tracker::reset();
large = std::move(small);
- THEN("2 move assignments and 1 destruction occurs")
+ THEN("2 move assignments and 3 destructions occur")
{
- REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 1);
+ REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 3);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_ctor_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_assignment_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::move_ctor_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::move_assignment_call_count == 2);
}
+
+ THEN("the moved-from buffer is empty")
+ {
+ REQUIRE(small.empty());
+ }
}
WHEN("move assigning the large to the small one")
@@ -431,14 +441,19 @@ SCENARIO("Ring Buffer assignment", "[kstd][ring_buffer]")
kstd::tests::static_copy_move_tracker::reset();
small = std::move(large);
- THEN("2 move assignments and 1 move construction occurs")
+ THEN("2 move assignments, 1 move construction, and 3 destructions occur")
{
- REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 0);
+ REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 3);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_ctor_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_assignment_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::move_ctor_call_count == 1);
REQUIRE(kstd::tests::static_copy_move_tracker::move_assignment_call_count == 2);
}
+
+ THEN("the moved-from buffer is empty")
+ {
+ REQUIRE(large.empty());
+ }
}
WHEN("move assigning the small to the same size one")
@@ -446,14 +461,19 @@ SCENARIO("Ring Buffer assignment", "[kstd][ring_buffer]")
kstd::tests::static_copy_move_tracker::reset();
same = std::move(small);
- THEN("2 move assignments occur")
+ THEN("2 move assignments and 2 destructions occur")
{
- REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 0);
+ REQUIRE(kstd::tests::static_copy_move_tracker::dtor_call_count == 2);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_ctor_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::copy_assignment_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::move_ctor_call_count == 0);
REQUIRE(kstd::tests::static_copy_move_tracker::move_assignment_call_count == 2);
}
+
+ THEN("the moved-from buffer is empty")
+ {
+ REQUIRE(small.empty());
+ }
}
WHEN("move assigning a buffer to itself")