diff --git a/wpiutil/src/main/native/include/wpi/circular_buffer.h b/wpiutil/src/main/native/include/wpi/circular_buffer.h index a8eb627d693..4fee5967554 100644 --- a/wpiutil/src/main/native/include/wpi/circular_buffer.h +++ b/wpiutil/src/main/native/include/wpi/circular_buffer.h @@ -33,7 +33,7 @@ class circular_buffer { class iterator { public: - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::bidirectional_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -51,6 +51,15 @@ class circular_buffer { ++(*this); return retval; } + constexpr iterator& operator--() { + --m_index; + return *this; + } + constexpr iterator operator--(int) { + iterator retval = *this; + --(*this); + return retval; + } constexpr bool operator==(const iterator&) const = default; constexpr reference operator*() { return (*m_buffer)[m_index]; } @@ -61,7 +70,7 @@ class circular_buffer { class const_iterator { public: - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::bidirectional_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -79,6 +88,15 @@ class circular_buffer { ++(*this); return retval; } + constexpr const_iterator& operator--() { + --m_index; + return *this; + } + constexpr const_iterator operator--(int) { + const_iterator retval = *this; + --(*this); + return retval; + } constexpr bool operator==(const const_iterator&) const = default; constexpr const_reference operator*() const { return (*m_buffer)[m_index]; } @@ -87,21 +105,83 @@ class circular_buffer { size_t m_index; }; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + /** + * Returns begin iterator. + */ constexpr iterator begin() { return iterator(this, 0); } + + /** + * Returns end iterator. + */ constexpr iterator end() { return iterator(this, ::wpi::circular_buffer::size()); } + /** + * Returns const begin iterator. + */ constexpr const_iterator begin() const { return const_iterator(this, 0); } + + /** + * Returns const end iterator. + */ constexpr const_iterator end() const { return const_iterator(this, ::wpi::circular_buffer::size()); } + /** + * Returns const begin iterator. + */ constexpr const_iterator cbegin() const { return const_iterator(this, 0); } + + /** + * Returns const end iterator. + */ constexpr const_iterator cend() const { return const_iterator(this, ::wpi::circular_buffer::size()); } + /** + * Returns reverse begin iterator. + */ + constexpr reverse_iterator rbegin() { return reverse_iterator(end()); } + + /** + * Returns reverse end iterator. + */ + constexpr reverse_iterator rend() { return reverse_iterator(begin()); } + + /** + * Returns const reverse begin iterator. + */ + constexpr const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + /** + * Returns const reverse end iterator. + */ + constexpr const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + /** + * Returns const reverse begin iterator. + */ + constexpr const_reverse_iterator crbegin() const { + return const_reverse_iterator(cend()); + } + + /** + * Returns const reverse end iterator. + */ + constexpr const_reverse_iterator crend() const { + return const_reverse_iterator(cbegin()); + } + /** * Returns number of elements in buffer */ diff --git a/wpiutil/src/main/native/include/wpi/static_circular_buffer.h b/wpiutil/src/main/native/include/wpi/static_circular_buffer.h index 73817c6dbc9..133c9e3a67c 100644 --- a/wpiutil/src/main/native/include/wpi/static_circular_buffer.h +++ b/wpiutil/src/main/native/include/wpi/static_circular_buffer.h @@ -24,7 +24,7 @@ class static_circular_buffer { class iterator { public: - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::bidirectional_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -42,6 +42,15 @@ class static_circular_buffer { ++(*this); return retval; } + constexpr iterator& operator--() { + --m_index; + return *this; + } + constexpr iterator operator--(int) { + iterator retval = *this; + --(*this); + return retval; + } constexpr bool operator==(const iterator&) const = default; constexpr reference operator*() { return (*m_buffer)[m_index]; } @@ -52,7 +61,7 @@ class static_circular_buffer { class const_iterator { public: - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::bidirectional_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -70,6 +79,15 @@ class static_circular_buffer { ++(*this); return retval; } + constexpr const_iterator& operator--() { + --m_index; + return *this; + } + constexpr const_iterator operator--(int) { + const_iterator retval = *this; + --(*this); + return retval; + } constexpr bool operator==(const const_iterator&) const = default; constexpr const_reference operator*() const { return (*m_buffer)[m_index]; } @@ -78,6 +96,9 @@ class static_circular_buffer { size_t m_index; }; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + /** * Returns begin iterator. */ @@ -91,29 +112,67 @@ class static_circular_buffer { } /** - * Returns begin iterator. + * Returns const begin iterator. */ constexpr const_iterator begin() const { return const_iterator(this, 0); } /** - * Returns end iterator. + * Returns const end iterator. */ constexpr const_iterator end() const { return const_iterator(this, ::wpi::static_circular_buffer::size()); } /** - * Returns begin iterator. + * Returns const begin iterator. */ constexpr const_iterator cbegin() const { return const_iterator(this, 0); } /** - * Returns end iterator. + * Returns const end iterator. */ constexpr const_iterator cend() const { return const_iterator(this, ::wpi::static_circular_buffer::size()); } + /** + * Returns reverse begin iterator. + */ + constexpr reverse_iterator rbegin() { return reverse_iterator(end()); } + + /** + * Returns reverse end iterator. + */ + constexpr reverse_iterator rend() { return reverse_iterator(begin()); } + + /** + * Returns const reverse begin iterator. + */ + constexpr const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + /** + * Returns const reverse end iterator. + */ + constexpr const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + /** + * Returns const reverse begin iterator. + */ + constexpr const_reverse_iterator crbegin() const { + return const_reverse_iterator(cend()); + } + + /** + * Returns const reverse end iterator. + */ + constexpr const_reverse_iterator crend() const { + return const_reverse_iterator(cbegin()); + } + /** * Returns number of elements in buffer */ diff --git a/wpiutil/src/test/native/cpp/CircularBufferTest.cpp b/wpiutil/src/test/native/cpp/CircularBufferTest.cpp index a56e2e5557f..07f050d3138 100644 --- a/wpiutil/src/test/native/cpp/CircularBufferTest.cpp +++ b/wpiutil/src/test/native/cpp/CircularBufferTest.cpp @@ -251,4 +251,18 @@ TEST(CircularBufferTest, Iterator) { EXPECT_EQ(values[i], elem); ++i; } + + // reverse_iterator + i = 2; + for (auto it = queue.rbegin(); it != queue.rend(); ++it) { + EXPECT_EQ(values[i], *it); + --i; + } + + // const_reverse_iterator + i = 2; + for (auto it = queue.crbegin(); it != queue.crend(); ++it) { + EXPECT_EQ(values[i], *it); + --i; + } } diff --git a/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp b/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp index 338bd8e2391..23c7eb99d26 100644 --- a/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp +++ b/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp @@ -145,4 +145,18 @@ TEST(StaticCircularBufferTest, Iterator) { EXPECT_EQ(values[i], elem); ++i; } + + // reverse_iterator + i = 2; + for (auto it = queue.rbegin(); it != queue.rend(); ++it) { + EXPECT_EQ(values[i], *it); + --i; + } + + // const_reverse_iterator + i = 2; + for (auto it = queue.crbegin(); it != queue.crend(); ++it) { + EXPECT_EQ(values[i], *it); + --i; + } }