// AMR ARRAY // GENERAL ARRAYS FOR C // > Mainly for prototyping and small internal programs // // Documentation: // // AMR_MALLOC: // malloc function, can be replace with a custom allocator (todo) // AMR_FREE: // free function, can be replace with a custom allocator (todo) // amr_arr_len: // get array length // amr_arr_cap: // get array capacity // amr_arr_init: // initialize array, see usage for how to use. // amr_arr_tinit: // initialize array with type. gets around void cast issue, annoying on // c++ // amr_arr_push(arr, value): // push an element on to the end of an array. // will not care about holes in array. // amr_arr_pushcarr(arr, carr): // push a c-style constant size array // amr_arr_join(arr_a, arr_b): // join/push all items from array b into array a // amr_arr_clear(arr): // clears array. (actually just resets the len variable of array, // since operations first work on array len, this is all // we need to "clear" it) // // Usage: // // typdef T arr_t; // optional, but recommended to signify a type is an array. // // Highlights intent, prevents confusion // // int main() { // arr_t *myarr; // amr_arr_init(myarr, capacity); // // amr_arr_push(myarr, 2); // ... // } #ifndef __AMR_INCLUDE_AMR_ARRAY_H #define __AMR_INCLUDE_AMR_ARRAY_H #include "stdlib.h" #include "assert.h" #include "string.h" struct ArrayHeader { int len; int cap; }; typedef struct ArrayHeader ArrayHeader; #define __CARR_LEN(CARR) (sizeof((CARR))/sizeof((CARR)[0])) #define AMR_MALLOC(x) malloc((x)) #define AMR_FREE(p) free((p)) #define amr_arr_len(A) ((((ArrayHeader*)(A)) - 1)->len) #define amr_arr_cap(A) ((((ArrayHeader*)(A)) -1)->cap) #define amr_arr_init(ARR, CAP) { \ ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \ H->len = 0; \ H->cap = (CAP); \ ARR = (void*)(H+1); \ } #define amr_arr_tinit(T, ARR, CAP) { \ ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \ H->len = 0; \ H->cap = (CAP); \ ARR = (T*)(H+1); \ } #define amr_arr_push(ARR, VAL) { \ ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \ assert(H->len+1 <= H->cap); \ (ARR)[H->len++] = (VAL); \ } #define amr_arr_pushcarr(ARR, ELE) { \ ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \ assert(H->len+(__CARR_LEN((ELE))) <= H->cap); \ memcpy((ARR)+H->len, (ELE), sizeof((ELE))); \ H->len += (__CARR_LEN((ELE))); \ } #define amr_arr_join(A, B) { \ ArrayHeader *HA = (ArrayHeader*)(A)-1; \ ArrayHeader *HB = (ArrayHeader*)(B)-1; \ assert(HA->len + HB->len <= HA->cap); \ memcpy((A) + HA->len, (B), sizeof((B)[0])*HB->len); \ HA->len += HB->len; \ } #define amr_arr_clear(ARR) { \ ArrayHeader *H = (ArrayHeader*)(ARR)-1; \ H->len = 0; \ } #define amr_arr_free(ARR) { \ AMR_FREE((ArrayHeader*)(ARR)-1); \ } #endif // __AMR_INCLUDE_AMR_ARRAY_H