resizable array


Resizable Array

A resizable array is a dynamically-sized array that can grow or shrink at runtime. The type of a resizable array of elements of type T is written [..] T. It stores three fields: count (the number of elements currently in use), data (a pointer to the first element), and allocated (the total number of elements the current allocation can hold before needing to grow). Memory is obtained from whatever allocator is active in the current context, which may or may not be the heap.

    
values: [..] int;
array_add(*values, 10);
array_add(*values, 20);
array_add(*values, 30);

print("count is %\n", values.count);      // 3
print("allocated is %\n", values.allocated); // >= 3
    

Adding Elements

Use array_add to append elements. If the array's allocated capacity is exceeded, the array automatically grows by allocating a larger block of memory and copying the existing elements.

    
items: [..] string;
array_add(*items, "alpha");
array_add(*items, "beta");
array_add(*items, "gamma");
    

array_add can also append several elements at once. When you already have an array or array view, use .. argument expansion to pass each element as a separate argument.

    
destination: [..] string;
source := string.["local_modules", "shared_modules"];

array_add(*destination, ..source);
// Same as:
// array_add(*destination, "local_modules", "shared_modules");
    

Subscripting

Resizable arrays support subscript access with bounds checking, just like fixed arrays and array views:

    
x := values[1];   // Read the second element.
values[0] = 99;   // Write to the first element.
    

Removing Elements

array_ordered_remove_by_index removes the element at the given index and shifts all subsequent elements down to preserve order. array_unordered_remove_by_index removes the element by swapping it with the last element, which is faster but does not preserve order.

    
values: [..] int;
array_add(*values, 10);
array_add(*values, 20);
array_add(*values, 30);

array_ordered_remove_by_index(*values, 0);
// values is now [20, 30]
    

Freeing Memory

If resizable array has allocated memory on the heap, you can free them when they are no longer needed:

    
array_free(values);
    

Iteration

Resizable arrays can be iterated with a for loop:

    
for values {
    print("index [%] has value %\n", it_index, it);
}
    

Conversion to Array View

A resizable array can be used anywhere an array view is expected. You can also assign a resizable array directly to an array view variable. The resulting view has its data pointing at the resizable array's current storage and its count set to the current element count. It does not copy the elements, and it does not keep the resizable array's allocated capacity or allocator information.

    
values: [..] int;
array_add(*values, 10);
array_add(*values, 20);

view: [] int = values;
    

Be careful keeping the view around while continuing to append to the resizable array. If the array grows, it may move its elements to new storage, leaving the old view pointing at stale memory. See Array View for the underlying descriptor behavior.