|
@@ -145,26 +145,25 @@ make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.al
|
|
}
|
|
}
|
|
|
|
|
|
@(builtin, require_results)
|
|
@(builtin, require_results)
|
|
-make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T) {
|
|
|
|
|
|
+make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
|
context.allocator = allocator
|
|
context.allocator = allocator
|
|
- reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc)
|
|
|
|
- return
|
|
|
|
|
|
+ reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc) or_return
|
|
|
|
+ return array, nil
|
|
}
|
|
}
|
|
|
|
|
|
@(builtin, require_results)
|
|
@(builtin, require_results)
|
|
-make_soa_dynamic_array_len :: proc($T: typeid/#soa[dynamic]$E, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: T) {
|
|
|
|
|
|
+make_soa_dynamic_array_len :: proc($T: typeid/#soa[dynamic]$E, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
|
context.allocator = allocator
|
|
context.allocator = allocator
|
|
- resize_soa(&array, length, loc)
|
|
|
|
- return
|
|
|
|
|
|
+ resize_soa(&array, length, loc) or_return
|
|
|
|
+ return array, nil
|
|
}
|
|
}
|
|
|
|
|
|
@(builtin, require_results)
|
|
@(builtin, require_results)
|
|
-make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]$E, #any_int length, capacity: int, allocator := context.allocator, loc := #caller_location) -> (array: T) {
|
|
|
|
|
|
+make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]$E, #any_int length, capacity: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
|
context.allocator = allocator
|
|
context.allocator = allocator
|
|
- if reserve_soa(&array, capacity, loc) {
|
|
|
|
- resize_soa(&array, length, loc)
|
|
|
|
- }
|
|
|
|
- return
|
|
|
|
|
|
+ reserve_soa(&array, capacity, loc) or_return
|
|
|
|
+ resize_soa(&array, length, loc) or_return
|
|
|
|
+ return array, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -178,27 +177,25 @@ make_soa :: proc{
|
|
|
|
|
|
|
|
|
|
@builtin
|
|
@builtin
|
|
-resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> bool {
|
|
|
|
|
|
+resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
|
|
if array == nil {
|
|
if array == nil {
|
|
- return false
|
|
|
|
- }
|
|
|
|
- if !reserve_soa(array, length, loc) {
|
|
|
|
- return false
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
+ reserve_soa(array, length, loc) or_return
|
|
footer := raw_soa_footer(array)
|
|
footer := raw_soa_footer(array)
|
|
footer.len = length
|
|
footer.len = length
|
|
- return true
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
@builtin
|
|
@builtin
|
|
-reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
|
|
|
|
|
|
+reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
|
if array == nil {
|
|
if array == nil {
|
|
- return false
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
old_cap := cap(array)
|
|
old_cap := cap(array)
|
|
if capacity <= old_cap {
|
|
if capacity <= old_cap {
|
|
- return true
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
if array.allocator.procedure == nil {
|
|
if array.allocator.procedure == nil {
|
|
@@ -209,7 +206,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
|
footer := raw_soa_footer(array)
|
|
footer := raw_soa_footer(array)
|
|
if size_of(E) == 0 {
|
|
if size_of(E) == 0 {
|
|
footer.cap = capacity
|
|
footer.cap = capacity
|
|
- return true
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
ti := type_info_of(typeid_of(T))
|
|
ti := type_info_of(typeid_of(T))
|
|
@@ -240,13 +237,10 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
|
|
|
|
|
old_data := (^rawptr)(array)^
|
|
old_data := (^rawptr)(array)^
|
|
|
|
|
|
- new_bytes, err := array.allocator.procedure(
|
|
|
|
|
|
+ new_bytes := array.allocator.procedure(
|
|
array.allocator.data, .Alloc, new_size, max_align,
|
|
array.allocator.data, .Alloc, new_size, max_align,
|
|
nil, old_size, loc,
|
|
nil, old_size, loc,
|
|
- )
|
|
|
|
- if new_bytes == nil || err != nil {
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
|
|
+ ) or_return
|
|
new_data := raw_data(new_bytes)
|
|
new_data := raw_data(new_bytes)
|
|
|
|
|
|
|
|
|
|
@@ -271,31 +265,28 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
|
new_offset += type.size * capacity
|
|
new_offset += type.size * capacity
|
|
}
|
|
}
|
|
|
|
|
|
- _, err = array.allocator.procedure(
|
|
|
|
|
|
+ array.allocator.procedure(
|
|
array.allocator.data, .Free, 0, max_align,
|
|
array.allocator.data, .Free, 0, max_align,
|
|
old_data, old_size, loc,
|
|
old_data, old_size, loc,
|
|
- )
|
|
|
|
|
|
+ ) or_return
|
|
|
|
|
|
- return true
|
|
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
@builtin
|
|
@builtin
|
|
-append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) {
|
|
|
|
|
|
+append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
if array == nil {
|
|
if array == nil {
|
|
- return
|
|
|
|
|
|
+ return 0, nil
|
|
}
|
|
}
|
|
|
|
|
|
- arg_len := 1
|
|
|
|
-
|
|
|
|
- if cap(array) <= len(array)+arg_len {
|
|
|
|
- cap := 2 * cap(array) + max(8, arg_len)
|
|
|
|
- _ = reserve_soa(array, cap, loc)
|
|
|
|
|
|
+ if cap(array) <= len(array) + 1 {
|
|
|
|
+ cap := 2 * cap(array) + 8
|
|
|
|
+ err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
|
|
}
|
|
}
|
|
- arg_len = min(cap(array)-len(array), arg_len)
|
|
|
|
|
|
|
|
footer := raw_soa_footer(array)
|
|
footer := raw_soa_footer(array)
|
|
|
|
|
|
- if size_of(E) > 0 && arg_len > 0 {
|
|
|
|
|
|
+ if size_of(E) > 0 && cap(array)-len(array) > 0 {
|
|
ti := type_info_of(typeid_of(T))
|
|
ti := type_info_of(typeid_of(T))
|
|
ti = type_info_base(ti)
|
|
ti = type_info_base(ti)
|
|
si := &ti.variant.(Type_Info_Struct)
|
|
si := &ti.variant.(Type_Info_Struct)
|
|
@@ -328,12 +319,14 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat
|
|
soa_offset += type.size * cap(array)
|
|
soa_offset += type.size * cap(array)
|
|
item_offset += type.size
|
|
item_offset += type.size
|
|
}
|
|
}
|
|
|
|
+ footer.len += 1
|
|
|
|
+ return 1, err
|
|
}
|
|
}
|
|
- footer.len += arg_len
|
|
|
|
|
|
+ return 0, err
|
|
}
|
|
}
|
|
|
|
|
|
@builtin
|
|
@builtin
|
|
-append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) {
|
|
|
|
|
|
+append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
if array == nil {
|
|
if array == nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -345,7 +338,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l
|
|
|
|
|
|
if cap(array) <= len(array)+arg_len {
|
|
if cap(array) <= len(array)+arg_len {
|
|
cap := 2 * cap(array) + max(8, arg_len)
|
|
cap := 2 * cap(array) + max(8, arg_len)
|
|
- _ = reserve_soa(array, cap, loc)
|
|
|
|
|
|
+ err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
|
|
}
|
|
}
|
|
arg_len = min(cap(array)-len(array), arg_len)
|
|
arg_len = min(cap(array)-len(array), arg_len)
|
|
|
|
|
|
@@ -382,8 +375,8 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l
|
|
item_offset += type.size
|
|
item_offset += type.size
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
footer.len += arg_len
|
|
footer.len += arg_len
|
|
|
|
+ return arg_len, err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -395,21 +388,23 @@ append_soa :: proc{
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) {
|
|
|
|
|
|
+delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
|
when intrinsics.type_struct_field_count(E) != 0 {
|
|
when intrinsics.type_struct_field_count(E) != 0 {
|
|
array := array
|
|
array := array
|
|
ptr := (^rawptr)(&array)^
|
|
ptr := (^rawptr)(&array)^
|
|
- free(ptr, allocator, loc)
|
|
|
|
|
|
+ free(ptr, allocator, loc) or_return
|
|
}
|
|
}
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
-delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) {
|
|
|
|
|
|
+delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error {
|
|
when intrinsics.type_struct_field_count(E) != 0 {
|
|
when intrinsics.type_struct_field_count(E) != 0 {
|
|
array := array
|
|
array := array
|
|
ptr := (^rawptr)(&array)^
|
|
ptr := (^rawptr)(&array)^
|
|
footer := raw_soa_footer(&array)
|
|
footer := raw_soa_footer(&array)
|
|
- free(ptr, footer.allocator, loc)
|
|
|
|
|
|
+ free(ptr, footer.allocator, loc) or_return
|
|
}
|
|
}
|
|
|
|
+ return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|