1 2 3 4 5 6 7 8 9 10 11  | struct SlicedArray
{
	MemArena arena;
	uptr *slices[128]; /* this can be dynamic too */
	sizet sliceCount;
	sizet itemCount;
	sizet effectiveItemSize;
	sizet itemsPerSlice;
};
 | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14  | INLINE void initSlicedArray(SlicedArray *array, sizet sliceSize, sizet itemSize, u32 alignment)
{
	array->effectiveItemSize = ALIGN_POW_2(itemSize, alignment);
	/* ensure that at least one item fits */
	ASSERT(sliceSize >= (array->effectiveItemSize + sizeof(MemBlockFooter)));
	sizet effectiveSliceSize = sliceSize - sizeof(MemBlockFooter);
	array->itemsPerSlice = (effectiveSliceSize / array->effectiveItemSize);
	sizet arenaBlockSize = sliceSize;
	initArena(&array->arena, win32Allocate, win32Deallocate, arenaBlockSize);
	array->sliceCount = 0;
	array->itemCount = 0;
}
 | 
1 2 3 4 5 6 7 8 9 10 11 12  | INLINE void *pushItem(SlicedArray *array)
{
	sizet prevSliceCount = array->sliceCount;
	void *result = pushSize(&array->arena, array->effectiveItemSize, noAlignNoClear());
	++array->itemCount;
	array->sliceCount = array->arena.blockCount;
	if (prevSliceCount != array->sliceCount)
	{
		array->slices[array->sliceCount - 1] = (uptr *)array->arena.base;
	}
	return result;
}
 | 
1 2 3 4 5 6 7 8  | INLINE void *getItem(SlicedArray *array, sizet index)
{
	sizet sliceIndex = (index / array->itemsPerSlice);
	sizet itemIndex = (index % array->itemsPerSlice);
	void *slice = array->slices[sliceIndex];
	void *result = (u8 *)slice + (itemIndex * array->effectiveItemSize);
	return result;
}
 | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14  | struct Item; /* some data type */
SlicedArray array;
initSlicedArray(&array, MEGABYTES(1), sizeof(Item), 4);
Item *item = pushItem(&array); /* adding */
Item *firstItem = getItem(&array, 0); /* fetching */
/* iteration */
sizet itemIndex;
for (itemIndex = 0; itemIndex < array.itemCount; ++itemIndex)
{
	Item *item = getItem(&array, itemIndex);
}
 |