You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
3.8 KiB
C
55 lines
3.8 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "scoped.h"
|
|
|
|
#define ARRAY_LIST_EMPTY ((struct array_list) { NULL, 0, 0 })
|
|
|
|
struct array_list {
|
|
void *buf;
|
|
size_t len;
|
|
size_t cap;
|
|
};
|
|
|
|
int array_list_raw_alloc(struct array_list *al, size_t cap, size_t elem_size);
|
|
void array_list_raw_cleanup(struct array_list *al);
|
|
|
|
#define DEF_ARRAY_LIST_TYPE(NAME, TYPE, UNOCCUPIED, CLEANUP_FN) \
|
|
static inline TYPE *array_list_##NAME##_get(struct array_list *al, size_t i) { \
|
|
if (i >= al->len) \
|
|
return NULL; \
|
|
return &((TYPE *)al->buf)[i]; \
|
|
} \
|
|
static inline const TYPE *array_list_##NAME##_cget(const struct array_list *al, size_t i) { \
|
|
if (i >= al->len) \
|
|
return NULL; \
|
|
return &((const TYPE *)al->buf)[i]; \
|
|
} \
|
|
static inline void array_list_##NAME##_cleanup(struct array_list *al) { \
|
|
size_t i; \
|
|
for (i = 0; i < al->len; i++) \
|
|
CLEANUP_FN(array_list_##NAME##_get(al, i)); \
|
|
array_list_raw_cleanup(al); \
|
|
} \
|
|
static inline int array_list_##NAME##_alloc(struct array_list *al, size_t cap) { \
|
|
size_t i; \
|
|
if (cap < al->len) { \
|
|
for (i = cap; i < al->len; i++) \
|
|
CLEANUP_FN(array_list_##NAME##_get(al, i)); \
|
|
al->len = cap; \
|
|
} \
|
|
return array_list_raw_alloc(al, cap, sizeof(TYPE)); \
|
|
} \
|
|
static inline int array_list_##NAME##_push_noalloc_byval(struct array_list *al, TYPE elem) { \
|
|
if (al->len >= al->cap) \
|
|
return -1; \
|
|
((TYPE *)al->buf)[al->len++] = elem; \
|
|
return 0; \
|
|
} \
|
|
DEF_SCOPED_TYPE( \
|
|
array_list_##NAME, \
|
|
struct array_list, \
|
|
ARRAY_LIST_EMPTY, \
|
|
array_list_##NAME##_cleanup)
|