Skip to content

Commit ec9c68c

Browse files
committed
Merge pull request #3301 from jld/vec-truncate
Add vec::truncate, for efficiently shortening a vector.
2 parents 5eef15d + 3e4b558 commit ec9c68c

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/libcore/vec.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export push, push_all, push_all_move;
4242
export grow;
4343
export grow_fn;
4444
export grow_set;
45+
export truncate;
4546
export map;
4647
export mapi;
4748
export map2;
@@ -611,6 +612,20 @@ fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
611612
}
612613
}
613614

615+
/// Shorten a vector, dropping excess elements.
616+
fn truncate<T>(&v: ~[const T], newlen: uint) {
617+
do as_buf(v) |p, oldlen| {
618+
assert(newlen <= oldlen);
619+
unsafe {
620+
// This loop is optimized out for non-drop types.
621+
for uint::range(newlen, oldlen) |i| {
622+
let _dropped <- *ptr::offset(p, i);
623+
}
624+
unsafe::set_len(v, newlen);
625+
}
626+
}
627+
}
628+
614629
// Appending
615630
#[inline(always)]
616631
pure fn append<T: copy>(+lhs: ~[T], rhs: &[const T]) -> ~[T] {
@@ -2166,6 +2181,15 @@ mod tests {
21662181
assert (v[4] == 5);
21672182
}
21682183

2184+
#[test]
2185+
fn test_truncate() {
2186+
let mut v = ~[@6,@5,@4];
2187+
truncate(v, 1);
2188+
assert(v.len() == 1);
2189+
assert(*(v[0]) == 6);
2190+
// If the unsafe block didn't drop things properly, we blow up here.
2191+
}
2192+
21692193
#[test]
21702194
fn test_map() {
21712195
// Test on-stack map.

0 commit comments

Comments
 (0)