Fix up the AOS RingBuffer to not default construct and iterate better
This lets us put more complicated objects in it.
Change-Id: I19ef2e1934c30e5f10ecdac9d9e8af03282c97aa
diff --git a/aos/containers/ring_buffer_test.cc b/aos/containers/ring_buffer_test.cc
index 01e057f..b4cf1fb 100644
--- a/aos/containers/ring_buffer_test.cc
+++ b/aos/containers/ring_buffer_test.cc
@@ -1,16 +1,70 @@
#include "aos/containers/ring_buffer.h"
+#include "glog/logging.h"
#include "gtest/gtest.h"
namespace aos {
namespace testing {
+// A class which is implicitly convertible to and from int, and tracks object
+// lifetimes.
+struct TrackedInt {
+ enum class State { kNoValue, kAlive, kDestroyed };
+
+ static int instance_count;
+ int value;
+ State state;
+
+ TrackedInt(int new_value) : value(new_value), state(State::kAlive) {
+ ++instance_count;
+ }
+
+ TrackedInt(const TrackedInt &other) = delete;
+ TrackedInt(TrackedInt &&other) : value(other.value), state(other.state) {
+ CHECK(other.state != State::kDestroyed);
+ other.state = State::kNoValue;
+ ++instance_count;
+ }
+ ~TrackedInt() {
+ CHECK(state != State::kDestroyed);
+ state = State::kDestroyed;
+ --instance_count;
+ CHECK_GE(instance_count, 0);
+ }
+ TrackedInt &operator=(const TrackedInt &other) = delete;
+ TrackedInt &operator=(TrackedInt &&other) {
+ CHECK(state != State::kDestroyed);
+ CHECK(other.state != State::kDestroyed);
+ state = other.state;
+ other.state = State::kNoValue;
+ value = other.value;
+ return *this;
+ }
+
+ operator int() const {
+ CHECK(state == State::kAlive);
+ return value;
+ }
+};
+
+int TrackedInt::instance_count;
+
+struct TrackedIntTracker {
+ TrackedIntTracker() {
+ CHECK_EQ(0, TrackedInt::instance_count) << ": Instances alive before test";
+ }
+ ~TrackedIntTracker() {
+ CHECK_EQ(0, TrackedInt::instance_count) << ": Instances alive after test";
+ }
+};
+
class RingBufferTest : public ::testing::Test {
public:
RingBufferTest() {}
protected:
- RingBuffer<int, 10> buffer_;
+ TrackedIntTracker tracked_int_tracker_;
+ RingBuffer<TrackedInt, 10> buffer_;
};
// Test if the RingBuffer is empty when initialized properly
@@ -37,9 +91,8 @@
buffer_.Push(i);
// The buffer shouldn't be empty and it's size should be 1 more since we
- // just
- // added an item. Also, the last item in the buffer should equal the one we
- // just added
+ // just added an item. Also, the last item in the buffer should equal the
+ // one we just added
ASSERT_FALSE(buffer_.empty());
ASSERT_EQ(i + 1, buffer_.size());
ASSERT_EQ(i, buffer_[i]);
@@ -60,8 +113,7 @@
ASSERT_TRUE(buffer_.full());
// Since the buffer is a size of 10 and has been filled up 2.5 times, it
- // should
- // now contain the numbers 15-24
+ // should now contain the numbers 15-24
for (size_t i = 0; i < buffer_.size(); ++i) {
ASSERT_EQ(15 + i, buffer_[i]);
}
@@ -144,7 +196,7 @@
buffer_.Push(i);
}
- const RingBuffer<int, 10> &cbuffer = buffer_;
+ const RingBuffer<TrackedInt, 10> &cbuffer = buffer_;
int i = 0;
for (const int element : cbuffer) {