]> git.lizzy.rs Git - rust.git/commitdiff
vec: More specialization for Extend<&T> for vec
authorUlrik Sverdrup <bluss@users.noreply.github.com>
Mon, 5 Dec 2016 20:48:53 +0000 (21:48 +0100)
committerUlrik Sverdrup <bluss@users.noreply.github.com>
Tue, 6 Dec 2016 06:58:56 +0000 (07:58 +0100)
Specialize to use copy_from_slice when extending a Vec with &[T] where
T: Copy.

src/libcollections/vec.rs

index f26324127003b32b12ecc7570b93ff627c19f8e6..c9f9e513ef3d6f7a34e789eb1d839af1916ebb9e 100644 (file)
@@ -1244,7 +1244,7 @@ fn extend_with_element(&mut self, n: usize, value: 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 @@ fn deref_mut(&mut self) -> &mut [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 @@ fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
 }
 
 // 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 @@ fn spec_extend(&mut self, iterator: I) {
     }
 }
 
+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 @@ fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
 #[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())
     }
 }