Stable_Array :: struct(T: Type, ITEMS_PER_CHUNK := 32) { allocator: Allocator; chunks: [..]*Chunk; count: int; Chunk :: Static_Array(ITEMS_PER_CHUNK, T); } operator [] :: (a: Stable_Array, index: int, loc := #caller_location) -> a.T #no_abc { b_idx := index / a.ITEMS_PER_CHUNK; i_idx := index % a.ITEMS_PER_CHUNK; assert(b_idx < a.chunks.count && i_idx < a.chunks[b_idx].count); return a.chunks[b_idx].items[i_idx]; } operator *[] :: (a: *Stable_Array, index: int, loc := #caller_location) -> *a.T #no_abc { b_idx := index / a.ITEMS_PER_CHUNK; i_idx := index % a.ITEMS_PER_CHUNK; assert(b_idx < a.chunks.count && i_idx < a.chunks[b_idx].count); return *a.chunks[b_idx].items[i_idx]; } for_expansion :: (a: Stable_Array, body: Code, flags: For_Flags) #expand { for i: 0..a.count - 1 { `it := a[i]; `it_index := i; #insert,scope(body) body; } } append :: (a: *Stable_Array) -> *a.T { chunk := get_chunk(a, 1); item := append(chunk); a.count += 1; return item; } append :: (a: *Stable_Array, value: a.T) -> *a.T { chunk := get_chunk(a, 1); item := append(chunk, value); a.count += 1; return item; } append :: (a: *Stable_Array, values: ..a.T) -> *a.T { first: *a.T; for values { if first == null { first = append(a, it); } else { append(a, it); } } return first; } reset :: (a: *Stable_Array, $keep_memory := true) { #if keep_memory { for a.chunks it.count = 0; } else { for a.chunks mem.release_memory(it,, allocator = a.allocator); mem.release_memory(a.chunks); } a.count = 0; a.chunks.count = 0; } #scope_file; mem :: #import "jc/memory"; get_chunk :: (a: *Stable_Array, amount: int) -> *a.Chunk { if a.chunks.count == 0 { if a.allocator.proc == null { a.allocator = context.allocator; a.chunks.allocator = a.allocator; } return make_chunk(a); } last := a.chunks[a.chunks.count - 1]; if amount > a.ITEMS_PER_CHUNK - last.count { last = make_chunk(a); } return last; } make_chunk :: (a: *Stable_Array) -> *a.Chunk { chunk := mem.request_memory(a.Chunk,, allocator = a.allocator); append(*a.chunks, chunk); return chunk; } // #run { // #import "Basic"; // { // a: Stable_Array(int); // for 0..64 { // append(*a, it * it); // } // reset(*a, keep_memory = false); // append(*a, 10); // append(*a, 20); // append(*a, 30); // for a { // print("%: %\n", it_index, it); // } // } // }