Created
March 8, 2017 19:17
-
-
Save ericlagergren/d1b7e13e4a490cde0c0b23bbe445b33c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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