## std.lists: Dynamic arrays. ## This module is imported by default. # reference: https://doc.rust-lang.org/nomicon/vec/vec.html use std.pointers ## The list type. type list[T] = struct data: unique[T] # hrm capacity: int length: int ## Initialize and return an empty list with inner type T. pub func init[T](): list[T] = ... # malloc? idk let (data, ) { data: , capacity: 0, length: 0 } ## Gets the length of a list. pub func len[T](self: list[T]): uint = self.length pub func empty[T](self: list[T]): bool = self.length == 0 ## Gets the internal capacity of a list. func cap[T](self: list[T]): uint = self.capacity ## Expands the capacity of a list. func grow[T](self: mut list[T]) = ... ## Pushes a new element to the end of a list. pub func push[T](self: mut list[T], val: owned T) = if self.length == self.capacity: self.grow() unsafe: # todo: do we want unsafe blocks, as they are in rust? self.data.raw_set(self.length, val) # fixme # unsafe { ptr::write(self.ptr().add(self.length), val); } self.length += 1 ## Takes ownership of and pushes all the values of a list into another list. pub func push[T](self: mut list[T], val: owned list[T]) = ... ## Removes & returns an element from the end of a list, if it exists. pub func pop[T](self: mut list[T]): T? = if self.length == 0: None unsafe: self.length -= 1 Some(self.data.raw_get[T](self.length)) # fixme # unsafe { Some(ptr::read(self.ptr().add(self.length))) } ## Returns a reference to an element of a list, if in range. pub func get[T](self: list[T], i: uint): lent T? = ... ## Sets the element of a list to a value. todo: when is `val` owned? ## todo: how do we deal with having the wrong offset? pub func set[T](self: mut list[T], i: uint, val: owned T) = ... ## Inserts a value at a location and shifts elements of the list accordingly. pub func insert[T](self: mut list[T], i: uint, val: T) = assert i <= self.length, "index out of bounds" if self.cap == self.len: self.grow() ... # unsafe { # ptr::copy( # self.ptr().add(index), # self.ptr().add(index + 1), # self.len - index, # ); # ptr::write(self.ptr().add(index), elem); # self.len += 1; # } ## Removes a value at a location and shifts elements of the list accordingly. pub func remove[T](self: mut list[T], i: uint): T = assert index < self.length, "index out of bounds" unsafe: self.length -= 1 result = ... # unsafe { # self.len -= 1; # let result = ptr::read(self.ptr().add(index)); # ptr::copy( # self.ptr().add(index + 1), # self.ptr().add(index), # self.len - index, # ); # result # } ## Gets the last element of a list, if it exists. pub func last[T](self: list[T]): lent T? = self.get(self.len - 1) # todo: iteration... # todo: destructors... # todo: syntax for inlining + other pragmas... as a macro, perhaps? # todo: slices type slice[T] = struct data: ptr[T] # hrm... length: uint