diff --git a/array/stable_array.jai b/array/stable_array.jai index f26c5a0..3fdbfab 100644 --- a/array/stable_array.jai +++ b/array/stable_array.jai @@ -6,20 +6,71 @@ Stable_Array :: struct(T: Type, ITEMS_PER_CHUNK := 32) { Chunk :: Static_Array(ITEMS_PER_CHUNK, T); } +init :: (a: *Stable_Array, allocator: Allocator) { + a.allocator = allocator; + a.chunks.allocator = allocator; +} + +append :: (a: *Stable_Array) -> *a.T { + chunk := find_or_create_chunk(a, 1); + item := append(chunk); + a.count += 1; + return item; +} + +append :: (a: *Stable_Array, value: a.T) -> *a.T { + chunk := find_or_create_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 = inline append(a, it); + } + else { + inline append(a, it); + } + } + + return first; +} + +reset :: (a: *Stable_Array) { + for a.chunks it.count = 0; + a.count = 0; + a.chunks.count = 0; +} + 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); + meta.check_bounds(b_idx, a.chunks.count, loc = loc); + meta.check_bounds(i_idx, a.chunks[b_idx].count, loc = loc); 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); + meta.check_bounds(b_idx, a.chunks.count, loc = loc); + meta.check_bounds(i_idx, a.chunks[b_idx].count, loc = loc); return *a.chunks[b_idx].items[i_idx]; } +operator []= :: (a: *Stable_Array, index: int, value: a.T, loc := #caller_location) #no_abc { + c_idx := index / a.ITEMS_PER_CHUNK; + i_idx := index % a.ITEMS_PER_CHUNK; + meta.check_bounds(c_idx, a.chunks.count, loc = loc); + meta.check_bounds(i_idx, a.chunks[b_idx].count, loc = loc); + + chunk := a.chunks[c_idx]; + chunk.items[i_idx] = value; +} + for_expansion :: (a: Stable_Array, body: Code, flags: For_Flags) #expand { for i: 0..a.count - 1 { `it := a[i]; @@ -28,76 +79,38 @@ for_expansion :: (a: Stable_Array, body: Code, flags: For_Flags) #expand { } } -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"; +meta :: #import "jc/meta"; -get_chunk :: (a: *Stable_Array, amount: int) -> *a.Chunk { +find_or_create_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); + return create_chunk(a); } last := a.chunks[a.chunks.count - 1]; if amount > a.ITEMS_PER_CHUNK - last.count { - last = make_chunk(a); + last = create_chunk(a); } return last; } -make_chunk :: (a: *Stable_Array) -> *a.Chunk { +create_chunk :: (a: *Stable_Array) -> *a.Chunk { + inline try_lazy_init(a); + chunk := mem.request_memory(a.Chunk,, allocator = a.allocator); append(*a.chunks, chunk); return chunk; } +try_lazy_init :: (a: *Stable_Array) { + if a.allocator.proc == null { + init(a, context.allocator); + } +} + // #run { // #import "Basic"; @@ -107,7 +120,7 @@ make_chunk :: (a: *Stable_Array) -> *a.Chunk { // append(*a, it * it); // } -// reset(*a, keep_memory = false); +// reset(*a); // append(*a, 10); // append(*a, 20); diff --git a/array/static_array.jai b/array/static_array.jai index 95c3ab3..0ff24a0 100644 --- a/array/static_array.jai +++ b/array/static_array.jai @@ -5,18 +5,18 @@ Static_Array :: struct(capacity: int, T: Type) { Default :: #run mem.default_of(T); } -operator [] :: inline (a: Static_Array, index: int, loc := #caller_location) -> a.T #no_abc { - assert(index >= 0 && index < a.count, "invalid index: % (max: %)", index, a.count - 1, loc = loc); +operator [] :: inline (a: Static_Array, $$index: int, loc := #caller_location) -> a.T #no_abc { + meta.check_bounds(index, a.count, loc = loc); return a.items[index]; } -operator *[] :: inline (a: *Static_Array, index: int, loc := #caller_location) -> *a.T #no_abc { - assert(index >= 0 && index < a.count, "invalid index: % (max: %)", index, a.count - 1, loc = loc); +operator *[] :: inline (a: *Static_Array, $$index: int, loc := #caller_location) -> *a.T #no_abc { + meta.check_bounds(index, a.count, loc = loc); return *a.items[index]; } -operator []= :: inline (a: *Static_Array, index: int, value: a.T, loc := #caller_location) #no_abc { - assert(index >= 0 && index < a.capacity, "invalid index: % (max: %)", index, a.count - 1, loc = loc); +operator []= :: inline (a: *Static_Array, $$index: int, value: a.T, loc := #caller_location) #no_abc { + meta.check_bounds(index, a.count, loc = loc); a.items[index] = value; } @@ -27,7 +27,7 @@ for_expansion :: (a: *Static_Array, body: Code, flags: For_Flags) #expand { } } -append :: inline (a: *Static_Array, item: a.T) -> *a.T { +append :: inline (a: *Static_Array, item: a.T) -> *a.T #no_abc { ensure_array_has_room(a, 1); ptr := *a.items[a.count]; ptr.* = item; @@ -35,14 +35,14 @@ append :: inline (a: *Static_Array, item: a.T) -> *a.T { return ptr; } -append :: inline (a: *Static_Array) -> *a.T { +append :: inline (a: *Static_Array) -> *a.T #no_abc { ensure_array_has_room(a, 1); ptr := *a.items[a.count]; a.count += 1; return ptr; } -append :: inline (a: *Static_Array, items: ..a.T) -> *a.T { +append :: inline (a: *Static_Array, items: ..a.T) -> *a.T #no_abc { ensure_array_has_room(a, items.count); first := *a.items[a.count]; memcpy(a.items.data + a.count, items.data, items.count * size_of(a.T)); @@ -50,8 +50,8 @@ append :: inline (a: *Static_Array, items: ..a.T) -> *a.T { return first; } -reset :: inline (a: *Static_Array, $keep_memory := true) { - #if !keep_memory for 0..a.count - 1 a.items[it] = a.Default; +reset :: inline (a: *Static_Array) #no_abc { + for 0..a.count - 1 a.items[it] = a.Default; a.count = 0; } @@ -77,6 +77,8 @@ ensure_array_has_room :: (array: *Static_Array, count: int, loc := #caller_locat } mem :: #import "jc/memory"; +meta :: #import "jc/meta"; + basic :: #import "Basic"; // @future