diff --git a/Utility/CMakeLists.txt b/Utility/CMakeLists.txt index 8504bd4..e28bacd 100644 --- a/Utility/CMakeLists.txt +++ b/Utility/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) add_library(utility STATIC - Src/utility_itmlogger.cpp + Src/utility_logging.cpp ) add_library(skullc::utility ALIAS utility) diff --git a/Utility/Inc/utility_ringbuffer.hpp b/Utility/Inc/utility_ringbuffer.hpp index 3425505..235ecb8 100644 --- a/Utility/Inc/utility_ringbuffer.hpp +++ b/Utility/Inc/utility_ringbuffer.hpp @@ -155,6 +155,9 @@ public: *_tail = value; ++_tail; + + if (_tail == _head) + _is_full = true; } template @@ -167,12 +170,21 @@ public: ++_tail; } + void increment_tail() + { + if (_tail == _head) + ++_head; + + ++_tail; + } + void pop_front() { if (empty()) return; ++_head; + _is_full = false; } reference front() @@ -198,7 +210,12 @@ public: size_type size() const { if (_head == _tail) - return 0; + { + if (_is_full) + return N; + else + return 0; + } const typename Ringbuffer::iterator::difference_type distance = _tail - _head; @@ -208,10 +225,15 @@ public: } else { - return _head - _tail; + return _head - _tail + 1; } } + constexpr size_type max_size() const + { + return N; + } + bool empty() const { return size() == 0; @@ -219,6 +241,7 @@ public: private: std::array _data; + bool _is_full = false; iterator _head; iterator _tail; diff --git a/Utility/Tests/ringbuffer.cpp b/Utility/Tests/ringbuffer.cpp index ddab506..6f42905 100644 --- a/Utility/Tests/ringbuffer.cpp +++ b/Utility/Tests/ringbuffer.cpp @@ -96,6 +96,50 @@ TEST_CASE("Constructed buffer is empty.", "[ringbuffer]") 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]") { Ringbuffer<10> buffer; @@ -248,3 +292,53 @@ TEST_CASE("Clearing a ringbuffer works.", "[ringbuffer]") 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); + } +}