blob: eb9ae8efecc79ad60f6e66f66586703e71b85f14 (
plain)
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
|
struct List[T](array: Array[T]) {
// TODO: generic effect
fun forEach(this, func: fn (T) ! Io -> Unit) ! Io -> Unit {
var index = 0;
val size = this.array.size();
while (index < size) {
func!(this.array.unsafeGet(index));
set index = index + 1;
}
}
}
struct ListBuilder[T](arrayBuilder: ArrayBuilder[T]) {
fun add(this, element: T) -> ListBuilder[T] {
if (this.arrayBuilder.size() < this.arrayBuilder.capacity()) {
ListBuilder(this.arrayBuilder.unsafeAdd(element))
} else {
val newCapacity = this.arrayBuilder.capacity() * 2;
val newArrayBuilder = this.arrayBuilder
.unsafeEnlarge(.capacity = newCapacity)
.unsafeAdd(element);
ListBuilder(newArrayBuilder)
}
}
fun build(this) -> List[T] {
List(this.arrayBuilder.build())
}
}
pub fun listBuilder[T]() -> ListBuilder[T] {
ListBuilder[T](arrayBuilder[T](.capacity = 16))
}
native type Array[T] {
// Precondition: the index is in the range [0, size).
native fun unsafeGet(This, Int) -> T;
native fun size(This) -> Int;
}
native type ArrayBuilder[T] {
native fun capacity(This) -> Int;
native fun size(This) -> Int;
// Precondition: size < capacity.
native fun unsafeAdd(This, T) -> ArrayBuilder[T];
// Precondition: the new capacity is greater than or equal to the current
// capacity.
native fun unsafeEnlarge(This, .capacity: Int) -> ArrayBuilder[T];
native fun build(This) -> Array[T];
}
native fun arrayBuilder[T](.capacity: Int) -> ArrayBuilder[T];
|