Improve core_builtin.odin docs

This commit is contained in:
gingerBill
2025-10-07 10:34:48 +01:00
parent 66401b2e73
commit d343afbad5
+94 -19
View File
@@ -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.
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.
If `new_cap` is negative, then `len(array)` is used. //
// Returns false if `cap(array) < new_cap`, or the allocator report failure.
Returns false if `cap(array) < new_cap`, or the allocator report failure. //
// If `len(array) < new_cap`, then `len(array)` will be left unchanged.
If `len(array) < new_cap`, then `len(array)` will be left unchanged. //
// Note: Prefer the procedure group `shrink`
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 // Evaluates the condition and panics the program iff the condition is false.
// false. This routine ignores `ODIN_DISABLE_ASSERT`, and will always // This uses the `context.assertion_failure_procedure` to assert.
// execute. // 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)