diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-10-01 18:30:07 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-10-01 18:30:07 +0200 |
| commit | cf26fc5750ec2161317b1ad3375fd9c971590cf4 (patch) | |
| tree | 000482d76688592cded34777e74f6db777f9620b | |
| parent | 6eec2dbb59294bbfd5daa3acc250bc243b12b1a1 (diff) | |
| download | kernel-cf26fc5750ec2161317b1ad3375fd9c971590cf4.tar.xz kernel-cf26fc5750ec2161317b1ad3375fd9c971590cf4.zip | |
kstd: ring_buffer: implement [c]begin()
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 23 | ||||
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.tests.cpp | 118 |
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); + } + } + } +} |
