specialize Extend for Vec with IntoIter

This commit is contained in:
Sean McArthur 2017-04-19 11:57:29 -07:00
parent fa332c9015
commit f85a5337ab
2 changed files with 41 additions and 8 deletions

View file

@ -84,6 +84,9 @@ fn test_extend() {
let mut v = Vec::new();
let mut w = Vec::new();
v.extend(w.clone());
assert_eq!(v, &[]);
v.extend(0..3);
for i in 0..3 {
w.push(i)
@ -100,6 +103,25 @@ fn test_extend() {
v.extend(w.clone()); // specializes to `append`
assert!(v.iter().eq(w.iter().chain(w.iter())));
// Zero sized types
#[derive(PartialEq, Debug)]
struct Foo;
let mut a = Vec::new();
let b = vec![Foo, Foo];
a.extend(b);
assert_eq!(a, &[Foo, Foo]);
// Double drop
let mut count_x = 0;
{
let mut x = Vec::new();
let y = vec![DropCounter { count: &mut count_x }];
x.extend(y);
}
assert_eq!(count_x, 1);
}
#[test]

View file

@ -1039,18 +1039,22 @@ impl<T> Vec<T> {
#[inline]
#[stable(feature = "append", since = "1.4.0")]
pub fn append(&mut self, other: &mut Self) {
self.reserve(other.len());
let len = self.len();
unsafe {
ptr::copy_nonoverlapping(other.as_ptr(), self.get_unchecked_mut(len), other.len());
}
self.len += other.len();
unsafe {
self.append_elements(other.as_slice() as _);
other.set_len(0);
}
}
/// Appends elements to `Self` from other buffer.
#[inline]
unsafe fn append_elements(&mut self, other: *const [T]) {
let count = (*other).len();
self.reserve(count);
let len = self.len();
ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count);
self.len += count;
}
/// Create a draining iterator that removes the specified range in the vector
/// and yields the removed items.
///
@ -1681,7 +1685,7 @@ impl<T, I> SpecExtend<T, I> for Vec<T>
vector
}
fn spec_extend(&mut self, iterator: I) {
default fn spec_extend(&mut self, iterator: I) {
// This is the case for a TrustedLen iterator.
let (low, high) = iterator.size_hint();
if let Some(high_value) = high {
@ -1726,6 +1730,13 @@ impl<T> SpecExtend<T, IntoIter<T>> for Vec<T> {
vector
}
}
fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
unsafe {
self.append_elements(iterator.as_slice() as _);
}
iterator.ptr = iterator.end;
}
}
impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T>