	\
    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;						\
}										\
/* ------------------------------------------------------------------------- */
