diff options
Diffstat (limited to 'src/kernel/NeKit/MutableArray.h')
| -rw-r--r-- | src/kernel/NeKit/MutableArray.h | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/kernel/NeKit/MutableArray.h b/src/kernel/NeKit/MutableArray.h new file mode 100644 index 00000000..e1138b3b --- /dev/null +++ b/src/kernel/NeKit/MutableArray.h @@ -0,0 +1,203 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <NeKit/Array.h> +#include <NeKit/Defines.h> + +#define RTL_TRY_FIND_NODE(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return NAME->fVal; \ + NAME = NAME->fNext; \ + } + +#define RTL_TRY_FIND_NODE2(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return Ref<T>{NAME->fVal}; \ + NAME = NAME->fNext; \ + } + +#define RTL_TRY_REMOVE_NODE(NODE) \ + if (NODE && NODE->fIndex == Index) { \ + NODE->fUsed = false; \ + NODE->fIndex = 0; \ + \ + return true; \ + } + +// FIXME: this is a shitty algorithm, because it is memory heavy. +// Remove and occurences of that, and remove that class. +namespace Kernel { +template <typename T> +class MutableArray; + +template <typename T, T _PlaceHolderValue> +class NullableMutableArray; + +template <typename T> +class MutableLinkedList { + public: + T fVal; + SizeT fIndex{0}; + Boolean fUsed{false}; + + MutableLinkedList* fPrev{nullptr}; + MutableLinkedList* fNext{nullptr}; +}; + +template <typename T, T _PlaceHolderValue> +class NullableMutableArray { + public: + // explicit this. + explicit NullableMutableArray() : fFirstNode(new MutableLinkedList<T>()) {} + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() { + auto* It = fFirstNode; + MutableLinkedList<T>* NextIt = nullptr; + + while (It) { + NextIt = It->fNext; + delete It; + + It = NextIt; + } + } + + NullableMutableArray& operator=(const NullableMutableArray&) = default; + NullableMutableArray(const NullableMutableArray&) = default; + + operator bool() { return Count() > 1; } + + public: + T operator[](SizeT Index) const { + RTL_TRY_FIND_NODE(first, fFirstNode); + RTL_TRY_FIND_NODE(last, fLastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const { return fNodeCount; } + + public: + Boolean Remove(SizeT Index) { + RTL_TRY_REMOVE_NODE(fFirstNode); + RTL_TRY_REMOVE_NODE(fLastNode); + + return false; + } + + Boolean Add(const T val) { + auto* iterationNode = fFirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) { + if (!iterationNode->fUsed) { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T>* fLastNode{nullptr}; + MutableLinkedList<T>* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{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; + + NE_COPY_DEFAULT(MutableArray) + + public: + Boolean Add(const T val) { + auto* iterationNode = fFirstNode; + + if (!iterationNode) { + fFirstNode = new MutableLinkedList<T>(); + iterationNode = fFirstNode; + } + + MUST_PASS(iterationNode); + + while (iterationNode) { + if (!iterationNode->fUsed) { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + public: + Ref<T> operator[](SizeT Index) const { + RTL_TRY_FIND_NODE2(first, fFirstNode); + RTL_TRY_FIND_NODE2(last, fLastNode); + + return {}; + } + + SizeT Count() const { return fNodeCount; } + + bool Contains(T& value) noexcept { + MutableLinkedList<T>* first = fFirstNode; + + while (first) { + if (first->fVal == value && first->fUsed) return true; + + first = first->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T>* fLastNode{nullptr}; + MutableLinkedList<T>* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; +}; +} // namespace Kernel |
