diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-10-02 15:21:54 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-10-02 15:21:54 +0200 |
| commit | a564a638466f52eba8f4bff04259d77be695217a (patch) | |
| tree | e7c51c175500d0ff00ea9e3f6b742911d0cc7bcb | |
| parent | d7d4e918e7a2ef893dff836554893dab6c833cc5 (diff) | |
| download | kernel-a564a638466f52eba8f4bff04259d77be695217a.tar.xz kernel-a564a638466f52eba8f4bff04259d77be695217a.zip | |
kstd: ring_buffer: implement front() and back()
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 60 | ||||
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.tests.cpp | 71 |
2 files changed, 131 insertions, 0 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp index 34f8a2d8..eec998e6 100644 --- a/libs/kstd/kstd/ring_buffer.hpp +++ b/libs/kstd/kstd/ring_buffer.hpp @@ -347,6 +347,66 @@ namespace kstd return *element_at(position); } + //! Get the first element in the buffer. + //! + //! @warning This function will panic if the buffer is empty. + //! + //! @return A reference to the first element in the buffer. + [[nodiscard]] constexpr auto front() -> reference + { + if (empty()) + { + os::panic("[KSTD] Tried to access an element from an empty ring_buffer!"); + } + + return *element_at(0); + } + + //! Get the first element in the buffer. + //! + //! @warning This function will panic if the buffer is empty. + //! + //! @return A reference to the first element in the buffer. + [[nodiscard]] constexpr auto front() const -> const_reference + { + if (empty()) + { + os::panic("[KSTD] Tried to access an element from an empty ring_buffer!"); + } + + return *element_at(0); + } + + //! Get the last element in the buffer. + //! + //! @warning This function will panic if the buffer is empty. + //! + //! @return A reference to the last element in the buffer. + [[nodiscard]] constexpr auto back() -> reference + { + if (empty()) + { + os::panic("[KSTD] Tried to access an element from an empty ring_buffer!"); + } + + return *element_at(m_size - 1); + } + + //! Get the last element in the buffer. + //! + //! @warning This function will panic if the buffer is empty. + //! + //! @return A reference to the last element in the buffer. + [[nodiscard]] constexpr auto back() const -> const_reference + { + if (empty()) + { + os::panic("[KSTD] Tried to access an element from an empty ring_buffer!"); + } + + return *element_at(m_size - 1); + } + //! @} //! @name Iterators diff --git a/libs/kstd/kstd/ring_buffer.tests.cpp b/libs/kstd/kstd/ring_buffer.tests.cpp index bd14223f..12a88e8f 100644 --- a/libs/kstd/kstd/ring_buffer.tests.cpp +++ b/libs/kstd/kstd/ring_buffer.tests.cpp @@ -192,6 +192,26 @@ SCENARIO("Ring Buffer interface types", "[kstd][ring_buffer]") { STATIC_REQUIRE(std::is_same_v<bool, decltype(std::declval<buffer &>().try_pop_front())>); } + + THEN("the return type of front() is `reference`") + { + STATIC_REQUIRE(std::is_same_v<buffer::reference, decltype(std::declval<buffer &>().front())>); + } + + THEN("the return type of front() is `const_reference` on a const buffer") + { + STATIC_REQUIRE(std::is_same_v<buffer::const_reference, decltype(std::declval<buffer const &>().front())>); + } + + THEN("the return type of back() is `reference`") + { + STATIC_REQUIRE(std::is_same_v<buffer::reference, decltype(std::declval<buffer &>().back())>); + } + + THEN("the return type of back() is `const_reference` on a const buffer") + { + STATIC_REQUIRE(std::is_same_v<buffer::const_reference, decltype(std::declval<buffer const &>().back())>); + } } } @@ -574,6 +594,37 @@ SCENARIO("Ring Buffer element access", "[kstd][ring_buffer]") Catch::Matchers::Message("[KSTD] Index out-of-bounds in ring_buffer element access!")); } } + + THEN("calling front() panics") + { + REQUIRE_THROWS_MATCHES(buffer.front(), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Tried to access an element from an empty ring_buffer!")); + } + + THEN("calling back() panics") + { + REQUIRE_THROWS_MATCHES(buffer.back(), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Tried to access an element from an empty ring_buffer!")); + } + + WHEN("working through a const reference") + { + auto const & ref = buffer; + + THEN("calling front() panics") + { + REQUIRE_THROWS_MATCHES( + ref.front(), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Tried to access an element from an empty ring_buffer!")); + } + + THEN("calling back() panics") + { + REQUIRE_THROWS_MATCHES( + ref.back(), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Tried to access an element from an empty ring_buffer!")); + } + } } GIVEN("A ring buffer with a capacity of 5 containing 3 copies of the letter 'a'") @@ -632,6 +683,16 @@ SCENARIO("Ring Buffer element access", "[kstd][ring_buffer]") } } + THEN("calling front() returns the same object as at(0)") + { + REQUIRE(std::addressof(buffer.front()) == std::addressof(buffer.at(0))); + } + + THEN("calling back() returns the same object as at(size() - 1)") + { + REQUIRE(std::addressof(buffer.back()) == std::addressof(buffer.at(buffer.size() - 1))); + } + WHEN("working through a const reference") { auto const & ref = buffer; @@ -655,6 +716,16 @@ SCENARIO("Ring Buffer element access", "[kstd][ring_buffer]") REQUIRE(ref[1] == 'a'); REQUIRE(ref[2] == 'a'); } + + THEN("calling front() returns the same object as at(0)") + { + REQUIRE(std::addressof(ref.front()) == std::addressof(ref.at(0))); + } + + THEN("calling back() returns the same object as at(size() - 1)") + { + REQUIRE(std::addressof(ref.back()) == std::addressof(ref.at(ref.size() - 1))); + } } } } |
