From 8d99ee9a5bd353dc0d07f8e1c5638323f3043e84 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Mon, 18 Aug 2025 12:51:50 -0400 Subject: [PATCH] Implement std::random_access_iterator_tag --- src/ThreadPipeline.h | 54 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/ThreadPipeline.h b/src/ThreadPipeline.h index e6c6874..e473785 100644 --- a/src/ThreadPipeline.h +++ b/src/ThreadPipeline.h @@ -78,8 +78,7 @@ template struct ThreadPipeline { Batch() : ring(), begin_(), end_() {} struct Iterator { - // TODO implement random_iterator_tag - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::random_access_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = T; using pointer = value_type *; @@ -100,6 +99,40 @@ template struct ThreadPipeline { ++(*this); return tmp; } + Iterator &operator--() { + --index; + return *this; + } + Iterator operator--(int) { + auto tmp = *this; + --(*this); + return tmp; + } + Iterator &operator+=(difference_type n) { + index += n; + return *this; + } + Iterator &operator-=(difference_type n) { + index -= n; + return *this; + } + Iterator operator+(difference_type n) const { + return Iterator(index + n, ring); + } + Iterator operator-(difference_type n) const { + return Iterator(index - n, ring); + } + difference_type operator-(const Iterator &rhs) const { + assert(ring == rhs.ring); + return static_cast(index) - + static_cast(rhs.index); + } + reference operator[](difference_type n) const { + return (*ring)[(index + n) & (ring->size() - 1)]; + } + friend Iterator operator+(difference_type n, const Iterator &iter) { + return iter + n; + } friend bool operator==(const Iterator &lhs, const Iterator &rhs) { assert(lhs.ring == rhs.ring); return lhs.index == rhs.index; @@ -108,6 +141,23 @@ template struct ThreadPipeline { assert(lhs.ring == rhs.ring); return lhs.index != rhs.index; } + friend bool operator<(const Iterator &lhs, const Iterator &rhs) { + assert(lhs.ring == rhs.ring); + // Handle potential uint32_t wraparound by using signed difference + return static_cast(lhs.index - rhs.index) < 0; + } + friend bool operator<=(const Iterator &lhs, const Iterator &rhs) { + assert(lhs.ring == rhs.ring); + return static_cast(lhs.index - rhs.index) <= 0; + } + friend bool operator>(const Iterator &lhs, const Iterator &rhs) { + assert(lhs.ring == rhs.ring); + return static_cast(lhs.index - rhs.index) > 0; + } + friend bool operator>=(const Iterator &lhs, const Iterator &rhs) { + assert(lhs.ring == rhs.ring); + return static_cast(lhs.index - rhs.index) >= 0; + } private: Iterator(uint32_t index, std::vector *const ring)