diff options
| -rw-r--r-- | src/libcollections/vec.rs | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 53b7ae0703b..24f8e3a2d91 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1499,26 +1499,7 @@ impl<T> ops::DerefMut for Vec<T> { impl<T> FromIterator<T> for Vec<T> { #[inline] fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> { - // Unroll the first iteration, as the vector is going to be - // expanded on this iteration in every case when the iterable is not - // empty, but the loop in extend_desugared() is not going to see the - // vector being full in the few subsequent loop iterations. - // So we get better branch prediction. - let mut iterator = iter.into_iter(); - let mut vector = match iterator.next() { - None => return Vec::new(), - Some(element) => { - let (lower, _) = iterator.size_hint(); - let mut vector = Vec::with_capacity(lower.saturating_add(1)); - unsafe { - ptr::write(vector.get_unchecked_mut(0), element); - vector.set_len(1); - } - vector - } - }; - vector.extend_desugared(iterator); - vector + <Self as SpecExtend<_>>::from_iter(iter.into_iter()) } } @@ -1590,13 +1571,37 @@ impl<T> Extend<T> for Vec<T> { } } +// Specialization trait used for Vec::from_iter and Vec::extend trait SpecExtend<I> { + fn from_iter(iter: I) -> Self; fn spec_extend(&mut self, iter: I); } impl<I, T> SpecExtend<I> for Vec<T> where I: Iterator<Item=T>, { + default fn from_iter(mut iterator: I) -> Self { + // Unroll the first iteration, as the vector is going to be + // expanded on this iteration in every case when the iterable is not + // empty, but the loop in extend_desugared() is not going to see the + // vector being full in the few subsequent loop iterations. + // So we get better branch prediction. + let mut vector = match iterator.next() { + None => return Vec::new(), + Some(element) => { + let (lower, _) = iterator.size_hint(); + let mut vector = Vec::with_capacity(lower.saturating_add(1)); + unsafe { + ptr::write(vector.get_unchecked_mut(0), element); + vector.set_len(1); + } + vector + } + }; + vector.spec_extend(iterator); + vector + } + default fn spec_extend(&mut self, iter: I) { self.extend_desugared(iter) } @@ -1605,6 +1610,12 @@ impl<I, T> SpecExtend<I> for Vec<T> impl<I, T> SpecExtend<I> for Vec<T> where I: TrustedLen<Item=T>, { + fn from_iter(iterator: I) -> Self { + let mut vector = Vec::new(); + vector.spec_extend(iterator); + vector + } + fn spec_extend(&mut self, iterator: I) { // This is the case for a TrustedLen iterator. let (low, high) = iterator.size_hint(); |
