about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2014-10-10 05:18:42 -0400
committerDaniel Micay <danielmicay@gmail.com>2014-10-10 11:42:30 -0400
commit310f2deb99a95bae63173f8f972a1f91f2138ca3 (patch)
tree0035502af60e67b7d6e70cea778e9fc699985700
parent0075c2762626d42a2b3036e0664f1372e1b143f4 (diff)
downloadrust-310f2deb99a95bae63173f8f972a1f91f2138ca3.tar.gz
rust-310f2deb99a95bae63173f8f972a1f91f2138ca3.zip
implement Box<[T]> <-> Vec<T> conversions
-rw-r--r--src/libcollections/slice.rs25
-rw-r--r--src/libcollections/vec.rs22
-rw-r--r--src/libstd/prelude.rs2
3 files changed, 48 insertions, 1 deletions
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index e07f6dbd35d..138bc63737e 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -87,6 +87,7 @@
 
 #![doc(primitive = "slice")]
 
+use alloc::boxed::Box;
 use core::cmp;
 use core::mem::size_of;
 use core::mem;
@@ -298,6 +299,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     fn into_vec(self) -> Vec<T> { self.to_vec() }
 }
 
+#[experimental]
+pub trait BoxedSlice<T> {
+    /// Convert `self` into a vector without clones or allocation.
+    fn into_vec(self) -> Vec<T>;
+}
+
+impl<T> BoxedSlice<T> for Box<[T]> {
+    #[experimental]
+    fn into_vec(mut self) -> Vec<T> {
+        unsafe {
+            let xs = Vec::from_raw_parts(self.len(), self.len(), self.as_mut_ptr());
+            mem::forget(self);
+            xs
+        }
+    }
+}
+
 /// Extension methods for vectors containing `Clone` elements.
 pub trait ImmutableCloneableVector<T> {
     /// Partitions the vector into two vectors `(a, b)`, where all
@@ -2308,6 +2326,13 @@ mod tests {
         let y: &mut [int] = [];
         assert!(y.last_mut().is_none());
     }
+
+    #[test]
+    fn test_into_vec() {
+        let xs = box [1u, 2, 3];
+        let ys = xs.into_vec();
+        assert_eq!(ys.as_slice(), [1u, 2, 3]);
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index a19efac4edc..d0105e3b24a 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -14,6 +14,7 @@
 
 use core::prelude::*;
 
+use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
 use core::cmp::max;
 use core::default::Default;
@@ -757,6 +758,20 @@ impl<T> Vec<T> {
         }
     }
 
+    /// Convert the vector into Box<[T]>.
+    ///
+    /// Note that this will drop any excess capacity. Calling this and converting back to a vector
+    /// with `into_vec()` is equivalent to calling `shrink_to_fit()`.
+    #[experimental]
+    pub fn into_boxed_slice(mut self) -> Box<[T]> {
+        self.shrink_to_fit();
+        unsafe {
+            let xs: Box<[T]> = mem::transmute(self.as_mut_slice());
+            mem::forget(self);
+            xs
+        }
+    }
+
     /// Deprecated, call `push` instead
     #[inline]
     #[deprecated = "call .push() instead"]
@@ -2631,6 +2646,13 @@ mod tests {
         assert!(vec2 == vec!((), (), ()));
     }
 
+    #[test]
+    fn test_into_boxed_slice() {
+        let xs = vec![1u, 2, 3];
+        let ys = xs.into_boxed_slice();
+        assert_eq!(ys.as_slice(), [1u, 2, 3]);
+    }
+
     #[bench]
     fn bench_new(b: &mut Bencher) {
         b.iter(|| {
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index abfb2de13c5..db9f3114cda 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -88,7 +88,7 @@
 #[doc(no_inline)] pub use slice::{MutableCloneableSlice, MutableOrdSlice};
 #[doc(no_inline)] pub use slice::{ImmutableSlice, MutableSlice};
 #[doc(no_inline)] pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice};
-#[doc(no_inline)] pub use slice::{AsSlice, VectorVector};
+#[doc(no_inline)] pub use slice::{AsSlice, VectorVector, BoxedSlice};
 #[doc(no_inline)] pub use slice::MutableSliceAllocating;
 #[doc(no_inline)] pub use string::String;
 #[doc(no_inline)] pub use vec::Vec;