diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-10-02 17:17:33 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-10-02 17:17:33 +0200 |
| commit | f652d85c8e5f635b67bcb57d4143568d1216cf6d (patch) | |
| tree | b39f85d80cea642138f947ea8e1dea6dc824c833 | |
| parent | caf47befa014c9f2d6a5503527198ac736db2456 (diff) | |
| download | kernel-f652d85c8e5f635b67bcb57d4143568d1216cf6d.tar.xz kernel-f652d85c8e5f635b67bcb57d4143568d1216cf6d.zip | |
kstd: ring_buffer: implement comparison
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 28 | ||||
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.tests.cpp | 127 |
2 files changed, 154 insertions, 1 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp index 10f45d72..9cd533c4 100644 --- a/libs/kstd/kstd/ring_buffer.hpp +++ b/libs/kstd/kstd/ring_buffer.hpp @@ -382,6 +382,34 @@ namespace kstd //! @} + //! @name Comparison + //! @{ + + //! Lexicographically compare two ring buffers. + //! + //! @param lhs The left-hand side ring buffer to compare. + //! @param rhs The right-hand side ring buffer to compare. + //! @return A value indicating the lexicographical comparison result. + constexpr auto friend operator<=>(ring_buffer const & lhs, ring_buffer const & rhs) noexcept + { + auto const lhs_common = lhs | std::views::common; + auto const rhs_common = rhs | std::views::common; + return std::lexicographical_compare_three_way(std::ranges::begin(lhs_common), std::ranges::end(lhs_common), + std::ranges::begin(rhs_common), std::ranges::end(rhs_common)); + } + + //! Check if two ring buffers are equal. + //! + //! @param lhs The left-hand side ring buffer to compare. + //! @param rhs The right-hand side ring buffer to compare. + //! @return `true` if the ring buffers are equal, `false` otherwise. + constexpr auto friend operator==(ring_buffer const & lhs, ring_buffer const & rhs) noexcept -> bool + { + return std::ranges::equal(lhs, rhs); + } + + //! @} + //! @name Element Access //! @{ diff --git a/libs/kstd/kstd/ring_buffer.tests.cpp b/libs/kstd/kstd/ring_buffer.tests.cpp index 453713ee..3476179e 100644 --- a/libs/kstd/kstd/ring_buffer.tests.cpp +++ b/libs/kstd/kstd/ring_buffer.tests.cpp @@ -222,6 +222,17 @@ SCENARIO("Ring Buffer interface types", "[kstd][ring_buffer]") { STATIC_REQUIRE(std::is_same_v<buffer::const_reference, decltype(std::declval<buffer const &>().back())>); } + + THEN("the return type of operator== is `bool`") + { + STATIC_REQUIRE(std::is_same_v<bool, decltype(std::declval<buffer const &>() == std::declval<buffer const &>())>); + } + + THEN("the return type of operator<=> is the same as for the value_type") + { + STATIC_REQUIRE(std::is_same_v<decltype(std::declval<buffer::value_type>() <=> std::declval<buffer::value_type>()), + decltype(std::declval<buffer const &>() <=> std::declval<buffer const &>())>); + } } } @@ -1618,7 +1629,7 @@ SCENARIO("Ring Buffer modifiers", "[kstd][ring_buffer]") } } -SCENARIO("Ring Buffer zero capacity", "[kstd][rin_buffer]") +SCENARIO("Ring Buffer zero capacity", "[kstd][ring_buffer]") { GIVEN("A ring buffer with a capacity of 0") { @@ -1830,4 +1841,118 @@ SCENARIO("Ring Buffer zero capacity", "[kstd][rin_buffer]") } } } +} + +SCENARIO("Ring Buffer comparison", "[kstd][ring_buffer]") +{ + GIVEN("Two ring buffers with the same content, constructed the same way") + { + auto lhs = kstd::ring_buffer<int, 5>{3, 1}; + auto rhs = kstd::ring_buffer<int, 5>{3, 1}; + + THEN("they compare equal") + { + REQUIRE(lhs == rhs); + } + + THEN("neither is less than the other") + { + REQUIRE_FALSE(lhs < rhs); + REQUIRE_FALSE(rhs < lhs); + } + + THEN("they are equivalent under <=>") + { + REQUIRE((lhs <=> rhs) == 0); + } + } + + GIVEN("A ring buffer compares equal to itself") + { + auto buffer = kstd::ring_buffer<int, 5>{3, 1}; + + THEN("it compares equal to itself") + { + REQUIRE(buffer == buffer); + } + } + + GIVEN("Two empty ring buffers") + { + auto lhs = kstd::ring_buffer<int, 5>{}; + auto rhs = kstd::ring_buffer<int, 5>{}; + + THEN("they compare equal") + { + REQUIRE(lhs == rhs); + } + } + + GIVEN("Two ring buffers with different content") + { + auto smaller = kstd::ring_buffer<int, 5>{3, 1}; + auto larger = kstd::ring_buffer<int, 5>{3, 2}; + + THEN("they do not compare equal") + { + REQUIRE_FALSE(smaller == larger); + } + + THEN("the one with the smaller elements orders first") + { + REQUIRE(smaller < larger); + REQUIRE_FALSE(larger < smaller); + } + } + + GIVEN("Two ring buffers holding the same elements with different sizes") + { + auto shorter = kstd::ring_buffer<int, 5>{2, 1}; + auto longer = kstd::ring_buffer<int, 5>{3, 1}; + + THEN("they do not compare equal") + { + REQUIRE_FALSE(shorter == longer); + } + + THEN("the shorter buffer, being a prefix of the longer one, orders first") + { + REQUIRE(shorter < longer); + } + } + + GIVEN("Two ring buffers with the same logical content but different physical layouts") + { + auto wrapped = kstd::ring_buffer<int, 3>{}; + wrapped.push_back(1); + wrapped.push_back(2); + wrapped.push_back(3); + wrapped.push_back(4); + + auto fresh = kstd::ring_buffer<int, 3>{}; + fresh.push_back(2); + fresh.push_back(3); + fresh.push_back(4); + + THEN("they compare equal despite differing internal layouts") + { + REQUIRE(wrapped == fresh); + } + + THEN("they are equivalent under <=>") + { + REQUIRE((wrapped <=> fresh) == 0); + } + } + + GIVEN("Two zero-capacity ring buffers") + { + auto lhs = kstd::ring_buffer<int, 0>{}; + auto rhs = kstd::ring_buffer<int, 0>{}; + + THEN("they compare equal") + { + REQUIRE(lhs == rhs); + } + } }
\ No newline at end of file |
