Kilobyte :: 1024; Megabyte :: 1024 * Kilobyte; Gigabyte :: 1024 * Megabyte; power_of_two :: (x: uint) -> bool { if x == 0 return false; return x & (x - 1) == 0; } align_forward :: (ptr: uint, align: uint = Default_Align) -> uint { basic.assert(power_of_two(align), "alignment must be a power of two"); p := ptr; mod := p & (align - 1); if mod != 0 then p += align - mod; return p; } init_or_zero :: inline (ptr: *$T, custom_init: (*T) = null) { init :: initializer_of(T); if custom_init != null { custom_init(ptr); } #if init != null { inline init(ptr); } else { memset(ptr, 0, size_of(T)); } } make :: ($T: Type, reserved := 0, $init := true) -> [..]T #modify { ok, info := type_is_array(T); if ok && info.array_type == .RESIZABLE { T = compiler.get_type(info.element_type); return true; } return false; } { size := align_forward(size_of(T) * basic.max(reserved, 0).(uint)).(sint); data := basic.alloc(size); #if init if size != 0 { memset(data, 0, size); } arr: [..]T; arr.data = data; arr.count = 0; arr.allocated = size / size_of(T); arr.allocator = context.allocator; return arr; } make :: ($T: Type, $init := true) -> *T #modify { return !type_is_array(T); } { ptr := basic.alloc(size_of(T)).(*T); #if init init_or_zero(ptr); return ptr; } #scope_file; #if RUN_TESTS #run { test :: #import,file "./test/module.jai"; test.run("make:dynamic arrays", (t) => { a1 := make([..]int); test.expect(t, a1.count == 0); test.expect(t, a1.allocated == 0); basic.array_add(*a1, 10, 20, 30); test.expect(t, a1.count == 3); test.expect(t, a1.allocated != 0, "%", a1.allocated); a2 := make([..]int, 8); test.expect(t, a2.count == 0); test.expect(t, a2.allocated == 8); }); test.run("make:values", (t) => { v1 := make(int); test.expect(t, v1.* == 0); }); }