Add iterators to ring_buffer
Change-Id: Id3185b94240da595925fc4878f068b673ea98dd9
diff --git a/aos/containers/ring_buffer.h b/aos/containers/ring_buffer.h
index d4cd92a..cd7872e 100644
--- a/aos/containers/ring_buffer.h
+++ b/aos/containers/ring_buffer.h
@@ -55,6 +55,74 @@
// Clears all the data out of the buffer.
void Reset() { size_ = 0; }
+ class iterator {
+ public:
+ using iterator_category = ::std::forward_iterator_tag;
+ using value_type = Data;
+ using difference_type = ::std::ptrdiff_t;
+ using pointer = Data *;
+ using reference = Data &;
+
+ explicit iterator(RingBuffer *buffer, size_t index)
+ : buffer_(buffer), index_(index) {}
+
+ iterator &operator++() {
+ ++index_;
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+ bool operator==(iterator other) const {
+ return buffer_ == other.buffer_ && index_ == other.index_;
+ }
+ bool operator!=(iterator other) const { return !(*this == other); }
+ reference operator*() const { return (*buffer_)[index_]; }
+
+ private:
+ RingBuffer *buffer_;
+ size_t index_;
+ };
+
+ class const_iterator {
+ public:
+ using iterator_category = ::std::forward_iterator_tag;
+ using value_type = Data;
+ using difference_type = ::std::ptrdiff_t;
+ using pointer = Data *;
+ using reference = Data &;
+
+ explicit const_iterator(const RingBuffer *buffer, size_t index)
+ : buffer_(buffer), index_(index) {}
+
+ const_iterator &operator++() {
+ ++index_;
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+ bool operator==(const_iterator other) const {
+ return buffer_ == other.buffer_ && index_ == other.index_;
+ }
+ bool operator!=(const_iterator other) const { return !(*this == other); }
+ const Data &operator*() const { return (*buffer_)[index_]; }
+
+ private:
+ const RingBuffer *buffer_;
+ size_t index_;
+ };
+
+ iterator begin() { return iterator(this, 0); }
+ iterator end() { return iterator(this, size()); }
+
+ const_iterator begin() const { return const_iterator(this, 0); }
+ const_iterator end() const { return const_iterator(this, size()); }
+
private:
::std::array<Data, buffer_size> data_;
diff --git a/aos/containers/ring_buffer_test.cc b/aos/containers/ring_buffer_test.cc
index 5fb2331..01e057f 100644
--- a/aos/containers/ring_buffer_test.cc
+++ b/aos/containers/ring_buffer_test.cc
@@ -118,5 +118,41 @@
}
}
+// Test that an iterator over the buffer works.
+TEST_F(RingBufferTest, Iterator) {
+ // Over fill it, and then clear it out.
+ ASSERT_TRUE(buffer_.empty());
+
+ for (int i = 0; i < 12; ++i) {
+ buffer_.Push(i);
+ }
+
+ int i = 0;
+ for (int element : buffer_) {
+ EXPECT_EQ(i + 2, element);
+ ++i;
+ }
+ EXPECT_EQ(i, buffer_.size());
+}
+
+// Test that a const iterator over the buffer works.
+TEST_F(RingBufferTest, CIterator) {
+ // Over fill it, and then clear it out.
+ ASSERT_TRUE(buffer_.empty());
+
+ for (int i = 0; i < 12; ++i) {
+ buffer_.Push(i);
+ }
+
+ const RingBuffer<int, 10> &cbuffer = buffer_;
+
+ int i = 0;
+ for (const int element : cbuffer) {
+ EXPECT_EQ(i + 2, element);
+ ++i;
+ }
+ EXPECT_EQ(i, buffer_.size());
+}
+
} // namespace testing
} // namespace aos