diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-09-30 16:39:57 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-09-30 16:39:57 +0200 |
| commit | ad7a0764d381ad1a5272ad6a949f4929c85fb179 (patch) | |
| tree | 4336a06cefe2907cffcd056edc166ba9ef3f409f /libs | |
| parent | 3d2b027d86ca65975c19a26968851dc50e142849 (diff) | |
| download | kernel-ad7a0764d381ad1a5272ad6a949f4929c85fb179.tar.xz kernel-ad7a0764d381ad1a5272ad6a949f4929c85fb179.zip | |
kstd: ring_buffer: implement at()
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 55 | ||||
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.tests.cpp | 29 |
2 files changed, 84 insertions, 0 deletions
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 <kstd/os/error.hpp> + +#include <array> #include <cstddef> namespace kstd @@ -13,8 +16,38 @@ namespace kstd template<typename ValueType, std::size_t Capacity> 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<pointer>(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<ring_buffer *>(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<std::byte, sizeof(value_type) * Capacity> 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 <kstd/ring_buffer.hpp> +#include <kstd/test_support/os_panic.hpp> + #include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers.hpp> +#include <catch2/matchers/catch_matchers_exception.hpp> 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<int, 5>{}; + + 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 |
