diff --git a/include/etl/circular_buffer.h b/include/etl/circular_buffer.h index 03ce5162..2544dd33 100644 --- a/include/etl/circular_buffer.h +++ b/include/etl/circular_buffer.h @@ -99,6 +99,12 @@ namespace etl return (in + 1U) % BUFFER_SIZE == out; } + //************************************************************************* + size_type available() const + { + return max_size() - size(); + } + //************************************************************************* size_type max_size() const { @@ -154,7 +160,7 @@ namespace etl public: friend class icircular_buffer; - + //************************************************************************* /// Constructor //************************************************************************* @@ -187,7 +193,7 @@ namespace etl //************************************************************************* /// * operator //************************************************************************* - T& operator *() + reference operator *() { return picb->pbuffer[current]; } @@ -195,7 +201,7 @@ namespace etl //************************************************************************* /// * operator //************************************************************************* - const T& operator *() const + const_reference operator *() const { return picb->pbuffer[current]; } @@ -203,7 +209,7 @@ namespace etl //************************************************************************* /// -> operator //************************************************************************* - T* operator ->() + pointer operator ->() { return picb->pbuffer[current]; } @@ -211,7 +217,7 @@ namespace etl //************************************************************************* /// -> operator //************************************************************************* - const T* operator ->() const + const_pointer operator ->() const { return picb->pbuffer[current]; } @@ -476,7 +482,7 @@ namespace etl //************************************************************************* /// * operator //************************************************************************* - const T& operator *() const + const_reference operator *() const { return picb->pbuffer[current]; } @@ -484,7 +490,7 @@ namespace etl //************************************************************************* /// -> operator //************************************************************************* - const T* operator ->() const + const_pointer operator ->() const { return picb->pbuffer[current]; } @@ -553,7 +559,7 @@ namespace etl const_iterator& operator +=(int n) { n = picb->BUFFER_SIZE + n; - + current += n; current %= picb->BUFFER_SIZE; @@ -821,6 +827,23 @@ namespace etl return pbuffer[in == 0U ? BUFFER_SIZE - 1 : in - 1U]; } + //************************************************************************* + /// Get a reference to the item. + //************************************************************************* + reference operator [](int index) + { + return pbuffer[(out + index) % BUFFER_SIZE]; + } + + //************************************************************************* + /// Get a const reference to the item at the back of the buffer. + /// Asserts an error if the buffer is empty. + //************************************************************************* + const_reference operator [](int index) const + { + return pbuffer[(out + index) % BUFFER_SIZE]; + } + //************************************************************************* /// push. /// Adds an item to the buffer. @@ -834,7 +857,7 @@ namespace etl // Did we catch up with the 'out' index? if (in == out) { - // Forget about the oldest one. + // Forget about the oldest one. pbuffer[out].~T(); out = (out + 1U) % BUFFER_SIZE; } @@ -1229,7 +1252,7 @@ namespace etl { if (this != &other) { - for (const_iterator itr = other.begin(); itr != other.end(); ++itr) + for (typename etl::icircular_buffer::iterator itr = other.begin(); itr != other.end(); ++itr) { this->push(etl::move(*itr)); } @@ -1299,4 +1322,4 @@ namespace etl #undef ETL_FILE -#endif \ No newline at end of file +#endif diff --git a/test/.kdev4/test.kdev4 b/test/.kdev4/test.kdev4 new file mode 100644 index 00000000..64b8fed2 --- /dev/null +++ b/test/.kdev4/test.kdev4 @@ -0,0 +1,2 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x08\x00t\x00e\x00s\x00t) diff --git a/test/test_circular_buffer.cpp b/test/test_circular_buffer.cpp index c33fdc7c..4fb28b36 100644 --- a/test/test_circular_buffer.cpp +++ b/test/test_circular_buffer.cpp @@ -60,6 +60,7 @@ namespace CHECK_EQUAL(0U, data.size()); CHECK_EQUAL(SIZE, data.max_size()); CHECK_EQUAL(SIZE, data.capacity()); + CHECK_EQUAL(SIZE, data.available()); CHECK(data.begin() == data.end()); CHECK(data.cbegin() == data.cend()); CHECK(data.rbegin() == data.rend()); @@ -142,6 +143,7 @@ namespace CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(SIZE - data.size(), data.available()); bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); CHECK(isEqual); @@ -385,6 +387,35 @@ namespace CHECK(isEqual); } + //************************************************************************* + TEST(test_available) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + for (auto v : test) + { + data.push(v); + CHECK_EQUAL(SIZE - data.size(), data.available()); + } + } + + //************************************************************************* + TEST(test_front) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data; + data.push(input1.begin(), input1.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + Ndc& ref1 = data.front(); + CHECK(ref1 == compare.front()); + + Ndc& ref2 = data.front(); + ref2 = compare.back(); + CHECK(ref2 == compare.back()); + } + //************************************************************************* TEST(test_front_const) { @@ -399,7 +430,7 @@ namespace } //************************************************************************* - TEST(test_back_const) + TEST(test_back) { Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; @@ -407,10 +438,66 @@ namespace Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Ndc& ref1 = data.back(); + CHECK(ref1 == compare.back()); + + Ndc& ref2 = data.back(); + ref2 = compare.front(); + CHECK(ref2 == compare.front()); + } + + //************************************************************************* + TEST(test_back_const) + { + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data; + data.push(input.begin(), input.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + const Ndc& ref = data.back(); CHECK(ref == compare.back()); } + //************************************************************************* + TEST(test_index_operator) + { + // Overrun by 3 + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare input2{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data; + data.push(input1.begin(), input1.end()); + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input1[i + 3], data[i]); + } + + for (int i = 0; i < SIZE; ++i) + { + data[i] = input2[i]; + } + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input2[i], data[i]); + } + } + + //************************************************************************* + TEST(test_index_operator_const) + { + // Overrun by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + data.push(input.begin(), input.end()); + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input[i + 3], data[i]); + } + } + //************************************************************************* TEST(test_random_iterator_plus) { diff --git a/test/test_circular_buffer_external_buffer.cpp b/test/test_circular_buffer_external_buffer.cpp index 54bcb127..f93b2bf9 100644 --- a/test/test_circular_buffer_external_buffer.cpp +++ b/test/test_circular_buffer_external_buffer.cpp @@ -69,6 +69,7 @@ namespace CHECK_EQUAL(0U, data.size()); CHECK_EQUAL(SIZE, data.max_size()); CHECK_EQUAL(SIZE, data.capacity()); + CHECK_EQUAL(SIZE, data.available()); CHECK(data.begin() == data.end()); CHECK(data.cbegin() == data.cend()); CHECK(data.rbegin() == data.rend()); @@ -151,6 +152,7 @@ namespace CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(SIZE - data.size(), data.available()); bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); CHECK(isEqual); @@ -394,6 +396,35 @@ namespace CHECK(isEqual); } + //************************************************************************* + TEST(test_available) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + for (auto v : test) + { + data.push(v); + CHECK_EQUAL(SIZE - data.size(), data.available()); + } + } + + //************************************************************************* + TEST(test_front) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + Ndc& ref1 = data.front(); + CHECK(ref1 == compare.front()); + + Ndc& ref2 = data.front(); + ref2 = compare.back(); + CHECK(ref2 == compare.back()); + } + //************************************************************************* TEST(test_front_const) { @@ -408,7 +439,7 @@ namespace } //************************************************************************* - TEST(test_back_const) + TEST(test_back) { Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data(buffer1.raw, SIZE); @@ -416,10 +447,66 @@ namespace Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Ndc& ref1 = data.back(); + CHECK(ref1 == compare.back()); + + Ndc& ref2 = data.back(); + ref2 = compare.front(); + CHECK(ref2 == compare.front()); + } + + //************************************************************************* + TEST(test_back_const) + { + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(input.begin(), input.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + const Ndc& ref = data.back(); CHECK(ref == compare.back()); } + //************************************************************************* + TEST(test_index_operator) + { + // Overrun by 3 + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare input2{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input1[i + 3], data[i]); + } + + for (int i = 0; i < SIZE; ++i) + { + data[i] = input2[i]; + } + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input2[i], data[i]); + } + } + + //************************************************************************* + TEST(test_index_operator_const) + { + // Overrun by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(input.begin(), input.end()); + + for (int i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(input[i + 3], data[i]); + } + } + //************************************************************************* TEST(test_random_iterator_plus) {