diff options
author | aap <aap@papnet.eu> | 2019-07-07 13:09:11 +0200 |
---|---|---|
committer | aap <aap@papnet.eu> | 2019-07-07 13:09:11 +0200 |
commit | 53023eb65bdcde43e341c1ecb7cf0c7f8ee524fb (patch) | |
tree | fc65a6c40fa719f9d43be9e0e15be79c490135e0 /src/core/templates.h | |
parent | 219a65b81a1141d6475fc48bdc6251bd20e44a70 (diff) |
the great reorganization
Diffstat (limited to 'src/core/templates.h')
-rw-r--r-- | src/core/templates.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/core/templates.h b/src/core/templates.h new file mode 100644 index 00000000..ef2db33a --- /dev/null +++ b/src/core/templates.h @@ -0,0 +1,205 @@ +#pragma once + +template<typename T, int n> +class CStore +{ +public: + int allocPtr; + T store[n]; + + T *alloc(void){ + if(this->allocPtr >= n){ + printf("Size of this thing:%d needs increasing\n", n); + assert(0); + } + return &this->store[this->allocPtr++]; + } + void clear(void){ + this->allocPtr = 0; + } +}; + +template<typename T, typename U = T> +class CPool +{ + U *m_entries; + union Flags { + struct { + uint8 id : 7; + uint8 free : 1; + }; + uint8 u; + } *m_flags; + int m_size; + int m_allocPtr; + +public: + CPool(int size){ + m_entries = (U*)malloc(sizeof(U)*size); + m_flags = (Flags*)malloc(sizeof(Flags)*size); + m_size = size; + m_allocPtr = 0; + for(int i = 0; i < size; i++){ + m_flags[i].id = 0; + m_flags[i].free = 1; + } + } + int GetSize(void) { return m_size; } + T *New(void){ + bool wrapped = false; + do + if(++m_allocPtr == m_size){ + if(wrapped) + return nil; + wrapped = true; + m_allocPtr = 0; + } + while(!m_flags[m_allocPtr].free); + m_flags[m_allocPtr].free = 0; + m_flags[m_allocPtr].id++; + return (T*)&m_entries[m_allocPtr]; + } + T *New(int handle){ + T *entry = (T*)&m_entries[handle>>8]; + SetNotFreeAt(handle); + return entry; + } + void SetNotFreeAt(int handle){ + int idx = handle>>8; + m_flags[idx].free = 0; + m_flags[idx].id = handle & 0x7F; + for(m_allocPtr = 0; m_allocPtr < m_size; m_allocPtr++) + if(m_flags[m_allocPtr].free) + return; + } + void Delete(T *entry){ + int i = GetJustIndex(entry); + m_flags[i].free = 1; + if(i < m_allocPtr) + m_allocPtr = i; + } + T *GetSlot(int i){ + return m_flags[i].free ? nil : (T*)&m_entries[i]; + } + T *GetAt(int handle){ + return m_flags[handle>>8].u == (handle & 0xFF) ? + (T*)&m_entries[handle >> 8] : nil; + } + int GetIndex(T *entry){ + int i = GetJustIndex(entry); + return m_flags[i].u + (i<<8); + } + int GetJustIndex(T *entry){ + // TODO: the cast is unsafe + return (int)((U*)entry - m_entries); + } + int GetNoOfUsedSpaces(void){ + int i; + int n = 0; + for(i = 0; i < m_size; i++) + if(!m_flags[i].free) + n++; + return n; + } + void ClearStorage(uint8 *&flags, U *&entries){ + free(flags); + free(entries); + flags = nil; + entries = nil; + } + void CopyBack(uint8 *&flags, U *&entries){ + memcpy(m_flags, flags, sizeof(uint8)*m_size); + memcpy(m_entries, entries, sizeof(U)*m_size); + debug("Size copied:%d (%d)\n", sizeof(U)*m_size, sizeof(Flags)*m_size); + m_allocPtr = 0; + ClearStorage(flags, entries); + debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ + } + void Store(uint8 *&flags, U *&entries){ + flags = (uint8*)malloc(sizeof(uint8)*m_size); + entries = (U*)malloc(sizeof(U)*m_size); + memcpy(flags, m_flags, sizeof(uint8)*m_size); + memcpy(entries, m_entries, sizeof(U)*m_size); + debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ + } +}; + +template<typename T> +class CLink +{ +public: + T item; + CLink<T> *prev; + CLink<T> *next; + + void Insert(CLink<T> *link){ + link->next = this->next; + this->next->prev = link; + link->prev = this; + this->next = link; + } + void Remove(void){ + this->prev->next = this->next; + this->next->prev = this->prev; + } +}; + +template<typename T> +class CLinkList +{ +public: + CLink<T> head, tail; + CLink<T> freeHead, freeTail; + CLink<T> *links; + + void Init(int n){ + links = new CLink<T>[n]; + head.next = &tail; + tail.prev = &head; + freeHead.next = &freeTail; + freeTail.prev = &freeHead; + while(n--) + freeHead.Insert(&links[n]); + } + void Shutdown(void){ + delete[] links; + links = nil; + } + void Clear(void){ + while(head.next != &tail) + Remove(head.next); + } + CLink<T> *Insert(T const &item){ + CLink<T> *node = freeHead.next; + if(node == &freeTail) + return nil; + node->item = item; + node->Remove(); // remove from free list + head.Insert(node); + return node; + } + CLink<T> *InsertSorted(T const &item){ + CLink<T> *sort; + for(sort = head.next; sort != &tail; sort = sort->next) + if(sort->item.sort >= item.sort) + break; + CLink<T> *node = freeHead.next; + if(node == &freeTail) + return nil; + node->item = item; + node->Remove(); // remove from free list + sort->prev->Insert(node); + return node; + } + void Remove(CLink<T> *link){ + link->Remove(); // remove from list + freeHead.Insert(link); // insert into free list + } + int Count(void){ + int n = 0; + CLink<T> *lnk; + for(lnk = head.next; lnk != &tail; lnk = lnk->next) + n++; + return n; + } +}; |