Merge pull request #3301 from jld/vec-truncate

Add vec::truncate, for efficiently shortening a vector.
This commit is contained in:
Tim Chevalier 2012-08-29 13:53:23 -07:00
commit ec9c68c1df

View File

@ -42,6 +42,7 @@ export push, push_all, push_all_move;
export grow;
export grow_fn;
export grow_set;
export truncate;
export map;
export mapi;
export map2;
@ -611,6 +612,20 @@ fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
}
}
/// Shorten a vector, dropping excess elements.
fn truncate<T>(&v: ~[const T], newlen: uint) {
do as_buf(v) |p, oldlen| {
assert(newlen <= oldlen);
unsafe {
// This loop is optimized out for non-drop types.
for uint::range(newlen, oldlen) |i| {
let _dropped <- *ptr::offset(p, i);
}
unsafe::set_len(v, newlen);
}
}
}
// Appending
#[inline(always)]
pure fn append<T: copy>(+lhs: ~[T], rhs: &[const T]) -> ~[T] {
@ -2166,6 +2181,15 @@ mod tests {
assert (v[4] == 5);
}
#[test]
fn test_truncate() {
let mut v = ~[@6,@5,@4];
truncate(v, 1);
assert(v.len() == 1);
assert(*(v[0]) == 6);
// If the unsafe block didn't drop things properly, we blow up here.
}
#[test]
fn test_map() {
// Test on-stack map.