From ad7a0764d381ad1a5272ad6a949f4929c85fb179 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 30 Sep 2026 16:39:57 +0200 Subject: kstd: ring_buffer: implement at() --- libs/kstd/kstd/ring_buffer.hpp | 55 ++++++++++++++++++++++++++++++++++++ libs/kstd/kstd/ring_buffer.tests.cpp | 29 +++++++++++++++++++ 2 files changed, 84 insertions(+) (limited to 'libs') diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp index 0e54c070..151ab994 100644 --- a/libs/kstd/kstd/ring_buffer.hpp +++ b/libs/kstd/kstd/ring_buffer.hpp @@ -1,6 +1,9 @@ #ifndef KSTD_RING_BUFFER_HPP #define KSTD_RING_BUFFER_HPP +#include + +#include #include namespace kstd @@ -13,8 +16,38 @@ namespace kstd template struct ring_buffer { + using value_type = ValueType; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; using size_type = std::size_t; + //! @name Element Access + //! @{ + + //! Get the element at the specified index. + //! + //! @param position The zero-based index of the element to get. + //! @return A reference to the element at the given position. + [[nodiscard]] constexpr auto at(size_type position) -> reference + { + panic_on_invalid_index(position); + return *element_at_index(position); + } + + //! Get the element at the specified index. + //! + //! @param position The zero-based index of the element to get. + //! @return A reference to the element at the given position. + [[nodiscard]] constexpr auto at(size_type position) const -> const_reference + { + panic_on_invalid_index(position); + return *element_at_index(position); + } + + //! @} + //! @name Capacity //! @{ @@ -61,6 +94,28 @@ namespace kstd //! @} private: + constexpr auto element_at_index(size_type index) noexcept -> pointer + { + auto base_pointer = reinterpret_cast(m_storage.data()); + auto storage_index = (m_tail + index) % capacity(); + return base_pointer + storage_index; + } + + constexpr auto element_at_index(size_type index) const noexcept -> const_pointer + { + return const_cast(this)->element_at_index(index); + } + + constexpr auto panic_on_invalid_index(size_type index) const -> void + { + if (index >= size()) + { + os::panic("[KSTD] Index out-of-bounds in ring_buffer element access!"); + } + } + + //! The underlying storage for the elements of this ring buffer. + alignas(ValueType) std::array m_storage{}; //! The index of the element that was most recently added to this ring buffer. size_type m_head{}; //! The index of the element that was least recently added to this ring buffer. diff --git a/libs/kstd/kstd/ring_buffer.tests.cpp b/libs/kstd/kstd/ring_buffer.tests.cpp index 6e936248..86ff4b30 100644 --- a/libs/kstd/kstd/ring_buffer.tests.cpp +++ b/libs/kstd/kstd/ring_buffer.tests.cpp @@ -1,6 +1,10 @@ #include +#include + #include +#include +#include SCENARIO("Ring Buffer initialization and construction", "[ring_buffer]") { @@ -31,4 +35,29 @@ SCENARIO("Ring Buffer initialization and construction", "[ring_buffer]") } } } +} + +SCENARIO("Ring Buffer element access", "[kstd][ring_buffer]") +{ + GIVEN("An empty ring buffer") + { + auto buffer = kstd::ring_buffer{}; + + THEN("accessing element 0 panics") + { + REQUIRE_THROWS_MATCHES(buffer.at(0), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Index out-of-bounds in ring_buffer element access!")); + } + + WHEN("working through a const reference") + { + auto const & ref = buffer; + + THEN("accessing element 0 panics") + { + REQUIRE_THROWS_MATCHES(ref.at(0), kstd::tests::os_panic, + Catch::Matchers::Message("[KSTD] Index out-of-bounds in ring_buffer element access!")); + } + } + } } \ No newline at end of file -- cgit v1.2.3