aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp
index eec998e6..ce737a81 100644
--- a/libs/kstd/kstd/ring_buffer.hpp
+++ b/libs/kstd/kstd/ring_buffer.hpp
@@ -38,6 +38,9 @@ namespace kstd
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ //! An iterator type for ring buffers.
+ //!
+ //! @tparam Const Whether this iterator is a const iterator.
template<bool Const>
struct ring_buffer_iterator
{
@@ -48,16 +51,29 @@ namespace kstd
using pointer = std::conditional_t<Const, ring_buffer::const_pointer, ring_buffer::pointer>;
using reference = std::conditional_t<Const, ring_buffer::const_reference, ring_buffer::reference>;
+ //! Create an empty iterator, pointing to nothing.
constexpr ring_buffer_iterator() = default;
+ //! Create a new iterator by copying an existing one.
constexpr ring_buffer_iterator(ring_buffer_iterator const &) = default;
+ //! Create a new const iterator from a non-const iterator.
+ //!
+ //! @note This constructor only participates in overload resolution if `Const` is `true`.
+ //!
+ //! @param it The non-const iterator to convert to a const iterator.
constexpr ring_buffer_iterator(ring_buffer_iterator<!Const> it)
requires Const
: m_buffer{it.m_buffer}
, m_index{it.m_index}
{}
+ //! Lexicographically compare two iterators.
+ //!
+ //! @tparam OtherConst Whether the other iterator is a const iterator.
+ //! @param lhs The left-hand side iterator.
+ //! @param rhs The right-hand side iterator.
+ //! @return A `std::strong_ordering` indicating the relative order of the iterators.
template<bool OtherConst>
[[nodiscard]] constexpr auto friend operator<=>(ring_buffer_iterator const & lhs,
ring_buffer_iterator<OtherConst> const & rhs) noexcept
@@ -66,6 +82,12 @@ namespace kstd
return lhs.m_index <=> rhs.m_index;
}
+ //! Check if two iterators are equal.
+ //!
+ //! @tparam OtherConst Whether the other iterator is a const iterator.
+ //! @param lhs The left-hand side iterator.
+ //! @param rhs The right-hand side iterator.
+ //! @return @p true iff. the iterators are equal, @p false otherwise.
template<bool OtherConst>
[[nodiscard]] constexpr auto friend operator==(ring_buffer_iterator const & lhs,
ring_buffer_iterator<OtherConst> const & rhs) noexcept -> bool
@@ -73,12 +95,22 @@ namespace kstd
return lhs.m_buffer == rhs.m_buffer && lhs.m_index == rhs.m_index;
}
+ //! Check if an iterator is equal to the end sentinel.
+ //!
+ //! @param lhs The iterator.
+ //! @param rhs The end sentinel.
+ //! @return @p true iff. the iterator is at the end, @p false otherwise.
[[nodiscard]] constexpr auto friend operator==(ring_buffer_iterator const & lhs, std::default_sentinel_t) noexcept
-> bool
{
return lhs.m_buffer == nullptr || lhs.m_index >= lhs.m_buffer->size();
}
+ //! Compute the distance between two iterators.
+ //!
+ //! @tparam OtherConst Whether the other iterator is a const iterator.
+ //! @param other The other iterator.
+ //! @return The number of elements between this iterator and the other iterator.
template<bool OtherConst>
[[nodiscard]] constexpr auto operator-(ring_buffer_iterator<OtherConst> const & other) const noexcept
-> difference_type
@@ -86,42 +118,71 @@ namespace kstd
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
}
+ //! Advance the iterator by a given offset.
+ //!
+ //! @param offset The number of positions to advance the iterator.
+ //! @return A reference to the advanced iterator.
constexpr auto operator+=(difference_type offset) noexcept -> ring_buffer_iterator &
{
m_index += offset;
return *this;
}
+ //! Create a new iterator by adding an offset to this iterator.
+ //!
+ //! @param it The iterator to advance.
+ //! @param offset The number of positions to advance the iterator.
+ //! @return A new iterator advanced by the given offset.
[[nodiscard]] constexpr auto friend operator+(ring_buffer_iterator it, difference_type offset) noexcept
-> ring_buffer_iterator
{
return it += offset;
}
+ //! Create a new iterator by adding an offset to this iterator.
+ //!
+ //! @param offset The number of positions to advance the iterator.
+ //! @param it The iterator to advance.
+ //! @return A new iterator advanced by the given offset.
[[nodiscard]] constexpr auto friend operator+(difference_type offset, ring_buffer_iterator it) noexcept
-> ring_buffer_iterator
{
return it += offset;
}
+ //! Move the iterator backward by a given offset.
+ //!
+ //! @param offset The number of positions to move the iterator backward.
+ //! @return A reference to the moved iterator.
constexpr auto operator-=(difference_type offset) noexcept -> ring_buffer_iterator &
{
m_index -= offset;
return *this;
}
+ //! Create a new iterator by subtracting an offset from this iterator.
+ //!
+ //! @param it The iterator to move backward.
+ //! @param offset The number of positions to move the iterator backward.
+ //! @return A new iterator moved backward by the given offset.
[[nodiscard]] constexpr auto friend operator-(ring_buffer_iterator it, difference_type offset) noexcept
-> ring_buffer_iterator
{
return it -= offset;
}
+ //! Move the iterator forward by one position.
+ //!
+ //! @return A reference to the advanced iterator.
constexpr auto operator++() noexcept -> ring_buffer_iterator &
{
++m_index;
return *this;
}
+ //! Move the iterator forward by one position.
+ //!
+ //! @return A copy of the iterator before it was advanced.
constexpr auto operator++(int) noexcept -> ring_buffer_iterator
{
auto copy = *this;
@@ -129,12 +190,18 @@ namespace kstd
return copy;
}
+ //! Move the iterator backward by one position.
+ //!
+ //! @return A reference to the moved iterator.
constexpr auto operator--() noexcept -> ring_buffer_iterator &
{
--m_index;
return *this;
}
+ //! Move the iterator backward by one position.
+ //!
+ //! @return A copy of the iterator before it was moved.
constexpr auto operator--(int) noexcept -> ring_buffer_iterator
{
auto copy = *this;
@@ -142,16 +209,26 @@ namespace kstd
return copy;
}
+ //! Access an element at a given offset from the current iterator position.
+ //!
+ //! @param offset The offset from the current iterator position.
+ //! @return A reference to the element at the given offset.
[[nodiscard]] constexpr auto operator[](difference_type offset) const noexcept -> reference
{
return (*m_buffer)[m_index + static_cast<size_type>(offset)];
}
+ //! Access the element at the current iterator position.
+ //!
+ //! @return A reference to the element at the current iterator position.
[[nodiscard]] constexpr auto operator*() const noexcept -> reference
{
return *m_buffer->element_at(m_index);
}
+ //! Access the pointer to the element at the current iterator position.
+ //!
+ //! @return A pointer to the element at the current iterator position.
[[nodiscard]] constexpr auto operator->() const noexcept -> pointer
{
return m_buffer->element_at(m_index);
@@ -161,14 +238,21 @@ namespace kstd
friend struct ring_buffer;
friend struct ring_buffer_iterator<!Const>;
+ //! The type of the referenced buffer.
using buffer_type = std::conditional_t<Const, ring_buffer const, ring_buffer>;
+ //! Construct an iterator for the given buffer and index.
+ //!
+ //! @param buffer The buffer to reference.
+ //! @param index The index within the buffer.
constexpr ring_buffer_iterator(buffer_type * buffer, size_type index)
: m_buffer{buffer}
, m_index{index}
{}
+ //! The buffer being referenced by this iterator.
buffer_type * m_buffer{};
+ //! The current index within the referenced buffer.
size_type m_index{};
};