diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index f937fd8caa6f8..8133d9210333c 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -94,6 +94,7 @@ syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCloneab syn keyword rustTrait OwnedVector OwnedCloneableVector OwnedEqVector syn keyword rustTrait MutableVector MutableTotalOrdVector syn keyword rustTrait Vector VectorVector CloneableVector ImmutableVector +syn keyword rustTrait Vec IntoVec "syn keyword rustFunction stream syn keyword rustTrait Sender Receiver diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 2960d55f337c7..a6dc47343f825 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -186,9 +186,6 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// Returns the path as a byte vector fn as_vec<'a>(&'a self) -> &'a [u8]; - /// Converts the Path into an owned byte vector - fn into_vec(self) -> Vec; - /// Returns an object that implements `Show` for printing paths /// /// This will print the equivalent of `to_display_str()` when used with a {} format parameter. diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 4affea37e35b2..f986e8d092c41 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -22,7 +22,7 @@ use str; use str::Str; use slice::{CloneableVector, RevSplits, Splits, Vector, VectorVector, ImmutableEqVector, OwnedVector, ImmutableVector}; -use vec::Vec; +use vec::{Vec,IntoVec}; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; @@ -181,10 +181,6 @@ impl GenericPath for Path { self.repr.as_slice() } - fn into_vec(self) -> Vec { - self.repr - } - fn dirname<'a>(&'a self) -> &'a [u8] { match self.sepidx { None if bytes!("..") == self.repr.as_slice() => self.repr.as_slice(), @@ -322,6 +318,13 @@ impl GenericPath for Path { } } +impl IntoVec for Path { + #[inline] + fn into_vec(self) -> Vec { + self.repr + } +} + impl Path { /// Returns a new Path from a byte vector or string /// diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 74ca8dc57859a..fc05be9449e23 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -23,7 +23,7 @@ use option::{Option, Some, None}; use slice::{Vector, OwnedVector, ImmutableVector}; use str::{CharSplits, Str, StrVector, StrSlice}; use strbuf::StrBuf; -use vec::Vec; +use vec::{Vec,IntoVec}; use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe}; @@ -332,11 +332,6 @@ impl GenericPath for Path { self.repr.as_bytes() } - #[inline] - fn into_vec(self) -> Vec { - Vec::from_slice(self.repr.as_bytes()) - } - #[inline] fn dirname<'a>(&'a self) -> &'a [u8] { self.dirname_str().unwrap().as_bytes() @@ -590,6 +585,13 @@ impl GenericPath for Path { } } +impl IntoVec for Path { + #[inline] + fn into_vec(self) -> Vec { + Vec::from_slice(self.repr.as_bytes()) + } +} + impl Path { /// Returns a new Path from a byte vector or string /// diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 724c4ca72ad0e..580d83da05c8b 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -60,7 +60,7 @@ pub use slice::{OwnedVector}; pub use slice::{MutableVector, MutableTotalOrdVector}; pub use slice::{Vector, VectorVector, CloneableVector, ImmutableVector}; pub use strbuf::StrBuf; -pub use vec::Vec; +pub use vec::{Vec,IntoVec}; // Reexported runtime types pub use comm::{sync_channel, channel, SyncSender, Sender, Receiver}; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index c5f3206d9d557..57d7f5b8836ea 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1435,6 +1435,35 @@ impl Drop for MoveItems { } } +/// A trait for types that can be converted into a Vec +pub trait IntoVec { + /// Convert `self` into a new Vec, copying if required. + fn into_vec(self) -> Vec; +} + +impl<'a, T: Clone> IntoVec for &'a [T] { + fn into_vec(self) -> Vec { + #![inline(always)] + Vec::from_slice(self) + } +} + +impl IntoVec for Vec { + fn into_vec(self) -> Vec { + #![inline(always)] + self + } +} + +impl IntoVec for ~[T] { + // someday this may be able to just reuse the data allocation, but for now, move + // all the items into the new Vec. + fn into_vec(self) -> Vec { + #![inline(always)] + self.move_iter().collect() + } +} + #[cfg(test)] mod tests { use prelude::*; @@ -1648,4 +1677,11 @@ mod tests { unsafe { v.set_len(0); } assert_eq!(v.mut_iter().len(), 0); } + + #[test] + fn test_into_vec() { + assert_eq!([1u, 2, 3, 4].into_vec(), Vec::from_slice([1u, 2, 3, 4])); + assert_eq!(["a","b"].to_owned().into_vec(), Vec::from_slice(["a","b"])); + assert_eq!(Vec::from_slice([1u, 2]).into_vec(), Vec::from_slice([1u, 2])); + } } diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 57529228b51f9..82509eb85d9f7 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -54,17 +54,6 @@ impl OwnedSlice { } } - #[inline(never)] - pub fn into_vec(self) -> Vec { - // null is ok, because len == 0 in that case, as required by Vec. - unsafe { - let ret = Vec::from_raw_parts(self.len, self.len, self.data); - // the vector owns the allocation now - cast::forget(self); - ret - } - } - pub fn as_slice<'a>(&'a self) -> &'a [T] { static PTR_MARKER: u8 = 0; let ptr = if self.data.is_null() { @@ -95,6 +84,19 @@ impl OwnedSlice { } } +impl IntoVec for OwnedSlice { + fn into_vec(self) -> Vec { + #![inline(never)] + // null is ok, because len == 0 in that case, as required by Vec. + unsafe { + let ret = Vec::from_raw_parts(self.len, self.len, self.data); + // the vector owns the allocation now + cast::forget(self); + ret + } + } +} + impl Default for OwnedSlice { fn default() -> OwnedSlice { OwnedSlice::empty()