#ifndef FOUR_ZED_ZED_DYNAMIC_ARRAY_HPP #define FOUR_ZED_ZED_DYNAMIC_ARRAY_HPP #include "memory.hpp" #include "macros.hpp" #include #include #include #define BAKE_DYN_ARRAY(T) template struct DynArray; struct DynArrayBase { char *ptr = nullptr; int64_t elementSize = 0; int64_t elementCount = 0; int64_t reservedCount = 0; }; template struct DynArray: DynArrayBase { DynArray(); ~DynArray(); T operator[](std::size_t index); T *GetPtr(); void Push(const T &val); T Pop(); void Reserve(int64_t count); void Resize(int64_t count); protected: using DynArrayBase::ptr; using DynArrayBase::elementSize; using DynArrayBase::elementCount; using DynArrayBase::reservedCount; }; void inline DynArrayReserve(DynArrayBase *arr, int64_t count); void inline DynArrayDestroy(DynArrayBase *arr); template inline DynArray::DynArray() { this->elementSize = sizeof(T); } template inline DynArray::~DynArray() { DynArrayDestroy(this); } template inline T DynArray::operator[](std::size_t index) { assert(index < this->elementCount && "Invalid DynArray[] index - out of bounds"); assert(index < this->reservedCount && "Invalid DynArray[] index - out of reserved bounds"); return *reinterpret_cast((this->ptr + (sizeof(T) * index))); } template inline T *DynArray::GetPtr() { return reinterpret_cast(reinterpret_cast(this->ptr)); } template inline void DynArray::Push(const T &val) { if (this->elementCount + 1 > this->reservedCount) { DynArrayReserve(this, int64_t(this->reservedCount * 1.5)); } std::memcpy(this->ptr + (sizeof(T) * this->elementCount), &val, sizeof(T)); this->elementCount += 1; } template inline T DynArray::Pop() { assert(this->elementCount == 0 && "Invalid DynArray::Pop() - Contains no elements"); this->elementCount -= 1; return *reinterpret_cast((this->ptr + (sizeof(T) * this->elementCount))); } template inline void DynArray::Reserve(int64_t count) { return DynArrayReserve(this, count); } template inline void DynArray::Resize(int64_t count) { DynArrayReserve(this, count); this->elementCount = count; } #endif /* FOUR_ZED_ZED_DYNAMIC_ARRAY_HPP */