Skip to content

Commit

Permalink
Auto merge of #32851 - apasel422:spec-extend, r=alexcrichton
Browse files Browse the repository at this point in the history
Specialize `Extend` to `append` for `{LinkedList, Vec}`
  • Loading branch information
bors committed Apr 15, 2016
2 parents 4091cd0 + cf37af1 commit a7b5d69
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,10 @@ pub enum Bound<T> {
/// An infinite endpoint. Indicates that there is no bound in this direction.
Unbounded,
}

/// An intermediate trait for specialization of `Extend`.
#[doc(hidden)]
trait SpecExtend<I: IntoIterator> {
/// Extends `self` with the contents of the given iterator.
fn spec_extend(&mut self, iter: I);
}
14 changes: 14 additions & 0 deletions src/libcollections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use core::mem;
use core::ops::{BoxPlace, InPlace, Place, Placer};
use core::ptr::{self, Shared};

use super::SpecExtend;

/// A doubly-linked list.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct LinkedList<T> {
Expand Down Expand Up @@ -969,12 +971,24 @@ impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Extend<A> for LinkedList<A> {
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
<Self as SpecExtend<T>>::spec_extend(self, iter);
}
}

impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> {
default fn spec_extend(&mut self, iter: I) {
for elt in iter {
self.push_back(elt);
}
}
}

impl<T> SpecExtend<LinkedList<T>> for LinkedList<T> {
fn spec_extend(&mut self, ref mut other: LinkedList<T>) {
self.append(other);
}
}

#[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
Expand Down
13 changes: 13 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ use core::ops;
use core::ptr;
use core::slice;

use super::SpecExtend;
use super::range::RangeArgument;

/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector.'
Expand Down Expand Up @@ -1390,10 +1391,22 @@ 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 as SpecExtend<I>>::spec_extend(self, iter);
}
}

impl<I: IntoIterator> SpecExtend<I> for Vec<I::Item> {
default fn spec_extend(&mut self, iter: I) {
self.extend_desugared(iter.into_iter())
}
}

impl<T> SpecExtend<Vec<T>> for Vec<T> {
fn spec_extend(&mut self, ref mut other: Vec<T>) {
self.append(other);
}
}

impl<T> Vec<T> {
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
// This function should be the moral equivalent of:
Expand Down
16 changes: 16 additions & 0 deletions src/libcollectionstest/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,22 @@ fn test_extend_ref() {
assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
}

#[test]
fn test_extend() {
let mut a = LinkedList::new();
a.push_back(1);
a.extend(vec![2, 3, 4]); // uses iterator

assert_eq!(a.len(), 4);
assert!(a.iter().eq(&[1, 2, 3, 4]));

let b: LinkedList<_> = vec![5, 6, 7].into_iter().collect();
a.extend(b); // specializes to `append`

assert_eq!(a.len(), 7);
assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
}

#[bench]
fn bench_collect_into(b: &mut test::Bencher) {
let v = &[0; 64];
Expand Down
3 changes: 3 additions & 0 deletions src/libcollectionstest/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ fn test_extend() {
for i in 3..10 { w.push(i) }

assert_eq!(v, w);

v.extend(w.clone()); // specializes to `append`
assert!(v.iter().eq(w.iter().chain(w.iter())));
}

#[test]
Expand Down

0 comments on commit a7b5d69

Please sign in to comment.