diff options
| author | Tim Chevalier <catamorphism@gmail.com> | 2012-08-29 13:53:23 -0700 |
|---|---|---|
| committer | Tim Chevalier <catamorphism@gmail.com> | 2012-08-29 13:53:23 -0700 |
| commit | ec9c68c1df2ab657e630993d34c859d8bcb3f18e (patch) | |
| tree | 7eac1102be9caf179238b7dc4066b9396a7bd4d5 | |
| parent | 5eef15df126e8dfedc9e72ee3d9456ead0c9d06d (diff) | |
| parent | 3e4b55807d9778c396ae449fe9a5680508d7d62d (diff) | |
Merge pull request #3301 from jld/vec-truncate
Add vec::truncate, for efficiently shortening a vector.
| -rw-r--r-- | src/libcore/vec.rs | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index db564fc4a6f..33199576c11 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -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] { @@ -2167,6 +2182,15 @@ mod tests { } #[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. let mut v = ~[1u, 2u, 3u]; |
