specialize Extend for Vec with IntoIter
This commit is contained in:
parent
fa332c9015
commit
f85a5337ab
2 changed files with 41 additions and 8 deletions
|
@ -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]
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue