#ifndef TURBO_LIST_HPP #define TURBO_LIST_HPP // TODO: malloclike and freelike refactor #include #include #include #ifndef TL_NOINLINE #define TL_NOINLINE __attribute__((noinline)) #endif /* TL_NOINLINE */ #ifndef TL_LIKELY #define TL_LIKELY(x) __builtin_expect(!!(x), 1) #endif /* TL_LIKELY */ #ifndef TL_UNLIKELY #define TL_UNLIKELY(x) __builtin_expect(!!(x), 0) #endif /* TL_UNLIKELY */ template class TurboList { T *old; T *nex; uint32_t mid; // non-inclusive . . . m uint32_t end; // non-inclusive e . . . . uint32_t capacity; TL_NOINLINE void grow_and_insert(T elem) noexcept { // assert(mid == 0); if(old) free(old); old = nex; mid = end; capacity *= 2; nex = (int *) malloc(this->capacity * sizeof(T)); // Will go into the INSERT code path here insert(elem); } public: inline TurboList(uint32_t initial_size = 0, uint32_t initial_cap = 16) noexcept : old(nullptr), mid(0), end(initial_size), capacity(initial_cap) { nex = (int *) malloc(this->capacity * sizeof(T)); } inline ~TurboList() noexcept { if(nex) free(nex); if(old) free(old); } inline T& operator[](uint32_t i) noexcept { return (i < mid) ? old[i] : nex[i]; } inline void insert(T elem) noexcept { if(TL_LIKELY(end < capacity)) { // INSERT /* Same as this: if(mid > 0) { nex[mid - 1] = old[mid - 1]; --mid; } */ bool hasmid = (mid > 0); mid -= hasmid; nex[mid] = hasmid ? old[mid] : nex[mid]; nex[end++] = elem; } else { // GROW grow_and_insert(elem); } } inline uint32_t size() noexcept { return mid + (capacity - end - 1); } }; #endif /* TURBO_LIST_HPP */