diff options
| author | bors <bors@rust-lang.org> | 2016-12-08 15:39:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-08 15:39:39 +0000 |
| commit | 7537f953e2d28dc0f34ab39737b058e7b79a7fb7 (patch) | |
| tree | 8af0e2635b2d7cc801be99ad33185577178040a3 /src | |
| parent | 47ffafcdcd01ec3f782b89e8ea27a7f1a7183ae0 (diff) | |
| parent | 02bf1ce9cc617979478aac09a95486696f2c4b36 (diff) | |
| download | rust-7537f953e2d28dc0f34ab39737b058e7b79a7fb7.tar.gz rust-7537f953e2d28dc0f34ab39737b058e7b79a7fb7.zip | |
Auto merge of #38182 - bluss:more-vec-extend, r=alexcrichton
Specialization for Extend<&T> for vec Specialize to use copy_from_slice when extending a Vec with &[T] where T: Copy. This specialization results in `.clone()` not being called in `extend_from_slice` and `extend` when the element is `Copy`. Fixes #38021
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcollections/vec.rs | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index f2632412700..c9f9e513ef3 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1244,7 +1244,7 @@ impl<T: Clone> Vec<T> { /// ``` #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] pub fn extend_from_slice(&mut self, other: &[T]) { - self.extend(other.iter().cloned()) + self.spec_extend(other.iter()) } } @@ -1499,7 +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> { - <Self as SpecExtend<_>>::from_iter(iter.into_iter()) + <Self as SpecExtend<_, _>>::from_iter(iter.into_iter()) } } @@ -1572,12 +1572,12 @@ impl<T> Extend<T> for Vec<T> { } // Specialization trait used for Vec::from_iter and Vec::extend -trait SpecExtend<I> { +trait SpecExtend<T, I> { fn from_iter(iter: I) -> Self; fn spec_extend(&mut self, iter: I); } -impl<I, T> SpecExtend<I> for Vec<T> +impl<T, I> SpecExtend<T, I> for Vec<T> where I: Iterator<Item=T>, { default fn from_iter(mut iterator: I) -> Self { @@ -1607,7 +1607,7 @@ impl<I, T> SpecExtend<I> for Vec<T> } } -impl<I, T> SpecExtend<I> for Vec<T> +impl<T, I> SpecExtend<T, I> for Vec<T> where I: TrustedLen<Item=T>, { fn from_iter(iterator: I) -> Self { @@ -1642,6 +1642,33 @@ impl<I, T> SpecExtend<I> for Vec<T> } } +impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T> + where I: Iterator<Item=&'a T>, + T: Clone, +{ + default fn from_iter(iterator: I) -> Self { + SpecExtend::from_iter(iterator.cloned()) + } + + default fn spec_extend(&mut self, iterator: I) { + self.spec_extend(iterator.cloned()) + } +} + +impl<'a, T: 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T> + where T: Copy, +{ + fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { + let slice = iterator.as_slice(); + self.reserve(slice.len()); + unsafe { + let len = self.len(); + self.set_len(len + slice.len()); + self.get_unchecked_mut(len..).copy_from_slice(slice); + } + } +} + impl<T> Vec<T> { fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) { // This is the case for a general iterator. @@ -1669,7 +1696,7 @@ impl<T> Vec<T> { #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, T: 'a + Copy> Extend<&'a T> for Vec<T> { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { - self.extend(iter.into_iter().map(|&x| x)) + self.spec_extend(iter.into_iter()) } } |
