forked from maplelang/compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvec.m
65 lines (55 loc) · 1.5 KB
/
vec.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
* Copyright (c) 2022-2023, Mate Kukri
* SPDX-License-Identifier: GPL-2.0-only
*
* Description: Implementation of a vector data structure
*/
import opt::Option
import mem
import prog
struct Vec<T>(mem: *mut T, length: Uintn, capacity: Uintn)
function (!Vec) new<T>() -> Vec<T> {
Vec(nil, 0, 0)
}
function (vec: *mut Vec<T>) delete<T>() {
mem::deallocate((*vec).mem)
}
function (vec: *mut Vec<T>) ensure_capacity<T>(capacity: Uintn) {
if (*vec).capacity < capacity {
(*vec).capacity = capacity * 2;
(*vec).mem = mem::reallocate_contiguous((*vec).mem, capacity * 2);
}
}
function (vec: *mut Vec<T>) push<T>(val: T) {
ensure_capacity(vec, (*vec).length + 1);
*mem::ptr_off((*vec).mem, (*vec).length) = val;
(*vec).length += 1;
}
function (vec: *mut Vec<T>) at<T>(index: Uintn) -> *mut T {
if index >= (*vec).length {
prog::panic(c"Tried to access vec out of bounds");
}
mem::ptr_off((*vec).mem, index)
}
function (vec: *mut Vec<T>) at_or_none<T>(index: Uintn) -> Option<*mut T> {
if index < (*vec).length {
Option::Some(mem::ptr_off((*vec).mem, index))
} else {
Option::None
}
}
function (vec: *mut Vec<T>) pop<T>() -> T {
if (*vec).length == 0 {
prog::panic(c"Tried to pop form empty vec");
}
(*vec).length -= 1;
*mem::ptr_off((*vec).mem, (*vec).length)
}
function (vec: *mut Vec<T>) pop_or_none<T>() -> opt::Option<T> {
if (*vec).length > 0 {
(*vec).length -= 1;
Option::Some(*mem::ptr_off((*vec).mem, (*vec).length))
} else {
Option::None
}
}