aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-10-01 18:30:07 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-10-01 18:30:07 +0200
commitcf26fc5750ec2161317b1ad3375fd9c971590cf4 (patch)
tree000482d76688592cded34777e74f6db777f9620b
parent6eec2dbb59294bbfd5daa3acc250bc243b12b1a1 (diff)
downloadkernel-cf26fc5750ec2161317b1ad3375fd9c971590cf4.tar.xz
kernel-cf26fc5750ec2161317b1ad3375fd9c971590cf4.zip
kstd: ring_buffer: implement [c]begin()
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp23
-rw-r--r--libs/kstd/kstd/ring_buffer.tests.cpp118
2 files changed, 140 insertions, 1 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp
index 8328655d..a848f3ce 100644
--- a/libs/kstd/kstd/ring_buffer.hpp
+++ b/libs/kstd/kstd/ring_buffer.hpp
@@ -257,6 +257,29 @@ namespace kstd
//! @}
+ //! @name Iterators
+ //! @{
+
+ //! Get an iterator to the first element.
+ [[nodiscard]] constexpr auto begin() noexcept -> iterator
+ {
+ return iterator{this, 0};
+ }
+
+ //! Get an iterator to the first element.
+ [[nodiscard]] constexpr auto begin() const noexcept -> const_iterator
+ {
+ return const_iterator{this, 0};
+ }
+
+ //! Get an iterator to the first element.
+ [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator
+ {
+ return const_iterator{this, 0};
+ }
+
+ //! @}
+
//! @name Capacity
//! @{
diff --git a/libs/kstd/kstd/ring_buffer.tests.cpp b/libs/kstd/kstd/ring_buffer.tests.cpp
index 91535e04..a3881aa6 100644
--- a/libs/kstd/kstd/ring_buffer.tests.cpp
+++ b/libs/kstd/kstd/ring_buffer.tests.cpp
@@ -106,6 +106,21 @@ SCENARIO("Ring Buffer interface types", "[kstd][ring_buffer]")
{
STATIC_REQUIRE(std::is_same_v<buffer::size_type, decltype(std::declval<buffer &>().max_size())>);
}
+
+ THEN("the return type of begin() is `iterator`")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::iterator, decltype(std::declval<buffer &>().begin())>);
+ }
+
+ THEN("the return type of begin() is `const_iterator` on a const buffer")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::const_iterator, decltype(std::declval<buffer const &>().begin())>);
+ }
+
+ THEN("the return type of cbegin() is `const_iterator`")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::const_iterator, decltype(std::declval<buffer &>().cbegin())>);
+ }
}
}
@@ -315,4 +330,105 @@ SCENARIO("Ring Buffer element access", "[kstd][ring_buffer]")
}
}
}
-} \ No newline at end of file
+}
+
+SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
+{
+ GIVEN("An empty ring buffer")
+ {
+ auto buffer = kstd::ring_buffer<int, 5>{};
+
+ THEN("begin() returns an iterator equal to std::default_sentinel")
+ {
+ REQUIRE(buffer.begin() == std::default_sentinel);
+ }
+
+ THEN("cbegin() returns an iterator equal to std::default_sentinel")
+ {
+ REQUIRE(buffer.cbegin() == std::default_sentinel);
+ }
+
+ WHEN("working through a const reference")
+ {
+ auto const & ref = buffer;
+
+ THEN("begin() returns an iterator equal to std::default_sentinel")
+ {
+ REQUIRE(ref.begin() == std::default_sentinel);
+ }
+ }
+ }
+
+ GIVEN("A ring buffer with a capacity of 5 containing 3 copies of the letter 'a'")
+ {
+ auto buffer = kstd::ring_buffer<char, 5>{3, 'a'};
+
+ THEN("begin() return an iterator that does not equal std::default_sentinel")
+ {
+ REQUIRE(buffer.begin() != std::default_sentinel);
+ }
+
+ THEN("begin() returns an iterator to the first element")
+ {
+ REQUIRE(*buffer.begin() == 'a');
+ }
+
+ THEN("cbegin() return an iterator that does not equal std::default_sentinel")
+ {
+ REQUIRE(buffer.cbegin() != std::default_sentinel);
+ }
+
+ THEN("cbegin() returns an iterator to the first element")
+ {
+ REQUIRE(*buffer.cbegin() == 'a');
+ }
+
+ THEN(
+ "incrementing the iterator returned by begin() past the end, yields an iterator equal to std::default_sentinel")
+ {
+ auto it = buffer.begin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == std::default_sentinel);
+ }
+
+ THEN("incrementing the iterator returned by cbegin() past the end, yields an iterator equal to "
+ "std::default_sentinel")
+ {
+ auto it = buffer.cbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == std::default_sentinel);
+ }
+
+ WHEN("working through a const reference")
+ {
+ auto const & ref = buffer;
+
+ THEN("begin() return an iterator that does not equal std::default_sentinel")
+ {
+ REQUIRE(ref.begin() != std::default_sentinel);
+ }
+
+ THEN("begin() returns an iterator to the first element")
+ {
+ REQUIRE(*ref.begin() == 'a');
+ }
+
+ THEN("incrementing the iterator returned by begin() past the end, yields an iterator equal to "
+ "std::default_sentinel")
+ {
+ auto it = ref.begin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == std::default_sentinel);
+ }
+ }
+ }
+}