aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-10-01 21:48:21 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-10-01 21:48:21 +0200
commit22c50a96dfb66d1503bccb9a4fc480507dc237c0 (patch)
tree9b84689901aab69eccad06bc70aeb6e5a86faaac
parent966f2a709f6aa4a022c7c13900f97c083ee8a92a (diff)
downloadkernel-22c50a96dfb66d1503bccb9a4fc480507dc237c0.tar.xz
kernel-22c50a96dfb66d1503bccb9a4fc480507dc237c0.zip
kstd: ring_buffer: implement [cr][begin|end]()
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp36
-rw-r--r--libs/kstd/kstd/ring_buffer.tests.cpp144
2 files changed, 180 insertions, 0 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp
index 48f4da0d..b015755d 100644
--- a/libs/kstd/kstd/ring_buffer.hpp
+++ b/libs/kstd/kstd/ring_buffer.hpp
@@ -296,6 +296,42 @@ namespace kstd
return std::default_sentinel;
}
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto rbegin() noexcept -> reverse_iterator
+ {
+ return std::make_reverse_iterator(iterator{this, m_size});
+ }
+
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto rbegin() const noexcept -> const_reverse_iterator
+ {
+ return std::make_reverse_iterator(const_iterator{this, m_size});
+ }
+
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator
+ {
+ return std::make_reverse_iterator(const_iterator{this, m_size});
+ }
+
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto rend() noexcept -> reverse_iterator
+ {
+ return std::make_reverse_iterator(iterator{this, 0});
+ }
+
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto rend() const noexcept -> const_reverse_iterator
+ {
+ return std::make_reverse_iterator(const_iterator{this, 0});
+ }
+
+ //! Get a reverse iterator to the first element.
+ [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator
+ {
+ return std::make_reverse_iterator(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 bff8f804..84adba91 100644
--- a/libs/kstd/kstd/ring_buffer.tests.cpp
+++ b/libs/kstd/kstd/ring_buffer.tests.cpp
@@ -136,6 +136,21 @@ SCENARIO("Ring Buffer interface types", "[kstd][ring_buffer]")
{
STATIC_REQUIRE(std::is_same_v<std::default_sentinel_t, decltype(std::declval<buffer &>().cend())>);
}
+
+ THEN("the return type of rbegin() is `reverse_iterator`")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::reverse_iterator, decltype(std::declval<buffer &>().rbegin())>);
+ }
+
+ THEN("the return type of rbegin() is `const_reverse_iterator` on a const buffer")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::const_reverse_iterator, decltype(std::declval<buffer const &>().rbegin())>);
+ }
+
+ THEN("the return type of crbegin() is `const_reverse_iterator`")
+ {
+ STATIC_REQUIRE(std::is_same_v<buffer::const_reverse_iterator, decltype(std::declval<buffer &>().crbegin())>);
+ }
}
}
@@ -418,6 +433,36 @@ SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
REQUIRE(std::ranges::distance(buffer) == 0);
}
+ THEN("rbegin() returns an iterator equal to rend()")
+ {
+ REQUIRE(buffer.rbegin() == buffer.rend());
+ }
+
+ THEN("rbegin() returns an iterator equal to crend()")
+ {
+ REQUIRE(buffer.rbegin() == buffer.crend());
+ }
+
+ THEN("crbegin() returns an iterator equal to rend()")
+ {
+ REQUIRE(buffer.crbegin() == buffer.rend());
+ }
+
+ THEN("crbegin() returns an iterator equal to crend()")
+ {
+ REQUIRE(buffer.crbegin() == buffer.crend());
+ }
+
+ THEN("the distance between rbegin() and rend() is 0")
+ {
+ REQUIRE(std::ranges::distance(buffer.rbegin(), buffer.rend()) == 0);
+ }
+
+ THEN("the distance between crbegin() and crend() is 0")
+ {
+ REQUIRE(std::ranges::distance(buffer.crbegin(), buffer.crend()) == 0);
+ }
+
WHEN("working through a const reference")
{
auto const & ref = buffer;
@@ -441,6 +486,16 @@ SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
{
REQUIRE(std::ranges::distance(buffer) == 0);
}
+
+ THEN("rbegin() returns an iterator equal to rend()")
+ {
+ REQUIRE(buffer.rbegin() == buffer.rend());
+ }
+
+ THEN("the distance between rbegin() and rend() is 0")
+ {
+ REQUIRE(std::ranges::distance(buffer.rbegin(), buffer.rend()) == 0);
+ }
}
}
@@ -503,6 +558,46 @@ SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
REQUIRE(*buffer.cbegin() == 'a');
}
+ THEN("rbegin() returns an iterator that does not equal rend()")
+ {
+ REQUIRE(buffer.rbegin() != buffer.rend());
+ }
+
+ THEN("rbegin() returns an iterator that does not equal crend()")
+ {
+ REQUIRE(buffer.rbegin() != buffer.crend());
+ }
+
+ THEN("the distance between rbegin() and rend() is 3")
+ {
+ REQUIRE(std::ranges::distance(buffer.rbegin(), buffer.rend()) == 3);
+ }
+
+ THEN("the distance between crbegin() and crend() is 3")
+ {
+ REQUIRE(std::ranges::distance(buffer.crbegin(), buffer.crend()) == 3);
+ }
+
+ THEN("rbegin() returns an iterator to the first element")
+ {
+ REQUIRE(*buffer.rbegin() == 'a');
+ }
+
+ THEN("crbegin() returns an iterator that does not equal rend()")
+ {
+ REQUIRE(buffer.crbegin() != buffer.rend());
+ }
+
+ THEN("crbegin() returns an iterator that does not equal crend()")
+ {
+ REQUIRE(buffer.crbegin() != buffer.crend());
+ }
+
+ THEN("crbegin() returns an iterator to the first element")
+ {
+ REQUIRE(*buffer.crbegin() == 'a');
+ }
+
THEN(
"incrementing the iterator returned by begin() past the end, yields an iterator equal to std::default_sentinel")
{
@@ -565,6 +660,45 @@ SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
REQUIRE(it == buffer.cend());
}
+ THEN("incrementing the iterator returned by rbegin() past the end, yields an iterator equal to rend()")
+ {
+ auto it = buffer.rbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == buffer.rend());
+ }
+
+ THEN("incrementing the iterator returned by rbegin() past the end, yields an iterator equal to crend()")
+ {
+ auto it = buffer.rbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == buffer.crend());
+ }
+
+ THEN("incrementing the iterator returned by crbegin() past the end, yields an iterator equal to rend()")
+ {
+ auto it = buffer.crbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == buffer.rend());
+ }
+
+ THEN("incrementing the iterator returned by crbegin() past the end, yields an iterator equal to crend()")
+ {
+ auto it = buffer.crbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == buffer.crend());
+ }
WHEN("working through a const reference")
{
auto const & ref = buffer;
@@ -614,6 +748,16 @@ SCENARIO("Ring Buffer iterators", "[kstd][ring_buffer]")
REQUIRE(it == ref.end());
}
+
+ THEN("incrementing the iterator returned by rbegin() past the end, yields an iterator equal to rend()")
+ {
+ auto it = ref.rbegin();
+ ++it;
+ ++it;
+ ++it;
+
+ REQUIRE(it == ref.rend());
+ }
}
}
}