Utility procedures for working with slices, including sorting and searching them.

Collection Info

View Source
Collection
core
Path
slice
Entries
118

Source Files

Types

5

Procedures

111

advance_slices #

Source
advance_slices :: proc(slices: $S/[][]$T, elems: int) -> $$deferred_return {…}

Removes the first n elements (`elems`) from a slice of slices, spanning inner slices and dropping empty ones. If `elems` is out of bounds (more than the total) this will trigger a bounds check. Example: import "core:fmt" import "core:slice" advance_slices_example :: proc() { slices := [][]byte { {1, 2, 3, 4}, {5, 6, 7}, } fmt.println(slice.advance_slices(slices, 4)) } Output: [[5, 6, 7]]

all_of #

Source
@(require_results)
all_of :: proc "contextless" (s: $S/[]$T, value: $T) -> bool {…}

any_of #

Source
@(require_results)
any_of :: proc "contextless" (s: $S/[]$T, value: $T) -> bool {…}

as_ptr #

Source
@(require_results)
as_ptr :: proc "contextless" (array: $T/[]$E) -> [^]$E {…}

binary_search #

Source
@(require_results)
binary_search :: proc(array: $A/[]$T, key: $T) -> (index: int, found: bool) {…}

Searches the given slice for the given element. If the slice is not sorted, the returned index is unspecified and meaningless. If the value is found then the returned int is the index of the matching element. If there are multiple matches, then any one of the matches could be returned. If the value is not found then the returned int is the index where a matching element could be inserted while maintaining sorted order. For slices of more complex types see: `binary_search_by` Example: /* Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in `[1, 4]`. */ index: int found: bool s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55} index, found = slice.binary_search(s, 13) assert(index == 9 && found == true) index, found = slice.binary_search(s, 4) assert(index == 7 && found == false) index, found = slice.binary_search(s, 100) assert(index == 13 && found == false) index, found = slice.binary_search(s, 1) assert(index >= 1 && index <= 4 && found == true)

binary_search_by #

Source
@(require_results)
binary_search_by :: proc(array: $A/[]$T, key: $K, f: proc($T, $K) -> Ordering) -> (index: int, found: bool) {…}

Searches the given slice for the given element. If the slice is not sorted, the returned index is unspecified and meaningless. If the value is found then the returned int is the index of the matching element. If there are multiple matches, then any one of the matches could be returned. If the value is not found then the returned int is the index where a matching element could be inserted while maintaining sorted order. The array elements and key may be different types. This allows the filter procedure to compare keys against a slice of structs, one struct value at a time. Returns: - index: int - found: bool

bitset_to_enum_slice_with_buffer #

Source
@(require_results)
bitset_to_enum_slice_with_buffer :: proc(buf: []$E, bs: $T) -> (slice: $$deferred_return) {…}

Turn a `bit_set[E]` into a `[]E` e.g.: sl := slice.bitset_to_enum_slice(flag_buf[:], bs)

bitset_to_enum_slice_with_make #

Source
@(require_results)
bitset_to_enum_slice_with_make :: proc(bs: $T, $E: typeid, allocator := context.allocator, loc := #caller_location) -> (slice: []typeid) {…}

Turn a `bit_set[E]` into a `[]E`, allocates e.g.: sl := slice.bitset_to_enum_slice(bs)

bytes_from_ptr #

Source
@(require_results)
bytes_from_ptr :: proc "contextless" (ptr: rawptr, byte_count: int) -> []u8 {…}

Turn a pointer and a length into a byte slice.

clone #

Source
@(require_results)
clone :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) #optional_ok {…}

copies a slice into a new slice

clone_to_dynamic #

Source
@(require_results)
clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) #optional_ok {…}

copies slice into a new dynamic array

concatenate #

