From cf26fc5750ec2161317b1ad3375fd9c971590cf4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 1 Oct 2026 18:30:07 +0200 Subject: kstd: ring_buffer: implement [c]begin() --- libs/kstd/kstd/ring_buffer.hpp | 23 +++++++ libs/kstd/kstd/ring_buffer.tests.cpp | 118 ++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) 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().max_size())>); } + + THEN("the return type of begin() is `iterator`") + { + STATIC_REQUIRE(std::is_same_v().begin())>); + } + + THEN("the return type of begin() is `const_iterator` on a const buffer") + { + STATIC_REQUIRE(std::is_same_v().begin())>); + } + + THEN("the return type of cbegin() is `const_iterator`") + { + STATIC_REQUIRE(std::is_same_v().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{}; + + 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{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); + } + } + } +} -- cgit v1.2.3