unsafe impl<T: Send> Send for Vec<T> { }
unsafe impl<T: Sync> Sync for Vec<T> { }
-/// A clone-on-write vector
-pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
-
-impl<'a, T> FromIterator<T> for CowVec<'a, T> where T: Clone {
- fn from_iter<I: Iterator<T>>(it: I) -> CowVec<'a, T> {
- Cow::Owned(FromIterator::from_iter(it))
- }
-}
-
-impl<'a, T: 'a> IntoCow<'a, Vec<T>, [T]> for Vec<T> where T: Clone {
- fn into_cow(self) -> CowVec<'a, T> {
- Cow::Owned(self)
- }
-}
-
-impl<'a, T> IntoCow<'a, Vec<T>, [T]> for &'a [T] where T: Clone {
- fn into_cow(self) -> CowVec<'a, T> {
- Cow::Borrowed(self)
- }
-}
+////////////////////////////////////////////////////////////////////////////////
+// Inherent methods
+////////////////////////////////////////////////////////////////////////////////
impl<T> Vec<T> {
/// Constructs a new, empty `Vec<T>`.
}
}
- /// Creates and initializes a `Vec<T>`.
- ///
- /// Creates a `Vec<T>` of size `length` and initializes the elements to the value returned by
- /// the closure `op`.
- ///
- /// # Examples
- ///
- /// ```
- /// let vec = Vec::from_fn(3, |idx| idx * 2);
- /// assert_eq!(vec, vec![0, 2, 4]);
- /// ```
+ /// Deprecated: use `iter::range(0, length).map(op).collect()` instead
#[inline]
- #[unstable = "the naming is uncertain as well as this migrating to unboxed \
- closures in the future"]
- pub fn from_fn<F>(length: uint, mut op: F) -> Vec<T> where F: FnMut(uint) -> T {
- unsafe {
- let mut xs = Vec::with_capacity(length);
- while xs.len < length {
- let len = xs.len;
- ptr::write(xs.unsafe_mut(len), op(len));
- xs.len += 1;
- }
- xs
- }
+ #[deprecated = "use iter::range(0, length).map(op).collect() instead"]
+ pub fn from_fn<F>(length: uint, op: F) -> Vec<T> where F: FnMut(uint) -> T {
+ range(0, length).map(op).collect()
}
/// Creates a `Vec<T>` directly from the raw components of another vector.
/// }
/// }
/// ```
- #[unstable = "needs finalization"]
+ #[stable]
pub unsafe fn from_raw_parts(ptr: *mut T, length: uint,
capacity: uint) -> Vec<T> {
Vec { ptr: NonZero::new(ptr), len: length, cap: capacity }
/// owned by the returned `Vec<T>`. The elements of the buffer are copied into the vector
/// without cloning, as if `ptr::read()` were called on them.
#[inline]
- #[unstable = "just renamed from raw::from_buf"]
+ #[stable]
pub unsafe fn from_raw_buf(ptr: *const T, elts: uint) -> Vec<T> {
let mut dst = Vec::with_capacity(elts);
dst.set_len(elts);
dst
}
- /// Consumes the `Vec<T>`, partitioning it based on a predicate.
- ///
- /// Partitions the `Vec<T>` into two `Vec<T>`s `(A,B)`, where all elements of `A` satisfy `f`
- /// and all elements of `B` do not. The order of elements is preserved.
+ /// Deprecated: use `into_iter().partition(f)` instead.
+ #[inline]
+ #[deprecated = "use into_iter().partition(f) instead"]
+ pub fn partition<F>(self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
+ self.into_iter().partition(f)
+ }
+
+ /// Returns the number of elements the vector can hold without
+ /// reallocating.
///
/// # Examples
///
/// ```
- /// let vec = vec![1i, 2i, 3i, 4i];
- /// let (even, odd) = vec.partition(|&n| n % 2 == 0);
- /// assert_eq!(even, vec![2, 4]);
- /// assert_eq!(odd, vec![1, 3]);
+ /// let vec: Vec<int> = Vec::with_capacity(10);
+ /// assert_eq!(vec.capacity(), 10);
/// ```
#[inline]
- #[experimental]
- pub fn partition<F>(self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
- let mut lefts = Vec::new();
- let mut rights = Vec::new();
-
- for elt in self.into_iter() {
- if f(&elt) {
- lefts.push(elt);
- } else {
- rights.push(elt);
- }
- }
+ #[stable]
+ pub fn capacity(&self) -> uint {
+ self.cap
+ }
- (lefts, rights)
+ /// Deprecated: Renamed to `reserve`.
+ #[deprecated = "Renamed to `reserve`"]
+ pub fn reserve_additional(&mut self, extra: uint) {
+ self.reserve(extra)
}
-}
-impl<T: Clone> Vec<T> {
- /// Constructs a `Vec<T>` with copies of a value.
+ /// Reserves capacity for at least `additional` more elements to be inserted in the given
+ /// `Vec`. The collection may reserve more space to avoid frequent reallocations.
///
- /// Creates a `Vec<T>` with `length` copies of `value`.
+ /// # Panics
+ ///
+ /// Panics if the new capacity overflows `uint`.
///
/// # Examples
///
/// ```
- /// let vec = Vec::from_elem(3, "hi");
- /// println!("{}", vec); // prints [hi, hi, hi]
+ /// let mut vec: Vec<int> = vec![1];
+ /// vec.reserve(10);
+ /// assert!(vec.capacity() >= 11);
/// ```
- #[inline]
- #[unstable = "this functionality may become more generic over all collections"]
- pub fn from_elem(length: uint, value: T) -> Vec<T> {
- unsafe {
- let mut xs = Vec::with_capacity(length);
- while xs.len < length {
- let len = xs.len;
- ptr::write(xs.unsafe_mut(len),
- value.clone());
- xs.len += 1;
- }
- xs
+ #[stable]
+ pub fn reserve(&mut self, additional: uint) {
+ if self.cap - self.len < additional {
+ let err_msg = "Vec::reserve: `uint` overflow";
+ let new_cap = self.len.checked_add(additional).expect(err_msg)
+ .checked_next_power_of_two().expect(err_msg);
+ self.grow_capacity(new_cap);
}
}
- /// Appends all elements in a slice to the `Vec<T>`.
+ /// Reserves the minimum capacity for exactly `additional` more elements to
+ /// be inserted in the given `Vec`. Does nothing if the capacity is already
+ /// sufficient.
///
- /// Iterates over the slice `other`, clones each element, and then appends
- /// it to this `Vec<T>`. The `other` vector is traversed in-order.
+ /// Note that the allocator may give the collection more space than it
+ /// requests. Therefore capacity can not be relied upon to be precisely
+ /// minimal. Prefer `reserve` if future insertions are expected.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the new capacity overflows `uint`.
///
/// # Examples
///
/// ```
- /// let mut vec = vec![1i];
- /// vec.push_all(&[2i, 3, 4]);
- /// assert_eq!(vec, vec![1, 2, 3, 4]);
+ /// let mut vec: Vec<int> = vec![1];
+ /// vec.reserve_exact(10);
+ /// assert!(vec.capacity() >= 11);
/// ```
- #[inline]
- #[experimental]
- pub fn push_all(&mut self, other: &[T]) {
- self.reserve(other.len());
-
- for i in range(0, other.len()) {
- let len = self.len();
-
- // Unsafe code so this can be optimised to a memcpy (or something similarly
- // fast) when T is Copy. LLVM is easily confused, so any extra operations
- // during the loop can prevent this optimisation.
- unsafe {
- ptr::write(
- self.unsafe_mut(len),
- other.unsafe_get(i).clone());
- self.set_len(len + 1);
+ #[stable]
+ pub fn reserve_exact(&mut self, additional: uint) {
+ if self.cap - self.len < additional {
+ match self.len.checked_add(additional) {
+ None => panic!("Vec::reserve: `uint` overflow"),
+ Some(new_cap) => self.grow_capacity(new_cap)
}
}
}
- /// Grows the `Vec<T>` in-place.
- ///
- /// Adds `n` copies of `value` to the `Vec<T>`.
+ /// Shrinks the capacity of the vector as much as possible. It will drop
+ /// down as close as possible to the length but the allocator may still
+ /// inform the vector that there is space for a few more elements.
///
/// # Examples
///
/// ```
- /// let mut vec = vec!["hello"];
- /// vec.grow(2, "world");
- /// assert_eq!(vec, vec!["hello", "world", "world"]);
+ /// let mut vec: Vec<int> = Vec::with_capacity(10);
+ /// vec.push_all(&[1, 2, 3]);
+ /// assert_eq!(vec.capacity(), 10);
+ /// vec.shrink_to_fit();
+ /// assert!(vec.capacity() >= 3);
/// ```
#[stable]
- pub fn grow(&mut self, n: uint, value: T) {
- self.reserve(n);
- let mut i: uint = 0u;
+ pub fn shrink_to_fit(&mut self) {
+ if mem::size_of::<T>() == 0 { return }
- while i < n {
- self.push(value.clone());
- i += 1u;
+ if self.len == 0 {
+ if self.cap != 0 {
+ unsafe {
+ dealloc(self.ptr, self.cap)
+ }
+ self.cap = 0;
+ }
+ } else {
+ unsafe {
+ // Overflow check is unnecessary as the vector is already at
+ // least this large.
+ self.ptr = reallocate(self.ptr as *mut u8,
+ self.cap * mem::size_of::<T>(),
+ self.len * mem::size_of::<T>(),
+ mem::min_align_of::<T>()) as *mut T;
+ if self.ptr.is_null() { ::alloc::oom() }
+ }
+ self.cap = self.len;
}
}
- /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
+ /// Convert the vector into Box<[T]>.
///
- /// Calls either `extend()` or `truncate()` depending on whether `new_len`
- /// is larger than the current value of `len()` or not.
+ /// 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
+ }
+ }
+
+ /// Shorten a vector, dropping excess elements.
+ ///
+ /// If `len` is greater than the vector's current length, this has no
+ /// effect.
///
/// # Examples
///
/// ```
- /// let mut vec = vec!["hello"];
- /// vec.resize(3, "world");
- /// assert_eq!(vec, vec!["hello", "world", "world"]);
- ///
/// let mut vec = vec![1i, 2, 3, 4];
- /// vec.resize(2, 0);
+ /// vec.truncate(2);
/// assert_eq!(vec, vec![1, 2]);
/// ```
- #[unstable = "matches collection reform specification; waiting for dust to settle"]
- pub fn resize(&mut self, new_len: uint, value: T) {
- let len = self.len();
-
- if new_len > len {
- self.extend(repeat(value).take(new_len - len));
- } else {
- self.truncate(new_len);
+ #[stable]
+ pub fn truncate(&mut self, len: uint) {
+ unsafe {
+ // drop any extra elements
+ while len < self.len {
+ // decrement len before the read(), so a panic on Drop doesn't
+ // re-drop the just-failed value.
+ self.len -= 1;
+ ptr::read(self.get_unchecked(self.len));
+ }
}
}
- /// Partitions a vector based on a predicate.
- ///
- /// Clones the elements of the vector, partitioning them into two `Vec<T>`s
- /// `(a, b)`, where all elements of `a` satisfy `f` and all elements of `b`
- /// do not. The order of elements is preserved.
+ /// Returns a mutable slice of the elements of `self`.
///
/// # Examples
///
/// ```
- /// let vec = vec![1i, 2, 3, 4];
- /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
- /// assert_eq!(even, vec![2i, 4]);
- /// assert_eq!(odd, vec![1i, 3]);
+ /// fn foo(slice: &mut [int]) {}
+ ///
+ /// let mut vec = vec![1i, 2];
+ /// foo(vec.as_mut_slice());
/// ```
- #[experimental]
- pub fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
- let mut lefts = Vec::new();
- let mut rights = Vec::new();
-
- for elt in self.iter() {
- if f(elt) {
- lefts.push(elt.clone());
- } else {
- rights.push(elt.clone());
- }
- }
-
- (lefts, rights)
- }
-}
-
-#[stable]
-impl<T:Clone> Clone for Vec<T> {
- fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
-
- fn clone_from(&mut self, other: &Vec<T>) {
- // drop anything in self that will not be overwritten
- if self.len() > other.len() {
- self.truncate(other.len())
- }
-
- // reuse the contained values' allocations/resources.
- for (place, thing) in self.iter_mut().zip(other.iter()) {
- place.clone_from(thing)
+ #[inline]
+ #[stable]
+ pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
+ unsafe {
+ mem::transmute(RawSlice {
+ data: self.ptr as *const T,
+ len: self.len,
+ })
}
-
- // self.len <= other.len due to the truncate above, so the
- // slice here is always in-bounds.
- let slice = other[self.len()..];
- self.push_all(slice);
}
-}
-#[experimental = "waiting on Index stability"]
-impl<T> Index<uint,T> for Vec<T> {
+ /// Creates a consuming iterator, that is, one that moves each
+ /// value out of the vector (from start to end). The vector cannot
+ /// be used after calling this.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = vec!["a".to_string(), "b".to_string()];
+ /// for s in v.into_iter() {
+ /// // s has type String, not &String
+ /// println!("{}", s);
+ /// }
+ /// ```
#[inline]
- fn index<'a>(&'a self, index: &uint) -> &'a T {
- &self.as_slice()[*index]
+ #[stable]
+ pub fn into_iter(self) -> IntoIter<T> {
+ unsafe {
+ let ptr = self.ptr;
+ let cap = self.cap;
+ let begin = self.ptr as *const T;
+ let end = if mem::size_of::<T>() == 0 {
+ (ptr as uint + self.len()) as *const T
+ } else {
+ ptr.offset(self.len() as int) as *const T
+ };
+ mem::forget(self);
+ IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end }
+ }
}
-}
-impl<T> IndexMut<uint,T> for Vec<T> {
+ /// Sets the length of a vector.
+ ///
+ /// This will explicitly set the size of the vector, without actually modifying its buffers, so
+ /// it is up to the caller to ensure that the vector is actually the specified size.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = vec![1u, 2, 3, 4];
+ /// unsafe {
+ /// v.set_len(1);
+ /// }
+ /// ```
#[inline]
- fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
- &mut self.as_mut_slice()[*index]
- }
-}
-
-impl<T> ops::Slice<uint, [T]> for Vec<T> {
- #[inline]
- fn as_slice_<'a>(&'a self) -> &'a [T] {
- self.as_slice()
- }
-
- #[inline]
- fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
- self.as_slice().slice_from_or_fail(start)
- }
-
- #[inline]
- fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
- self.as_slice().slice_to_or_fail(end)
- }
- #[inline]
- fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
- self.as_slice().slice_or_fail(start, end)
- }
-}
-
-impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
- #[inline]
- fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
- self.as_mut_slice()
- }
-
- #[inline]
- fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
- self.as_mut_slice().slice_from_or_fail_mut(start)
- }
-
- #[inline]
- fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
- self.as_mut_slice().slice_to_or_fail_mut(end)
- }
- #[inline]
- fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
- self.as_mut_slice().slice_or_fail_mut(start, end)
- }
-}
-
-#[experimental = "waiting on Deref stability"]
-impl<T> ops::Deref<[T]> for Vec<T> {
- fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() }
-}
-
-#[experimental = "waiting on DerefMut stability"]
-impl<T> ops::DerefMut<[T]> for Vec<T> {
- fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
-}
-
-#[experimental = "waiting on FromIterator stability"]
-impl<T> FromIterator<T> for Vec<T> {
- #[inline]
- fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
- let (lower, _) = iterator.size_hint();
- let mut vector = Vec::with_capacity(lower);
- for element in iterator {
- vector.push(element)
- }
- vector
- }
-}
-
-#[experimental = "waiting on Extend stability"]
-impl<T> Extend<T> for Vec<T> {
- #[inline]
- fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
- let (lower, _) = iterator.size_hint();
- self.reserve(lower);
- for element in iterator {
- self.push(element)
- }
- }
-}
-
-impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
- #[inline]
- fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-macro_rules! impl_eq {
- ($lhs:ty, $rhs:ty) => {
- impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
- #[inline]
- fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
- }
-
- impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
- #[inline]
- fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
- }
- }
-}
-
-impl_eq! { Vec<A>, &'b [B] }
-impl_eq! { Vec<A>, &'b mut [B] }
-
-impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
- #[inline]
- fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
- #[inline]
- fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-macro_rules! impl_eq_for_cowvec {
- ($rhs:ty) => {
- impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
- #[inline]
- fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
- }
-
- impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
- #[inline]
- fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
- #[inline]
- fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
- }
- }
-}
-
-impl_eq_for_cowvec! { &'b [B] }
-impl_eq_for_cowvec! { &'b mut [B] }
-
-#[unstable = "waiting on PartialOrd stability"]
-impl<T: PartialOrd> PartialOrd for Vec<T> {
- #[inline]
- fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
- self.as_slice().partial_cmp(other.as_slice())
- }
-}
-
-#[unstable = "waiting on Eq stability"]
-impl<T: Eq> Eq for Vec<T> {}
-
-#[allow(deprecated)]
-#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
-impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
- #[inline]
- fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
-}
-
-#[unstable = "waiting on Ord stability"]
-impl<T: Ord> Ord for Vec<T> {
- #[inline]
- fn cmp(&self, other: &Vec<T>) -> Ordering {
- self.as_slice().cmp(other.as_slice())
- }
-}
-
-impl<S: hash::Writer, T: Hash<S>> Hash<S> for Vec<T> {
- #[inline]
- fn hash(&self, state: &mut S) {
- self.as_slice().hash(state);
- }
-}
-
-// FIXME: #13996: need a way to mark the return value as `noalias`
-#[inline(never)]
-unsafe fn alloc_or_realloc<T>(ptr: *mut T, old_size: uint, size: uint) -> *mut T {
- if old_size == 0 {
- allocate(size, mem::min_align_of::<T>()) as *mut T
- } else {
- reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::<T>()) as *mut T
- }
-}
-
-#[inline]
-unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
- if mem::size_of::<T>() != 0 {
- deallocate(ptr as *mut u8,
- len * mem::size_of::<T>(),
- mem::min_align_of::<T>())
- }
-}
-
-impl<T> Vec<T> {
- /// Returns the number of elements the vector can hold without reallocating.
- ///
- /// # Examples
- ///
- /// ```
- /// let vec: Vec<int> = Vec::with_capacity(10);
- /// assert_eq!(vec.capacity(), 10);
- /// ```
- #[inline]
- #[stable]
- pub fn capacity(&self) -> uint {
- self.cap
- }
-
- /// Deprecated: Renamed to `reserve`.
- #[deprecated = "Renamed to `reserve`"]
- pub fn reserve_additional(&mut self, extra: uint) {
- self.reserve(extra)
- }
-
- /// Reserves capacity for at least `additional` more elements to be inserted in the given
- /// `Vec<T>`. The collection may reserve more space to avoid frequent reallocations.
- ///
- /// # Panics
- ///
- /// Panics if the new capacity overflows `uint`.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut vec: Vec<int> = vec![1];
- /// vec.reserve(10);
- /// assert!(vec.capacity() >= 11);
- /// ```
- #[unstable = "matches collection reform specification, waiting for dust to settle"]
- pub fn reserve(&mut self, additional: uint) {
- if self.cap - self.len < additional {
- let err_msg = "Vec::reserve: `uint` overflow";
- let new_cap = self.len.checked_add(additional).expect(err_msg)
- .checked_next_power_of_two().expect(err_msg);
- self.grow_capacity(new_cap);
- }
- }
-
- /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
- /// given `Vec<T>`. Does nothing if the capacity is already sufficient.
- ///
- /// Note that the allocator may give the collection more space than it requests. Therefore
- /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
- /// insertions are expected.
- ///
- /// # Panics
- ///
- /// Panics if the new capacity overflows `uint`.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut vec: Vec<int> = vec![1];
- /// vec.reserve_exact(10);
- /// assert!(vec.capacity() >= 11);
- /// ```
- #[unstable = "matches collection reform specification, waiting for dust to settle"]
- pub fn reserve_exact(&mut self, additional: uint) {
- if self.cap - self.len < additional {
- match self.len.checked_add(additional) {
- None => panic!("Vec::reserve: `uint` overflow"),
- Some(new_cap) => self.grow_capacity(new_cap)
- }
- }
- }
-
- /// Shrinks the capacity of the vector as much as possible.
- ///
- /// It will drop down as close as possible to the length but the allocator may still inform the
- /// vector that there is space for a few more elements.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut vec: Vec<int> = Vec::with_capacity(10);
- ///
- /// vec.push_all(&[1, 2, 3]);
- /// assert_eq!(vec.capacity(), 10);
- ///
- /// vec.shrink_to_fit();
- /// assert!(vec.capacity() >= 3);
- /// ```
- #[stable]
- pub fn shrink_to_fit(&mut self) {
- if mem::size_of::<T>() == 0 { return }
-
- if self.len == 0 {
- if self.cap != 0 {
- unsafe {
- dealloc(*self.ptr, self.cap)
- }
- self.cap = 0;
- }
- } else {
- unsafe {
- // Overflow check is unnecessary as the vector is already at
- // least this large.
- let ptr = reallocate(*self.ptr as *mut u8,
- self.cap * mem::size_of::<T>(),
- self.len * mem::size_of::<T>(),
- mem::min_align_of::<T>()) as *mut T;
- if ptr.is_null() { ::alloc::oom() }
- self.ptr = NonZero::new(ptr);
- }
- self.cap = self.len;
- }
- }
-
- /// 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
- }
- }
-
- /// Shorten a vector, dropping excess elements.
- ///
- /// If `len` is greater than the vector's current length, this has no
- /// effect.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut vec = vec![1i, 2, 3, 4];
- /// vec.truncate(2);
- /// assert_eq!(vec, vec![1, 2]);
- /// ```
- #[unstable = "matches collection reform specification; waiting on panic semantics"]
- pub fn truncate(&mut self, len: uint) {
- unsafe {
- // drop any extra elements
- while len < self.len {
- // decrement len before the read(), so a panic on Drop doesn't
- // re-drop the just-failed value.
- self.len -= 1;
- ptr::read(self.unsafe_get(self.len));
- }
- }
- }
-
- /// Returns a mutable slice of the elements of `self`.
- ///
- /// # Examples
- ///
- /// ```
- /// fn foo(slice: &mut [int]) {}
- ///
- /// let mut vec = vec![1i, 2];
- /// foo(vec.as_mut_slice());
- /// ```
- #[inline]
- #[stable]
- pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
- unsafe {
- mem::transmute(RawSlice {
- data: *self.ptr as *const T,
- len: self.len,
- })
- }
- }
-
- /// Creates a consuming iterator, that is, one that moves each value out of the vector (from
- /// start to end). The vector cannot be used after calling this.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = vec!["a".to_string(), "b".to_string()];
- ///
- /// for s in v.into_iter() {
- /// // s has type String, not &String
- /// println!("{}", s);
- /// }
- /// ```
- #[inline]
- #[unstable = "matches collection reform specification, waiting for dust to settle"]
- pub fn into_iter(self) -> IntoIter<T> {
- unsafe {
- let ptr = *self.ptr;
- let cap = self.cap;
- let begin = ptr as *const T;
- let end = if mem::size_of::<T>() == 0 {
- (ptr as uint + self.len()) as *const T
- } else {
- ptr.offset(self.len() as int) as *const T
- };
- mem::forget(self);
- IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end }
- }
- }
-
- /// Sets the length of a vector.
- ///
- /// This will explicitly set the size of the vector, without actually modifying its buffers, so
- /// it is up to the caller to ensure that the vector is actually the specified size.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = vec![1u, 2, 3, 4];
- /// unsafe {
- /// v.set_len(1);
- /// }
- /// ```
- #[inline]
- #[stable]
- pub unsafe fn set_len(&mut self, len: uint) {
- self.len = len;
+ #[stable]
+ pub unsafe fn set_len(&mut self, len: uint) {
+ self.len = len;
}
/// Removes an element from anywhere in the vector and return it, replacing it with the last
///
/// This does not preserve ordering, but is O(1).
///
- /// Returns `None` if `index` is out of bounds.
+ /// # Panics
+ ///
+ /// Panics if `index` is out of bounds.
///
/// # Examples
///
/// assert_eq!(v.swap_remove(2), None);
/// ```
#[inline]
- #[unstable = "the naming of this function may be altered"]
- pub fn swap_remove(&mut self, index: uint) -> Option<T> {
+ #[stable]
+ pub fn swap_remove(&mut self, index: uint) -> T {
let length = self.len();
- if length > 0 && index < length - 1 {
- self.swap(index, length - 1);
- } else if index >= length {
- return None
- }
- self.pop()
+ self.swap(index, length - 1);
+ self.pop().unwrap()
}
/// Inserts an element at position `index` within the vector, shifting all elements after
/// vec.insert(4, 5);
/// assert_eq!(vec, vec![1, 4, 2, 3, 5]);
/// ```
- #[unstable = "panic semantics need settling"]
+ #[stable]
pub fn insert(&mut self, index: uint, element: T) {
let len = self.len();
assert!(index <= len);
}
}
- /// Removes and returns the element at position `index` within the vector, shifting all
- /// elements after position `index` one position to the left. Returns `None` if `i` is out of
- /// bounds.
+ /// Removes and returns the element at position `index` within the vector,
+ /// shifting all elements after position `index` one position to the left.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `i` is out of bounds.
///
/// # Examples
///
/// // v is unchanged:
/// assert_eq!(v, vec![1, 3]);
/// ```
- #[unstable = "panic semantics need settling"]
- pub fn remove(&mut self, index: uint) -> Option<T> {
+ #[stable]
+ pub fn remove(&mut self, index: uint) -> T {
let len = self.len();
- if index < len {
- unsafe { // infallible
- let ret;
- {
- // the place we are taking from.
- let ptr = self.as_mut_ptr().offset(index as int);
- // copy it out, unsafely having a copy of the value on
- // the stack and in the vector at the same time.
- ret = Some(ptr::read(ptr as *const T));
-
- // Shift everything down to fill in that spot.
- ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
- }
- self.set_len(len - 1);
- ret
+ assert!(index < len);
+ unsafe { // infallible
+ let ret;
+ {
+ // the place we are taking from.
+ let ptr = self.as_mut_ptr().offset(index as int);
+ // copy it out, unsafely having a copy of the value on
+ // the stack and in the vector at the same time.
+ ret = ptr::read(ptr as *const T);
+
+ // Shift everything down to fill in that spot.
+ ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
}
- } else {
- None
+ self.set_len(len - 1);
+ ret
}
}
/// vec.retain(|&x| x%2 == 0);
/// assert_eq!(vec, vec![2, 4]);
/// ```
- #[unstable = "the closure argument may become an unboxed closure"]
+ #[stable]
pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
let len = self.len();
let mut del = 0u;
}
}
- /// Expands a vector in place, initializing the new elements to the result of a function.
- ///
- /// The vector is grown by `n` elements. The i-th new element are initialized to the value
- /// returned by `f(i)` where `i` is in the range [0, n).
- ///
- /// # Examples
- ///
- /// ```
- /// let mut vec = vec![0u, 1];
- /// vec.grow_fn(3, |i| i);
- /// assert_eq!(vec, vec![0, 1, 0, 1, 2]);
- /// ```
- #[unstable = "this function may be renamed or change to unboxed closures"]
- pub fn grow_fn<F>(&mut self, n: uint, mut f: F) where F: FnMut(uint) -> T {
- self.reserve(n);
- for i in range(0u, n) {
- self.push(f(i));
- }
+ /// Deprecated: use `extend(range(0, n).map(f))` instead.
+ #[deprecated = "use extend(range(0, n).map(f)) instead"]
+ pub fn grow_fn<F>(&mut self, n: uint, f: F) where F: FnMut(uint) -> T {
+ self.extend(range(0, n).map(f));
}
/// Appends an element to the back of a collection.
} else {
unsafe {
self.len -= 1;
- Some(ptr::read(self.unsafe_get(self.len())))
+ Some(ptr::read(self.get_unchecked(self.len())))
}
}
}
/// v.push(1i);
/// assert!(!v.is_empty());
/// ```
- #[unstable = "matches collection reform specification, waiting for dust to settle"]
+ #[stable]
pub fn is_empty(&self) -> bool { self.len() == 0 }
- /// Reserves capacity for exactly `capacity` elements in the given vector.
+ /// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same
+ /// size and in case they are not zero-sized the same minimal alignment.
///
- /// If the capacity for `self` is already equal to or greater than the
- /// requested capacity, then no action is taken.
- fn grow_capacity(&mut self, capacity: uint) {
- if mem::size_of::<T>() == 0 { return }
+ /// # Panics
+ ///
+ /// Panics if `T` and `U` have differing sizes or are not zero-sized and
+ /// have differing minimal alignments.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = vec![0u, 1, 2];
+ /// let w = v.map_in_place(|i| i + 3);
+ /// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
+ ///
+ /// #[deriving(PartialEq, Show)]
+ /// struct Newtype(u8);
+ /// let bytes = vec![0x11, 0x22];
+ /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
+ /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
+ /// ```
+ #[experimental = "API may change to provide stronger guarantees"]
+ pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
+ // FIXME: Assert statically that the types `T` and `U` have the same
+ // size.
+ assert!(mem::size_of::<T>() == mem::size_of::<U>());
- if capacity > self.cap {
- let size = capacity.checked_mul(mem::size_of::<T>())
- .expect("capacity overflow");
+ let mut vec = self;
+
+ if mem::size_of::<T>() != 0 {
+ // FIXME: Assert statically that the types `T` and `U` have the
+ // same minimal alignment in case they are not zero-sized.
+
+ // These asserts are necessary because the `min_align_of` of the
+ // types are passed to the allocator by `Vec`.
+ assert!(mem::min_align_of::<T>() == mem::min_align_of::<U>());
+
+ // This `as int` cast is safe, because the size of the elements of the
+ // vector is not 0, and:
+ //
+ // 1) If the size of the elements in the vector is 1, the `int` may
+ // overflow, but it has the correct bit pattern so that the
+ // `.offset()` function will work.
+ //
+ // Example:
+ // Address space 0x0-0xF.
+ // `u8` array at: 0x1.
+ // Size of `u8` array: 0x8.
+ // Calculated `offset`: -0x8.
+ // After `array.offset(offset)`: 0x9.
+ // (0x1 + 0x8 = 0x1 - 0x8)
+ //
+ // 2) If the size of the elements in the vector is >1, the `uint` ->
+ // `int` conversion can't overflow.
+ let offset = vec.len() as int;
+ let start = vec.as_mut_ptr();
+
+ let mut pv = PartialVecNonZeroSized {
+ vec: vec,
+
+ start_t: start,
+ // This points inside the vector, as the vector has length
+ // `offset`.
+ end_t: unsafe { start.offset(offset) },
+ start_u: start as *mut U,
+ end_u: start as *mut U,
+ };
+ // start_t
+ // start_u
+ // |
+ // +-+-+-+-+-+-+
+ // |T|T|T|...|T|
+ // +-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+
+ while pv.end_u as *mut T != pv.end_t {
+ unsafe {
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+-+-+-+
+ // |U|...|U|T|T|...|T|
+ // +-+-+-+-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+
+ let t = ptr::read(pv.start_t as *const T);
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+-+-+-+
+ // |U|...|U|X|T|...|T|
+ // +-+-+-+-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+ // We must not panic here, one cell is marked as `T`
+ // although it is not `T`.
+
+ pv.start_t = pv.start_t.offset(1);
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+-+-+-+
+ // |U|...|U|X|T|...|T|
+ // +-+-+-+-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+ // We may panic again.
+
+ // The function given by the user might panic.
+ let u = f(t);
+
+ ptr::write(pv.end_u, u);
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+-+-+-+
+ // |U|...|U|U|T|...|T|
+ // +-+-+-+-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+ // We should not panic here, because that would leak the `U`
+ // pointed to by `end_u`.
+
+ pv.end_u = pv.end_u.offset(1);
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+-+-+-+
+ // |U|...|U|U|T|...|T|
+ // +-+-+-+-+-+-+-+-+-+
+ // | |
+ // end_u end_t
+ // We may panic again.
+ }
+ }
+
+ // start_u start_t
+ // | |
+ // +-+-+-+-+-+-+
+ // |U|...|U|U|U|
+ // +-+-+-+-+-+-+
+ // |
+ // end_t
+ // end_u
+ // Extract `vec` and prevent the destructor of
+ // `PartialVecNonZeroSized` from running. Note that none of the
+ // function calls can panic, thus no resources can be leaked (as the
+ // `vec` member of `PartialVec` is the only one which holds
+ // allocations -- and it is returned from this function. None of
+ // this can panic.
+ unsafe {
+ let vec_len = pv.vec.len();
+ let vec_cap = pv.vec.capacity();
+ let vec_ptr = pv.vec.as_mut_ptr() as *mut U;
+ mem::forget(pv);
+ Vec::from_raw_parts(vec_ptr, vec_len, vec_cap)
+ }
+ } else {
+ // Put the `Vec` into the `PartialVecZeroSized` structure and
+ // prevent the destructor of the `Vec` from running. Since the
+ // `Vec` contained zero-sized objects, it did not allocate, so we
+ // are not leaking memory here.
+ let mut pv = PartialVecZeroSized::<T,U> {
+ num_t: vec.len(),
+ num_u: 0,
+ marker_t: InvariantType,
+ marker_u: InvariantType,
+ };
+ unsafe { mem::forget(vec); }
+
+ while pv.num_t != 0 {
+ unsafe {
+ // Create a `T` out of thin air and decrement `num_t`. This
+ // must not panic between these steps, as otherwise a
+ // destructor of `T` which doesn't exist runs.
+ let t = mem::uninitialized();
+ pv.num_t -= 1;
+
+ // The function given by the user might panic.
+ let u = f(t);
+
+ // Forget the `U` and increment `num_u`. This increment
+ // cannot overflow the `uint` as we only do this for a
+ // number of times that fits into a `uint` (and start with
+ // `0`). Again, we should not panic between these steps.
+ mem::forget(u);
+ pv.num_u += 1;
+ }
+ }
+ // Create a `Vec` from our `PartialVecZeroSized` and make sure the
+ // destructor of the latter will not run. None of this can panic.
+ let mut result = Vec::new();
+ unsafe {
+ result.set_len(pv.num_u);
+ mem::forget(pv);
+ }
+ result
+ }
+ }
+}
+
+impl<T: Clone> Vec<T> {
+ /// Deprecated: use `repeat(value).take(length).collect()` instead.
+ #[inline]
+ #[deprecated = "use repeat(value).take(length).collect() instead"]
+ pub fn from_elem(length: uint, value: T) -> Vec<T> {
+ repeat(value).take(length).collect()
+ }
+
+ /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
+ ///
+ /// Calls either `extend()` or `truncate()` depending on whether `new_len`
+ /// is larger than the current value of `len()` or not.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut vec = vec!["hello"];
+ /// vec.resize(3, "world");
+ /// assert_eq!(vec, vec!["hello", "world", "world"]);
+ ///
+ /// let mut vec = vec![1i, 2, 3, 4];
+ /// vec.resize(2, 0);
+ /// assert_eq!(vec, vec![1, 2]);
+ /// ```
+ #[unstable = "matches collection reform specification; waiting for dust to settle"]
+ pub fn resize(&mut self, new_len: uint, value: T) {
+ let len = self.len();
+
+ if new_len > len {
+ self.extend(repeat(value).take(new_len - len));
+ } else {
+ self.truncate(new_len);
+ }
+ }
+
+ /// Appends all elements in a slice to the `Vec`.
+ ///
+ /// Iterates over the slice `other`, clones each element, and then appends
+ /// it to this `Vec`. The `other` vector is traversed in-order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut vec = vec![1i];
+ /// vec.push_all(&[2i, 3, 4]);
+ /// assert_eq!(vec, vec![1, 2, 3, 4]);
+ /// ```
+ #[inline]
+ #[experimental = "likely to be replaced by a more optimized extend"]
+ pub fn push_all(&mut self, other: &[T]) {
+ self.reserve(other.len());
+
+ for i in range(0, other.len()) {
+ let len = self.len();
+
+ // Unsafe code so this can be optimised to a memcpy (or something similarly
+ // fast) when T is Copy. LLVM is easily confused, so any extra operations
+ // during the loop can prevent this optimisation.
unsafe {
- let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::<T>(), size);
- if ptr.is_null() { ::alloc::oom() }
- self.ptr = NonZero::new(ptr);
+ ptr::write(
+ self.get_unchecked_mut(len),
+ other.get_unchecked(i).clone());
+ self.set_len(len + 1);
}
- self.cap = capacity;
}
}
+
+ /// Deprecated: use `extend(repeat(value).take(n))` instead
+ #[deprecated = "use extend(repeat(value).take(n)) instead"]
+ pub fn grow(&mut self, n: uint, value: T) {
+ self.extend(repeat(value).take(n))
+ }
+
+ /// Deprecated: use `iter().cloned().partition(f)` instead.
+ #[deprecated = "use iter().cloned().partition(f) instead"]
+ pub fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
+ self.iter().cloned().partition(f)
+ }
}
impl<T: PartialEq> Vec<T> {
///
/// assert_eq!(vec, vec![1i, 2, 3, 2]);
/// ```
- #[unstable = "this function may be renamed"]
+ #[stable]
pub fn dedup(&mut self) {
unsafe {
// Although we have a mutable reference to `self`, we cannot make
r += 1;
}
- self.truncate(w);
- }
+ self.truncate(w);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Public free fns
+////////////////////////////////////////////////////////////////////////////////
+
+/// Deprecated: use `unzip` directly on the iterator instead.
+#[deprecated = "use unzip directly on the iterator instead"]
+pub fn unzip<T, U, V: Iterator<(T, U)>>(iter: V) -> (Vec<T>, Vec<U>) {
+ iter.unzip()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Internal methods and functions
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T> Vec<T> {
+ /// Reserves capacity for exactly `capacity` elements in the given vector.
+ ///
+ /// If the capacity for `self` is already equal to or greater than the
+ /// requested capacity, then no action is taken.
+ fn grow_capacity(&mut self, capacity: uint) {
+ if mem::size_of::<T>() == 0 { return }
+
+ if capacity > self.cap {
+ let size = capacity.checked_mul(mem::size_of::<T>())
+ .expect("capacity overflow");
+ unsafe {
+ self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size);
+ if self.ptr.is_null() { ::alloc::oom() }
+ }
+ self.cap = capacity;
+ }
+ }
+}
+
+// FIXME: #13996: need a way to mark the return value as `noalias`
+#[inline(never)]
+unsafe fn alloc_or_realloc<T>(ptr: *mut T, old_size: uint, size: uint) -> *mut T {
+ if old_size == 0 {
+ allocate(size, mem::min_align_of::<T>()) as *mut T
+ } else {
+ reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::<T>()) as *mut T
+ }
+}
+
+#[inline]
+unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
+ if mem::size_of::<T>() != 0 {
+ deallocate(ptr as *mut u8,
+ len * mem::size_of::<T>(),
+ mem::min_align_of::<T>())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Common trait implementations for Vec
+////////////////////////////////////////////////////////////////////////////////
+
+#[unstable]
+impl<T:Clone> Clone for Vec<T> {
+ fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
+
+ fn clone_from(&mut self, other: &Vec<T>) {
+ // drop anything in self that will not be overwritten
+ if self.len() > other.len() {
+ self.truncate(other.len())
+ }
+
+ // reuse the contained values' allocations/resources.
+ for (place, thing) in self.iter_mut().zip(other.iter()) {
+ place.clone_from(thing)
+ }
+
+ // self.len <= other.len due to the truncate above, so the
+ // slice here is always in-bounds.
+ let slice = other[self.len()..];
+ self.push_all(slice);
+ }
+}
+
+impl<S: hash::Writer, T: Hash<S>> Hash<S> for Vec<T> {
+ #[inline]
+ fn hash(&self, state: &mut S) {
+ self.as_slice().hash(state);
+ }
+}
+
+#[experimental = "waiting on Index stability"]
+impl<T> Index<uint,T> for Vec<T> {
+ #[inline]
+ fn index<'a>(&'a self, index: &uint) -> &'a T {
+ &self.as_slice()[*index]
+ }
+}
+
+impl<T> IndexMut<uint,T> for Vec<T> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
+ &mut self.as_mut_slice()[*index]
+ }
+}
+
+impl<T> ops::Slice<uint, [T]> for Vec<T> {
+ #[inline]
+ fn as_slice_<'a>(&'a self) -> &'a [T] {
+ self.as_slice()
+ }
+
+ #[inline]
+ fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
+ self.as_slice().slice_from_or_fail(start)
+ }
+
+ #[inline]
+ fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
+ self.as_slice().slice_to_or_fail(end)
+ }
+ #[inline]
+ fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
+ self.as_slice().slice_or_fail(start, end)
+ }
+}
+
+impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
+ #[inline]
+ fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
+ self.as_mut_slice()
+ }
+
+ #[inline]
+ fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
+ self.as_mut_slice().slice_from_or_fail_mut(start)
+ }
+
+ #[inline]
+ fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
+ self.as_mut_slice().slice_to_or_fail_mut(end)
+ }
+ #[inline]
+ fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
+ self.as_mut_slice().slice_or_fail_mut(start, end)
+ }
+}
+
+#[experimental = "waiting on Deref stability"]
+impl<T> ops::Deref<[T]> for Vec<T> {
+ fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() }
+}
+
+#[experimental = "waiting on DerefMut stability"]
+impl<T> ops::DerefMut<[T]> for Vec<T> {
+ fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
+}
+
+#[experimental = "waiting on FromIterator stability"]
+impl<T> FromIterator<T> for Vec<T> {
+ #[inline]
+ fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
+ let (lower, _) = iterator.size_hint();
+ let mut vector = Vec::with_capacity(lower);
+ for element in iterator {
+ vector.push(element)
+ }
+ vector
+ }
+}
+
+#[experimental = "waiting on Extend stability"]
+impl<T> Extend<T> for Vec<T> {
+ #[inline]
+ fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
+ let (lower, _) = iterator.size_hint();
+ self.reserve(lower);
+ for element in iterator {
+ self.push(element)
+ }
+ }
+}
+
+impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
+ #[inline]
+ fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
+}
+
+macro_rules! impl_eq {
+ ($lhs:ty, $rhs:ty) => {
+ impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
+ #[inline]
+ fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
+ }
+
+ impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
+ #[inline]
+ fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
+ }
+ }
+}
+
+impl_eq! { Vec<A>, &'b [B] }
+impl_eq! { Vec<A>, &'b mut [B] }
+
+impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+ #[inline]
+ fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
+}
+
+impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
+ #[inline]
+ fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+}
+
+macro_rules! impl_eq_for_cowvec {
+ ($rhs:ty) => {
+ impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+ #[inline]
+ fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
+ }
+
+ impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
+ #[inline]
+ fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+ #[inline]
+ fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+ }
+ }
+}
+
+impl_eq_for_cowvec! { &'b [B] }
+impl_eq_for_cowvec! { &'b mut [B] }
+
+#[unstable = "waiting on PartialOrd stability"]
+impl<T: PartialOrd> PartialOrd for Vec<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
+ self.as_slice().partial_cmp(other.as_slice())
+ }
+}
+
+#[unstable = "waiting on Eq stability"]
+impl<T: Eq> Eq for Vec<T> {}
+
+#[allow(deprecated)]
+#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
+impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
+ #[inline]
+ fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+}
+
+#[unstable = "waiting on Ord stability"]
+impl<T: Ord> Ord for Vec<T> {
+ #[inline]
+ fn cmp(&self, other: &Vec<T>) -> Ordering {
+ self.as_slice().cmp(other.as_slice())
}
}
}
}
+impl<'a> fmt::FormatWriter for Vec<u8> {
+ fn write(&mut self, buf: &[u8]) -> fmt::Result {
+ self.push_all(buf);
+ Ok(())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Clone-on-write
+////////////////////////////////////////////////////////////////////////////////
+
+#[experimental = "unclear how valuable this alias is"]
+/// A clone-on-write vector
+pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
+
+impl<'a, T> FromIterator<T> for CowVec<'a, T> where T: Clone {
+ fn from_iter<I: Iterator<T>>(it: I) -> CowVec<'a, T> {
+ Cow::Owned(FromIterator::from_iter(it))
+ }
+}
+
+impl<'a, T: 'a> IntoCow<'a, Vec<T>, [T]> for Vec<T> where T: Clone {
+ fn into_cow(self) -> CowVec<'a, T> {
+ Cow::Owned(self)
+ }
+}
+
+impl<'a, T> IntoCow<'a, Vec<T>, [T]> for &'a [T] where T: Clone {
+ fn into_cow(self) -> CowVec<'a, T> {
+ Cow::Borrowed(self)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Iterators
+////////////////////////////////////////////////////////////////////////////////
+
/// An iterator that moves out of a vector.
+#[stable]
pub struct IntoIter<T> {
allocation: *mut T, // the block of memory allocated for the vector
cap: uint, // the capacity of the vector
end: *const T
}
+#[deprecated = "use IntoIter instead"]
+pub type MoveItems<T> = IntoIter<T>;
+
impl<T> IntoIter<T> {
- /// Drops all items that have not yet been moved and returns the empty vector.
#[inline]
+ /// Drops all items that have not yet been moved and returns the empty vector.
#[unstable]
pub fn into_inner(mut self) -> Vec<T> {
unsafe {
/// An iterator that drains a vector.
#[unsafe_no_drop_flag]
+#[unstable = "recently added as part of collections reform 2"]
pub struct Drain<'a, T> {
ptr: *const T,
end: *const T,
}
}
-/// Converts an iterator of pairs into a pair of vectors.
-///
-/// Returns a tuple containing two vectors where the i-th element of the first vector contains the
-/// first element of the i-th tuple of the input iterator, and the i-th element of the second
-/// vector contains the second element of the i-th tuple of the input iterator.
-#[unstable = "this functionality may become more generic over time"]
-pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
- let (lo, _) = iter.size_hint();
- let mut ts = Vec::with_capacity(lo);
- let mut us = Vec::with_capacity(lo);
- for (t, u) in iter {
- ts.push(t);
- us.push(u);
- }
- (ts, us)
-}
+////////////////////////////////////////////////////////////////////////////////
+// Conversion from &[T] to &Vec<T>
+////////////////////////////////////////////////////////////////////////////////
/// Wrapper type providing a `&Vec<T>` reference via `Deref`.
#[experimental]
l: ContravariantLifetime<'a>
}
+#[experimental]
impl<'a, T> Deref<Vec<T>> for DerefVec<'a, T> {
fn deref<'b>(&'b self) -> &'b Vec<T> {
&self.x
// Prevent the inner `Vec<T>` from attempting to deallocate memory.
#[unsafe_destructor]
+#[experimental]
impl<'a, T> Drop for DerefVec<'a, T> {
fn drop(&mut self) {
self.x.len = 0;
}
}
+////////////////////////////////////////////////////////////////////////////////
+// Raw module (deprecated)
+////////////////////////////////////////////////////////////////////////////////
+
/// Unsafe vector operations.
#[deprecated]
pub mod raw {
}
}
+////////////////////////////////////////////////////////////////////////////////
+// Partial vec, used for map_in_place
+////////////////////////////////////////////////////////////////////////////////
+
/// An owned, partially type-converted vector of elements with non-zero size.
///
/// `T` and `U` must have the same, non-zero size. They must also have the same
}
}
-impl<T> Vec<T> {
- /// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same
- /// size and in case they are not zero-sized the same minimal alignment.
- ///
- /// # Panics
- ///
- /// Panics if `T` and `U` have differing sizes or are not zero-sized and
- /// have differing minimal alignments.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = vec![0u, 1, 2];
- /// let w = v.map_in_place(|i| i + 3);
- /// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
- ///
- /// #[deriving(PartialEq, Show)]
- /// struct Newtype(u8);
- /// let bytes = vec![0x11, 0x22];
- /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
- /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
- /// ```
- pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
- // FIXME: Assert statically that the types `T` and `U` have the same
- // size.
- assert!(mem::size_of::<T>() == mem::size_of::<U>());
-
- let mut vec = self;
-
- if mem::size_of::<T>() != 0 {
- // FIXME: Assert statically that the types `T` and `U` have the
- // same minimal alignment in case they are not zero-sized.
-
- // These asserts are necessary because the `min_align_of` of the
- // types are passed to the allocator by `Vec`.
- assert!(mem::min_align_of::<T>() == mem::min_align_of::<U>());
-
- // This `as int` cast is safe, because the size of the elements of the
- // vector is not 0, and:
- //
- // 1) If the size of the elements in the vector is 1, the `int` may
- // overflow, but it has the correct bit pattern so that the
- // `.offset()` function will work.
- //
- // Example:
- // Address space 0x0-0xF.
- // `u8` array at: 0x1.
- // Size of `u8` array: 0x8.
- // Calculated `offset`: -0x8.
- // After `array.offset(offset)`: 0x9.
- // (0x1 + 0x8 = 0x1 - 0x8)
- //
- // 2) If the size of the elements in the vector is >1, the `uint` ->
- // `int` conversion can't overflow.
- let offset = vec.len() as int;
- let start = vec.as_mut_ptr();
-
- let mut pv = PartialVecNonZeroSized {
- vec: vec,
-
- start_t: start,
- // This points inside the vector, as the vector has length
- // `offset`.
- end_t: unsafe { start.offset(offset) },
- start_u: start as *mut U,
- end_u: start as *mut U,
- };
- // start_t
- // start_u
- // |
- // +-+-+-+-+-+-+
- // |T|T|T|...|T|
- // +-+-+-+-+-+-+
- // | |
- // end_u end_t
-
- while pv.end_u as *mut T != pv.end_t {
- unsafe {
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+-+-+-+
- // |U|...|U|T|T|...|T|
- // +-+-+-+-+-+-+-+-+-+
- // | |
- // end_u end_t
-
- let t = ptr::read(pv.start_t as *const T);
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+-+-+-+
- // |U|...|U|X|T|...|T|
- // +-+-+-+-+-+-+-+-+-+
- // | |
- // end_u end_t
- // We must not panic here, one cell is marked as `T`
- // although it is not `T`.
-
- pv.start_t = pv.start_t.offset(1);
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+-+-+-+
- // |U|...|U|X|T|...|T|
- // +-+-+-+-+-+-+-+-+-+
- // | |
- // end_u end_t
- // We may panic again.
-
- // The function given by the user might panic.
- let u = f(t);
-
- ptr::write(pv.end_u, u);
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+-+-+-+
- // |U|...|U|U|T|...|T|
- // +-+-+-+-+-+-+-+-+-+
- // | |
- // end_u end_t
- // We should not panic here, because that would leak the `U`
- // pointed to by `end_u`.
-
- pv.end_u = pv.end_u.offset(1);
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+-+-+-+
- // |U|...|U|U|T|...|T|
- // +-+-+-+-+-+-+-+-+-+
- // | |
- // end_u end_t
- // We may panic again.
- }
- }
-
- // start_u start_t
- // | |
- // +-+-+-+-+-+-+
- // |U|...|U|U|U|
- // +-+-+-+-+-+-+
- // |
- // end_t
- // end_u
- // Extract `vec` and prevent the destructor of
- // `PartialVecNonZeroSized` from running. Note that none of the
- // function calls can panic, thus no resources can be leaked (as the
- // `vec` member of `PartialVec` is the only one which holds
- // allocations -- and it is returned from this function. None of
- // this can panic.
- unsafe {
- let vec_len = pv.vec.len();
- let vec_cap = pv.vec.capacity();
- let vec_ptr = pv.vec.as_mut_ptr() as *mut U;
- mem::forget(pv);
- Vec::from_raw_parts(vec_ptr, vec_len, vec_cap)
- }
- } else {
- // Put the `Vec` into the `PartialVecZeroSized` structure and
- // prevent the destructor of the `Vec` from running. Since the
- // `Vec` contained zero-sized objects, it did not allocate, so we
- // are not leaking memory here.
- let mut pv = PartialVecZeroSized::<T,U> {
- num_t: vec.len(),
- num_u: 0,
- marker_t: InvariantType,
- marker_u: InvariantType,
- };
- unsafe { mem::forget(vec); }
-
- while pv.num_t != 0 {
- unsafe {
- // Create a `T` out of thin air and decrement `num_t`. This
- // must not panic between these steps, as otherwise a
- // destructor of `T` which doesn't exist runs.
- let t = mem::uninitialized();
- pv.num_t -= 1;
-
- // The function given by the user might panic.
- let u = f(t);
-
- // Forget the `U` and increment `num_u`. This increment
- // cannot overflow the `uint` as we only do this for a
- // number of times that fits into a `uint` (and start with
- // `0`). Again, we should not panic between these steps.
- mem::forget(u);
- pv.num_u += 1;
- }
- }
- // Create a `Vec` from our `PartialVecZeroSized` and make sure the
- // destructor of the latter will not run. None of this can panic.
- let mut result = Vec::new();
- unsafe {
- result.set_len(pv.num_u);
- mem::forget(pv);
- }
- result
- }
- }
-}
-
-impl<'a> fmt::FormatWriter for Vec<u8> {
- fn write(&mut self, buf: &[u8]) -> fmt::Result {
- self.push_all(buf);
- Ok(())
- }
-}
-
#[cfg(test)]
mod tests {
use prelude::*;