Browse Source

Add `non_zero_*` variants for `#soa` dynamic array

gingerBill 1 year ago
parent
commit
942f3f5220
2 changed files with 61 additions and 6 deletions
  1. 18 3
      base/runtime/core_builtin.odin
  2. 43 3
      base/runtime/core_builtin_soa.odin

+ 18 - 3
base/runtime/core_builtin.odin

@@ -180,7 +180,11 @@ reserve :: proc{
 }
 }
 
 
 @builtin
 @builtin
-non_zero_reserve :: proc{non_zero_reserve_dynamic_array}
+non_zero_reserve :: proc{
+	non_zero_reserve_dynamic_array,
+
+	non_zero_reserve_soa,
+}
 
 
 // `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`).
 // `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`).
 @builtin
 @builtin
@@ -191,7 +195,11 @@ resize :: proc{
 }
 }
 
 
 @builtin
 @builtin
-non_zero_resize :: proc{non_zero_resize_dynamic_array}
+non_zero_resize :: proc{
+	non_zero_resize_dynamic_array,
+
+	non_zero_resize_soa,
+}
 
 
 // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity.
 // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity.
 @builtin
 @builtin
@@ -569,7 +577,14 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_
 	append_soa_elems,
 	append_soa_elems,
 }
 }
 
 
-@builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string}
+@builtin non_zero_append :: proc{
+	non_zero_append_elem,
+	non_zero_append_elems,
+	non_zero_append_elem_string,
+
+	non_zero_append_soa_elem,
+	non_zero_append_soa_elems,
+}
 
 
 
 
 @builtin
 @builtin

+ 43 - 3
base/runtime/core_builtin_soa.odin

@@ -182,8 +182,28 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_locat
 	return nil
 	return nil
 }
 }
 
 
+@builtin
+non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
+	if array == nil {
+		return nil
+	}
+	non_zero_reserve_soa(array, length, loc) or_return
+	footer := raw_soa_footer(array)
+	footer.len = length
+	return nil
+}
+
 @builtin
 @builtin
 reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
 reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
+	return _reserve_soa(array, capacity, true, loc)
+}
+
+@builtin
+non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
+	return _reserve_soa(array, capacity, false, loc)
+}
+
+_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, zero_memory: bool, loc := #caller_location) -> Allocator_Error {
 	if array == nil {
 	if array == nil {
 		return nil
 		return nil
 	}
 	}
@@ -228,7 +248,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
 	old_data := (^rawptr)(array)^
 	old_data := (^rawptr)(array)^
 
 
 	new_bytes := array.allocator.procedure(
 	new_bytes := array.allocator.procedure(
-		array.allocator.data, .Alloc, new_size, max_align,
+		array.allocator.data, .Alloc if zero_memory else .Alloc_Non_Zeroed, new_size, max_align,
 		nil, old_size, loc,
 		nil, old_size, loc,
 	) or_return
 	) or_return
 	new_data := raw_data(new_bytes)
 	new_data := raw_data(new_bytes)
@@ -263,8 +283,18 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
 	return nil
 	return nil
 }
 }
 
 
+
 @builtin
 @builtin
 append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+	return _append_soa_elem(array, true, arg, loc)
+}
+
+@builtin
+non_zero_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+	return _append_soa_elem(array, false, arg, loc)
+}
+
+_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	if array == nil {
 	if array == nil {
 		return 0, nil
 		return 0, nil
 	}
 	}
@@ -272,7 +302,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc :=
 	if cap(array) <= len(array) + 1 {
 	if cap(array) <= len(array) + 1 {
 		// Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY.
 		// Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY.
 		cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY
 		cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY
-		err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
+		err = _reserve_soa(array, cap, zero_memory, loc) // do not 'or_return' here as it could be a partial success
 	}
 	}
 
 
 	footer := raw_soa_footer(array)
 	footer := raw_soa_footer(array)
@@ -313,6 +343,16 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc :=
 
 
 @builtin
 @builtin
 append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+	return _append_soa_elems(array, true, args=args, loc=loc)
+}
+
+@builtin
+non_zero_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
+	return _append_soa_elems(array, false, args=args, loc=loc)
+}
+
+
+_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
 	if array == nil {
 	if array == nil {
 		return
 		return
 	}
 	}
@@ -324,7 +364,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, lo
 
 
 	if cap(array) <= len(array)+arg_len {
 	if cap(array) <= len(array)+arg_len {
 		cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len)
 		cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len)
-		err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
+		err = _reserve_soa(array, cap, zero_memory, 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)