diff options
| -rw-r--r-- | src/libcollections/vec.rs | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 71c49ee616c..53b7ae0703b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1586,36 +1586,34 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> { impl<T> Extend<T> for Vec<T> { #[inline] fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()) + self.spec_extend(iter.into_iter()) } } -trait IsTrustedLen : Iterator { - fn trusted_len(&self) -> Option<usize> { None } +trait SpecExtend<I> { + fn spec_extend(&mut self, iter: I); } -impl<I> IsTrustedLen for I where I: Iterator { } -impl<I> IsTrustedLen for I where I: TrustedLen +impl<I, T> SpecExtend<I> for Vec<T> + where I: Iterator<Item=T>, { - fn trusted_len(&self) -> Option<usize> { - let (low, high) = self.size_hint(); + default fn spec_extend(&mut self, iter: I) { + self.extend_desugared(iter) + } +} + +impl<I, T> SpecExtend<I> for Vec<T> + where I: TrustedLen<Item=T>, +{ + fn spec_extend(&mut self, iterator: I) { + // This is the case for a TrustedLen iterator. + let (low, high) = iterator.size_hint(); if let Some(high_value) = high { debug_assert_eq!(low, high_value, "TrustedLen iterator's size hint is not exact: {:?}", (low, high)); } - high - } -} - -impl<T> Vec<T> { - fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) { - // This function should be the moral equivalent of: - // - // for item in iterator { - // self.push(item); - // } - if let Some(additional) = iterator.trusted_len() { + if let Some(additional) = high { self.reserve(additional); unsafe { let mut ptr = self.as_mut_ptr().offset(self.len() as isize); @@ -1628,17 +1626,30 @@ impl<T> Vec<T> { } } } else { - while let Some(element) = iterator.next() { - let len = self.len(); - if len == self.capacity() { - let (lower, _) = iterator.size_hint(); - self.reserve(lower.saturating_add(1)); - } - unsafe { - ptr::write(self.get_unchecked_mut(len), element); - // NB can't overflow since we would have had to alloc the address space - self.set_len(len + 1); - } + self.extend_desugared(iterator) + } + } +} + +impl<T> Vec<T> { + fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) { + // This is the case for a general iterator. + // + // This function should be the moral equivalent of: + // + // for item in iterator { + // self.push(item); + // } + while let Some(element) = iterator.next() { + let len = self.len(); + if len == self.capacity() { + let (lower, _) = iterator.size_hint(); + self.reserve(lower.saturating_add(1)); + } + unsafe { + ptr::write(self.get_unchecked_mut(len), element); + // NB can't overflow since we would have had to alloc the address space + self.set_len(len + 1); } } } |
