#ifndef DA_H #define DA_H #include #include #define CONCAT(a, b) CONCAT_INNER(a, b) #define CONCAT_INNER(a, b) a ## b #define UNIQUE_NAME(base) CONCAT(base, __COUNTER__) #define DA_DEF_STRUCT(type, name) \ struct name { \ type *items; \ size_t size; \ size_t cap; \ } #define DA_DEF_STRUCT_ITEM(type, name) \ struct { \ type *items; \ size_t size; \ size_t cap; \ } name #define DA_CREATE(da) \ do { \ (da).cap = 16; \ (da).size = 0; \ (da).items = calloc((da).cap, sizeof(*(da).items)); \ } while(0) #define DA_DESTROY(da) \ do { \ free((da).items); \ } while(0) #define DA_INC_CAP(da) \ (da).items = _realloc((da).items, \ (da).cap, \ ((da).cap*2) * sizeof(*(da).items)); \ (da).cap *= 2; #define DA_CLEAR(da) \ do { \ (da).size = 0; \ } while(0) #define _DA_DELETE(da, index, i) \ do { \ if ( index > (da).size ) { \ break; \ } \ memmove((da).items+index, (da).items+index+1, \ (da).cap - (index+1)); \ --(da).size; \ } while(0) #define DA_DELETE(da, index) \ _DA_DELETE(da, index, UNIQUE_NAME(_i)) #define _DA_INSERT(da, item, index, i) \ do { \ if ( index > (da.size) ) { \ break; \ } \ if ( (da).size+1 >= (da).cap ) { \ DA_INC_CAP(da) \ } \ memmove((da).items+index+1, (da).items+index, \ (da).cap - index-1); \ (da).items[index] = item; \ (da).size++; \ } while(0) #define DA_INSERT(da, item, index) \ _DA_INSERT(da, item, index, UNIQUE_NAME(_i)) #define DA_APPEND(da, item) \ do { \ if ( (da).size+1 >= (da).cap ) { \ DA_INC_CAP(da) \ } \ (da).items[(da).size++] = item; \ } while(0) #define DA_TAIL(da) (da).items[(da).size-1] #define DA_ASSIGN(dst, src) \ (dst).items = (src).items; \ (dst).size = (src).size; \ (dst).cap = (src).cap; #include void * _realloc(void *old, size_t old_size, size_t new_size); #if defined(DA_IMP) || defined(IMP) #include #include void * _realloc(void *old, size_t old_size, size_t new_size) { return realloc(old, new_size); void *new = malloc(new_size); memset(new, 0, new_size); memcpy(new, old, old_size); free(old); return new; } #endif /* defined(DA_IMP) || defined(IMP) */ #endif