Skip to content

Commit 310f2de

Browse files
committed
implement Box<[T]> <-> Vec<T> conversions
1 parent 0075c27 commit 310f2de

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

src/libcollections/slice.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
8888
#![doc(primitive = "slice")]
8989

90+
use alloc::boxed::Box;
9091
use core::cmp;
9192
use core::mem::size_of;
9293
use core::mem;
@@ -298,6 +299,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
298299
fn into_vec(self) -> Vec<T> { self.to_vec() }
299300
}
300301

302+
#[experimental]
303+
pub trait BoxedSlice<T> {
304+
/// Convert `self` into a vector without clones or allocation.
305+
fn into_vec(self) -> Vec<T>;
306+
}
307+
308+
impl<T> BoxedSlice<T> for Box<[T]> {
309+
#[experimental]
310+
fn into_vec(mut self) -> Vec<T> {
311+
unsafe {
312+
let xs = Vec::from_raw_parts(self.len(), self.len(), self.as_mut_ptr());
313+
mem::forget(self);
314+
xs
315+
}
316+
}
317+
}
318+
301319
/// Extension methods for vectors containing `Clone` elements.
302320
pub trait ImmutableCloneableVector<T> {
303321
/// Partitions the vector into two vectors `(a, b)`, where all
@@ -2308,6 +2326,13 @@ mod tests {
23082326
let y: &mut [int] = [];
23092327
assert!(y.last_mut().is_none());
23102328
}
2329+
2330+
#[test]
2331+
fn test_into_vec() {
2332+
let xs = box [1u, 2, 3];
2333+
let ys = xs.into_vec();
2334+
assert_eq!(ys.as_slice(), [1u, 2, 3]);
2335+
}
23112336
}
23122337

23132338
#[cfg(test)]

src/libcollections/vec.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
1515
use core::prelude::*;
1616

17+
use alloc::boxed::Box;
1718
use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
1819
use core::cmp::max;
1920
use core::default::Default;
@@ -757,6 +758,20 @@ impl<T> Vec<T> {
757758
}
758759
}
759760

761+
/// Convert the vector into Box<[T]>.
762+
///
763+
/// Note that this will drop any excess capacity. Calling this and converting back to a vector
764+
/// with `into_vec()` is equivalent to calling `shrink_to_fit()`.
765+
#[experimental]
766+
pub fn into_boxed_slice(mut self) -> Box<[T]> {
767+
self.shrink_to_fit();
768+
unsafe {
769+
let xs: Box<[T]> = mem::transmute(self.as_mut_slice());
770+
mem::forget(self);
771+
xs
772+
}
773+
}
774+
760775
/// Deprecated, call `push` instead
761776
#[inline]
762777
#[deprecated = "call .push() instead"]
@@ -2631,6 +2646,13 @@ mod tests {
26312646
assert!(vec2 == vec!((), (), ()));
26322647
}
26332648

2649+
#[test]
2650+
fn test_into_boxed_slice() {
2651+
let xs = vec![1u, 2, 3];
2652+
let ys = xs.into_boxed_slice();
2653+
assert_eq!(ys.as_slice(), [1u, 2, 3]);
2654+
}
2655+
26342656
#[bench]
26352657
fn bench_new(b: &mut Bencher) {
26362658
b.iter(|| {

src/libstd/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
#[doc(no_inline)] pub use slice::{MutableCloneableSlice, MutableOrdSlice};
8989
#[doc(no_inline)] pub use slice::{ImmutableSlice, MutableSlice};
9090
#[doc(no_inline)] pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice};
91-
#[doc(no_inline)] pub use slice::{AsSlice, VectorVector};
91+
#[doc(no_inline)] pub use slice::{AsSlice, VectorVector, BoxedSlice};
9292
#[doc(no_inline)] pub use slice::MutableSliceAllocating;
9393
#[doc(no_inline)] pub use string::String;
9494
#[doc(no_inline)] pub use vec::Vec;

0 commit comments

Comments
 (0)