\ assert(arr->size != 0xdeadbeef); \ assert(!AT##_IsEmpty(arr)); \ return &arr->buf[0]; \ } \ \ __TK_ARRAY_UNUSED \ static ElemType * \ AT##_Back(AT *arr) \ { \ assert(arr); \ assert(arr->size != 0xdeadbeef); \ assert(!AT##_IsEmpty(arr)); \ return &arr->buf[arr->size - 1]; \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_Resize(AT **arrp, size_t newSize) \ { \ assert(arrp); \ assert(!*arrp || (*arrp)->size != 0xdeadbeef); \ if (newSize == 0) { \ assert(!*arrp || ((*arrp)->size = 0xdeadbeef)); \ ckfree(*arrp); \ *arrp = NULL; \ } else { \ int init = *arrp == NULL; \ size_t memSize = AT##_BufferSize(newSize - 1) + sizeof(AT); \ *arrp = ckrealloc(*arrp, memSize); \ if (init) { \ (*arrp)->size = 0; \ } else if (newSize < (*arrp)->size) { \ (*arrp)->size = newSize; \ } \ (*arrp)->capacity = newSize; \ } \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_Clear(AT *arr, size_t from, size_t to) \ { \ assert(arr); \ assert(arr->size != 0xdeadbeef); \ assert(to <= AT##_Capacity(arr)); \ assert(from <= to); \ memset(arr->buf + from, 0, AT##_BufferSize(to - from)); \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_ResizeAndClear(AT **arrp, size_t newSize) \ { \ size_t oldCapacity; \ assert(arrp); \ oldCapacity = *arrp ? (*arrp)->capacity : 0; \ AT##_Resize(arrp, newSize); \ if (newSize > oldCapacity) { \ AT##_Clear(*arrp, oldCapacity, newSize); \ } \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_SetSize(AT *arr, size_t newSize) \ { \ assert(newSize <= AT##_Capacity(arr)); \ assert(!arr || arr->size != 0xdeadbeef); \ if (arr) { \ arr->size = newSize; \ } \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_Append(AT **arrp, ElemType *elem) \ { \ assert(arrp); \ if (!*arrp) { \ AT##_Resize(arrp, 1); \ } else if ((*arrp)->size == (*arrp)->capacity) { \ AT##_Resize(arrp, (*arrp)->capacity + ((*arrp)->capacity + 1)/2); \ } \ (*arrp)->buf[(*arrp)->size++] = *elem; \ } \ \ __TK_ARRAY_UNUSED \ static size_t \ AT##_PopBack(AT *arr) \ { \ assert(!AT##_IsEmpty(arr)); \ return arr->size -= 1; \ } \ \ __TK_ARRAY_UNUSED \ static ElemType * \ AT##_Get(const AT *arr, size_t at) \ { \ assert(arr); \ assert(at < AT##_Size(arr)); \ return (ElemType *) &arr->buf[at]; \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_Set(AT *arr, size_t at, ElemType *elem) \ { \ assert(arr); \ assert(at < AT##_Size(arr)); \ arr->buf[at] = *elem; \ } \ \ __TK_ARRAY_UNUSED \ static void \ AT##_Free(AT **arrp) \ { \ AT##_Resize(arrp, 0); \ } \ \ __TK_ARRAY_UNUSED \ static int \ AT##_Find(const AT *arr, const ElemType *elem) \ { \ assert(!arr || arr->size != 0xdeadbeef); \ if (arr) { \ const ElemType *buf = arr->buf; \ size_t i; \ for (i = 0; i < arr->size; ++i) { \ if (memcmp(&buf[i], elem, sizeof(ElemType)) == 0) { \ return (int) i; \ } \ } \ } \ return -1; \ } \ \ __TK_ARRAY_UNUSED \ static int \ AT##_Contains(const AT *arr, const ElemType *elem) \ { \ return AT##_Find(arr, elem) != -1; \ } \ /* ------------------------------------------------------------------------- */