diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2015-02-18 23:50:21 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2015-02-18 23:50:21 +1100 |
| commit | dfc5c0f1e8799f47f9033bdcc8a7cd8a217620a5 (patch) | |
| tree | e9c32f2e58b3462a23dd9c472d2f236640b78811 /src/libcollections/vec.rs | |
| parent | 6c065fc8cb036785f61ff03e05c1563cbb2dd081 (diff) | |
| parent | 47f91a9484eceef10536d4caac6ef578cd254567 (diff) | |
Manual merge of #22475 - alexcrichton:rollup, r=alexcrichton
One windows bot failed spuriously.
Diffstat (limited to 'src/libcollections/vec.rs')
| -rw-r--r-- | src/libcollections/vec.rs | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index f294dd3c3e0..bde733644b5 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1252,6 +1252,30 @@ unsafe fn dealloc<T>(ptr: *mut T, len: usize) { } } +#[doc(hidden)] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> { + unsafe { + let mut v = Vec::with_capacity(n); + let mut ptr = v.as_mut_ptr(); + + // Write all elements except the last one + for i in 1..n { + ptr::write(ptr, Clone::clone(&elem)); + ptr = ptr.offset(1); + v.set_len(i); // Increment the length in every step in case Clone::clone() panics + } + + if n > 0 { + // We can write the last element directly without cloning needlessly + ptr::write(ptr, elem); + v.set_len(n); + } + + v + } +} + //////////////////////////////////////////////////////////////////////////////// // Common trait implementations for Vec //////////////////////////////////////////////////////////////////////////////// @@ -1383,7 +1407,7 @@ impl<T> ops::DerefMut for Vec<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T> FromIterator<T> for Vec<T> { #[inline] - fn from_iter<I:Iterator<Item=T>>(iterator: I) -> Vec<T> { + fn from_iter<I:Iterator<Item=T>>(mut iterator: I) -> Vec<T> { let (lower, _) = iterator.size_hint(); let mut vector = Vec::with_capacity(lower); @@ -1393,13 +1417,20 @@ impl<T> FromIterator<T> for Vec<T> { // vector.push(item); // } // - // This equivalent crucially runs the iterator precisely once. The - // optimization below (eliding bound/growth checks) means that we - // actually run the iterator twice. To ensure the "moral equivalent" we - // do a `fuse()` operation to ensure that the iterator continues to - // return `None` after seeing the first `None`. - let mut i = iterator.fuse(); - for element in i.by_ref().take(vector.capacity()) { + // This equivalent crucially runs the iterator precisely once. Below we + // actually in theory run the iterator twice (one without bounds checks + // and one with). To achieve the "moral equivalent", we use the `if` + // statement below to break out early. + // + // If the first loop has terminated, then we have one of two conditions. + // + // 1. The underlying iterator returned `None`. In this case we are + // guaranteed that less than `vector.capacity()` elements have been + // returned, so we break out early. + // 2. The underlying iterator yielded `vector.capacity()` elements and + // has not yielded `None` yet. In this case we run the iterator to + // its end below. + for element in iterator.by_ref().take(vector.capacity()) { let len = vector.len(); unsafe { ptr::write(vector.get_unchecked_mut(len), element); @@ -1407,24 +1438,16 @@ impl<T> FromIterator<T> for Vec<T> { } } - for element in i { - vector.push(element) + if vector.len() == vector.capacity() { + for element in iterator { + vector.push(element); + } } vector } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<T> IntoIterator for Vec<T> { - type IntoIter = IntoIter<T>; - - fn into_iter(self) -> IntoIter<T> { - self.into_iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<T> IntoIterator for Vec<T> { type Item = T; type IntoIter = IntoIter<T>; @@ -1434,17 +1457,7 @@ impl<T> IntoIterator for Vec<T> { } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<'a, T> IntoIterator for &'a Vec<T> { - type IntoIter = slice::Iter<'a, T>; - - fn into_iter(self) -> slice::Iter<'a, T> { - self.iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> IntoIterator for &'a Vec<T> { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -1454,17 +1467,7 @@ impl<'a, T> IntoIterator for &'a Vec<T> { } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<'a, T> IntoIterator for &'a mut Vec<T> { - type IntoIter = slice::IterMut<'a, T>; - - fn into_iter(mut self) -> slice::IterMut<'a, T> { - self.iter_mut() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> IntoIterator for &'a mut Vec<T> { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; |
