From 900aed5ee690102cee8c3207ff0ebc89cc67bd5a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Dec 2022 22:55:47 -0600 Subject: [PATCH] feat(array): add CSimpleSortedArray --- common/Array.hpp | 6 ++ common/array/CSimpleSortedArray.hpp | 92 +++++++++++++++++++++++++++++ test/Array.cpp | 88 +++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 common/Array.hpp create mode 100644 common/array/CSimpleSortedArray.hpp create mode 100644 test/Array.cpp diff --git a/common/Array.hpp b/common/Array.hpp new file mode 100644 index 0000000..2557f47 --- /dev/null +++ b/common/Array.hpp @@ -0,0 +1,6 @@ +#ifndef COMMON_ARRAY_HPP +#define COMMON_ARRAY_HPP + +#include "common/array/CSimpleSortedArray.hpp" + +#endif diff --git a/common/array/CSimpleSortedArray.hpp b/common/array/CSimpleSortedArray.hpp new file mode 100644 index 0000000..7ddfe0b --- /dev/null +++ b/common/array/CSimpleSortedArray.hpp @@ -0,0 +1,92 @@ +#ifndef COMMON_ARRAY_C_SIMPLE_SORTED_ARRAY_HPP +#define COMMON_ARRAY_C_SIMPLE_SORTED_ARRAY_HPP + +#include +#include +#include +#include +#include +#include + +template +class CSimpleSortedArray { + public: + // Member variables + TSGrowableArray m_array; + uint32_t m_count = 0; + uint32_t m_maxcount = 0; + uint32_t m_iterator = 0; + + // Member functions + T& operator[](uint32_t index); + uint32_t Count(); + void Insert(T element); + void Remove(uint32_t index); +}; + +template +T& CSimpleSortedArray::operator[](uint32_t index) { + return this->m_array[index]; +} + +template +uint32_t CSimpleSortedArray::Count() { + return this->m_count; +} + +template +void CSimpleSortedArray::Insert(T element) { + if (this->m_count == this->m_maxcount) { + this->m_maxcount += 8; + this->m_array.SetCount(this->m_maxcount); + } + + uint32_t index = 0; + + // Search for appropriate insertion index based on priority + for (int32_t i = 0; i < this->m_count; i++) { + if (element->priority > this->m_array[i]->priority) { + index = i; + break; + } + + if (i == this->m_count - 1) { + index = i + 1; + break; + } + } + + // Shift any elements after insertion index ahead by 1 + for (int32_t s = this->m_count; s > index; s--) { + this->m_array[s] = this->m_array[s - 1]; + } + + this->m_array[index] = element; + + if (index < this->m_iterator) { + this->m_iterator++; + } + + this->m_count++; +} + +template +void CSimpleSortedArray::Remove(uint32_t index) { + // Shift any elements after removal index back by 1 + for (int32_t s = index; s < this->m_count - 1; s++) { + this->m_array[s] = this->m_array[s + 1]; + } + + if (index < this->m_iterator) { + this->m_iterator--; + } + + this->m_count--; + + if (this->m_maxcount - this->m_count > 8) { + this->m_maxcount -= 8; + this->m_array.SetCount(this->m_maxcount); + } +} + +#endif diff --git a/test/Array.cpp b/test/Array.cpp new file mode 100644 index 0000000..2971b91 --- /dev/null +++ b/test/Array.cpp @@ -0,0 +1,88 @@ +#include "common/Array.hpp" +#include "test/Test.hpp" + +struct PrioritizedEntry { + const char* name; + uint32_t priority; +}; + +TEST_CASE("CSimpleSortedArray::CSimpleSortedArray", "[array]") { + SECTION("constructs new sorted array") { + CSimpleSortedArray array; + REQUIRE(array.Count() == 0); + } +} + +TEST_CASE("CSimpleSortedArray::Insert", "[array]") { + SECTION("sorts entries as new elements are inserted") { + CSimpleSortedArray array; + + PrioritizedEntry* entry1 = new PrioritizedEntry(); + entry1->name = "Entry1"; + entry1->priority = 1; + + PrioritizedEntry* entry2 = new PrioritizedEntry(); + entry2->name = "Entry2"; + entry2->priority = 10; + + PrioritizedEntry* entry3 = new PrioritizedEntry(); + entry3->name = "Entry3"; + entry3->priority = 100; + + array.Insert(entry2); + + CHECK(array[0]->priority == entry2->priority); + CHECK(array.Count() == 1); + + array.Insert(entry1); + + CHECK(array[0]->priority == entry2->priority); + CHECK(array[1]->priority == entry1->priority); + CHECK(array.Count() == 2); + + array.Insert(entry3); + + CHECK(array[0]->priority == entry3->priority); + CHECK(array[1]->priority == entry2->priority); + CHECK(array[2]->priority == entry1->priority); + CHECK(array.Count() == 3); + } +} + +TEST_CASE("CSimpleSortedArray::Remove", "[array]") { + SECTION("consolidates entries as elements are removed") { + CSimpleSortedArray array; + + PrioritizedEntry* entry1 = new PrioritizedEntry(); + entry1->name = "Entry1"; + entry1->priority = 1; + + PrioritizedEntry* entry2 = new PrioritizedEntry(); + entry2->name = "Entry2"; + entry2->priority = 10; + + PrioritizedEntry* entry3 = new PrioritizedEntry(); + entry3->name = "Entry3"; + entry3->priority = 100; + + array.Insert(entry1); + array.Insert(entry2); + array.Insert(entry3); + + CHECK(array[0]->priority == entry3->priority); + CHECK(array[1]->priority == entry2->priority); + CHECK(array[2]->priority == entry1->priority); + CHECK(array.Count() == 3); + + array.Remove(1); + + CHECK(array[0]->priority == entry3->priority); + CHECK(array[1]->priority == entry1->priority); + CHECK(array.Count() == 2); + + array.Remove(0); + + CHECK(array[0]->priority == entry1->priority); + CHECK(array.Count() == 1); + } +}