mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
Improve error handling for resize and reserve procedures
This commit is contained in:
@@ -177,12 +177,10 @@ decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocato
|
|||||||
max_output_size := decompress_bound(len(input), model)
|
max_output_size := decompress_bound(len(input), model)
|
||||||
|
|
||||||
buf: [dynamic]u8
|
buf: [dynamic]u8
|
||||||
if !resize(&buf, max_output_size) {
|
resize(&buf, max_output_size) or_return
|
||||||
return "", .Out_Of_Memory
|
|
||||||
}
|
|
||||||
|
|
||||||
length, result := decompress_slice_to_output_buffer(input, buf[:])
|
length, result := decompress_slice_to_output_buffer(input, buf[:])
|
||||||
resize(&buf, length)
|
resize(&buf, length) or_return
|
||||||
return string(buf[:]), result
|
return string(buf[:]), result
|
||||||
}
|
}
|
||||||
decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string}
|
decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string}
|
||||||
@@ -307,12 +305,10 @@ compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := cont
|
|||||||
max_output_size := compress_bound(len(input))
|
max_output_size := compress_bound(len(input))
|
||||||
|
|
||||||
buf: [dynamic]u8
|
buf: [dynamic]u8
|
||||||
if !resize(&buf, max_output_size) {
|
resize(&buf, max_output_size) or_return
|
||||||
return {}, .Out_Of_Memory
|
|
||||||
}
|
|
||||||
|
|
||||||
length, result := compress_string_to_buffer(input, buf[:])
|
length, result := compress_string_to_buffer(input, buf[:])
|
||||||
resize(&buf, length)
|
resize(&buf, length) or_return
|
||||||
return buf[:length], result
|
return buf[:length], result
|
||||||
}
|
}
|
||||||
compress :: proc{compress_string_to_buffer, compress_string}
|
compress :: proc{compress_string_to_buffer, compress_string}
|
||||||
@@ -634,7 +634,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator :=
|
|||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
// Can we allocate the return buffer?
|
// Can we allocate the return buffer?
|
||||||
if !resize(&buf.buf, bytes_wanted) {
|
if resize(&buf.buf, bytes_wanted) != nil {
|
||||||
delete(buf.buf)
|
delete(buf.buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -826,7 +826,7 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
|
|||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
// Can we allocate the return buffer?
|
// Can we allocate the return buffer?
|
||||||
if !resize(&buf.buf, bytes_wanted) {
|
if resize(&buf.buf, bytes_wanted) != nil {
|
||||||
delete(buf.buf)
|
delete(buf.buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -1075,7 +1075,7 @@ apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := con
|
|||||||
// Can we allocate the return buffer?
|
// Can we allocate the return buffer?
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
|
bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
|
||||||
if !resize(&buf.buf, bytes_wanted) {
|
if resize(&buf.buf, bytes_wanted) != nil {
|
||||||
delete(buf.buf)
|
delete(buf.buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -1112,7 +1112,7 @@ apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := c
|
|||||||
// Can we allocate the return buffer?
|
// Can we allocate the return buffer?
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
|
bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
|
||||||
if !resize(&buf.buf, bytes_wanted) {
|
if resize(&buf.buf, bytes_wanted) != nil {
|
||||||
delete(buf.buf)
|
delete(buf.buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -1147,7 +1147,7 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo
|
|||||||
// Can we allocate the return buffer?
|
// Can we allocate the return buffer?
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
|
bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
|
||||||
if !resize(&buf.buf, bytes_wanted) {
|
if resize(&buf.buf, bytes_wanted) != nil {
|
||||||
delete(buf.buf)
|
delete(buf.buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -731,7 +731,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
// We need to create a new image buffer
|
// We need to create a new image buffer
|
||||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
||||||
t := bytes.Buffer{}
|
t := bytes.Buffer{}
|
||||||
if !resize(&t.buf, dest_raw_size) {
|
if resize(&t.buf, dest_raw_size) != nil {
|
||||||
return {}, .Unable_To_Allocate_Or_Resize
|
return {}, .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,7 +812,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
// We need to create a new image buffer
|
// We need to create a new image buffer
|
||||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16)
|
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16)
|
||||||
t := bytes.Buffer{}
|
t := bytes.Buffer{}
|
||||||
if !resize(&t.buf, dest_raw_size) {
|
if resize(&t.buf, dest_raw_size) != nil {
|
||||||
return {}, .Unable_To_Allocate_Or_Resize
|
return {}, .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,7 +1011,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
// We need to create a new image buffer
|
// We need to create a new image buffer
|
||||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
||||||
t := bytes.Buffer{}
|
t := bytes.Buffer{}
|
||||||
if !resize(&t.buf, dest_raw_size) {
|
if resize(&t.buf, dest_raw_size) != nil {
|
||||||
return {}, .Unable_To_Allocate_Or_Resize
|
return {}, .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1522,7 +1522,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
|
|||||||
bytes_per_channel := depth == 16 ? 2 : 1
|
bytes_per_channel := depth == 16 ? 2 : 1
|
||||||
|
|
||||||
num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8)
|
num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8)
|
||||||
if !resize(&img.pixels.buf, num_bytes) {
|
if resize(&img.pixels.buf, num_bytes) != nil {
|
||||||
return .Unable_To_Allocate_Or_Resize
|
return .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1564,7 +1564,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
|
|||||||
if x > 0 && y > 0 {
|
if x > 0 && y > 0 {
|
||||||
temp: bytes.Buffer
|
temp: bytes.Buffer
|
||||||
temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8)
|
temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8)
|
||||||
if !resize(&temp.buf, temp_len) {
|
if resize(&temp.buf, temp_len) != nil {
|
||||||
return .Unable_To_Allocate_Or_Resize
|
return .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
|
|||||||
// Calculate and allocate maximum size. We'll reclaim space to actually written output at the end.
|
// Calculate and allocate maximum size. We'll reclaim space to actually written output at the end.
|
||||||
max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be)
|
max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be)
|
||||||
|
|
||||||
if !resize(&output.buf, max_size) {
|
if resize(&output.buf, max_size) != nil {
|
||||||
return .Unable_To_Allocate_Or_Resize
|
return .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
|
|
||||||
bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8)
|
bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8)
|
||||||
|
|
||||||
if !resize(&img.pixels.buf, bytes_needed) {
|
if resize(&img.pixels.buf, bytes_needed) != nil {
|
||||||
return img, .Unable_To_Allocate_Or_Resize
|
return img, .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
|
|||||||
// Calculate and allocate necessary space.
|
// Calculate and allocate necessary space.
|
||||||
necessary := pixels * img.channels + size_of(image.TGA_Header)
|
necessary := pixels * img.channels + size_of(image.TGA_Header)
|
||||||
|
|
||||||
if !resize(&output.buf, necessary) {
|
if resize(&output.buf, necessary) != nil {
|
||||||
return .Unable_To_Allocate_Or_Resize
|
return .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !resize(&img.pixels.buf, dest_channels * img.width * img.height) {
|
if resize(&img.pixels.buf, dest_channels * img.width * img.height) != nil {
|
||||||
return img, .Unable_To_Allocate_Or_Resize
|
return img, .Unable_To_Allocate_Or_Resize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -289,10 +289,9 @@ reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int, loc := #caller_location) ->
|
|||||||
Shrinks the capacity of a map down to the current length.
|
Shrinks the capacity of a map down to the current length.
|
||||||
*/
|
*/
|
||||||
@builtin
|
@builtin
|
||||||
shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool) {
|
shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
err := map_shrink_dynamic((^Raw_Map)(m), map_info(T), loc)
|
return map_shrink_dynamic((^Raw_Map)(m), map_info(T), loc)
|
||||||
did_shrink = err == nil
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -315,18 +314,18 @@ delete_key :: proc(m: ^$T/map[$K]$V, key: K) -> (deleted_key: K, deleted_value:
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> int {
|
append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return 0
|
return 0, nil
|
||||||
}
|
}
|
||||||
when size_of(E) == 0 {
|
when size_of(E) == 0 {
|
||||||
array := (^Raw_Dynamic_Array)(array)
|
array := (^Raw_Dynamic_Array)(array)
|
||||||
array.len += 1
|
array.len += 1
|
||||||
return 1
|
return 1, nil
|
||||||
} else {
|
} else {
|
||||||
if cap(array) < len(array)+1 {
|
if cap(array) < len(array)+1 {
|
||||||
cap := 2 * cap(array) + max(8, 1)
|
cap := 2 * cap(array) + max(8, 1)
|
||||||
_ = reserve(array, cap, loc)
|
err = reserve(array, cap, loc) // do not 'or_return' here as it could be a partial success
|
||||||
}
|
}
|
||||||
if cap(array)-len(array) > 0 {
|
if cap(array)-len(array) > 0 {
|
||||||
a := (^Raw_Dynamic_Array)(array)
|
a := (^Raw_Dynamic_Array)(array)
|
||||||
@@ -336,31 +335,31 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) ->
|
|||||||
data[a.len] = arg
|
data[a.len] = arg
|
||||||
}
|
}
|
||||||
a.len += 1
|
a.len += 1
|
||||||
return 1
|
return 1, err
|
||||||
}
|
}
|
||||||
return 0
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> int {
|
append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return 0
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_len := len(args)
|
arg_len := len(args)
|
||||||
if arg_len <= 0 {
|
if arg_len <= 0 {
|
||||||
return 0
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
when size_of(E) == 0 {
|
when size_of(E) == 0 {
|
||||||
array := (^Raw_Dynamic_Array)(array)
|
array := (^Raw_Dynamic_Array)(array)
|
||||||
array.len += arg_len
|
array.len += arg_len
|
||||||
return arg_len
|
return arg_len, nil
|
||||||
} else {
|
} else {
|
||||||
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(array, cap, loc)
|
err = reserve(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)
|
||||||
if arg_len > 0 {
|
if arg_len > 0 {
|
||||||
@@ -372,13 +371,13 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location)
|
|||||||
}
|
}
|
||||||
a.len += arg_len
|
a.len += arg_len
|
||||||
}
|
}
|
||||||
return arg_len
|
return arg_len, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type
|
// The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type
|
||||||
@builtin
|
@builtin
|
||||||
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> int {
|
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
||||||
args := transmute([]E)arg
|
args := transmute([]E)arg
|
||||||
return append_elems(array=array, args=args, loc=loc)
|
return append_elems(array=array, args=args, loc=loc)
|
||||||
}
|
}
|
||||||
@@ -386,9 +385,14 @@ append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #ca
|
|||||||
|
|
||||||
// The append_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type
|
// The append_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type
|
||||||
@builtin
|
@builtin
|
||||||
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int) {
|
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
||||||
|
n_arg: int
|
||||||
for arg in args {
|
for arg in args {
|
||||||
n += append(array = array, args = transmute([]E)(arg), loc = loc)
|
n_arg, err = append(array = array, args = transmute([]E)(arg), loc = loc)
|
||||||
|
n += n_arg
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -398,18 +402,18 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> int {
|
append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return 0
|
return 0, nil
|
||||||
}
|
}
|
||||||
prev_len := len(array)
|
prev_len := len(array)
|
||||||
resize(array, len(array)+1, loc)
|
resize(array, len(array)+1, loc) or_return
|
||||||
return len(array)-prev_len
|
return len(array)-prev_len, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -417,18 +421,17 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle
|
|||||||
m :: 1
|
m :: 1
|
||||||
new_size := n + m
|
new_size := n + m
|
||||||
|
|
||||||
if resize(array, new_size, loc) {
|
resize(array, new_size, loc) or_return
|
||||||
when size_of(E) != 0 {
|
when size_of(E) != 0 {
|
||||||
copy(array[index + m:], array[index:])
|
copy(array[index + m:], array[index:])
|
||||||
array[index] = arg
|
array[index] = arg
|
||||||
}
|
}
|
||||||
ok = true
|
ok = true
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -441,18 +444,17 @@ inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #c
|
|||||||
m := len(args)
|
m := len(args)
|
||||||
new_size := n + m
|
new_size := n + m
|
||||||
|
|
||||||
if resize(array, new_size, loc) {
|
resize(array, new_size, loc) or_return
|
||||||
when size_of(E) != 0 {
|
when size_of(E) != 0 {
|
||||||
copy(array[index + m:], array[index:])
|
copy(array[index + m:], array[index:])
|
||||||
copy(array[index:], args)
|
copy(array[index:], args)
|
||||||
}
|
}
|
||||||
ok = true
|
ok = true
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -465,11 +467,10 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string
|
|||||||
m := len(arg)
|
m := len(arg)
|
||||||
new_size := n + m
|
new_size := n + m
|
||||||
|
|
||||||
if resize(array, new_size, loc) {
|
resize(array, new_size, loc) or_return
|
||||||
copy(array[index+m:], array[index:])
|
copy(array[index+m:], array[index:])
|
||||||
copy(array[index:], arg)
|
copy(array[index:], arg)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,11 +479,12 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if index < len(array) {
|
if index < len(array) {
|
||||||
array[index] = arg
|
array[index] = arg
|
||||||
ok = true
|
ok = true
|
||||||
} else if resize(array, index+1, loc) {
|
} else {
|
||||||
|
resize(array, index+1, loc) or_return
|
||||||
array[index] = arg
|
array[index] = arg
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -491,11 +493,12 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if index+len(args) < len(array) {
|
if index+len(args) < len(array) {
|
||||||
copy(array[index:], args)
|
copy(array[index:], args)
|
||||||
ok = true
|
ok = true
|
||||||
} else if resize(array, index+1+len(args), loc) {
|
} else {
|
||||||
|
resize(array, index+1+len(args), loc) or_return
|
||||||
copy(array[index:], args)
|
copy(array[index:], args)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -504,13 +507,14 @@ assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #c
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool) #no_bounds_check {
|
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ok = true
|
ok = true
|
||||||
} else if index+len(args) < len(array) {
|
} else if index+len(args) < len(array) {
|
||||||
copy(array[index:], args)
|
copy(array[index:], args)
|
||||||
ok = true
|
ok = true
|
||||||
} else if resize(array, index+1+len(args), loc) {
|
} else {
|
||||||
|
resize(array, index+1+len(args), loc) or_return
|
||||||
copy(array[index:], args)
|
copy(array[index:], args)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -530,14 +534,14 @@ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
|
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
a := (^Raw_Dynamic_Array)(array)
|
a := (^Raw_Dynamic_Array)(array)
|
||||||
|
|
||||||
if capacity <= a.cap {
|
if capacity <= a.cap {
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.allocator.procedure == nil {
|
if a.allocator.procedure == nil {
|
||||||
@@ -549,26 +553,26 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal
|
|||||||
new_size := capacity * size_of(E)
|
new_size := capacity * size_of(E)
|
||||||
allocator := a.allocator
|
allocator := a.allocator
|
||||||
|
|
||||||
new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc)
|
new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return
|
||||||
if new_data == nil || err != nil {
|
if new_data == nil && new_size > 0 {
|
||||||
return false
|
return .Out_Of_Memory
|
||||||
}
|
}
|
||||||
|
|
||||||
a.data = raw_data(new_data)
|
a.data = raw_data(new_data)
|
||||||
a.cap = capacity
|
a.cap = capacity
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> bool {
|
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
a := (^Raw_Dynamic_Array)(array)
|
a := (^Raw_Dynamic_Array)(array)
|
||||||
|
|
||||||
if length <= a.cap {
|
if length <= a.cap {
|
||||||
a.len = max(length, 0)
|
a.len = max(length, 0)
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.allocator.procedure == nil {
|
if a.allocator.procedure == nil {
|
||||||
@@ -580,15 +584,15 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller
|
|||||||
new_size := length * size_of(E)
|
new_size := length * size_of(E)
|
||||||
allocator := a.allocator
|
allocator := a.allocator
|
||||||
|
|
||||||
new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc)
|
new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return
|
||||||
if new_data == nil || err != nil {
|
if new_data == nil && new_size > 0 {
|
||||||
return false
|
return .Out_Of_Memory
|
||||||
}
|
}
|
||||||
|
|
||||||
a.data = raw_data(new_data)
|
a.data = raw_data(new_data)
|
||||||
a.len = length
|
a.len = length
|
||||||
a.cap = length
|
a.cap = length
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -600,7 +604,7 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller
|
|||||||
|
|
||||||
If `len(array) < new_cap`, then `len(array)` will be left unchanged.
|
If `len(array) < new_cap`, then `len(array)` will be left unchanged.
|
||||||
*/
|
*/
|
||||||
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #caller_location) -> (did_shrink: bool) {
|
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -620,15 +624,12 @@ shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #call
|
|||||||
old_size := a.cap * size_of(E)
|
old_size := a.cap * size_of(E)
|
||||||
new_size := new_cap * size_of(E)
|
new_size := new_cap * size_of(E)
|
||||||
|
|
||||||
new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), a.allocator, loc)
|
new_data := mem_resize(a.data, old_size, new_size, align_of(E), a.allocator, loc) or_return
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
a.data = raw_data(new_data)
|
a.data = raw_data(new_data)
|
||||||
a.len = min(new_cap, a.len)
|
a.len = min(new_cap, a.len)
|
||||||
a.cap = new_cap
|
a.cap = new_cap
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
|
|||||||
Reference in New Issue
Block a user