Files
honey/std/arraylist/arraylist.hon
T

75 lines
2.2 KiB
Plaintext

import "@std/mem"
#! owns item storage and retains its allocator; release storage with deinit.
#! items is a borrowed view invalidated by growth or deinit.
ArrayList proc($T type) type {
return struct {
items []mut T
capacity usize
allocator mem.Allocator
}
}
#! retain `allocator` for later growth and cleanup; this call does not allocate.
init proc($T type, allocator mem.Allocator) ArrayList(T) {
return ArrayList(T) {
items = &[],
capacity = 0,
allocator = allocator,
}
}
#! release owned storage using the retained allocator and reset the list.
deinit proc($T type, list @mut ArrayList(T)) void {
allocation :: list.items.ptr[..list.capacity]
mem.free(list.allocator, allocation)
list.items = &[]
list.capacity = 0
}
#! grow owned storage with the retained allocator; growth invalidates borrowed item views.
reserve proc(
$T type,
list @mut ArrayList(T),
min_capacity usize,
) void ! mem.AllocError {
if (min_capacity <= list.capacity) return
new_capacity := 8
if list.capacity >= 8 {
half :: divtrunc!(list.capacity, 2)
if (list.capacity > maxval!(usize) - half) new_capacity = min_capacity
else new_capacity = list.capacity + half
}
if (new_capacity < min_capacity) new_capacity = min_capacity
length :: list.items.len
allocation :: list.items.ptr[..list.capacity]
grown :: mem.realloc(list.allocator, allocation, new_capacity) catch |_| {
return .out_of_memory
}
list.items = grown.ptr[..length]
list.capacity = new_capacity
return
}
append proc($T type, list @mut ArrayList(T), value T) void ! mem.AllocError {
length :: list.items.len
if (length == maxval!(usize)) return .out_of_memory
try reserve(list, length + 1)
list.items = list.items.ptr[..length + 1]
list.items[length] = value
return
}
pop proc($T type, list @mut ArrayList(T)) ?T {
if (list.items.len == 0) return null
value :: list.items[list.items.len - 1]
list.items = list.items.ptr[..list.items.len - 1]
return value
}
clear proc($T type, list @mut ArrayList(T)) void {
list.items = list.items.ptr[..0]
}