diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 2f9577c08de..cb1199a59f6 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1410,42 +1410,8 @@ fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() } impl FromIterator for Vec { #[inline] fn from_iter>(iterable: I) -> Vec { - let mut iterator = iterable.into_iter(); - let (lower, _) = iterator.size_hint(); - let mut vector = Vec::with_capacity(lower); - - // This function should be the moral equivalent of: - // - // for item in iterator { - // vector.push(item); - // } - // - // 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); - vector.set_len(len + 1); - } - } - - if vector.len() == vector.capacity() { - for element in iterator { - vector.push(element); - } - } + let mut vector = Vec::new(); + vector.extend(iterable); vector } } @@ -1482,13 +1448,31 @@ fn into_iter(mut self) -> slice::IterMut<'a, T> { #[unstable(feature = "collections", reason = "waiting on Extend stability")] impl Extend for Vec { - #[inline] fn extend>(&mut self, iterable: I) { - let iterator = iterable.into_iter(); - let (lower, _) = iterator.size_hint(); - self.reserve(lower); - for element in iterator { - self.push(element) + let mut iterator = iterable.into_iter(); + + // This function should be the moral equivalent of: + // + // for item in iterator { + // self.push(item); + // } + loop { + match iterator.next() { + None => { + break; + } + Some(element) => { + let len = self.len(); + if len == self.capacity() { + let (lower, _) = iterator.size_hint(); + self.reserve(lower + 1); + } + unsafe { + ptr::write(self.get_unchecked_mut(len), element); + self.set_len(len + 1); + } + } + } } } }