Source
@(require_results)
concatenate :: proc(a: []$T/[]$E, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

contains #

Source
@(require_results)
contains :: proc "contextless" (array: $T/[]$E, value: $E) -> bool {…}

count #

Source
@(require_results)
count :: proc "contextless" (s: $S/[]$T, value: $T) -> (n: int) {…}

count_proc #

Source
@(require_results)
count_proc :: proc(s: $S/[]$T, f: proc($T) -> bool) -> (n: int) {…}

destroy_permutation_iterator #

Source
destroy_permutation_iterator :: proc(iter: Permutation_Iterator($T), allocator := context.allocator) {…}

Free the state allocated by `make_permutation_iterator`. Inputs: - iter: The iterator created by `make_permutation_iterator`. - allocator: The allocator used to create the iterator. (default is context.allocator)

dot_product #

Source
@(require_results)
dot_product :: proc "contextless" (a, b: $S/[]$T) -> (r: $$deferred_return, ok: bool) {…}

enum_slice_to_bitset #

Source
@(require_results)
enum_slice_to_bitset :: proc "contextless" (enums: []$E, $T: typeid/bit_set[$E]) -> (bits: $$deferred_return) {…}

Turn a `[]E` into `bit_set[E]` e.g.: bs := slice.enum_slice_to_bitset(my_flag_slice, rl.ConfigFlags)

enumerated_array #

Source
@(require_results)
enumerated_array :: proc "contextless" (ptr: ^$T) -> $$deferred_return {…}

Convert a pointer to an enumerated array to a slice of the element type

equal #

Source
@(require_results)
equal :: proc "contextless" (a, b: $T/[]$E) -> bool {…}

fill #

Source
fill :: proc "contextless" (array: $T/[]$E, value: $E) {…}

filter #

Source
@(require_results)
filter :: proc(s: $S/[]$U, f: proc($U) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

filter_reverse #

Source
@(require_results)
filter_reverse :: proc(s: $S/[]$U, f: proc($U) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

first #

Source
@(require_results)
first :: proc(array: $T/[]$E) -> $$deferred_return {…}

first_ptr #

Source
@(require_results)
first_ptr :: proc(array: $T/[]$E) -> $$deferred_return {…}

from_ptr #

Source
@(require_results)
from_ptr :: proc "contextless" (ptr: ^$T, count: int) -> $$deferred_return {…}

Turn a pointer and a length into a slice.

get #

Source
@(require_results)
get :: proc "contextless" (array: $T/[]$E, index: int) -> (value: $$deferred_return, ok: bool) {…}

get_ptr #

Source
@(require_results)
get_ptr :: proc "contextless" (array: $T/[]$E, index: int) -> (value: $$deferred_return, ok: bool) {…}

has_prefix #

Source
@(require_results)
has_prefix :: proc "contextless" (array: $T/[]$E, needle: $T/[]$E) -> bool {…}

has_suffix #

Source
@(require_results)
has_suffix :: proc "contextless" (array: $T/[]$E, needle: $T/[]$E) -> bool {…}

into_dynamic #

Source
@(require_results)
into_dynamic :: proc(a: $T/[]$E) -> $$deferred_return {…}

Converts slice into a dynamic array without cloning or allocating memory

is_empty #

Source
@(require_results)
is_empty :: proc "contextless" (a: $T/[]$E) -> bool {…}

is_sorted_by #

Source
@(require_results)
is_sorted_by :: proc(array: $T/[]$E, less: proc(i, j: $E) -> bool) -> bool {…}

is_sorted_by_cmp #

Source
@(require_results)
is_sorted_by_cmp :: proc(array: $T/[]$E, cmp: proc(i, j: $E) -> Ordering) -> bool {…}

is_sorted_by_key #

Source
@(require_results)
is_sorted_by_key :: proc(array: $T/[]$E, key: proc($E) -> $K) -> bool {…}

last #

Source
@(require_results)
last :: proc(array: $T/[]$E) -> $$deferred_return {…}

last_ptr #

Source
@(require_results)
last_ptr :: proc(array: $T/[]$E) -> $$deferred_return {…}

length #

Source
@(require_results)
length :: proc "contextless" (a: $T/[]$E) -> int {…}

linear_search #

Source
@(require_results)
linear_search :: proc "contextless" (array: $A/[]$T, key: $T) -> (index: int, found: bool) {…}

Searches the given slice for the given element in O(n) time. If you need a custom search condition, see `linear_search_proc` Inputs: - array: The slice to search in. - key: The element to search for. Returns: - index: The index `i`, such that `array[i]` is the first occurrence of `key` in `array`, or -1 if `key` is not present in `array`. Example: index: int found: bool a := []i32{10, 10, 10, 20} index, found = linear_search_reverse(a, 10) assert(index == 0 && found == true) index, found = linear_search_reverse(a, 30) assert(index == -1 && found == false) // Note that `index == 1`, since it is relative to `a[2:]` index, found = linear_search_reverse(a[2:], 20) assert(index == 1 && found == true)

linear_search_proc #

Source
@(require_results)
linear_search_proc :: proc(array: $A/[]$T, f: proc($T) -> bool) -> (index: int, found: bool) {…}

Searches the given slice for the first element satisfying predicate `f` in O(n) time. Inputs: - array: The slice to search in. - f: The search condition. Returns: - index: The index `i`, such that `array[i]` is the first `x` in `array` for which `f(x) == true`, or -1 if such `x` does not exist.

linear_search_reverse #

Source
@(require_results)
linear_search_reverse :: proc "contextless" (array: $A/[]$T, key: $T) -> (index: int, found: bool) {…}

Searches the given slice for the given element in O(n) time, starting from the slice end. If you need a custom search condition, see `linear_search_reverse_proc` Inputs: - array: The slice to search in. - key: The element to search for. Returns: - index: The index `i`, such that `array[i]` is the last occurrence of `key` in `array`, or -1 if `key` is not present in `array`. Example: index: int found: bool a := []i32{10, 10, 10, 20} index, found = linear_search_reverse(a, 20) assert(index == 3 && found == true) index, found = linear_search_reverse(a, 10) assert(index == 2 && found == true) index, found = linear_search_reverse(a, 30) assert(index == -1 && found == false) // Note that `index == 1`, since it is relative to `a[2:]` index, found = linear_search_reverse(a[2:], 20) assert(index == 1 && found == true)

linear_search_reverse_proc #

Source
@(require_results)
linear_search_reverse_proc :: proc(array: $A/[]$T, f: proc($T) -> bool) -> (index: int, found: bool) {…}

Searches the given slice for the last element satisfying predicate `f` in O(n) time, starting from the slice end. Inputs: - array: The slice to search in. - f: The search condition. Returns: - index: The index `i`, such that `array[i]` is the last `x` in `array` for which `f(x) == true`, or -1 if such `x` does not exist.

make_permutation_iterator #

Source
make_permutation_iterator :: proc(slice: []$T, allocator := context.allocator, loc := #caller_location) -> (iter: $$deferred_return, error: Allocator_Error) #optional_ok {…}

Make an iterator to permute a slice in-place. *Allocates Using Provided Allocator* This procedure allocates some state to assist in permutation and does not make a copy of the underlying slice. If you want to permute a slice without altering the underlying data, use `clone` to create a copy, then permute that instead. Inputs: - slice: The slice to permute. - allocator: (default is context.allocator) Returns: - iter: The iterator, to be passed to `permute`. - error: An `Allocator_Error`, if allocation failed.

map_entries #

Source
map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (entries: $$deferred_return, err: Allocator_Error) {…}

map_entry_infos #

Source
map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (entries: $$deferred_return, err: Allocator_Error) {…}

map_keys #

Source
map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (keys: $$deferred_return, err: Allocator_Error) {…}

map_values #

Source
map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (values: $$deferred_return, err: Allocator_Error) {…}

mapper #

Source
@(require_results)
mapper :: proc(s: $S/[]$U, f: proc($U) -> $V, allocator := context.allocator, loc := #caller_location) -> (r: $$deferred_return, err: Allocator_Error) #optional_ok {…}

max #

Source
@(require_results)
max :: proc "contextless" (s: $S/[]$T) -> (res: $$deferred_return, ok: bool) #optional_ok {…}

max_index #

Source
@(require_results)
max_index :: proc "contextless" (s: $S/[]$T) -> (max_index: int, ok: bool) #optional_ok {…}

Find the index of the (first) maximum element in a slice.

min #

Source
@(require_results)
min :: proc "contextless" (s: $S/[]$T) -> (res: $$deferred_return, ok: bool) #optional_ok {…}

min_index #

Source
@(require_results)
min_index :: proc "contextless" (s: $S/[]$T) -> (min_index: int, ok: bool) #optional_ok {…}

Find the index of the (first) minimum element in a slice.

min_max #

Source
@(require_results)
min_max :: proc "contextless" (s: $S/[]$T) -> (min, max: $$deferred_return, ok: bool) {…}

none_of #

Source
@(require_results)
none_of :: proc "contextless" (s: $S/[]$T, value: $T) -> bool {…}

permute #

Source
permute :: proc(iter: ^Permutation_Iterator($T)) -> (ok: bool) {…}

Permute a slice in-place. Note that the first iteration will always be the original, unpermuted slice. Inputs: - iter: The iterator created by `make_permutation_iterator`. Returns: - ok: True if the permutation succeeded, false if the iteration is complete.

prefix_length #

Source
@(require_results)
prefix_length :: proc "contextless" (a, b: $T/[]$E) -> (n: int) {…}

return the prefix length common between slices `a` and `b`. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 1 slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3}) -> 3 slice.prefix_length([]u8{1, 2, 3, 4}, []u8{2, 3, 4}) -> 0

ptr_add #

Source
ptr_add :: proc "contextless" (p: $P/^$T, x: int) -> $$deferred_return {…}

ptr_sub #

Source
ptr_sub :: proc "contextless" (p: $P/^$T, x: int) -> $$deferred_return {…}

reduce #

Source
@(require_results)
reduce :: proc(s: $S/[]$U, initializer: $V, f: proc($V, $U) -> $$deferred_return) -> $$deferred_return {…}

reduce_reverse #

Source
@(require_results)
reduce_reverse :: proc(s: $S/[]$U, initializer: $V, f: proc($V, $U) -> $$deferred_return) -> $$deferred_return {…}

reinterpret #

Source
@(require_results)
reinterpret :: proc "contextless" ($T: typeid/[]$U, s: []$V) -> $$deferred_return {…}

Turn a slice of one type, into a slice of another type. Only converts the type and length of the slice itself. The length is rounded down to the nearest whole number of items. Example: import "core:fmt" import "core:slice" i64s_as_i32s :: proc() { large_items := []i64{1, 2, 3, 4} small_items := slice.reinterpret([]i32, large_items) assert(len(small_items) == 8) fmt.println(large_items, "->", small_items) } bytes_as_i64s :: proc() { small_items := [12]byte{} small_items[0] = 1 small_items[8] = 2 large_items := slice.reinterpret([]i64, small_items[:]) assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes. fmt.println(small_items, "->", large_items) } reinterpret_example :: proc() { i64s_as_i32s() bytes_as_i64s() } Output: [1, 2, 3, 4] -> [1, 0, 2, 0, 3, 0, 4, 0] [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0] -> [1]

repeat #

Source
@(require_results)
repeat :: proc(s: $S/[]$U, count: int, allocator := context.allocator, loc := #caller_location) -> (b: $$deferred_return, err: Allocator_Error) #optional_ok {…}

reverse_sort_by #

Source
reverse_sort_by :: proc(data: $T/[]$E, less: proc(i, j: $E) -> bool) {…}

reverse_sort_by_cmp #

Source
reverse_sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: $E) -> Ordering) {…}

reverse_sort_by_key #

Source
reverse_sort_by_key :: proc(data: $T/[]$E, key: proc($E) -> $K) {…}

rotate_left #

Source
rotate_left :: proc "contextless" (array: $T/[]$E, mid: int) {…}

rotate_right #

Source
rotate_right :: proc "contextless" (array: $T/[]$E, k: int) {…}

scanner #

Source
@(require_results)
scanner :: proc(s: $S/[]$U, initializer: $V, f: proc($V, $U) -> $$deferred_return, allocator := context.allocator, loc := #caller_location) -> (res: $$deferred_return, err: Allocator_Error) #optional_ok {…}

simple_equal #

Source
@(require_results)
simple_equal :: proc "contextless" (a, b: $T/[]$E) -> bool {…}

size #

Source
@(require_results)
size :: proc "contextless" (a: $T/[]$E) -> int {…}

Gets the byte size of the backing data

sort #

Source
sort :: proc(data: $T/[]$E) {…}

sort sorts a slice This sort is not guaranteed to be stable

sort_by #

Source
sort_by :: proc(data: $T/[]$E, less: proc(i, j: $E) -> bool) {…}

sort_by sorts a slice with a given procedure to test whether two values are ordered "i < j" This sort is not guaranteed to be stable

sort_by_indices_allocate #

Source
sort_by_indices_allocate :: proc(data: $T/[]$E, indices: []int, allocator := context.allocator, loc := #caller_location) -> (sorted: $$deferred_return) {…}

sort_by_indices_overwrite #

Source
sort_by_indices_overwrite :: proc(data: $T/[]$E, indices: []int) {…}

sort_by_key #

Source
sort_by_key :: proc(data: $T/[]$E, key: proc($E) -> $K) {…}

TODO(bill): Should `sort_by_key` exist or is `sort_by` more than enough?

sort_by_with_indices #

Source
sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: $E) -> bool, allocator := context.allocator, loc := #caller_location) -> (indices: []int) {…}

sort_by sorts a slice with a given procedure to test whether two values are ordered "i < j" This sort is not guaranteed to be stable

sort_by_with_indices_with_data #

Source
sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: $E, user_data: rawptr) -> bool, user_data: rawptr, allocator := context.allocator, loc := #caller_location) -> (indices: []int) {…}

sort_from_permutation_indices #

Source
sort_from_permutation_indices :: proc(data: $T/[]$E, indices: []int) {…}

sort_with_indices #

Source
sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> (indices: []int) {…}

sort sorts a slice and returns a slice of the original indices This sort is not guaranteed to be stable

split_at #

Source
@(require_results)
split_at :: proc(array: $T/[]$E, index: int) -> (a, b: $$deferred_return) {…}

split_first #

Source
@(require_results)
split_first :: proc(array: $T/[]$E) -> (first: $$deferred_return, rest: $$deferred_return) {…}

split_last #

Source
@(require_results)
split_last :: proc(array: $T/[]$E) -> (rest: $$deferred_return, last: $$deferred_return) {…}

stable_sort #

Source
stable_sort :: proc(data: $T/[]$E) {…}

Sorts a slice while maintaining the relative order of elements with the same key. For an example see either `stable_sort_by` or `stable_sort_by_cmp`.

stable_sort_by #

Source
stable_sort_by :: proc(data: $T/[]$E, less: proc(i, j: $E) -> bool) {…}

Sorts a slice while maintaining the relative order of elements with the same key. Two items `i` and `j` are ordered if `less(i, j)` returns `true`. Example: import "core:slice" import "core:fmt" stable_sort_by_example :: proc() { Example :: struct { n: int, s: string } arr := []Example { {2, "name"}, {3, "Bill"}, {1, "My"}, {2, "is"} } slice.stable_sort_by(arr, proc(i, j: Example) -> bool { return i.n < j.n }) for e in arr do fmt.printf("%s ", e.s) fmt.println() } Output: My name is Bill

stable_sort_by_cmp #

Source
stable_sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: $E) -> Ordering) {…}

