diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
| commit | 5339d016c07bf717ee388f4feb73544087324af0 (patch) | |
| tree | 94be6f67ed626091f24aee24ec3b3be03d01e4e7 /NewKit/MutableArray.hpp | |
git: port from mercurial repo.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'NewKit/MutableArray.hpp')
| -rw-r--r-- | NewKit/MutableArray.hpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/NewKit/MutableArray.hpp b/NewKit/MutableArray.hpp new file mode 100644 index 00000000..5739305a --- /dev/null +++ b/NewKit/MutableArray.hpp @@ -0,0 +1,225 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ +#pragma once + +#include <CompilerKit/Compiler.hpp> +#include <NewKit/Array.hpp> +#include <NewKit/Defines.hpp> + +#define TRY_FIND_NODE(NAME, NODE) \ + auto *NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->m_Index == Index) \ + return NAME->m_Val; \ + NAME = NAME->m_Next; \ + } + + + +#define TRY_FIND_NODE2(NAME, NODE) \ + auto *NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->m_Index == Index) \ + return Ref<T>{NAME->m_Val}; \ + NAME = NAME->m_Next; \ + } + + + +#define TRY_REMOVE_NODE(NODE) \ + if (NODE && NODE->m_Index == Index) \ + { \ + NODE->m_Used = false; \ + NODE->m_Index = 0; \ + \ + return true; \ + } + + + +// FIXME: this is a shitty algorithm, which is consumer hungry. +// Remove and occurences of that, and remove that class. +namespace hCore +{ +template <typename T> class MutableArray; + +template <typename T, T _PlaceHolderValue> class NullableMutableArray; + +template <typename T> class MutableLinkedList +{ + public: + T m_Val; + SizeT m_Index{0}; + Boolean m_Used{false}; + + MutableLinkedList *m_Prev{nullptr}; + MutableLinkedList *m_Next{nullptr}; +}; + +template <typename T, T _PlaceHolderValue> class NullableMutableArray +{ + public: + // explicit this. + explicit NullableMutableArray() : m_FirstNode(new MutableLinkedList<T>()) {} + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() + { + auto *It = m_FirstNode; + MutableLinkedList<T> *NextIt = nullptr; + + while (It) + { + NextIt = It->m_Next; + delete It; + + It = NextIt; + } + } + + NullableMutableArray &operator=(const NullableMutableArray &) = default; + NullableMutableArray(const NullableMutableArray &) = default; + + operator bool() { return Count() > 1; } + + public: + T operator[](const SizeT &Index) const + { + TRY_FIND_NODE(first, m_FirstNode); + TRY_FIND_NODE(last, m_LastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const { return m_NodeCount; } + + public: + Boolean Remove(const SizeT &Index) + { + TRY_REMOVE_NODE(m_FirstNode); + TRY_REMOVE_NODE(m_LastNode); + + return false; + } + + Boolean Add(const T val) + { + auto *iterationNode = m_FirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->m_Used) + { + iterationNode->m_Val = val; + iterationNode->m_Index = 0; + + iterationNode->m_Used = true; + + ++m_NodeCount; + + return true; + } + + iterationNode = iterationNode->m_Next; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T> *m_LastNode{nullptr}; + MutableLinkedList<T> *m_FirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + hCore::SizeT m_NodeCount{0}; + + private: + // don't remove that + friend MutableArray<T>; +}; + +template <typename T> +class MutableArray : public NullableMutableArray<voidPtr, nullptr> +{ + public: + // explicit this. + explicit MutableArray() = default; + virtual ~MutableArray() = default; + + HCORE_COPY_DEFAULT(MutableArray) + + public: + Boolean Add(const T val) + { + auto *iterationNode = m_FirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->m_Used) + { + iterationNode->m_Val = val; + iterationNode->m_Index = 0; + + iterationNode->m_Used = true; + + ++m_NodeCount; + + return true; + } + + iterationNode = iterationNode->m_Next; + } + + return false; + } + + public: + Ref<T> operator[](const SizeT &Index) const + { + TRY_FIND_NODE2(first, m_FirstNode); + TRY_FIND_NODE2(last, m_LastNode); + + return {}; + } + + SizeT Count() const { return m_NodeCount; } + + bool Contains(T &value) noexcept + { + MutableLinkedList<T> *first = m_FirstNode; + + while (first) + { + if (first->m_Val == value && first->m_Used) + return true; + + first = first->m_Next; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T> *m_LastNode{nullptr}; + MutableLinkedList<T> *m_FirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + hCore::SizeT m_NodeCount{0}; +}; +} // namespace hCore |
