1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

all: replace generic <> with [] - part 2 (#16536)

This commit is contained in:
yuyi
2022-11-27 00:23:26 +08:00
committed by GitHub
parent b19b97e7b1
commit ef5be22f81
297 changed files with 1959 additions and 1943 deletions

View File

@ -14,7 +14,7 @@ your actual elements. For example:
```v
import datatypes
mut stack := datatypes.Stack<int>{}
mut stack := datatypes.Stack[int]{}
stack.push(1)
println(stack)
```

View File

@ -2,36 +2,36 @@ module datatypes
/// Internal rapresentation of the tree node
[heap]
struct BSTreeNode<T> {
struct BSTreeNode[T] {
mut:
// Mark a node as initialized
is_init bool
// Value of the node
value T
// The parent of the node
parent &BSTreeNode<T> = unsafe { 0 }
parent &BSTreeNode[T] = unsafe { 0 }
// The left side with value less than the
// value of this node
left &BSTreeNode<T> = unsafe { 0 }
left &BSTreeNode[T] = unsafe { 0 }
// The right side with value grater than the
// value of thiss node
right &BSTreeNode<T> = unsafe { 0 }
right &BSTreeNode[T] = unsafe { 0 }
}
// Create new root bst node
fn new_root_node<T>(value T) &BSTreeNode<T> {
return &BSTreeNode<T>{
fn new_root_node[T](value T) &BSTreeNode[T] {
return &BSTreeNode[T]{
is_init: true
value: value
parent: new_none_node<T>(true)
left: new_none_node<T>(false)
right: new_none_node<T>(false)
parent: new_none_node[T](true)
left: new_none_node[T](false)
right: new_none_node[T](false)
}
}
// new_node creates a new bst node with a parent reference.
fn new_node<T>(parent &BSTreeNode<T>, value T) &BSTreeNode<T> {
return &BSTreeNode<T>{
fn new_node[T](parent &BSTreeNode[T], value T) &BSTreeNode[T] {
return &BSTreeNode[T]{
is_init: true
value: value
parent: parent
@ -39,19 +39,19 @@ fn new_node<T>(parent &BSTreeNode<T>, value T) &BSTreeNode<T> {
}
// new_none_node creates a dummy node.
fn new_none_node<T>(init bool) &BSTreeNode<T> {
return &BSTreeNode<T>{
fn new_none_node[T](init bool) &BSTreeNode[T] {
return &BSTreeNode[T]{
is_init: init
}
}
// bind to an actual instance of a node.
fn (mut node BSTreeNode<T>) bind(mut to_bind BSTreeNode<T>, left bool) {
fn (mut node BSTreeNode[T]) bind(mut to_bind BSTreeNode[T], left bool) {
node.left = to_bind.left
node.right = to_bind.right
node.value = to_bind.value
node.is_init = to_bind.is_init
to_bind = new_none_node<T>(false)
to_bind = new_none_node[T](false)
}
// Pure Binary Seach Tree implementation
@ -59,13 +59,13 @@ fn (mut node BSTreeNode<T>) bind(mut to_bind BSTreeNode<T>, left bool) {
// Pure V implementation of the Binary Search Tree
// Time complexity of main operation O(log N)
// Space complexity O(N)
pub struct BSTree<T> {
pub struct BSTree[T] {
mut:
root &BSTreeNode<T> = unsafe { 0 }
root &BSTreeNode[T] = unsafe { 0 }
}
// insert give the possibility to insert an element in the BST.
pub fn (mut bst BSTree<T>) insert(value T) bool {
pub fn (mut bst BSTree[T]) insert(value T) bool {
if bst.is_empty() {
bst.root = new_root_node(value)
return true
@ -74,7 +74,7 @@ pub fn (mut bst BSTree<T>) insert(value T) bool {
}
// insert_helper walks the tree and inserts the given node.
fn (mut bst BSTree<T>) insert_helper(mut node BSTreeNode<T>, value T) bool {
fn (mut bst BSTree[T]) insert_helper(mut node BSTreeNode[T], value T) bool {
if node.value < value {
if unsafe { node.right != 0 } && node.right.is_init {
return bst.insert_helper(mut node.right, value)
@ -92,13 +92,13 @@ fn (mut bst BSTree<T>) insert_helper(mut node BSTreeNode<T>, value T) bool {
}
// contains checks if an element with a given `value` is inside the BST.
pub fn (bst &BSTree<T>) contains(value T) bool {
pub fn (bst &BSTree[T]) contains(value T) bool {
return bst.contains_helper(bst.root, value)
}
// contains_helper is a helper function to walk the tree, and return
// the absence or presence of the `value`.
fn (bst &BSTree<T>) contains_helper(node &BSTreeNode<T>, value T) bool {
fn (bst &BSTree[T]) contains_helper(node &BSTreeNode[T], value T) bool {
if unsafe { node == 0 } || !node.is_init {
return false
}
@ -112,14 +112,14 @@ fn (bst &BSTree<T>) contains_helper(node &BSTreeNode<T>, value T) bool {
}
// remove removes an element with `value` from the BST.
pub fn (mut bst BSTree<T>) remove(value T) bool {
pub fn (mut bst BSTree[T]) remove(value T) bool {
if bst.is_empty() {
return false
}
return bst.remove_helper(mut bst.root, value, false)
}
fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool) bool {
fn (mut bst BSTree[T]) remove_helper(mut node BSTreeNode[T], value T, left bool) bool {
if !node.is_init {
return false
}
@ -136,11 +136,11 @@ fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool)
} else {
mut parent := node.parent
if left {
parent.left = new_none_node<T>(false)
parent.left = new_none_node[T](false)
} else {
parent.right = new_none_node<T>(false)
parent.right = new_none_node[T](false)
}
node = new_none_node<T>(false)
node = new_none_node[T](false)
}
return true
}
@ -152,9 +152,9 @@ fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool)
}
// get_max_from_right returns the max element of the BST following the right branch.
fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
fn (bst &BSTree[T]) get_max_from_right(node &BSTreeNode[T]) &BSTreeNode[T] {
if unsafe { node == 0 } {
return new_none_node<T>(false)
return new_none_node[T](false)
}
right_node := node.right
if unsafe { right_node == 0 } || !right_node.is_init {
@ -164,9 +164,9 @@ fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
}
// get_min_from_left returns the min element of the BST by following the left branch.
fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> {
fn (bst &BSTree[T]) get_min_from_left(node &BSTreeNode[T]) &BSTreeNode[T] {
if unsafe { node == 0 } {
return new_none_node<T>(false)
return new_none_node[T](false)
}
left_node := node.left
if unsafe { left_node == 0 } || !left_node.is_init {
@ -176,19 +176,19 @@ fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> {
}
// is_empty checks if the BST is empty
pub fn (bst &BSTree<T>) is_empty() bool {
pub fn (bst &BSTree[T]) is_empty() bool {
return unsafe { bst.root == 0 }
}
// in_order_traversal traverses the BST in order, and returns the result as an array.
pub fn (bst &BSTree<T>) in_order_traversal() []T {
pub fn (bst &BSTree[T]) in_order_traversal() []T {
mut result := []T{}
bst.in_order_traversal_helper(bst.root, mut result)
return result
}
// in_order_traversal_helper helps traverse the BST, and accumulates the result in the `result` array.
fn (bst &BSTree<T>) in_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
fn (bst &BSTree[T]) in_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
if unsafe { node == 0 } || !node.is_init {
return
}
@ -198,7 +198,7 @@ fn (bst &BSTree<T>) in_order_traversal_helper(node &BSTreeNode<T>, mut result []
}
// post_order_traversal traverses the BST in post order, and returns the result in an array.
pub fn (bst &BSTree<T>) post_order_traversal() []T {
pub fn (bst &BSTree[T]) post_order_traversal() []T {
mut result := []T{}
bst.post_order_traversal_helper(bst.root, mut result)
return result
@ -206,7 +206,7 @@ pub fn (bst &BSTree<T>) post_order_traversal() []T {
// post_order_traversal_helper is a helper function that traverses the BST in post order,
// accumulating the result in an array.
fn (bst &BSTree<T>) post_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
fn (bst &BSTree[T]) post_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
if unsafe { node == 0 } || !node.is_init {
return
}
@ -217,7 +217,7 @@ fn (bst &BSTree<T>) post_order_traversal_helper(node &BSTreeNode<T>, mut result
}
// pre_order_traversal traverses the BST in pre order, and returns the result as an array.
pub fn (bst &BSTree<T>) pre_order_traversal() []T {
pub fn (bst &BSTree[T]) pre_order_traversal() []T {
mut result := []T{}
bst.pre_order_traversal_helper(bst.root, mut result)
return result
@ -225,7 +225,7 @@ pub fn (bst &BSTree<T>) pre_order_traversal() []T {
// pre_order_traversal_helper is a helper function to traverse the BST
// in pre order and accumulates the results in an array.
fn (bst &BSTree<T>) pre_order_traversal_helper(node &BSTreeNode<T>, mut result []T) {
fn (bst &BSTree[T]) pre_order_traversal_helper(node &BSTreeNode[T], mut result []T) {
if unsafe { node == 0 } || !node.is_init {
return
}
@ -235,9 +235,9 @@ fn (bst &BSTree<T>) pre_order_traversal_helper(node &BSTreeNode<T>, mut result [
}
// get_node is a helper method to ge the internal rapresentation of the node with the `value`.
fn (bst &BSTree<T>) get_node(node &BSTreeNode<T>, value T) &BSTreeNode<T> {
fn (bst &BSTree[T]) get_node(node &BSTreeNode[T], value T) &BSTreeNode[T] {
if unsafe { node == 0 } || !node.is_init {
return new_none_node<T>(false)
return new_none_node[T](false)
}
if node.value == value {
return node
@ -256,7 +256,7 @@ fn (bst &BSTree<T>) get_node(node &BSTreeNode<T>, value T) &BSTreeNode<T> {
//```v
// left_value, exist := bst.to_left(10)
//```
pub fn (bst &BSTree<T>) to_left(value T) ?T {
pub fn (bst &BSTree[T]) to_left(value T) ?T {
if bst.is_empty() {
return none
}
@ -275,7 +275,7 @@ pub fn (bst &BSTree<T>) to_left(value T) ?T {
//```v
// left_value, exist := bst.to_right(10)
//```
pub fn (bst &BSTree<T>) to_right(value T) ?T {
pub fn (bst &BSTree[T]) to_right(value T) ?T {
if bst.is_empty() {
return none
}
@ -289,7 +289,7 @@ pub fn (bst &BSTree<T>) to_right(value T) ?T {
// max return the max element inside the BST.
// Time complexity O(N) if the BST is not balanced
pub fn (bst &BSTree<T>) max() ?T {
pub fn (bst &BSTree[T]) max() ?T {
if bst.is_empty() {
return none
}
@ -302,7 +302,7 @@ pub fn (bst &BSTree<T>) max() ?T {
// min return the minimum element in the BST.
// Time complexity O(N) if the BST is not balanced.
pub fn (bst &BSTree<T>) min() ?T {
pub fn (bst &BSTree[T]) min() ?T {
if bst.is_empty() {
return none
}

View File

@ -3,7 +3,7 @@ module datatypes
// Make an insert of one element and check if
// the bst is able to fin it.
fn test_insert_into_bst_one() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10) == true
assert bst.contains(10) == true
assert bst.contains(20) == false
@ -12,7 +12,7 @@ fn test_insert_into_bst_one() {
// Make the insert of more element inside the BST
// and check if the BST is able to find all the values
fn test_insert_into_bst_two() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(9)
@ -26,7 +26,7 @@ fn test_insert_into_bst_two() {
// Test if the in_order_traversals list return the correct
// result array
fn test_in_order_bst_visit_one() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -38,7 +38,7 @@ fn test_in_order_bst_visit_one() {
// Test if the post_order_bst_visit return the correct
// result array
fn test_post_order_bst_visit_one() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -49,7 +49,7 @@ fn test_post_order_bst_visit_one() {
// Test if the pre_order_traversal return the correct result array
fn test_pre_order_bst_visit_one() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -61,7 +61,7 @@ fn test_pre_order_bst_visit_one() {
// After many insert check if we are abe to get the correct
// right and left value of the root.
fn test_get_left_root() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -76,7 +76,7 @@ fn test_get_left_root() {
// Check if BST panic if we call some operation on an empty BST.
fn test_get_left_on_empty_bst() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
left_val := bst.to_left(10) or { -1 }
assert left_val == -1
@ -88,7 +88,7 @@ fn test_get_left_on_empty_bst() {
// Check the remove operation if it is able to remove
// all elements required, and mantains the BST propriety.
fn test_remove_from_bst_one() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -102,7 +102,7 @@ fn test_remove_from_bst_one() {
// Another test n the remove BST, this remove an intermidia node
// that it is a triky operation.
fn test_remove_from_bst_two() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert bst.insert(10)
assert bst.insert(20)
assert bst.insert(21)
@ -115,7 +115,7 @@ fn test_remove_from_bst_two() {
// check if we are able to get the max from the BST.
fn test_get_max_in_bst() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert (bst.max() or { -1 }) == -1
assert bst.insert(10)
assert bst.insert(20)
@ -127,7 +127,7 @@ fn test_get_max_in_bst() {
// check if we are able to get the min from the BST.
fn test_get_min_in_bst() {
mut bst := BSTree<int>{}
mut bst := BSTree[int]{}
assert (bst.min() or { -1 }) == -1
assert bst.insert(10)
assert bst.insert(20)

View File

@ -1,36 +1,36 @@
module datatypes
struct DoublyListNode<T> {
struct DoublyListNode[T] {
mut:
data T
next &DoublyListNode<T> = unsafe { 0 }
prev &DoublyListNode<T> = unsafe { 0 }
next &DoublyListNode[T] = unsafe { 0 }
prev &DoublyListNode[T] = unsafe { 0 }
}
// DoublyLinkedList<T> represents a generic doubly linked list of elements, each of type T.
pub struct DoublyLinkedList<T> {
pub struct DoublyLinkedList[T] {
mut:
head &DoublyListNode<T> = unsafe { 0 }
tail &DoublyListNode<T> = unsafe { 0 }
head &DoublyListNode[T] = unsafe { 0 }
tail &DoublyListNode[T] = unsafe { 0 }
// Internal iter pointer for allowing safe modification
// of the list while iterating. TODO: use an option
// instead of a pointer to determine it is initialized.
iter &DoublyListIter<T> = unsafe { 0 }
iter &DoublyListIter[T] = unsafe { 0 }
len int
}
// is_empty checks if the linked list is empty
pub fn (list DoublyLinkedList<T>) is_empty() bool {
pub fn (list DoublyLinkedList[T]) is_empty() bool {
return list.len == 0
}
// len returns the length of the linked list
pub fn (list DoublyLinkedList<T>) len() int {
pub fn (list DoublyLinkedList[T]) len() int {
return list.len
}
// first returns the first element of the linked list
pub fn (list DoublyLinkedList<T>) first() ?T {
pub fn (list DoublyLinkedList[T]) first() ?T {
if list.is_empty() {
return error('Linked list is empty')
}
@ -38,7 +38,7 @@ pub fn (list DoublyLinkedList<T>) first() ?T {
}
// last returns the last element of the linked list
pub fn (list DoublyLinkedList<T>) last() ?T {
pub fn (list DoublyLinkedList[T]) last() ?T {
if list.is_empty() {
return error('Linked list is empty')
}
@ -46,8 +46,8 @@ pub fn (list DoublyLinkedList<T>) last() ?T {
}
// push_back adds an element to the end of the linked list
pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
mut new_node := &DoublyListNode<T>{
pub fn (mut list DoublyLinkedList[T]) push_back(item T) {
mut new_node := &DoublyListNode[T]{
data: item
}
if list.is_empty() {
@ -63,8 +63,8 @@ pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
}
// push_front adds an element to the beginning of the linked list
pub fn (mut list DoublyLinkedList<T>) push_front(item T) {
mut new_node := &DoublyListNode<T>{
pub fn (mut list DoublyLinkedList[T]) push_front(item T) {
mut new_node := &DoublyListNode[T]{
data: item
}
if list.is_empty() {
@ -80,7 +80,7 @@ pub fn (mut list DoublyLinkedList<T>) push_front(item T) {
}
// pop_back removes the last element of the linked list
pub fn (mut list DoublyLinkedList<T>) pop_back() ?T {
pub fn (mut list DoublyLinkedList[T]) pop_back() ?T {
if list.is_empty() {
return error('Linked list is empty')
}
@ -101,7 +101,7 @@ pub fn (mut list DoublyLinkedList<T>) pop_back() ?T {
}
// pop_front removes the last element of the linked list
pub fn (mut list DoublyLinkedList<T>) pop_front() ?T {
pub fn (mut list DoublyLinkedList[T]) pop_front() ?T {
if list.is_empty() {
return error('Linked list is empty')
}
@ -122,7 +122,7 @@ pub fn (mut list DoublyLinkedList<T>) pop_front() ?T {
}
// insert adds an element to the linked list at the given index
pub fn (mut list DoublyLinkedList<T>) insert(idx int, item T) ? {
pub fn (mut list DoublyLinkedList[T]) insert(idx int, item T) ? {
if idx < 0 || idx > list.len {
return error('Index ${idx} out of bounds [0..${list.len}]')
} else if idx == 0 {
@ -142,7 +142,7 @@ pub fn (mut list DoublyLinkedList<T>) insert(idx int, item T) ? {
// (determined from the forward index). This function should be called
// when idx > list.len/2. This helper function assumes idx bounds have
// already been checked and idx is not at the edges.
fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
fn (mut list DoublyLinkedList[T]) insert_back(idx int, item T) {
mut node := list.node(idx + 1)
mut prev := node.prev
// prev node
@ -150,7 +150,7 @@ fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
// |next|---->|next|
// |prev|<----|prev|
// ------ ------
new := &DoublyListNode<T>{
new := &DoublyListNode[T]{
data: item
next: node
prev: prev
@ -169,7 +169,7 @@ fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
// (determined from the forward index). This function should be called
// when idx <= list.len/2. This helper function assumes idx bounds have
// already been checked and idx is not at the edges.
fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
fn (mut list DoublyLinkedList[T]) insert_front(idx int, item T) {
mut node := list.node(idx - 1)
mut next := node.next
// node next
@ -177,7 +177,7 @@ fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
// |next|---->|next|
// |prev|<----|prev|
// ------ ------
new := &DoublyListNode<T>{
new := &DoublyListNode[T]{
data: item
next: next
prev: node
@ -195,7 +195,7 @@ fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
// node walks from the head or tail and finds the node at index idx.
// This helper function assumes the list is not empty and idx is in
// bounds.
fn (list &DoublyLinkedList<T>) node(idx int) &DoublyListNode<T> {
fn (list &DoublyLinkedList[T]) node(idx int) &DoublyListNode[T] {
if idx <= list.len / 2 {
mut node := list.head
for h := 0; h < idx; h += 1 {
@ -212,7 +212,7 @@ fn (list &DoublyLinkedList<T>) node(idx int) &DoublyListNode<T> {
// index searches the linked list for item and returns the forward index
// or none if not found.
pub fn (list &DoublyLinkedList<T>) index(item T) ?int {
pub fn (list &DoublyLinkedList[T]) index(item T) ?int {
mut hn := list.head
mut tn := list.tail
for h, t := 0, list.len - 1; h <= t; {
@ -231,7 +231,7 @@ pub fn (list &DoublyLinkedList<T>) index(item T) ?int {
// delete removes index idx from the linked list and is safe to call
// for any idx.
pub fn (mut list DoublyLinkedList<T>) delete(idx int) {
pub fn (mut list DoublyLinkedList[T]) delete(idx int) {
if idx < 0 || idx >= list.len {
return
} else if idx == 0 {
@ -249,12 +249,12 @@ pub fn (mut list DoublyLinkedList<T>) delete(idx int) {
}
// str returns a string representation of the linked list
pub fn (list DoublyLinkedList<T>) str() string {
pub fn (list DoublyLinkedList[T]) str() string {
return list.array().str()
}
// array returns a array representation of the linked list
pub fn (list DoublyLinkedList<T>) array() []T {
pub fn (list DoublyLinkedList[T]) array() []T {
mut result_array := []T{cap: list.len}
mut node := list.head
for unsafe { node != 0 } {
@ -266,10 +266,10 @@ pub fn (list DoublyLinkedList<T>) array() []T {
// next implements the iter interface to use DoublyLinkedList with
// V's `for x in list {` loop syntax.
pub fn (mut list DoublyLinkedList<T>) next() ?T {
pub fn (mut list DoublyLinkedList[T]) next() ?T {
if list.iter == unsafe { nil } {
// initialize new iter object
list.iter = &DoublyListIter<T>{
list.iter = &DoublyListIter[T]{
node: list.head
}
return list.next()
@ -285,15 +285,15 @@ pub fn (mut list DoublyLinkedList<T>) next() ?T {
}
// iterator returns a new iterator instance for the `list`.
pub fn (mut list DoublyLinkedList<T>) iterator() DoublyListIter<T> {
return DoublyListIter<T>{
pub fn (mut list DoublyLinkedList[T]) iterator() DoublyListIter[T] {
return DoublyListIter[T]{
node: list.head
}
}
// back_iterator returns a new backwards iterator instance for the `list`.
pub fn (mut list DoublyLinkedList<T>) back_iterator() DoublyListIterBack<T> {
return DoublyListIterBack<T>{
pub fn (mut list DoublyLinkedList[T]) back_iterator() DoublyListIterBack[T] {
return DoublyListIterBack[T]{
node: list.tail
}
}
@ -303,14 +303,14 @@ pub fn (mut list DoublyLinkedList<T>) back_iterator() DoublyListIterBack<T> {
// It can be used with V's `for x in iter {` construct.
// One list can have multiple independent iterators, pointing to different positions/places in the list.
// A DoublyListIter iterator instance always traverses the list from *start to finish*.
pub struct DoublyListIter<T> {
pub struct DoublyListIter[T] {
mut:
node &DoublyListNode<T> = unsafe { 0 }
node &DoublyListNode[T] = unsafe { 0 }
}
// next returns *the next* element of the list, or `none` when the end of the list is reached.
// It is called by V's `for x in iter{` on each iteration.
pub fn (mut iter DoublyListIter<T>) next() ?T {
pub fn (mut iter DoublyListIter[T]) next() ?T {
if iter.node == unsafe { nil } {
return none
}
@ -324,14 +324,14 @@ pub fn (mut iter DoublyListIter<T>) next() ?T {
// It can be used with V's `for x in iter {` construct.
// One list can have multiple independent iterators, pointing to different positions/places in the list.
// A DoublyListIterBack iterator instance always traverses the list from *finish to start*.
pub struct DoublyListIterBack<T> {
pub struct DoublyListIterBack[T] {
mut:
node &DoublyListNode<T> = unsafe { 0 }
node &DoublyListNode[T] = unsafe { 0 }
}
// next returns *the previous* element of the list, or `none` when the start of the list is reached.
// It is called by V's `for x in iter{` on each iteration.
pub fn (mut iter DoublyListIterBack<T>) next() ?T {
pub fn (mut iter DoublyListIterBack[T]) next() ?T {
if iter.node == unsafe { nil } {
return none
}

View File

@ -1,14 +1,14 @@
module datatypes
fn test_is_empty() {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
assert list.is_empty() == true
list.push_back(1)
assert list.is_empty() == false
}
fn test_len() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
assert list.len() == 0
list.push_back(1)
assert list.len() == 1
@ -17,29 +17,29 @@ fn test_len() ? {
}
fn test_first() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
assert list.first()? == 1
list.push_back(2)
assert list.first()? == 1
list = DoublyLinkedList<int>{}
list = DoublyLinkedList[int]{}
list.first() or { return }
assert false
}
fn test_last() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
assert list.last()? == 1
list.push_back(2)
assert list.last()? == 2
list = DoublyLinkedList<int>{}
list = DoublyLinkedList[int]{}
list.last() or { return }
assert false
}
fn test_push() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
assert list.last()? == 1
list.push_back(2)
@ -49,7 +49,7 @@ fn test_push() ? {
}
fn test_pop() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -57,13 +57,13 @@ fn test_pop() ? {
list.push_back(4)
assert list.pop_back()? == 4
assert list.pop_back()? == 2
list = DoublyLinkedList<int>{}
list = DoublyLinkedList[int]{}
list.pop_back() or { return }
assert false
}
fn test_pop_front() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -71,13 +71,13 @@ fn test_pop_front() ? {
list.push_back(4)
assert list.pop_front()? == 2
assert list.pop_front()? == 3
list = DoublyLinkedList<int>{}
list = DoublyLinkedList[int]{}
list.pop_front() or { return }
assert false
}
fn test_insert() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -93,7 +93,7 @@ fn test_insert() ? {
}
fn test_push_front() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -102,7 +102,7 @@ fn test_push_front() ? {
}
fn test_delete() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(0)
list.push_back(1)
list.push_back(2)
@ -119,7 +119,7 @@ fn test_delete() ? {
}
fn test_iter() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
for i := 0; i < 10; i++ {
list.push_back(i * 10)
}
@ -141,7 +141,7 @@ fn test_iter() ? {
}
fn test_index() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
for i := 0; i < 10; i++ {
list.push_back(i * 10)
}
@ -152,7 +152,7 @@ fn test_index() ? {
}
fn test_str() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -160,7 +160,7 @@ fn test_str() ? {
}
fn test_array() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -168,7 +168,7 @@ fn test_array() ? {
}
fn test_string_array() ? {
mut list := DoublyLinkedList<[]string>{}
mut list := DoublyLinkedList[[]string]{}
list.push_back(['a'])
list.push_back(['b'])
list.push_back(['c'])
@ -176,7 +176,7 @@ fn test_string_array() ? {
}
fn test_iteration_with_for() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -188,7 +188,7 @@ fn test_iteration_with_for() ? {
}
fn test_iterator() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)
@ -201,7 +201,7 @@ fn test_iterator() ? {
}
fn test_back_iterator() ? {
mut list := DoublyLinkedList<int>{}
mut list := DoublyLinkedList[int]{}
list.push_back(1)
list.push_back(2)
list.push_back(3)

View File

@ -1,13 +1,13 @@
module datatypes
// MinHeap is a binary minimum heap data structure.
pub struct MinHeap<T> {
pub struct MinHeap[T] {
mut:
data []T
}
// insert adds an element to the heap.
pub fn (mut heap MinHeap<T>) insert(item T) {
pub fn (mut heap MinHeap[T]) insert(item T) {
// push item to the end of the array
heap.data << item
// swap the new node with its parent until the heap is in order
@ -21,7 +21,7 @@ pub fn (mut heap MinHeap<T>) insert(item T) {
}
// pop removes the top-most element from the heap.
pub fn (mut heap MinHeap<T>) pop() ?T {
pub fn (mut heap MinHeap[T]) pop() ?T {
if heap.data.len == 0 {
return none
} else if heap.data.len == 1 {
@ -46,7 +46,7 @@ pub fn (mut heap MinHeap<T>) pop() ?T {
}
// peek gets the top-most element from the heap without removing it.
pub fn (heap MinHeap<T>) peek() ?T {
pub fn (heap MinHeap[T]) peek() ?T {
if heap.data.len == 0 {
return none
}
@ -54,13 +54,13 @@ pub fn (heap MinHeap<T>) peek() ?T {
}
// len returns the number of elements in the heap.
pub fn (heap MinHeap<T>) len() int {
pub fn (heap MinHeap[T]) len() int {
return heap.data.len
}
// left_child is a helper function that returns the index of the left
// child given a parent idx, or none if there is no left child.
fn (heap MinHeap<T>) left_child(idx int) ?int {
fn (heap MinHeap[T]) left_child(idx int) ?int {
child := 2 * idx + 1
if child >= heap.data.len {
return none
@ -70,7 +70,7 @@ fn (heap MinHeap<T>) left_child(idx int) ?int {
// right_child is a helper function that returns the index of the right
// child given a parent idx, or none if there is no right child.
fn (heap MinHeap<T>) right_child(idx int) ?int {
fn (heap MinHeap[T]) right_child(idx int) ?int {
child := 2 * idx + 2
if child >= heap.data.len {
return none
@ -79,6 +79,6 @@ fn (heap MinHeap<T>) right_child(idx int) ?int {
}
// parent is a helper function that returns the parent index of the child.
fn (heap MinHeap<T>) parent(idx int) int {
fn (heap MinHeap[T]) parent(idx int) int {
return (idx - 1) / 2
}

View File

@ -1,7 +1,7 @@
module datatypes
fn test_min_heap() ? {
mut heap := MinHeap<int>{}
mut heap := MinHeap[int]{}
heap.insert(2)
heap.insert(0)
heap.insert(8)
@ -28,7 +28,7 @@ fn (lhs Item) < (rhs Item) bool {
}
fn test_min_heap_custom() ? {
mut heap := MinHeap<Item>{}
mut heap := MinHeap[Item]{}
heap.insert(Item{'buz', 10})
heap.insert(Item{'qux', 0})
heap.insert(Item{'baz', 50})
@ -46,7 +46,7 @@ fn test_min_heap_custom() ? {
}
fn test_heap_len() ? {
mut heap := MinHeap<int>{}
mut heap := MinHeap[int]{}
heap.insert(2)
assert heap.len() == 1
heap.insert(0)

View File

@ -1,38 +1,38 @@
module datatypes
pub struct ListNode<T> {
pub struct ListNode[T] {
mut:
data T
next &ListNode<T> = unsafe { 0 }
next &ListNode[T] = unsafe { 0 }
}
pub struct LinkedList<T> {
pub struct LinkedList[T] {
mut:
head &ListNode<T> = unsafe { 0 }
head &ListNode[T] = unsafe { 0 }
len int
// Internal iter pointer for allowing safe modification
// of the list while iterating. TODO: use an option
// instead of a pointer to determine if it is initialized.
iter &ListIter<T> = unsafe { 0 }
iter &ListIter[T] = unsafe { 0 }
}
// is_empty checks if the linked list is empty
pub fn (list LinkedList<T>) is_empty() bool {
pub fn (list LinkedList[T]) is_empty() bool {
return list.len == 0
}
// len returns the length of the linked list
pub fn (list LinkedList<T>) len() int {
pub fn (list LinkedList[T]) len() int {
return list.len
}
// first returns the first element of the linked list
pub fn (list LinkedList<T>) first() ?T {
pub fn (list LinkedList[T]) first() ?T {
return if !list.is_empty() { list.head.data } else { error('Linked list is empty') }
}
// last returns the last element of the linked list
pub fn (list LinkedList<T>) last() ?T {
pub fn (list LinkedList[T]) last() ?T {
if unsafe { list.head == 0 } {
return error('Linked list is empty')
} else {
@ -45,7 +45,7 @@ pub fn (list LinkedList<T>) last() ?T {
}
// index returns the element at the given index of the linked list
pub fn (list LinkedList<T>) index(idx int) ?T {
pub fn (list LinkedList[T]) index(idx int) ?T {
if unsafe { list.head == 0 } {
return error('Linked list is empty')
} else {
@ -64,8 +64,8 @@ pub fn (list LinkedList<T>) index(idx int) ?T {
}
// push adds an element to the end of the linked list
pub fn (mut list LinkedList<T>) push(item T) {
new_node := &ListNode<T>{
pub fn (mut list LinkedList[T]) push(item T) {
new_node := &ListNode[T]{
data: item
}
if unsafe { list.head == 0 } {
@ -82,7 +82,7 @@ pub fn (mut list LinkedList<T>) push(item T) {
}
// pop removes the last element of the linked list
pub fn (mut list LinkedList<T>) pop() ?T {
pub fn (mut list LinkedList[T]) pop() ?T {
if unsafe { list.head == 0 } {
return error('Linked list is empty')
}
@ -105,7 +105,7 @@ pub fn (mut list LinkedList<T>) pop() ?T {
}
// shift removes the first element of the linked list
pub fn (mut list LinkedList<T>) shift() ?T {
pub fn (mut list LinkedList[T]) shift() ?T {
if unsafe { list.head == 0 } {
return error('Linked list is empty')
} else {
@ -117,7 +117,7 @@ pub fn (mut list LinkedList<T>) shift() ?T {
}
// insert adds an element to the linked list at the given index
pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
pub fn (mut list LinkedList[T]) insert(idx int, item T) ? {
if idx < 0 || idx > list.len {
return error('Index ${idx} out of bounds [0..${list.len}]')
} else if list.len == 0 {
@ -128,7 +128,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
if idx == 0 {
// first node case
list.head = &ListNode<T>{
list.head = &ListNode[T]{
data: item
next: node
}
@ -136,7 +136,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
for i := 0; i < idx - 1; i++ {
node = node.next
}
node.next = &ListNode<T>{
node.next = &ListNode[T]{
data: item
next: node.next
}
@ -145,17 +145,17 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
}
// prepend adds an element to the beginning of the linked list (equivalent to insert(0, item))
pub fn (mut list LinkedList<T>) prepend(item T) {
pub fn (mut list LinkedList[T]) prepend(item T) {
list.insert(0, item) or {}
}
// str returns a string representation of the linked list
pub fn (list LinkedList<T>) str() string {
pub fn (list LinkedList[T]) str() string {
return list.array().str()
}
// array returns a array representation of the linked list
pub fn (list LinkedList<T>) array() []T {
pub fn (list LinkedList[T]) array() []T {
mut result_array := []T{cap: list.len}
mut node := list.head
for unsafe { node != 0 } {
@ -167,10 +167,10 @@ pub fn (list LinkedList<T>) array() []T {
// next implements the iteration interface to use LinkedList
// with V's `for` loop syntax.
pub fn (mut list LinkedList<T>) next() ?T {
pub fn (mut list LinkedList[T]) next() ?T {
if list.iter == unsafe { nil } {
// initialize new iter object
list.iter = &ListIter<T>{
list.iter = &ListIter[T]{
node: list.head
}
return list.next()
@ -186,8 +186,8 @@ pub fn (mut list LinkedList<T>) next() ?T {
}
// iterator returns a new iterator instance for the `list`.
pub fn (mut list LinkedList<T>) iterator() ListIter<T> {
return ListIter<T>{
pub fn (mut list LinkedList[T]) iterator() ListIter[T] {
return ListIter[T]{
node: list.head
}
}
@ -196,14 +196,14 @@ pub fn (mut list LinkedList<T>) iterator() ListIter<T> {
// It can be used with V's `for x in iter {` construct.
// One list can have multiple independent iterators, pointing to different positions/places in the list.
// An iterator instance always traverses the list from start to finish.
pub struct ListIter<T> {
pub struct ListIter[T] {
mut:
node &ListNode<T> = unsafe { 0 }
node &ListNode[T] = unsafe { 0 }
}
// next returns the next element of the list, or `none` when the end of the list is reached.
// It is called by V's `for x in iter{` on each iteration.
pub fn (mut iter ListIter<T>) next() ?T {
pub fn (mut iter ListIter[T]) next() ?T {
if iter.node == unsafe { nil } {
return none
}

View File

@ -1,14 +1,14 @@
module datatypes
fn test_is_empty() {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
assert list.is_empty() == true
list.push(1)
assert list.is_empty() == false
}
fn test_len() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
assert list.len() == 0
list.push(1)
assert list.len() == 1
@ -17,29 +17,29 @@ fn test_len() ? {
}
fn test_first() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
assert list.first()? == 1
list.push(2)
assert list.first()? == 1
list = LinkedList<int>{}
list = LinkedList[int]{}
list.first() or { return }
assert false
}
fn test_last() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
assert list.last()? == 1
list.push(2)
assert list.last()? == 2
list = LinkedList<int>{}
list = LinkedList[int]{}
list.last() or { return }
assert false
}
fn test_index() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
assert list.index(0)? == 1
list.push(2)
@ -50,7 +50,7 @@ fn test_index() ? {
}
fn test_push() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
assert list.last()? == 1
list.push(2)
@ -60,7 +60,7 @@ fn test_push() ? {
}
fn test_pop() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -68,13 +68,13 @@ fn test_pop() ? {
list.push(4)
assert list.pop()? == 4
assert list.pop()? == 2
list = LinkedList<int>{}
list = LinkedList[int]{}
list.pop() or { return }
assert false
}
fn test_shift() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -82,13 +82,13 @@ fn test_shift() ? {
list.push(4)
assert list.shift()? == 2
assert list.shift()? == 3
list = LinkedList<int>{}
list = LinkedList[int]{}
list.shift() or { return }
assert false
}
fn test_insert() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -97,7 +97,7 @@ fn test_insert() ? {
}
fn test_prepend() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -106,7 +106,7 @@ fn test_prepend() ? {
}
fn test_str() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -114,7 +114,7 @@ fn test_str() ? {
}
fn test_array() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -122,7 +122,7 @@ fn test_array() ? {
}
fn test_linked_list_iterating_with_for() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)
@ -134,7 +134,7 @@ fn test_linked_list_iterating_with_for() ? {
}
fn test_linked_list_separate_iterators() ? {
mut list := LinkedList<int>{}
mut list := LinkedList[int]{}
list.push(1)
list.push(2)
list.push(3)

View File

@ -1,51 +1,51 @@
module datatypes
pub struct Queue<T> {
pub struct Queue[T] {
mut:
elements LinkedList<T>
elements LinkedList[T]
}
// is_empty checks if the queue is empty
pub fn (queue Queue<T>) is_empty() bool {
pub fn (queue Queue[T]) is_empty() bool {
return queue.elements.is_empty()
}
// len returns the length of the queue
pub fn (queue Queue<T>) len() int {
pub fn (queue Queue[T]) len() int {
return queue.elements.len()
}
// peek returns the head of the queue (first element added)
pub fn (queue Queue<T>) peek() ?T {
pub fn (queue Queue[T]) peek() ?T {
return queue.elements.first()
}
// last returns the tail of the queue (last element added)
pub fn (queue Queue<T>) last() ?T {
pub fn (queue Queue[T]) last() ?T {
return queue.elements.last()
}
// index returns the element at the given index of the queue
pub fn (queue Queue<T>) index(idx int) ?T {
pub fn (queue Queue[T]) index(idx int) ?T {
return queue.elements.index(idx)
}
// push adds an element to the tail of the queue
pub fn (mut queue Queue<T>) push(item T) {
pub fn (mut queue Queue[T]) push(item T) {
queue.elements.push(item)
}
// pop removes the element at the head of the queue and returns it
pub fn (mut queue Queue<T>) pop() ?T {
pub fn (mut queue Queue[T]) pop() ?T {
return queue.elements.shift()
}
// str returns a string representation of the queue
pub fn (queue Queue<T>) str() string {
pub fn (queue Queue[T]) str() string {
return queue.elements.str()
}
// array returns a array representation of the queue
pub fn (queue Queue<T>) array() []T {
pub fn (queue Queue[T]) array() []T {
return queue.elements.array()
}

View File

@ -1,14 +1,14 @@
module datatypes
fn test_is_empty() {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
assert queue.is_empty() == true
queue.push(1)
assert queue.is_empty() == false
}
fn test_len() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
assert queue.len() == 0
queue.push(1)
assert queue.len() == 1
@ -17,29 +17,29 @@ fn test_len() ? {
}
fn test_peek() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
assert queue.peek()? == 1
queue.push(2)
assert queue.peek()? == 1
queue = Queue<int>{}
queue = Queue[int]{}
queue.peek() or { return }
assert false
}
fn test_last() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
assert queue.last()? == 1
queue.push(2)
assert queue.last()? == 2
queue = Queue<int>{}
queue = Queue[int]{}
queue.last() or { return }
assert false
}
fn test_index() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
assert queue.index(0)? == 1
queue.push(2)
@ -50,14 +50,14 @@ fn test_index() ? {
}
fn test_push() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
queue.push(2)
assert queue.peek()? == 1
}
fn test_pop() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
queue.push(2)
queue.push(3)
@ -65,13 +65,13 @@ fn test_pop() ? {
queue.push(4)
assert queue.pop()? == 2
assert queue.pop()? == 3
queue = Queue<int>{}
queue = Queue[int]{}
queue.pop() or { return }
assert false
}
fn test_array() ? {
mut queue := Queue<int>{}
mut queue := Queue[int]{}
queue.push(1)
queue.push(2)
assert queue.array() == [1, 2]

View File

@ -3,7 +3,7 @@
module datatypes
// RingBuffer - public struct that represents the ringbuffer
pub struct RingBuffer<T> {
pub struct RingBuffer[T] {
mut:
reader int // index of the tail where data is going to be read
writer int // index of the head where data is going to be written
@ -11,14 +11,14 @@ mut:
}
// new_ringbuffer - creates an empty ringbuffer
pub fn new_ringbuffer<T>(s int) RingBuffer<T> {
return RingBuffer<T>{
pub fn new_ringbuffer[T](s int) RingBuffer[T] {
return RingBuffer[T]{
content: []T{len: s + 1, cap: s + 1}
} // increasing custom set size by one element in order to make ring flow possible, so that writer cannot equal reader before reader-index has been read.
}
// push - adds an element to the ringbuffer
pub fn (mut rb RingBuffer<T>) push(element T) ? {
pub fn (mut rb RingBuffer[T]) push(element T) ? {
if rb.is_full() {
return error('Buffer overflow')
} else {
@ -28,7 +28,7 @@ pub fn (mut rb RingBuffer<T>) push(element T) ? {
}
// pop - returns the oldest element of the buffer
pub fn (mut rb RingBuffer<T>) pop() ?T {
pub fn (mut rb RingBuffer[T]) pop() ?T {
mut v := rb.content[rb.reader]
if rb.is_empty() {
return error('Buffer is empty')
@ -39,14 +39,14 @@ pub fn (mut rb RingBuffer<T>) pop() ?T {
}
// push_many - pushes an array to the buffer
pub fn (mut rb RingBuffer<T>) push_many(elements []T) ? {
pub fn (mut rb RingBuffer[T]) push_many(elements []T) ? {
for v in elements {
rb.push(v) or { return err }
}
}
// pop_many - returns a given number(n) of elements of the buffer starting with the oldest one
pub fn (mut rb RingBuffer<T>) pop_many(n u64) ?[]T {
pub fn (mut rb RingBuffer[T]) pop_many(n u64) ?[]T {
mut elements := []T{}
for _ in 0 .. n {
elements << rb.pop() or { return err }
@ -55,12 +55,12 @@ pub fn (mut rb RingBuffer<T>) pop_many(n u64) ?[]T {
}
// is_empty - checks if the ringbuffer is empty
pub fn (rb RingBuffer<T>) is_empty() bool {
pub fn (rb RingBuffer[T]) is_empty() bool {
return rb.reader == rb.writer // if reader equals writer it means that no value to read has been written before. It follows that the buffer is empty.
}
// is_full - checks if the ringbuffer is full
pub fn (rb RingBuffer<T>) is_full() bool {
pub fn (rb RingBuffer[T]) is_full() bool {
if rb.writer + 1 == rb.reader {
return true
} else if rb.writer == rb.content.len - 1 && rb.reader == 0 {
@ -71,19 +71,19 @@ pub fn (rb RingBuffer<T>) is_full() bool {
}
// capacity - returns the capacity of the ringbuffer
pub fn (rb RingBuffer<T>) capacity() int {
pub fn (rb RingBuffer[T]) capacity() int {
return rb.content.cap - 1 // reduce by one because of the extra element explained in function `new_ringbuffer()`
}
// clear - emptys the ringbuffer and all pushed elements
pub fn (mut rb RingBuffer<T>) clear() {
rb = RingBuffer<T>{
pub fn (mut rb RingBuffer[T]) clear() {
rb = RingBuffer[T]{
content: []T{len: rb.content.len, cap: rb.content.cap}
}
}
// occupied - returns occupied capacity of the buffer.
pub fn (rb RingBuffer<T>) occupied() int {
pub fn (rb RingBuffer[T]) occupied() int {
mut reader := rb.reader
mut v := 0
if rb.is_empty() {
@ -103,20 +103,20 @@ pub fn (rb RingBuffer<T>) occupied() int {
}
// remaining - returns remaining capacity of the buffer
pub fn (rb RingBuffer<T>) remaining() int {
pub fn (rb RingBuffer[T]) remaining() int {
return rb.capacity() - rb.occupied()
}
// head an tail-pointer move methods
// these methods are not public, they are just an eneasement for handling the pointer-movement process.
fn (mut rb RingBuffer<T>) move_reader() {
fn (mut rb RingBuffer[T]) move_reader() {
rb.reader++
if rb.reader > rb.content.len - 1 {
rb.reader = 0
}
}
fn (mut rb RingBuffer<T>) move_writer() {
fn (mut rb RingBuffer[T]) move_writer() {
rb.writer++
if rb.writer > rb.content.len - 1 {
rb.writer = 0

View File

@ -1,7 +1,7 @@
import datatypes
fn test_push_and_pop() {
mut r := datatypes.new_ringbuffer<int>(2)
mut r := datatypes.new_ringbuffer[int](2)
r.push(3) or { panic(err) }
r.push(4) or { panic(err) }
@ -18,7 +18,7 @@ fn test_push_and_pop() {
}
fn test_clear_and_empty() {
mut r := datatypes.new_ringbuffer<int>(4)
mut r := datatypes.new_ringbuffer[int](4)
r.push(3) or { panic(err) }
r.push(4) or { panic(err) }
@ -31,7 +31,7 @@ fn test_clear_and_empty() {
}
fn test_capacity_and_is_full() {
mut r := datatypes.new_ringbuffer<int>(4)
mut r := datatypes.new_ringbuffer[int](4)
assert r.capacity() == 4
@ -44,7 +44,7 @@ fn test_capacity_and_is_full() {
}
fn test_occupied_and_remaining() {
mut r := datatypes.new_ringbuffer<int>(4)
mut r := datatypes.new_ringbuffer[int](4)
r.push(3) or { panic(err) }
r.push(4) or { panic(err) }
@ -53,7 +53,7 @@ fn test_occupied_and_remaining() {
}
fn test_push_and_pop_many() {
mut r := datatypes.new_ringbuffer<int>(4)
mut r := datatypes.new_ringbuffer[int](4)
a := [1, 2, 3, 4]
r.push_many(a) or { panic(err) }

View File

@ -1,27 +1,27 @@
module datatypes
pub struct Set<T> {
pub struct Set[T] {
mut:
elements map[T]u8
}
// checks the element is exists.
pub fn (set Set<T>) exists(element T) bool {
pub fn (set Set[T]) exists(element T) bool {
return element in set.elements
}
// adds the element to set, if it is not present already.
pub fn (mut set Set<T>) add(element T) {
pub fn (mut set Set[T]) add(element T) {
set.elements[element] = 1
}
// removes the element from set.
pub fn (mut set Set<T>) remove(element T) {
pub fn (mut set Set[T]) remove(element T) {
set.elements.delete(element)
}
// pick returns an arbitrary element of set, if set is not empty.
pub fn (set Set<T>) pick() ?T {
pub fn (set Set[T]) pick() ?T {
for k, _ in set.elements {
return k
}
@ -29,31 +29,31 @@ pub fn (set Set<T>) pick() ?T {
}
// rest returns the set consisting of all elements except for the arbitrary element.
pub fn (mut set Set<T>) rest() ?[]T {
pub fn (mut set Set[T]) rest() ?[]T {
element := set.pick()?
return set.elements.keys().filter(it != element)
}
// pop returns an arbitrary element and deleting it from set.
pub fn (mut set Set<T>) pop() ?T {
pub fn (mut set Set[T]) pop() ?T {
element := set.pick()?
set.elements.delete(element)
return element
}
// delete all elements of set.
pub fn (mut set Set<T>) clear() {
pub fn (mut set Set[T]) clear() {
set.elements = map[T]u8{}
}
// equal checks whether the two given sets are equal (i.e. contain all and only the same elements).
[deprecated: 'use set1<T> == set2<T> instead']
pub fn (l Set<T>) equal(r Set<T>) bool {
pub fn (l Set[T]) equal(r Set[T]) bool {
return l == r
}
// == checks whether the two given sets are equal (i.e. contain all and only the same elements).
pub fn (l Set<T>) == (r Set<T>) bool {
pub fn (l Set[T]) == (r Set[T]) bool {
if l.elements.len != r.elements.len {
return false
}
@ -66,31 +66,31 @@ pub fn (l Set<T>) == (r Set<T>) bool {
}
// is_empty checks whether the set is empty or not.
pub fn (set Set<T>) is_empty() bool {
pub fn (set Set[T]) is_empty() bool {
return set.size() == 0
}
// size returns the number of elements in the set.
pub fn (set Set<T>) size() int {
pub fn (set Set[T]) size() int {
return set.elements.len
}
// copy returns a copy of all the elements in the set.
pub fn (set Set<T>) copy() Set<T> {
return Set<T>{
pub fn (set Set[T]) copy() Set[T] {
return Set[T]{
elements: set.elements.clone()
}
}
// add_all adds the whole `elements` array to the set
pub fn (mut set Set<T>) add_all(elements []T) {
pub fn (mut set Set[T]) add_all(elements []T) {
for element in elements {
set.add(element)
}
}
// @union returns the union of the two sets.
pub fn (l Set<T>) @union(r Set<T>) Set<T> {
pub fn (l Set[T]) @union(r Set[T]) Set[T] {
mut set := l
for e, _ in r.elements {
set.add(e)
@ -99,7 +99,7 @@ pub fn (l Set<T>) @union(r Set<T>) Set<T> {
}
// intersection returns the intersection of sets.
pub fn (l Set<T>) intersection(r Set<T>) Set<T> {
pub fn (l Set[T]) intersection(r Set[T]) Set[T] {
mut set := l
for e, _ in l.elements {
if !r.exists(e) {
@ -116,12 +116,12 @@ pub fn (l Set<T>) intersection(r Set<T>) Set<T> {
// difference returns the difference of sets.
[deprecated: 'use set1<T> - set2<T> instead']
pub fn (l Set<T>) difference(r Set<T>) Set<T> {
pub fn (l Set[T]) difference(r Set[T]) Set[T] {
return l - r
}
// - returns the difference of sets.
pub fn (l Set<T>) - (r Set<T>) Set<T> {
pub fn (l Set[T]) - (r Set[T]) Set[T] {
mut set := l
for e, _ in l.elements {
if r.exists(e) {
@ -132,7 +132,7 @@ pub fn (l Set<T>) - (r Set<T>) Set<T> {
}
// subset returns true if the set `r` is a subset of the set `l`.
pub fn (l Set<T>) subset(r Set<T>) bool {
pub fn (l Set[T]) subset(r Set[T]) bool {
for e, _ in r.elements {
if e !in l.elements {
return false

View File

@ -1,14 +1,14 @@
module datatypes
fn test_exists() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add('foo')
assert set.exists('foo')
assert set.exists('bar') == false
}
fn test_remove() {
mut set := Set<string>{}
mut set := Set[string]{}
set.remove('foo')
set.add('foo')
assert set.exists('foo')
@ -17,28 +17,28 @@ fn test_remove() {
}
fn test_size() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add('foo')
set.add('foo')
assert set.size() == 1
}
fn test_pop() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add('foo')
set.pop() or { return }
assert set.exists('foo') == false
}
fn test_clear() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add('foo')
set.clear()
assert set.size() == 0
}
fn test_rest() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add('foo')
set.add('bar')
array := set.rest() or { return }
@ -46,8 +46,8 @@ fn test_rest() {
}
fn test_equal() {
mut first_set := Set<string>{}
mut second_set := Set<string>{}
mut first_set := Set[string]{}
mut second_set := Set[string]{}
first_set.add('foo')
assert second_set != first_set
second_set.add('foo')
@ -55,15 +55,15 @@ fn test_equal() {
}
fn test_is_empty() {
mut set := Set<string>{}
mut set := Set[string]{}
assert set.is_empty()
set.add('foo')
assert set.is_empty() == false
}
fn test_union() {
mut first_set := Set<string>{}
mut second_set := Set<string>{}
mut first_set := Set[string]{}
mut second_set := Set[string]{}
first_set.add_all(['b', 'c', 'd'])
second_set.add_all(['a', 'e'])
mut third_set := first_set.@union(second_set)
@ -75,9 +75,9 @@ fn test_union() {
}
fn test_intersection() {
mut first_set := Set<string>{}
mut first_set := Set[string]{}
first_set.add_all(['foo', 'bar', 'baz'])
mut second_set := Set<string>{}
mut second_set := Set[string]{}
second_set.add_all(['bar', 'baz', 'boo'])
mut third_set := first_set.intersection(second_set)
assert third_set.exists('foo') == false
@ -87,8 +87,8 @@ fn test_intersection() {
}
fn test_difference() {
mut first_set := Set<string>{}
mut second_set := Set<string>{}
mut first_set := Set[string]{}
mut second_set := Set[string]{}
first_set.add_all(['foo', 'bar', 'baz'])
second_set.add_all(['bar', 'baz', 'boo'])
mut third_set := first_set - second_set
@ -109,9 +109,9 @@ fn test_difference() {
}
fn test_subset() {
mut set := Set<string>{}
mut set := Set[string]{}
set.add_all(['a', 'b', 'c'])
mut subset := Set<string>{}
mut subset := Set[string]{}
subset.add_all(['b', 'c'])
assert set.subset(subset)
}

View File

@ -1,41 +1,41 @@
module datatypes
pub struct Stack<T> {
pub struct Stack[T] {
mut:
elements []T
}
// is_empty checks if the stack is empty
pub fn (stack Stack<T>) is_empty() bool {
pub fn (stack Stack[T]) is_empty() bool {
return stack.elements.len == 0
}
// len returns the length of the stack
pub fn (stack Stack<T>) len() int {
pub fn (stack Stack[T]) len() int {
return stack.elements.len
}
// peek returns the top of the stack
pub fn (stack Stack<T>) peek() ?T {
pub fn (stack Stack[T]) peek() ?T {
return if !stack.is_empty() { stack.elements.last() } else { error('Stack is empty') }
}
// push adds an element to the top of the stack
pub fn (mut stack Stack<T>) push(item T) {
pub fn (mut stack Stack[T]) push(item T) {
stack.elements << item
}
// pop removes the element at the top of the stack and returns it
pub fn (mut stack Stack<T>) pop() ?T {
pub fn (mut stack Stack[T]) pop() ?T {
return if !stack.is_empty() { stack.elements.pop() } else { error('Stack is empty') }
}
// str returns a string representation of the stack
pub fn (stack Stack<T>) str() string {
pub fn (stack Stack[T]) str() string {
return stack.elements.str()
}
// array returns a array representation of the stack
pub fn (stack Stack<T>) array() []T {
pub fn (stack Stack[T]) array() []T {
return stack.elements
}

View File

@ -1,14 +1,14 @@
import datatypes as dt
fn test_is_empty() {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
assert stack.is_empty() == true
stack.push(1)
assert stack.is_empty() == false
}
fn test_len() ? {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
assert stack.len() == 0
stack.push(1)
assert stack.len() == 1
@ -17,18 +17,18 @@ fn test_len() ? {
}
fn test_peek() ? {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
stack.push(1)
assert stack.peek()? == 1
stack.push(2)
assert stack.peek()? == 2
stack = dt.Stack<int>{}
stack = dt.Stack[int]{}
stack.peek() or { return }
assert false
}
fn test_push() ? {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
stack.push(1)
assert stack.peek()? == 1
stack.push(2)
@ -38,7 +38,7 @@ fn test_push() ? {
}
fn test_pop() ? {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
stack.push(1)
stack.push(2)
stack.push(3)
@ -46,13 +46,13 @@ fn test_pop() ? {
stack.push(4)
assert stack.pop()? == 4
assert stack.pop()? == 2
stack = dt.Stack<int>{}
stack = dt.Stack[int]{}
stack.pop() or { return }
assert false
}
fn test_array() ? {
mut stack := dt.Stack<int>{}
mut stack := dt.Stack[int]{}
stack.push(1)
stack.push(2)
assert stack.array() == [1, 2]