turbolist/turbolist.h

104 lines
2.3 KiB
C
Raw Normal View History

2024-08-27 15:38:03 +02:00
#ifndef TURBO_LIST_H
#define TURBO_LIST_H
2024-09-07 21:25:03 +02:00
#ifndef TL_NO_CSTDLIB
#include<cstdlib>
#endif /* TL_NO_CSTDLIB */
2024-08-27 15:38:03 +02:00
#include<stdint.h>
#include<assert.h>
#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 */
struct turbolist{
int *old;
int *nex;
uint32_t mid; // non-inclusive . . . m
uint32_t end; // non-inclusive e . . . .
uint32_t capacity;
void* (*malloc)(size_t size);
void (*free)(void*);
2024-08-27 15:38:03 +02:00
};
typedef struct turbolist turbolist;
static inline void turbolist_insert(turbolist *tl, int elem);
static TL_NOINLINE void __turbolist_grow_and_insert(turbolist *tl, int elem) {
// assert(mid == 0);
if(tl->old) tl->free(tl->old);
2024-08-27 15:38:03 +02:00
tl->old = tl->nex;
tl->mid = tl->end;
tl->capacity *= 2;
tl->nex = (int *) tl->malloc(tl->capacity * sizeof(int));
2024-08-27 15:38:03 +02:00
// Will go into the INSERT code path here
turbolist_insert(tl, elem);
}
static inline turbolist turbolist_create_adv(void* (*malloc_like)(size_t size), void (*free_like)(void*), uint32_t initial_size, uint32_t initial_cap) {
2024-08-27 15:38:03 +02:00
assert(initial_size <= initial_cap);
turbolist tl;
tl.old = NULL;
tl.mid = 0;
tl.end = initial_size;
tl.capacity = initial_cap;
tl.malloc = malloc_like;
tl.free = free_like;
tl.nex = (int *) tl.malloc(tl.capacity * sizeof(int));
2024-08-27 15:38:03 +02:00
return tl;
}
2024-09-07 21:25:03 +02:00
#ifndef TL_NO_CSTDLIB
static inline turbolist turbolist_create() {
return turbolist_create_adv(malloc, free, 0, 16);
}
2024-09-07 21:25:03 +02:00
#endif /* TL_NO_CSTDLIB */
2024-08-27 15:38:03 +02:00
static inline void turbolist_delete(turbolist *tl) {
if(tl->nex) tl->free(tl->nex);
if(tl->old) tl->free(tl->old);
2024-08-27 15:38:03 +02:00
}
static inline int turbolist_get(turbolist *tl, uint32_t i) {
return (i < tl->mid) ? tl->old[i] : tl->nex[i];
}
static inline void turbolist_insert(turbolist *tl, int elem) {
if(TL_LIKELY(tl->end < tl->capacity)) {
// INSERT
/* Same as this:
if(mid > 0) {
nex[mid - 1] = old[mid - 1];
--mid;
}
*/
bool hasmid = (tl->mid > 0);
tl->mid -= hasmid;
tl->nex[tl->mid] = hasmid ? tl->old[tl->mid] : tl->nex[tl->mid];
tl->nex[tl->end++] = elem;
} else {
// GROW
__turbolist_grow_and_insert(tl, elem);
}
}
static inline uint32_t turbolist_size(turbolist *tl) {
return tl->end;
2024-08-27 15:38:03 +02:00
}
#endif /* TURBO_LIST_H */