aboutsummaryrefslogtreecommitdiff
path: root/src/containers.hh
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-05-28 02:56:09 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-05-28 02:56:59 -0300
commit02d243c531a5c7886c89024e592a2ccdeab3d3b3 (patch)
tree1240702a1c514982b0e9dd8753daaea1b1ee6d75 /src/containers.hh
parent5505f28c358a50e9d610784303485cc757459162 (diff)
downloadgame-02d243c531a5c7886c89024e592a2ccdeab3d3b3.tar.gz
game-02d243c531a5c7886c89024e592a2ccdeab3d3b3.zip
impl all remaining containers
Diffstat (limited to 'src/containers.hh')
-rw-r--r--src/containers.hh207
1 files changed, 203 insertions, 4 deletions
diff --git a/src/containers.hh b/src/containers.hh
index d79946c..9cab94e 100644
--- a/src/containers.hh
+++ b/src/containers.hh
@@ -39,7 +39,9 @@ struct vector{
}
}
- // TODO(fusion): Probably missing some inlined destructor?
+ ~vector(void){
+ delete[] this->entry;
+ }
T *at(int index){
// TODO(fusion): This is probably not the best way to achieve this.
@@ -135,7 +137,9 @@ struct priority_queue{
Entries = 0;
}
- // TODO(fusion): Probably missing some inlined destructor?
+ ~priority_queue(void){
+ delete Entry;
+ }
void insert(K Key, T *Data){
this->Entries += 1;
@@ -241,7 +245,9 @@ struct matrix{
}
}
- // TODO(fusion): Probably missing some inlined destructor?
+ ~matrix(void){
+ delete[] this->entry;
+ }
T *at(int x, int y){
int xoffset = x - this->xmin;
@@ -305,7 +311,9 @@ struct matrix3d{
}
}
- // TODO(fusion): Probably missing some inlined destructor?
+ ~matrix3d(void){
+ delete[] this->entry;
+ }
T *at(int x, int y, int z){
int xoffset = x - this->xmin;
@@ -335,4 +343,195 @@ struct matrix3d{
T *entry;
};
+template<typename T>
+struct listnode{
+ listnode *next;
+ listnode *prev;
+ T data;
+};
+
+template<typename T>
+struct list{
+ // REGULAR FUNCTIONS
+ // =========================================================================
+ list(void){
+ firstNode = NULL;
+ lastNode = NULL;
+ }
+
+ ~list(void){
+ while(this->firstNode != NULL){
+ this->remove(this->firstNode);
+ }
+ }
+
+ listnode<T> *append(void){
+ listnode<T> *node = new listnode<T>;
+ node->next = NULL;
+ node->prev = NULL;
+ if(this->firstNode == NULL){
+ ASSERT(this->lastNode == NULL);
+ this->firstNode = node;
+ }else{
+ ASSERT(this->lastNode != NULL);
+ this->lastNode->next = node;
+ node->prev = this->lastNode;
+ }
+ this->lastNode = node;
+ return node;
+ }
+
+ void remove(listnode<T> *node){
+ if(node == NULL){
+ error("list::remove: node ist NULL.\n");
+ return;
+ }
+
+ if(node->prev == NULL){
+ ASSERT(this->firstNode == node);
+ this->firstNode = node->next;
+ }else{
+ node->prev->next = node->next;
+ }
+
+ if(node->next == NULL){
+ ASSERT(this->lastNode == node);
+ this->lastNode = node->prev;
+ }else{
+ node->next->prev = node->prev;
+ }
+
+ delete node;
+ }
+
+ // DATA
+ // =========================================================================
+ listnode<T> *firstNode;
+ listnode<T> *lastNode;
+};
+
+template<typename T>
+struct fifo{
+ // REGULAR FUNCTIONS
+ // =========================================================================
+ fifo(int InitialSize){
+ ASSERT(InitialSize > 0);
+ this->Entry = new T[InitialSize];
+ this->Size = InitialSize;
+ this->Head = -1;
+ this->Tail = 0;
+ }
+
+ ~fifo(void){
+ delete[] this->Entry;
+ }
+
+ T *next(void){
+ T *Next = NULL;
+ if(this->Tail <= this->Head){
+ Next = &this->Entry[this->Tail % this->Size];
+ }
+ return Next;
+ }
+
+ T *append(void){
+ if((this->Head - this->Tail + 1) == this->Size){
+ int NewSize = this->Size * 2;
+ T *NewEntry = new T[NewSize];
+ // TODO(fusion): Is it even possible to have `this->Entry == NULL`?
+ if(this->Entry != NULL){
+ for(int Index = this->Tail; Index <= this->Head; Index += 1){
+ NewEntry[Index % NewSize] = this->Entry[Index % this->Size];
+ }
+ delete[] this->Entry;
+ }
+ this->Entry = NewEntry;
+ this->Size = NewSize;
+ }
+
+ // TODO(fusion): We don't consider integer overflow at all.
+ this->Head += 1;
+ return this->Entry[this->Head % this->Size];
+ }
+
+ void remove(void){
+ if(this->Tail > this->Head){
+ error("fifo::remove: Fifo ist leer.\n");
+ return;
+ }
+
+ this->Tail += 1;
+ }
+
+ // TODO(fusion): There is also a `fifoIterator` used a few times and it is
+ // essentially iterating from `this->Head` towards `this->Tail`. All its
+ // functions were inlined so I'm not sure it is needed.
+
+ // DATA
+ // =========================================================================
+ T *Entry;
+ int Size;
+ int Head;
+ int Tail;
+};
+
+template<typename T>
+union storeitem{
+ // IMPORTANT(fusion): This will only work properly with POD structures. We
+ // could also manually handle `data` construction and destruction but I don't
+ // think we need it.
+ STATIC_ASSERT(std::is_pod<T>::value);
+ storeitem<T> *next;
+ T data;
+};
+
+template<typename T, usize N>
+struct storeunit{
+ STATIC_ASSERT(N > 0);
+ storeitem<T> item[N];
+};
+
+// NOTE(fusion): The `store` container is an allocator that manages a single type.
+// It is also known as a slab allocator.
+template<typename T, usize N>
+struct store{
+ // REGULAR FUNCTIONS
+ // =========================================================================
+ store(void){
+ this->Units = new list<storeunit<T, N>>;
+ this->firstFreeItem = NULL;
+ }
+
+ ~store(void){
+ delete this->Units;
+ }
+
+ T *getFreeItem(void){
+ if(this->firstFreeItem == NULL){
+ storeunit<T, N> *Unit = &this->Units.append()->data;
+ for(usize i = 0; i < (N - 1); i += 1){
+ Unit->item[i].next = &Unit->item[i + 1];
+ }
+ Unit->item[N - 1].next = NULL;
+ this->firstFreeItem = &Unit->item[0];
+ }
+
+ storeitem<T> *Item = this->firstFreeItem;
+ this->firstFreeItem = Item->next;
+ return &Item->data;
+ }
+
+ void putFreeItem(T *Item){
+ // TODO(fusion): Not the safest thing to do.
+ ASSERT(Item != NULL);
+ ((storeitem<T>*)Item)->next = this->firstFreeItem;
+ this->firstfreeItem = (storeitem<T>*)Item;
+ }
+
+ // DATA
+ // =========================================================================
+ list<storeunit<T, N>> *Units;
+ storeitem<T> *firstFreeItem;
+};
+
#endif //TIBIA_CONTAINERS_HH_ \ No newline at end of file