Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ericlagergren/d1b7e13e4a490cde0c0b23bbe445b33c to your computer and use it in GitHub Desktop.
Save ericlagergren/d1b7e13e4a490cde0c0b23bbe445b33c to your computer and use it in GitHub Desktop.
#ifndef ListH
#define ListH
#include <stdlib.h>
#include <string.h>
#define LIST_DECLARE_EX(n,t,r) \
typedef struct list_##n { t* v; unsigned c, a; } list_##n; \
void list_init_##n (list_##n * list); \
void list_clear_##n (list_##n * list); \
int list_add_##n (list_##n * list, r item); \
void list_remove_##n (list_##n * list, r item); \
void list_remove_at_##n (list_##n * list, unsigned index); \
void list_pack_##n (list_##n * list); \
int list_find_##n (list_##n * list, r item, unsigned* idx); \
int list_find_using_##n (list_##n * list, unsigned* idx, int (*pred)(r, void*), void* data); \
void list_foreach_##n (list_##n * list, int (*func)(r, void*), void* data);
#define LIST_IMPLEMENT_EX(n,t,r,cmp,inc) \
void list_init_##n (list_##n * list) { memset(list, 0, sizeof(list_##n)); } \
void list_clear_##n (list_##n * list) { \
free(list->v); list->v = NULL; list->a = list->c = 0; } \
int list_add_##n (list_##n * list, r item) {\
if (list->c == list->a) { \
t* nt; \
list->a += inc; \
nt = realloc(list->v, sizeof(t)*list->a); \
if (!nt) { \
list->a -= inc; \
return 0; \
} \
list->v = nt; \
} \
list->v[list->c++] = item; \
return 1; \
} \
void list_remove_##n (list_##n * list, r item) { \
unsigned idx; \
if (list_find_##n(list, item, &idx)) \
list_remove_at_##n(list, idx); \
} \
void list_remove_at_##n (list_##n * list, unsigned index) { \
unsigned i; \
if (index >= list->c) return; \
list->c--; \
for (i=index; i < list->c; i++) list->v[i] = list->v[i + 1]; \
} \
void list_pack_##n (list_##n * list) { \
if (list->c && list->c != list->a) { \
t* nt = realloc(list->v, sizeof(t)*list->c); \
if (nt) { \
list->a = list->c; \
list->v = nt; \
} \
list->v = nt; \
} \
} \
int list_find_##n (list_##n * list, r item, unsigned* idx) { \
unsigned i; \
for (i=0; i < list->c; i++) \
cmp \
{ *idx = i; return 1; } \
return 0; \
} \
int list_find_using_##n (list_##n * list, unsigned* idx, int (*pred)(r, void*), void* data) { \
unsigned i; \
for (i=0; i < list->c; i++) \
if (pred(list->v[i], data)) { *idx = i; return 1; } \
return 0; \
} \
void list_foreach_##n (list_##n * list, int (*func)(r, void*), void* data) { \
unsigned i; \
for (i=0; i < list->c; i++) func(list->v[i], data); \
}
#define LIST_CMP_SIMPLE if (item == list->v[i])
#define LIST_CMP_STRUCT if (!memcmp(&item, list->v + i, sizeof(item)))
#define LIST_DECLARE_SIMPLE(n,t) LIST_DECLARE_EX(n,t,t)
#define LIST_DECLARE_STRUCT(n,t) LIST_DECLARE_EX(n,t,t)
#define LIST_IMPLEMENT_SIMPLE(n,t) LIST_IMPLEMENT_EX(n,t,t,LIST_CMP_SIMPLE,16)
#define LIST_IMPLEMENT_STRUCT(n,t) LIST_IMPLEMENT_EX(n,t,t,LIST_CMP_STRUCT,4)
LIST_DECLARE_SIMPLE(ptr,void*)
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment