mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 22:05:14 +00:00
auto merge of #17920 : thestinger/rust/vec, r=aturon
Introduce conversions between `Box<[T]>` and `Vec<T>` and use it to reimplement the `vec![]` macro for efficiency.
This commit is contained in:
commit
1add4dedc1
@ -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].as_slice());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -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"]
|
||||
@ -1734,7 +1749,7 @@ impl<T> MutableSeq<T> for Vec<T> {
|
||||
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
|
||||
if old_size > size { fail!("capacity overflow") }
|
||||
unsafe {
|
||||
self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size);
|
||||
self.ptr = alloc_or_realloc(self.ptr, old_size, size);
|
||||
}
|
||||
self.cap = max(self.cap, 2) * 2;
|
||||
}
|
||||
@ -1758,7 +1773,6 @@ impl<T> MutableSeq<T> for Vec<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An iterator that moves out of a vector.
|
||||
@ -2632,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].as_slice());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_new(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
@ -18,7 +18,6 @@
|
||||
//! listener (socket server) implements the `Listener` and `Acceptor` traits.
|
||||
|
||||
use clone::Clone;
|
||||
use collections::MutableSeq;
|
||||
use io::IoResult;
|
||||
use iter::Iterator;
|
||||
use slice::ImmutableSlice;
|
||||
|
@ -272,7 +272,9 @@ mod std {
|
||||
// The test runner calls ::std::os::args() but really wants realstd
|
||||
#[cfg(test)] pub use realstd::os as os;
|
||||
// The test runner requires std::slice::Vector, so re-export std::slice just for it.
|
||||
#[cfg(test)] pub use slice;
|
||||
//
|
||||
// It is also used in vec![]
|
||||
pub use slice;
|
||||
|
||||
pub use collections; // vec!() uses MutableSeq
|
||||
pub use boxed; // used for vec![]
|
||||
}
|
||||
|
@ -323,16 +323,14 @@ macro_rules! try(
|
||||
|
||||
/// Create a `std::vec::Vec` containing the arguments.
|
||||
#[macro_export]
|
||||
macro_rules! vec(
|
||||
($($e:expr),*) => ({
|
||||
// leading _ to allow empty construction without a warning.
|
||||
let mut _temp = ::std::vec::Vec::new();
|
||||
$(_temp.push($e);)*
|
||||
_temp
|
||||
macro_rules! vec[
|
||||
($($x:expr),*) => ({
|
||||
use std::slice::BoxedSlice;
|
||||
let xs: ::std::boxed::Box<[_]> = box [$($x),*];
|
||||
xs.into_vec()
|
||||
});
|
||||
($($e:expr),+,) => (vec!($($e),+))
|
||||
)
|
||||
|
||||
($($x:expr,)*) => (vec![$($x),*])
|
||||
]
|
||||
|
||||
/// A macro to select an event from a number of receivers.
|
||||
///
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user