#import "std/array"
Compiler builtin dynamic array is automatically growing memory storage allocated on heap. The array allocated memory block groves over time when we push new values to the array. It's guaranteed that all pushed elements are stored in single continuous block of memory. When there is no space reminding in currently allocated block, new one is allocated and all already pushed data are copied from old block to the new one.
// First of all we must load API functions for dynamic array. The #load hash
// directive can be used to "include" other source files.
#import "std/array"
main :: fn () s32 {
// Now we create new dynamic array to store numbers. No heap alloacation
// is done here, we only specify element type of the array. As it's with
// regular static arrays or slices, we can access the element count via
// .len and allocated memory block via .ptr member. Compared to static
// arrays, there is additional member .allocated telling us how many
// elements could array handle till next allocation is needed.
nums: [..]s32;
// Fill the dynamic array with some values.
loop i := 0; i < 100; i += 1 {
// To append new value at the end of the array we can use 'array_push'
// function.
array_push(&nums, i);
// We can push only numbers of s32 type into the array (based on
// declaration type), you can try to push something else and see what
// happens.
}
// Dynamic arrays can be printed as usual...
print("nums = %\n", nums);
// We can use [N] operator to access single array elements like this:
print("nums[10] = %\n", nums[10]);
print("nums[20] = %\n", nums[20]);
// Since dynamic array will allocate memory on heap, we must free this
// memory by 'array_terminate' call when array is no longer needed.
array_terminate(&nums);
// There is lot of other ways to modify dynamic array content, check out
// API documentation.
return 0;
}
ARRAY_ALLOC_BLOCK_SIZE : usize = 32
File: array.bl
ARRAY_GROW_FACTOR : f32 = 1.500000
File: array.bl
array_init :: fn (_arr: *[..]?T, n : s64: 0, allocator : *Allocator: null) #inline
Sets dynamic array to default state. If array contains already allocated memory array_terminate
must be called first.
Initial capacity can be specified by n
(count of elements). If n
is greater than 0, needed
memory is preallocated using specified allocator
; otherwise no allocation is done.
It's usually enough to rely on default implicit initialization in case we don't need specify
custom allocator or preallocate storage to specified n
of entries.
File: array.bl
array_terminate :: fn (_arr: *[..]?T) #inline
Release memory allocated by dynamic array. This function is supposed to be called when dynamic array is no longer needed. Passed dynamic array is set to default state also.
File: array.bl
array_push :: fn {
impl_push_empty;
impl_push;
}
Append new value at the dynamic array end. New heap allocation is done here only in cases when there is not enough memory allocated to store all values. Returns pointer to the new appended element.
Note: When there is no element to push provided, function will just allocate memory for a new empty element without any initialization.
File: array.bl
array_push_all :: fn (_arr: *[..]?T, data: []T)
Append all data
at the dynamic array end. New heap allocation is done here only in cases when
there is not enough memory allocated to store all values.
Does nothing when data.len < 1
.
File: array.bl
array_pop :: fn (_arr: *[..]?T, out : *T: null) bool #inline
Duplicate the last array element into out
argument (if not null) and reduce the array length by
one. Returns true
in case the element was erased.
File: array.bl
array_pop_first :: fn (_arr: *[..]?T, out : *T: null) bool #inline
Duplicate first array element into out
location (if not null) and shift all other elements by
one slot left (the ordeing is kept). Returns true
in case the element was erased.
File: array.bl
array_reserve :: fn (_arr: *[..]?T, n: s64) #inline
Reserve heap memory for n
elements in array. Does nothing in case the already allocated block is
large enough to hold n
elements, the allocated memory block might be bigger then requested size.
File: array.bl
array_resize :: fn (_arr: *[..]?T, n: s64) #inline
File: array.bl
array_erase :: fn (_arr: *[..]?T, i: s64)
Erase element on index i
. Call to this function can cause reordering of an dynamic array.
Allocated memory is kept even if we erase entire dynamic array. Function invoke panic in case
of index overflow.
File: array.bl
array_erase_keep_order :: fn (_arr: *[..]?T, i: s64)
Erase element on index i
and move all following elements left. This might be slow in case the array is
large.
File: array.bl
array_erase_value :: fn (arr: *[..]?T, v: T) bool
Erase element of the value v
and return true
in case element was erased. Note this might be expensive
since all elements in array might be visited in the worst case.
File: array.bl
array_insert :: fn (_arr: *[..]?T, before_index: s64, value: T) s64
Insert a new element into the array before position before_index
and return index of the new
inserted element. All elements after the new one are moved in the memory by one slot.
Value of before_index
must be in range <0, arr.len>. Inserting at before_index
= 0 basically
adds a new element at the array begin; insering at before_index
= arr.len is the same as
array_push
.
Order of already existing elements is preserved.
File: array.bl
array_clear :: fn (_arr: *[..]?T) #inline
Erase all elements in dynamic array but keep allocated memory.
File: array.bl
array_allocated_bytes :: fn (_arr: *[..]?T) usize #inline
File: array.bl