std.str 은 eq/starts_with/find/trim/parse_int 을 바이트 슬라이스 위에서 한다. std.list 는 자라는 제네릭 시퀀스다 -- 버퍼를 소유하므로 리스트를 놓으면 원소도 놓인다. 성장은 두 배씩이라 push 당 복사량이 상수로 눌린다. 찾은 버그 넷: - 메서드가 자기 타입의 유닛이 아니라 호출한 유닛에 속한 것으로 계산됐다. 다른 유닛의 제네릭 타입을 쓰면 필드가 전부 private 으로 보였다. - 참조로 도달한 메서드를 찾지 못했다. self.grow() 가 안 됐다. - 이미 참조인 수신자의 주소를 한 번 더 떠서 넘겼다. 포인터의 포인터를 받은 메서드가 그것을 구조체로 읽었다. - 유닛으로 한정된 제네릭 타입(list.List(i32))이 타입 자리에서도 식 자리에서도 해석되지 않았다. drop 을 가진 타입은 인스턴스마다 그 메서드가 존재해야 한다 -- 이름으로 부르는 사람이 없어도 스코프 정리가 부른다. 그리고 자기 drop 안에서는 필드를 꺼낼 수 있다. 객체가 사라지는 중이라 뒤에 남아 읽힐 것이 없다. run.py 207/207, exec.py 19/19.
54 lines
1.6 KiB
Plaintext
54 lines
1.6 KiB
Plaintext
unit std.list;
|
|
|
|
// A growable sequence. The buffer is owned, so a List owns its elements and
|
|
// releasing it releases them (SPEC 5 R1). Growth doubles, which keeps the
|
|
// total copying proportional to the number of pushes.
|
|
|
|
pub struct List(T) {
|
|
items: ^[]mut T,
|
|
len: usize,
|
|
|
|
pub fn with_capacity(n: usize) -> !Self {
|
|
let room: ^[]mut T = try mem.alloc_slice(T, n);
|
|
return Self{ items: room, len: 0 };
|
|
}
|
|
|
|
pub fn count(self: &Self) -> usize { return self.len; }
|
|
|
|
pub fn at(self: &Self, i: usize) -> T {
|
|
return self.items.^[i];
|
|
}
|
|
|
|
pub fn set(self: &mut Self, i: usize, v: T) -> void {
|
|
self.items.^[i] = v;
|
|
}
|
|
|
|
pub fn push(self: &mut Self, v: T) -> !void {
|
|
if self.len == self.items.^.n { try self.grow(); }
|
|
self.items.^[self.len] = v;
|
|
self.len = self.len + 1;
|
|
return;
|
|
}
|
|
|
|
/// Move to a buffer twice the size. Kept apart from `push` because the
|
|
/// borrow that hands over the old buffer must not be live while the old
|
|
/// buffer is still being read (SPEC 5 R6).
|
|
fn grow(self: &mut Self) -> !void {
|
|
var room: usize = self.items.^.n * 2;
|
|
if room == 0 { room = 4; }
|
|
let bigger: ^[]mut T = try mem.alloc_slice(T, room);
|
|
var i: usize = 0;
|
|
while i < self.len {
|
|
bigger.^[i] = self.items.^[i];
|
|
i = i + 1;
|
|
}
|
|
let old: ^[]mut T = mem.replace(&mut self.items, bigger);
|
|
mem.destroy(old);
|
|
return;
|
|
}
|
|
|
|
pub fn drop(self: &mut Self) -> void {
|
|
mem.destroy(self.items);
|
|
}
|
|
}
|