]> git.lizzy.rs Git - rust.git/commitdiff
implement Box<[T]> <-> Vec<T> conversions
authorDaniel Micay <danielmicay@gmail.com>
Fri, 10 Oct 2014 09:18:42 +0000 (05:18 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Fri, 10 Oct 2014 15:42:30 +0000 (11:42 -0400)
src/libcollections/slice.rs
src/libcollections/vec.rs
src/libstd/prelude.rs

index e07f6dbd35d0240931c94de6255b5f11c07ec3ab..138bc63737ed0ca5482a9cd9b1124581481a9361 100644 (file)
@@ -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 @@ fn to_vec(&self) -> Vec<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 @@ fn test_mut_last() {
         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)]
index a19efac4edcd5dd83623f8f3fc90a2c5f995c401..d0105e3b24ab38c73a4eb3d6f8b7d8771fa0236d 100644 (file)
@@ -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 @@ pub fn shrink_to_fit(&mut self) {
         }
     }
 
+    /// 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 @@ fn test_move_items_zero_sized() {
         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(|| {
index abfb2de13c5badca1b52c51263271afa9436fc9b..db9f3114cda14b255dabaf4638fa51b1dd46fc44 100644 (file)
@@ -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;