diff options
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 84 |
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{}; }; |
