Skip to content

Add trait std::vec::IntoVec #13737

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/etc/vim/syntax/rust.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/libstd/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>;

/// Returns an object that implements `Show` for printing paths
///
/// This will print the equivalent of `to_display_str()` when used with a {} format parameter.
Expand Down
13 changes: 8 additions & 5 deletions src/libstd/path/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -181,10 +181,6 @@ impl GenericPath for Path {
self.repr.as_slice()
}

fn into_vec(self) -> Vec<u8> {
self.repr
}

fn dirname<'a>(&'a self) -> &'a [u8] {
match self.sepidx {
None if bytes!("..") == self.repr.as_slice() => self.repr.as_slice(),
Expand Down Expand Up @@ -322,6 +318,13 @@ impl GenericPath for Path {
}
}

impl IntoVec<u8> for Path {
#[inline]
fn into_vec(self) -> Vec<u8> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I marked this #[inline] to match WindowsPath. It seems like something that should be trivially inlined anyway, I'm not sure why it wasn't marked as such before.

self.repr
}
}

impl Path {
/// Returns a new Path from a byte vector or string
///
Expand Down
14 changes: 8 additions & 6 deletions src/libstd/path/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -332,11 +332,6 @@ impl GenericPath for Path {
self.repr.as_bytes()
}

#[inline]
fn into_vec(self) -> Vec<u8> {
Vec::from_slice(self.repr.as_bytes())
}

#[inline]
fn dirname<'a>(&'a self) -> &'a [u8] {
self.dirname_str().unwrap().as_bytes()
Expand Down Expand Up @@ -590,6 +585,13 @@ impl GenericPath for Path {
}
}

impl IntoVec<u8> for Path {
#[inline]
fn into_vec(self) -> Vec<u8> {
Vec::from_slice(self.repr.as_bytes())
}
}

impl Path {
/// Returns a new Path from a byte vector or string
///
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
36 changes: 36 additions & 0 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,35 @@ impl<T> Drop for MoveItems<T> {
}
}

/// A trait for types that can be converted into a Vec
pub trait IntoVec<T> {
/// Convert `self` into a new Vec, copying if required.
fn into_vec(self) -> Vec<T>;
}

impl<'a, T: Clone> IntoVec<T> for &'a [T] {
fn into_vec(self) -> Vec<T> {
#![inline(always)]
Vec::from_slice(self)
}
}

impl<T> IntoVec<T> for Vec<T> {
fn into_vec(self) -> Vec<T> {
#![inline(always)]
self
}
}

impl<T> IntoVec<T> 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<T> {
#![inline(always)]
self.move_iter().collect()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 impls all use #![inline(always)] to match the std::slice::CloneableVector impls (for .into_owned()). I assume that was done deliberately, so I matched it.

}

#[cfg(test)]
mod tests {
use prelude::*;
Expand Down Expand Up @@ -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]));
}
}
24 changes: 13 additions & 11 deletions src/libsyntax/owned_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,6 @@ impl<T> OwnedSlice<T> {
}
}

#[inline(never)]
pub fn into_vec(self) -> Vec<T> {
// 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() {
Expand Down Expand Up @@ -95,6 +84,19 @@ impl<T> OwnedSlice<T> {
}
}

impl<T> IntoVec<T> for OwnedSlice<T> {
fn into_vec(self) -> Vec<T> {
#![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<T> Default for OwnedSlice<T> {
fn default() -> OwnedSlice<T> {
OwnedSlice::empty()
Expand Down