|
@@ -62,6 +62,8 @@ when !NO_DEFAULT_TEMP_ALLOCATOR {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Initializes the global temporary allocator used as the default `context.temp_allocator`.
|
|
|
|
+// This is ignored when `NO_DEFAULT_TEMP_ALLOCATOR` is true.
|
|
@(builtin, disabled=NO_DEFAULT_TEMP_ALLOCATOR)
|
|
@(builtin, disabled=NO_DEFAULT_TEMP_ALLOCATOR)
|
|
init_global_temporary_allocator :: proc(size: int, backup_allocator := context.allocator) {
|
|
init_global_temporary_allocator :: proc(size: int, backup_allocator := context.allocator) {
|
|
when !NO_DEFAULT_TEMP_ALLOCATOR {
|
|
when !NO_DEFAULT_TEMP_ALLOCATOR {
|
|
@@ -564,6 +566,7 @@ _append_elem :: #force_no_inline proc(array: ^Raw_Dynamic_Array, size_of_elem, a
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `append_elem` appends an element to the end of a dynamic array.
|
|
@builtin
|
|
@builtin
|
|
append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
when size_of(E) == 0 {
|
|
when size_of(E) == 0 {
|
|
@@ -575,6 +578,9 @@ append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `non_zero_append_elem` appends an element to the end of a dynamic array, without zeroing any reserved memory
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `non_zero_append
|
|
@builtin
|
|
@builtin
|
|
non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
non_zero_append_elem :: proc(array: ^$T/[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
when size_of(E) == 0 {
|
|
when size_of(E) == 0 {
|
|
@@ -613,6 +619,9 @@ _append_elems :: #force_no_inline proc(array: ^Raw_Dynamic_Array, size_of_elem,
|
|
return arg_len, err
|
|
return arg_len, err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `append_elems` appends `args` to the end of a dynamic array.
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `append`.
|
|
@builtin
|
|
@builtin
|
|
append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
when size_of(E) == 0 {
|
|
when size_of(E) == 0 {
|
|
@@ -624,6 +633,9 @@ append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #ca
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `non_zero_append_elems` appends `args` to the end of a dynamic array, without zeroing any reserved memory
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `non_zero_append
|
|
@builtin
|
|
@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 {
|
|
non_zero_append_elems :: proc(array: ^$T/[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
when size_of(E) == 0 {
|
|
when size_of(E) == 0 {
|
|
@@ -640,10 +652,16 @@ _append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, should_ze
|
|
return _append_elems((^Raw_Dynamic_Array)(array), 1, 1, should_zero, loc, raw_data(arg), len(arg))
|
|
return _append_elems((^Raw_Dynamic_Array)(array), 1, 1, should_zero, loc, raw_data(arg), len(arg))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `append_elem_string` appends a string to the end of a dynamic array of bytes
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `append`.
|
|
@builtin
|
|
@builtin
|
|
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
return _append_elem_string(array, arg, true, loc)
|
|
return _append_elem_string(array, arg, true, loc)
|
|
}
|
|
}
|
|
|
|
+// `non_zero_append_elem_string` appends a string to the end of a dynamic array of bytes, without zeroing any reserved memory
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `non_zero_append`.
|
|
@builtin
|
|
@builtin
|
|
non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
return _append_elem_string(array, arg, false, loc)
|
|
return _append_elem_string(array, arg, false, loc)
|
|
@@ -651,6 +669,8 @@ non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, l
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
+//
|
|
|
|
+// Note: Prefer using the procedure group `append`.
|
|
@builtin
|
|
@builtin
|
|
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
n_arg: int
|
|
n_arg: int
|
|
@@ -665,7 +685,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_
|
|
}
|
|
}
|
|
|
|
|
|
// The append built-in procedure appends elements to the end of a dynamic array
|
|
// The append built-in procedure appends elements to the end of a dynamic array
|
|
-@builtin append :: proc{
|
|
|
|
|
|
+@builtin
|
|
|
|
+append :: proc{
|
|
append_elem,
|
|
append_elem,
|
|
append_elems,
|
|
append_elems,
|
|
append_elem_string,
|
|
append_elem_string,
|
|
@@ -674,7 +695,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_
|
|
append_soa_elems,
|
|
append_soa_elems,
|
|
}
|
|
}
|
|
|
|
|
|
-@builtin non_zero_append :: proc{
|
|
|
|
|
|
+@builtin
|
|
|
|
+non_zero_append :: proc{
|
|
non_zero_append_elem,
|
|
non_zero_append_elem,
|
|
non_zero_append_elems,
|
|
non_zero_append_elems,
|
|
non_zero_append_elem_string,
|
|
non_zero_append_elem_string,
|
|
@@ -684,6 +706,8 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+// `append_nothing` appends an empty value to a dynamic array. It returns `1, nil` if successful, and `0, err` when it was not possible,
|
|
|
|
+// whatever `err` happens to be.
|
|
@builtin
|
|
@builtin
|
|
append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error {
|
|
if array == nil {
|
|
if array == nil {
|
|
@@ -695,6 +719,7 @@ append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: i
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+// `inject_at_elem` injects an element in a dynamic array at a specified index and moves the previous elements after that index "across"
|
|
@builtin
|
|
@builtin
|
|
inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
@@ -716,6 +741,7 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcas
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `inject_at_elems` injects multiple elements in a dynamic array at a specified index and moves the previous elements after that index "across"
|
|
@builtin
|
|
@builtin
|
|
inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
@@ -742,6 +768,7 @@ inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadca
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `inject_at_elem_string` injects a string into a dynamic array at a specified index and moves the previous elements after that index "across"
|
|
@builtin
|
|
@builtin
|
|
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
when !ODIN_NO_BOUNDS_CHECK {
|
|
@@ -766,10 +793,13 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, ar
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `inject_at` injects something into a dynamic array at a specified index and moves the previous elements after that index "across"
|
|
@builtin inject_at :: proc{inject_at_elem, inject_at_elems, inject_at_elem_string}
|
|
@builtin inject_at :: proc{inject_at_elem, inject_at_elems, inject_at_elem_string}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+// `assign_at_elem` assigns a value at a given index. If the requested index is smaller than the current
|
|
|
|
+// size of the dynamic array, it will attempt to `resize` the a new length of `index+1` and then assign as `index`.
|
|
@builtin
|
|
@builtin
|
|
assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int 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) {
|
|
@@ -784,6 +814,8 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, arg: E, loc
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+// `assign_at_elems` assigns a values at a given index. If the requested index is smaller than the current
|
|
|
|
+// size of the dynamic array, it will attempt to `resize` the a new length of `index+len(args)` and then assign as `index`.
|
|
@builtin
|
|
@builtin
|
|
assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
new_size := index + len(args)
|
|
new_size := index + len(args)
|
|
@@ -800,7 +832,8 @@ assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadca
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+// `assign_at_elem_string` assigns a string at a given index. If the requested index is smaller than the current
|
|
|
|
+// size of the dynamic array, it will attempt to `resize` the a new length of `index+len(arg)` and then assign as `index`.
|
|
@builtin
|
|
@builtin
|
|
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
|
new_size := index + len(arg)
|
|
new_size := index + len(arg)
|
|
@@ -817,7 +850,14 @@ assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, ar
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
-@builtin assign_at :: proc{assign_at_elem, assign_at_elems, assign_at_elem_string}
|
|
|
|
|
|
+// `assign_at` assigns a value at a given index. If the requested index is smaller than the current
|
|
|
|
+// size of the dynamic array, it will attempt to `resize` the a new length of `index+size_needed` and then assign as `index`.
|
|
|
|
+@builtin
|
|
|
|
+assign_at :: proc{
|
|
|
|
+ assign_at_elem,
|
|
|
|
+ assign_at_elems,
|
|
|
|
+ assign_at_elem_string,
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -834,6 +874,8 @@ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) {
|
|
|
|
|
|
// `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
|
// `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
|
//
|
|
//
|
|
|
|
+// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`).
|
|
|
|
+//
|
|
// Note: Prefer the procedure group `reserve`.
|
|
// Note: Prefer the procedure group `reserve`.
|
|
_reserve_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_elem, align_of_elem: int, capacity: int, should_zero: bool, loc := #caller_location) -> Allocator_Error {
|
|
_reserve_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_elem, align_of_elem: int, capacity: int, should_zero: bool, loc := #caller_location) -> Allocator_Error {
|
|
if a == nil {
|
|
if a == nil {
|
|
@@ -868,11 +910,21 @@ _reserve_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_e
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
|
|
|
+//
|
|
|
|
+// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`).
|
|
|
|
+//
|
|
|
|
+// Note: Prefer the procedure group `reserve`.
|
|
@builtin
|
|
@builtin
|
|
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
|
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
|
return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, true, loc)
|
|
return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, true, loc)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `non_zero_reserve_dynamic_array` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
|
|
|
+//
|
|
|
|
+// When a memory resize allocation is required, the memory will be asked to not be zeroed (i.e. it calls `non_zero_mem_resize`).
|
|
|
|
+//
|
|
|
|
+// Note: Prefer the procedure group `non_zero_reserve`.
|
|
@builtin
|
|
@builtin
|
|
non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
|
non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
|
return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, false, loc)
|
|
return _reserve_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), capacity, false, loc)
|
|
@@ -921,28 +973,33 @@ _resize_dynamic_array :: #force_no_inline proc(a: ^Raw_Dynamic_Array, size_of_el
|
|
|
|
|
|
// `resize_dynamic_array` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`).
|
|
// `resize_dynamic_array` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`).
|
|
//
|
|
//
|
|
|
|
+// When a memory resize allocation is required, the memory will be asked to be zeroed (i.e. it calls `mem_resize`).
|
|
|
|
+//
|
|
// Note: Prefer the procedure group `resize`
|
|
// Note: Prefer the procedure group `resize`
|
|
@builtin
|
|
@builtin
|
|
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
|
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
|
return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, true, loc=loc)
|
|
return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, true, loc=loc)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// `non_zero_resize_dynamic_array` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`).
|
|
|
|
+//
|
|
|
|
+// When a memory resize allocation is required, the memory will be asked to not be zeroed (i.e. it calls `non_zero_mem_resize`).
|
|
|
|
+//
|
|
|
|
+// Note: Prefer the procedure group `non_zero_resize`
|
|
@builtin
|
|
@builtin
|
|
non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
|
non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
|
return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, false, loc=loc)
|
|
return _resize_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), length, false, loc=loc)
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- Shrinks the capacity of a dynamic array down to the current length, or the given capacity.
|
|
|
|
-
|
|
|
|
- If `new_cap` is negative, then `len(array)` is used.
|
|
|
|
-
|
|
|
|
- Returns false if `cap(array) < new_cap`, or the allocator report failure.
|
|
|
|
-
|
|
|
|
- If `len(array) < new_cap`, then `len(array)` will be left unchanged.
|
|
|
|
-
|
|
|
|
- Note: Prefer the procedure group `shrink`
|
|
|
|
-*/
|
|
|
|
|
|
+// Shrinks the capacity of a dynamic array down to the current length, or the given capacity.
|
|
|
|
+//
|
|
|
|
+// If `new_cap` is negative, then `len(array)` is used.
|
|
|
|
+//
|
|
|
|
+// Returns false if `cap(array) < new_cap`, or the allocator report failure.
|
|
|
|
+//
|
|
|
|
+// If `len(array) < new_cap`, then `len(array)` will be left unchanged.
|
|
|
|
+//
|
|
|
|
+// Note: Prefer the procedure group `shrink`
|
|
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
|
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
|
return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc)
|
|
return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc)
|
|
}
|
|
}
|
|
@@ -1023,6 +1080,7 @@ map_entry :: proc(m: ^$T/map[$K]$V, key: K, loc := #caller_location) -> (key_ptr
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+// `card` returns the number of bits that are set in a bit_set—its cardinality
|
|
@builtin
|
|
@builtin
|
|
card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
|
|
card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
|
|
return int(intrinsics.count_ones(transmute(intrinsics.type_bit_set_underlying_type(S))s))
|
|
return int(intrinsics.count_ones(transmute(intrinsics.type_bit_set_underlying_type(S))s))
|
|
@@ -1030,6 +1088,10 @@ card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+// Evaluates the condition and panics the program iff the condition is false.
|
|
|
|
+// This uses the `context.assertion_failure_procedure` to assert.
|
|
|
|
+//
|
|
|
|
+// This routine will be ignored when `ODIN_DISABLE_ASSERT` is true.
|
|
@builtin
|
|
@builtin
|
|
@(disabled=ODIN_DISABLE_ASSERT)
|
|
@(disabled=ODIN_DISABLE_ASSERT)
|
|
assert :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
assert :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
@@ -1050,9 +1112,9 @@ assert :: proc(condition: bool, message := #caller_expression(condition), loc :=
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// Evaluates the condition and aborts the program iff the condition is
|
|
|
|
-// false. This routine ignores `ODIN_DISABLE_ASSERT`, and will always
|
|
|
|
-// execute.
|
|
|
|
|
|
+// Evaluates the condition and panics the program iff the condition is false.
|
|
|
|
+// This uses the `context.assertion_failure_procedure` to assert.
|
|
|
|
+// This routine ignores `ODIN_DISABLE_ASSERT`, and will always execute.
|
|
@builtin
|
|
@builtin
|
|
ensure :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
ensure :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
if !condition {
|
|
if !condition {
|
|
@@ -1068,6 +1130,8 @@ ensure :: proc(condition: bool, message := #caller_expression(condition), loc :=
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Panics the program with a message.
|
|
|
|
+// This uses the `context.assertion_failure_procedure` to panic.
|
|
@builtin
|
|
@builtin
|
|
panic :: proc(message: string, loc := #caller_location) -> ! {
|
|
panic :: proc(message: string, loc := #caller_location) -> ! {
|
|
p := context.assertion_failure_proc
|
|
p := context.assertion_failure_proc
|
|
@@ -1077,6 +1141,8 @@ panic :: proc(message: string, loc := #caller_location) -> ! {
|
|
p("panic", message, loc)
|
|
p("panic", message, loc)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Panics the program with a message to indicate something has yet to be implemented.
|
|
|
|
+// This uses the `context.assertion_failure_procedure` to assert.
|
|
@builtin
|
|
@builtin
|
|
unimplemented :: proc(message := "", loc := #caller_location) -> ! {
|
|
unimplemented :: proc(message := "", loc := #caller_location) -> ! {
|
|
p := context.assertion_failure_proc
|
|
p := context.assertion_failure_proc
|
|
@@ -1086,7 +1152,10 @@ unimplemented :: proc(message := "", loc := #caller_location) -> ! {
|
|
p("not yet implemented", message, loc)
|
|
p("not yet implemented", message, loc)
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+// Evaluates the condition and panics the program iff the condition is false.
|
|
|
|
+// This uses the `default_assertion_contextless_failure_proc` to assert.
|
|
|
|
+//
|
|
|
|
+// This routine will be ignored when `ODIN_DISABLE_ASSERT` is true.
|
|
@builtin
|
|
@builtin
|
|
@(disabled=ODIN_DISABLE_ASSERT)
|
|
@(disabled=ODIN_DISABLE_ASSERT)
|
|
assert_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
assert_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
@@ -1103,6 +1172,8 @@ assert_contextless :: proc "contextless" (condition: bool, message := #caller_ex
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Evaluates the condition and panics the program iff the condition is false.
|
|
|
|
+// This uses the `default_assertion_contextless_failure_proc` to assert.
|
|
@builtin
|
|
@builtin
|
|
ensure_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
ensure_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) {
|
|
if !condition {
|
|
if !condition {
|
|
@@ -1114,11 +1185,15 @@ ensure_contextless :: proc "contextless" (condition: bool, message := #caller_ex
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Panics the program with a message to indicate something has yet to be implemented.
|
|
|
|
+// This uses the `default_assertion_contextless_failure_proc` to assert.
|
|
@builtin
|
|
@builtin
|
|
panic_contextless :: proc "contextless" (message: string, loc := #caller_location) -> ! {
|
|
panic_contextless :: proc "contextless" (message: string, loc := #caller_location) -> ! {
|
|
default_assertion_contextless_failure_proc("panic", message, loc)
|
|
default_assertion_contextless_failure_proc("panic", message, loc)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Panics the program with a message.
|
|
|
|
+// This uses the `default_assertion_contextless_failure_proc` to assert.
|
|
@builtin
|
|
@builtin
|
|
unimplemented_contextless :: proc "contextless" (message := "", loc := #caller_location) -> ! {
|
|
unimplemented_contextless :: proc "contextless" (message := "", loc := #caller_location) -> ! {
|
|
default_assertion_contextless_failure_proc("not yet implemented", message, loc)
|
|
default_assertion_contextless_failure_proc("not yet implemented", message, loc)
|