summaryrefslogtreecommitdiffhomepage
path: root/src/kernel/NeKit/MutableArray.h
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-23 21:06:27 -0500
committerGitHub <noreply@github.com>2025-11-23 21:06:27 -0500
commit23040fad647634c08697451fc22ee2ca999629c8 (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/NeKit/MutableArray.h
parente5cc7351f0577b54c528fb827a7c7e6306c3e843 (diff)
parent83d870e58457a1d335a1d9b9966a6a1887cc297b (diff)
Merge pull request #81 from nekernel-org/dev
feat! breaking changes on kernel sources.
Diffstat (limited to 'src/kernel/NeKit/MutableArray.h')
-rw-r--r--src/kernel/NeKit/MutableArray.h203
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