diff options
| author | gingerBill <bill@gingerbill.org> | 2024-07-14 23:20:50 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-07-14 23:20:50 +0100 |
| commit | 83b7dd122a533cf60673e7afc3d86e8332845ff9 (patch) | |
| tree | 97282d01022d99f98eb2f61174a2315a20c71425 /base/runtime | |
| parent | b0fbaf24a015b9ce4a2473173c5103a629596317 (diff) | |
Type erase for `append_elems`
Diffstat (limited to 'base/runtime')
| -rw-r--r-- | base/runtime/core_builtin.odin | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index a751a6151..d82164a00 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -453,9 +453,10 @@ _append_elem :: #force_inline proc(array: ^Raw_Dynamic_Array, size_of_elem, alig err = _reserve_dynamic_array(array, size_of_elem, align_of_elem, cap, should_zero, loc) } if array.cap-array.len > 0 { - assert(array.data != nil, loc=loc) - dst := ([^]byte)(array.data)[array.len*size_of_elem:] - intrinsics.mem_copy_non_overlapping(dst, arg_ptr, size_of_elem) + data := ([^]byte)(array.data) + assert(data != nil, loc=loc) + data = data[array.len*size_of_elem:] + intrinsics.mem_copy_non_overlapping(data, arg_ptr, size_of_elem) array.len += 1 return 1, err } @@ -484,53 +485,53 @@ non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc : } } -_append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, loc := #caller_location, args: []E) -> (n: int, err: Allocator_Error) #optional_allocator_error { +_append_elems :: #force_inline proc(array: ^Raw_Dynamic_Array, size_of_elem, align_of_elem: int, should_zero: bool, loc := #caller_location, args: rawptr, arg_len: int) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } - arg_len := len(args) if arg_len <= 0 { return 0, nil } - when size_of(E) == 0 { - array := (^Raw_Dynamic_Array)(array) + if array.cap < array.len+arg_len { + cap := 2 * array.cap + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) + + // do not 'or_return' here as it could be a partial success + err = _reserve_dynamic_array(array, size_of_elem, align_of_elem, cap, should_zero, loc) + } + arg_len := arg_len + arg_len = min(array.cap-array.len, arg_len) + if arg_len > 0 { + data := ([^]byte)(array.data) + assert(data != nil, loc=loc) + data = data[array.len*size_of_elem:] + intrinsics.mem_copy(data, args, size_of_elem * arg_len) // must be mem_copy (overlapping) array.len += arg_len - return arg_len, nil - } else { - if cap(array) < len(array)+arg_len { - cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) - - // do not 'or_return' here as it could be a partial success - if should_zero { - err = reserve(array, cap, loc) - } else { - err = non_zero_reserve(array, cap, loc) - } - } - arg_len = min(cap(array)-len(array), arg_len) - if arg_len > 0 { - a := (^Raw_Dynamic_Array)(array) - when size_of(E) != 0 { - data := ([^]E)(a.data) - assert(data != nil, loc=loc) - intrinsics.mem_copy(&data[a.len], raw_data(args), size_of(E) * arg_len) - } - a.len += arg_len - } - return arg_len, err } + return arg_len, err } @builtin append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { - return _append_elems(array, true, loc, args) + when size_of(E) == 0 { + a := (^Raw_Dynamic_Array)(array) + a.len += len(args) + return len(args), nil + } else { + return _append_elems((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), true, loc, raw_data(args), len(args)) + } } @builtin non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { - return _append_elems(array, false, loc, args) + when size_of(E) == 0 { + a := (^Raw_Dynamic_Array)(array) + a.len += len(args) + return len(args), nil + } else { + return _append_elems((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), false, loc, raw_data(args), len(args)) + } } // The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type |