aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp60
-rw-r--r--libs/kstd/kstd/ring_buffer.tests.cpp71
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)));
+ }
}
}
}