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);
}
}
} 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);
}
}
}