Specialize Extend
to append
for {LinkedList, Vec}
This commit is contained in:
parent
7e99694378
commit
cf37af1627
@ -133,3 +133,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);
|
||||
}
|
||||
|
@ -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> {
|
||||
@ -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) {
|
||||
|
@ -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.'
|
||||
@ -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:
|
||||
|
@ -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];
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user