jc/memory.jai

91 lines
1.9 KiB
Text

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);
});
}