Update ringbuffer

This commit is contained in:
Erki 2021-03-21 17:02:55 +02:00
parent d945e7a799
commit b7789064fa
3 changed files with 120 additions and 3 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR) cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
add_library(utility STATIC add_library(utility STATIC
Src/utility_itmlogger.cpp Src/utility_logging.cpp
) )
add_library(skullc::utility ALIAS utility) add_library(skullc::utility ALIAS utility)

View File

@ -155,6 +155,9 @@ public:
*_tail = value; *_tail = value;
++_tail; ++_tail;
if (_tail == _head)
_is_full = true;
} }
template<typename... Args> template<typename... Args>
@ -167,12 +170,21 @@ public:
++_tail; ++_tail;
} }
void increment_tail()
{
if (_tail == _head)
++_head;
++_tail;
}
void pop_front() void pop_front()
{ {
if (empty()) if (empty())
return; return;
++_head; ++_head;
_is_full = false;
} }
reference front() reference front()
@ -198,7 +210,12 @@ public:
size_type size() const size_type size() const
{ {
if (_head == _tail) if (_head == _tail)
return 0; {
if (_is_full)
return N;
else
return 0;
}
const typename Ringbuffer<T, N>::iterator::difference_type distance = _tail - _head; const typename Ringbuffer<T, N>::iterator::difference_type distance = _tail - _head;
@ -208,10 +225,15 @@ public:
} }
else else
{ {
return _head - _tail; return _head - _tail + 1;
} }
} }
constexpr size_type max_size() const
{
return N;
}
bool empty() const bool empty() const
{ {
return size() == 0; return size() == 0;
@ -219,6 +241,7 @@ public:
private: private:
std::array<T, N> _data; std::array<T, N> _data;
bool _is_full = false;
iterator _head; iterator _head;
iterator _tail; iterator _tail;

View File

@ -96,6 +96,50 @@ TEST_CASE("Constructed buffer is empty.", "[ringbuffer]")
REQUIRE(buffer.empty()); REQUIRE(buffer.empty());
} }
TEST_CASE("Buffer reports size properly.", "[ringbuffer]")
{
Ringbuffer<3> buffer;
buffer.push_back(1);
buffer.push_back(2);
SECTION("max_size() reports maximum size properly.")
{
REQUIRE(buffer.max_size() == 3);
}
SECTION("After pushing 2 elements, size is reported properly.")
{
REQUIRE(buffer.size() == 2);
}
SECTION("A full buffer reports size as max_size.")
{
buffer.push_back(3);
REQUIRE(buffer.size() == 3);
REQUIRE(buffer.size() == buffer.max_size());
}
SECTION("Removing an element updates size properly.")
{
buffer.pop_front();
REQUIRE(buffer.size() == 1);
}
SECTION("Removing and adding an element updates size properly.")
{
buffer.pop_front();
buffer.push_back(4);
REQUIRE(buffer.size() == 2);
buffer.push_back(5);
REQUIRE(buffer.size() == 3);
}
}
TEST_CASE("Adding single element.", "[ringbuffer]") TEST_CASE("Adding single element.", "[ringbuffer]")
{ {
Ringbuffer<10> buffer; Ringbuffer<10> buffer;
@ -248,3 +292,53 @@ TEST_CASE("Clearing a ringbuffer works.", "[ringbuffer]")
REQUIRE(buffer.begin() == buffer.end()); REQUIRE(buffer.begin() == buffer.end());
} }
} }
TEST_CASE("Manually incrementing tail works.", "[ringbuffer]")
{
Ringbuffer<10> buffer;
buffer.push_back(1);
auto old_end = buffer.end();
*old_end = 2;
buffer.increment_tail();
SECTION("New end is set forward by 1.")
{
const auto new_end = buffer.end();
REQUIRE(old_end != new_end);
REQUIRE(new_end - old_end == 1);
}
}
TEST_CASE("Manually incrementing tail when full deletes data.", "[ringbuffer]")
{
Ringbuffer<2> buffer;
buffer.push_back(1);
buffer.push_back(2);
const auto old_start = buffer.begin();
const auto old_end = buffer.end();
REQUIRE(buffer.size() == buffer.max_size());
buffer.increment_tail();
REQUIRE(buffer.size() == buffer.max_size());
SECTION("End is incremented properly.")
{
const auto new_end = buffer.end();
REQUIRE(old_end != new_end);
REQUIRE(new_end - old_end == 1);
}
SECTION("Begin is incremented properly.")
{
const auto new_start = buffer.begin();
REQUIRE(old_start != new_start);
REQUIRE(new_start - old_start == 1);
}
}