mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-07 02:54:18 +00:00
Add more documentation to numerous @builtin procedures in package runtime
This commit is contained in:
@@ -27,6 +27,11 @@ init_global_temporary_allocator :: proc(size: int, backup_allocator := context.a
|
||||
}
|
||||
|
||||
|
||||
// `copy_slice` is a built-in procedure that copies elements from a source slice `src` to a destination slice `dst`.
|
||||
// The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
|
||||
// of len(src) and len(dst).
|
||||
//
|
||||
// Prefer the procedure group `copy`.
|
||||
@builtin
|
||||
copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
@@ -35,6 +40,11 @@ copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int {
|
||||
}
|
||||
return n
|
||||
}
|
||||
// `copy_from_string` is a built-in procedure that copies elements from a source slice `src` to a destination string `dst`.
|
||||
// The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
|
||||
// of len(src) and len(dst).
|
||||
//
|
||||
// Prefer the procedure group `copy`.
|
||||
@builtin
|
||||
copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
@@ -43,11 +53,20 @@ copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int
|
||||
}
|
||||
return n
|
||||
}
|
||||
// `copy` is a built-in procedure that copies elements from a source slice `src` to a destination slice/string `dst`.
|
||||
// The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
|
||||
// of len(src) and len(dst).
|
||||
@builtin
|
||||
copy :: proc{copy_slice, copy_from_string}
|
||||
|
||||
|
||||
|
||||
// `unordered_remove` removed the element at the specified `index`. It does so by replacing the current end value
|
||||
// with the old value, and reducing the length of the dynamic array by 1.
|
||||
//
|
||||
// Note: This is an O(1) operation.
|
||||
// Note: If you the elements to remain in their order, use `ordered_remove`.
|
||||
// Note: If the index is out of bounds, this procedure will panic.
|
||||
@builtin
|
||||
unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
||||
bounds_check_error_loc(loc, index, len(array))
|
||||
@@ -57,7 +76,11 @@ unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_loca
|
||||
}
|
||||
(^Raw_Dynamic_Array)(array).len -= 1
|
||||
}
|
||||
|
||||
// `ordered_remove` removed the element at the specified `index` whilst keeping the order of the other elements.
|
||||
//
|
||||
// Note: This is an O(N) operation.
|
||||
// Note: If you the elements do not have to remain in their order, prefer `unordered_remove`.
|
||||
// Note: If the index is out of bounds, this procedure will panic.
|
||||
@builtin
|
||||
ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
||||
bounds_check_error_loc(loc, index, len(array))
|
||||
@@ -67,6 +90,10 @@ ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_locati
|
||||
(^Raw_Dynamic_Array)(array).len -= 1
|
||||
}
|
||||
|
||||
// `remove_range` removes a range of elements specified by the range `lo` and `hi`, whilst keeping the order of the other elements.
|
||||
//
|
||||
// Note: This is an O(N) operation.
|
||||
// Note: If the range is out of bounds, this procedure will panic.
|
||||
@builtin
|
||||
remove_range :: proc(array: ^$D/[dynamic]$T, lo, hi: int, loc := #caller_location) #no_bounds_check {
|
||||
slice_expr_error_lo_hi_loc(loc, lo, hi, len(array))
|
||||
@@ -80,6 +107,9 @@ remove_range :: proc(array: ^$D/[dynamic]$T, lo, hi: int, loc := #caller_locatio
|
||||
}
|
||||
|
||||
|
||||
// `pop` will remove and return the end value of dynamic array `array` and reduces the length of `array` by 1.
|
||||
//
|
||||
// Note: If the dynamic array as no elements (`len(array) == 0`), this procedure will panic.
|
||||
@builtin
|
||||
pop :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: E) #no_bounds_check {
|
||||
assert(len(array) > 0, "", loc)
|
||||
@@ -89,6 +119,8 @@ pop :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: E) #no_bou
|
||||
}
|
||||
|
||||
|
||||
// `pop_safe` trys to remove and return the end value of dynamic array `array` and reduces the length of `array` by 1.
|
||||
// If the operation is not possible, it will return false.
|
||||
@builtin
|
||||
pop_safe :: proc(array: ^$T/[dynamic]$E) -> (res: E, ok: bool) #no_bounds_check {
|
||||
if len(array) == 0 {
|
||||
@@ -99,6 +131,9 @@ pop_safe :: proc(array: ^$T/[dynamic]$E) -> (res: E, ok: bool) #no_bounds_check
|
||||
return
|
||||
}
|
||||
|
||||
// `pop_front` will remove and return the first value of dynamic array `array` and reduces the length of `array` by 1.
|
||||
//
|
||||
// Note: If the dynamic array as no elements (`len(array) == 0`), this procedure will panic.
|
||||
@builtin
|
||||
pop_front :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: E) #no_bounds_check {
|
||||
assert(len(array) > 0, "", loc)
|
||||
@@ -110,6 +145,8 @@ pop_front :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (res: E) #
|
||||
return res
|
||||
}
|
||||
|
||||
// `pop_front_safe` trys to return and remove the first value of dynamic array `array` and reduces the length of `array` by 1.
|
||||
// If the operation is not possible, it will return false.
|
||||
@builtin
|
||||
pop_front_safe :: proc(array: ^$T/[dynamic]$E) -> (res: E, ok: bool) #no_bounds_check {
|
||||
if len(array) == 0 {
|
||||
@@ -124,12 +161,15 @@ pop_front_safe :: proc(array: ^$T/[dynamic]$E) -> (res: E, ok: bool) #no_bounds_
|
||||
}
|
||||
|
||||
|
||||
// `clear` will set the length of a passed dynamic array or map to `0`
|
||||
@builtin
|
||||
clear :: proc{clear_dynamic_array, clear_map}
|
||||
|
||||
// `reserve` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
||||
@builtin
|
||||
reserve :: proc{reserve_dynamic_array, reserve_map}
|
||||
|
||||
// `resize` will try to resize memory of a passed dynamic array or map to the requested element count (setting the `len`, and possibly `cap`).
|
||||
@builtin
|
||||
resize :: proc{resize_dynamic_array}
|
||||
|
||||
@@ -137,36 +177,56 @@ resize :: proc{resize_dynamic_array}
|
||||
@builtin
|
||||
shrink :: proc{shrink_dynamic_array, shrink_map}
|
||||
|
||||
// `free` will try to free the passed pointer, with the given `allocator` if the allocator supports this operation.
|
||||
@builtin
|
||||
free :: proc{mem_free}
|
||||
|
||||
// `free_all` will try to free/reset all of the memory of the given `allocator` if the allocator supports this operation.
|
||||
@builtin
|
||||
free_all :: proc{mem_free_all}
|
||||
|
||||
|
||||
|
||||
// `delete_string` will try to free the underlying data of the passed string, with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer the procedure group `delete`.
|
||||
@builtin
|
||||
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return mem_free_with_size(raw_data(str), len(str), allocator, loc)
|
||||
}
|
||||
// `delete_cstring` will try to free the underlying data of the passed string, with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer the procedure group `delete`.
|
||||
@builtin
|
||||
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return mem_free((^byte)(str), allocator, loc)
|
||||
}
|
||||
// `delete_dynamic_array` will try to free the underlying data of the passed dynamic array, with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer the procedure group `delete`.
|
||||
@builtin
|
||||
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {
|
||||
return mem_free_with_size(raw_data(array), cap(array)*size_of(E), array.allocator, loc)
|
||||
}
|
||||
// `delete_slice` will try to free the underlying data of the passed sliced, with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer the procedure group `delete`.
|
||||
@builtin
|
||||
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return mem_free_with_size(raw_data(array), len(array)*size_of(E), allocator, loc)
|
||||
}
|
||||
// `delete_map` will try to free the underlying data of the passed map, with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer the procedure group `delete`.
|
||||
@builtin
|
||||
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) -> Allocator_Error {
|
||||
return map_free_dynamic(transmute(Raw_Map)m, map_info(T), loc)
|
||||
}
|
||||
|
||||
|
||||
// `delete` will try to free the underlying data of the passed built-in data structure (string, cstring, dynamic array, slice, or map), with the given `allocator` if the allocator supports this operation.
|
||||
//
|
||||
// Note: Prefer `delete` over the specific `delete_*` procedures where possible.
|
||||
@builtin
|
||||
delete :: proc{
|
||||
delete_string,
|
||||
@@ -213,18 +273,34 @@ make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocat
|
||||
return transmute(T)s, err
|
||||
}
|
||||
|
||||
// `make_slice` allocates and initializes a slice. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_aligned(T, len, align_of(E), allocator, loc)
|
||||
}
|
||||
// `make_dynamic_array` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc)
|
||||
}
|
||||
// `make_dynamic_array_len` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_dynamic_array_len_cap(T, len, len, allocator, loc)
|
||||
}
|
||||
// `make_dynamic_array_len_cap` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||
make_dynamic_array_error_loc(loc, len, cap)
|
||||
@@ -236,6 +312,10 @@ make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #a
|
||||
array = transmute(T)s
|
||||
return
|
||||
}
|
||||
// `make_map` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1<<MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> (m: T, err: Allocator_Error) #optional_allocator_error {
|
||||
make_map_expr_error_loc(loc, capacity)
|
||||
@@ -244,6 +324,12 @@ make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1<<MAP_MIN_LOG2_
|
||||
err = reserve_map(&m, capacity, loc)
|
||||
return
|
||||
}
|
||||
// `make_multi_pointer` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value.
|
||||
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
|
||||
//
|
||||
// This is "similar" to doing `raw_data(make([]E, len, allocator))`.
|
||||
//
|
||||
// Note: Prefer using the procedure group `make`.
|
||||
@(builtin, require_results)
|
||||
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) #optional_allocator_error {
|
||||
make_slice_error_loc(loc, len)
|
||||
@@ -256,8 +342,9 @@ make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := con
|
||||
}
|
||||
|
||||
|
||||
// The make built-in procedure allocates and initializes a value of type slice, dynamic array, or map (only)
|
||||
// Similar to new, the first argument is a type, not a value. Unlike new, make's return type is the same as the
|
||||
// `make` built-in procedure allocates and initializes a value of type slice, dynamic array, map, or multi-pointer (only).
|
||||
//
|
||||
// Similar to `new`, the first argument is a type, not a value. Unlike new, make's return type is the same as the
|
||||
// type of its argument, not a pointer to it.
|
||||
// Make uses the specified allocator, default is context.allocator, default is context.allocator
|
||||
@builtin
|
||||
@@ -272,6 +359,9 @@ make :: proc{
|
||||
|
||||
|
||||
|
||||
// `clear_map` will set the length of a passed map to `0`
|
||||
//
|
||||
// Note: Prefer the procedure group `clear`
|
||||
@builtin
|
||||
clear_map :: proc "contextless" (m: ^$T/map[$K]$V) {
|
||||
if m == nil {
|
||||
@@ -280,14 +370,17 @@ clear_map :: proc "contextless" (m: ^$T/map[$K]$V) {
|
||||
map_clear_dynamic((^Raw_Map)(m), map_info(T))
|
||||
}
|
||||
|
||||
// `reserve_map` will try to reserve memory of a passed map to the requested element count (setting the `cap`).
|
||||
//
|
||||
// Note: Prefer the procedure group `reserve`
|
||||
@builtin
|
||||
reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int, loc := #caller_location) -> Allocator_Error {
|
||||
return __dynamic_map_reserve((^Raw_Map)(m), map_info(T), uint(capacity), loc) if m != nil else nil
|
||||
}
|
||||
|
||||
/*
|
||||
Shrinks the capacity of a map down to the current length.
|
||||
*/
|
||||
// Shrinks the capacity of a map down to the current length.
|
||||
//
|
||||
// Note: Prefer the procedure group `shrink`
|
||||
@builtin
|
||||
shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
||||
if m != nil {
|
||||
@@ -526,6 +619,9 @@ assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string
|
||||
|
||||
|
||||
|
||||
// `clear_dynamic_array` will set the length of a passed dynamic array to `0`
|
||||
//
|
||||
// Note: Prefer the procedure group `clear`.
|
||||
@builtin
|
||||
clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) {
|
||||
if array != nil {
|
||||
@@ -533,6 +629,9 @@ 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`).
|
||||
//
|
||||
// Note: Prefer the procedure group `reserve`.
|
||||
@builtin
|
||||
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
||||
if array == nil {
|
||||
@@ -563,6 +662,9 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal
|
||||
return nil
|
||||
}
|
||||
|
||||
// `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`).
|
||||
//
|
||||
// Note: Prefer the procedure group `resize`
|
||||
@builtin
|
||||
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
|
||||
if array == nil {
|
||||
@@ -603,6 +705,8 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller
|
||||
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, new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
||||
if array == nil {
|
||||
|
||||
Reference in New Issue
Block a user