-
Notifications
You must be signed in to change notification settings - Fork 3
/
raw_dynamic_array_helpers.odin
47 lines (39 loc) · 1.4 KB
/
raw_dynamic_array_helpers.odin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package ecs
import "core:runtime"
import "core:intrinsics"
// Copied and adjusted from here: https://github.com/odin-lang/Odin/blob/8fd318ea7a76b75974c834bb9d329958c81ce652/base/runtime/core_builtin.odin#L736
@private
// `resize_raw_dynamic_array` will try to resize memory of a passed raw dynamic array or map to the requested element count (setting the `len`, and possibly `cap`).
__resize_raw_dynamic_array :: #force_inline proc(array: rawptr, elem_size, elem_align: int, length: int, should_zero: bool, loc := #caller_location) -> runtime.Allocator_Error {
if array == nil {
return nil
}
a := (^runtime.Raw_Dynamic_Array)(array)
if length <= a.cap {
if should_zero && a.len < length {
intrinsics.mem_zero(([^]byte)(a.data)[a.len*elem_size:], (length-a.len)*elem_size)
}
a.len = max(length, 0)
return nil
}
if a.allocator.procedure == nil {
a.allocator = context.allocator
}
assert(a.allocator.procedure != nil)
old_size := a.cap * elem_size
new_size := length * elem_size
allocator := a.allocator
new_data : []byte
if should_zero {
new_data = runtime.mem_resize(a.data, old_size, new_size, elem_align, allocator, loc) or_return
} else {
new_data = runtime.non_zero_mem_resize(a.data, old_size, new_size, elem_align, allocator, loc) or_return
}
if new_data == nil && new_size > 0 {
return .Out_Of_Memory
}
a.data = raw_data(new_data)
a.len = length
a.cap = length
return nil
}