Sorts a slice while maintaining the relative order of elements with the same key. The ordering of the any two items is defined by the user-provided `cmp`. Example: import "core:slice" import "core:fmt" stable_sort_by_cmp_example :: proc() { Example :: struct { n: int, s: string } arr := []Example { {2, "name"}, {3, "Bill"}, {1, "My"}, {2, "is"} } slice.stable_sort_by_cmp(arr, proc(i, j: Example) -> slice.Ordering { return slice.cmp(i.n, j.n) }) for e in arr do fmt.printf("%s ", e.s) fmt.println() } Output: My name is Bill

suffix_length #

Source
@(require_results)
suffix_length :: proc "contextless" (a, b: $T/[]$E) -> (n: int) {…}

return the suffix length common between slices `a` and `b`. slice.suffix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3, 4}) -> 4 slice.suffix_length([]u8{1, 2, 3, 4}, []u8{3, 4}) -> 2 slice.suffix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 0 slice.suffix_length([]u8{1, 2, 3, 4}, []u8{1, 3, 5}) -> 0 slice.suffix_length([]u8{3, 4, 5}, []u8{3, 5}) -> 1

swap_between #

Source
swap_between :: proc "contextless" (a, b: $T/[]$E) {…}

swap_with_slice #

Source
swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) {…}

to_bytes #

Source
@(require_results)
to_bytes :: proc "contextless" (s: []$T) -> []u8 {…}

Turn a slice into a byte slice. See `slice.reinterpret` to go the other way.

to_dynamic #

Source
@(require_results)
to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) #optional_ok {…}

copies slice into a new dynamic array

unique #

Source
@(require_results)
unique :: proc "contextless" (s: $S/[]$T) -> $$deferred_return {…}

'unique' replaces consecutive runs of equal elements with a single copy. The procedures modifies the slice in-place and returns the modified slice.

unique_proc #

Source
@(require_results)
unique_proc :: proc(s: $S/[]$T, eq: proc($T, $T) -> bool) -> $$deferred_return {…}

'unique_proc' replaces consecutive runs of equal elements with a single copy using a comparison procedure The procedures modifies the slice in-place and returns the modified slice.

Procedure Groups

2