Skip to content

Commit f85a533

Browse files
committed
specialize Extend for Vec with IntoIter
1 parent fa332c9 commit f85a533

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

src/libcollections/tests/vec.rs

+22
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ fn test_extend() {
8484
let mut v = Vec::new();
8585
let mut w = Vec::new();
8686

87+
v.extend(w.clone());
88+
assert_eq!(v, &[]);
89+
8790
v.extend(0..3);
8891
for i in 0..3 {
8992
w.push(i)
@@ -100,6 +103,25 @@ fn test_extend() {
100103

101104
v.extend(w.clone()); // specializes to `append`
102105
assert!(v.iter().eq(w.iter().chain(w.iter())));
106+
107+
// Zero sized types
108+
#[derive(PartialEq, Debug)]
109+
struct Foo;
110+
111+
let mut a = Vec::new();
112+
let b = vec![Foo, Foo];
113+
114+
a.extend(b);
115+
assert_eq!(a, &[Foo, Foo]);
116+
117+
// Double drop
118+
let mut count_x = 0;
119+
{
120+
let mut x = Vec::new();
121+
let y = vec![DropCounter { count: &mut count_x }];
122+
x.extend(y);
123+
}
124+
assert_eq!(count_x, 1);
103125
}
104126

105127
#[test]

src/libcollections/vec.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -1039,18 +1039,22 @@ impl<T> Vec<T> {
10391039
#[inline]
10401040
#[stable(feature = "append", since = "1.4.0")]
10411041
pub fn append(&mut self, other: &mut Self) {
1042-
self.reserve(other.len());
1043-
let len = self.len();
1044-
unsafe {
1045-
ptr::copy_nonoverlapping(other.as_ptr(), self.get_unchecked_mut(len), other.len());
1046-
}
1047-
1048-
self.len += other.len();
10491042
unsafe {
1043+
self.append_elements(other.as_slice() as _);
10501044
other.set_len(0);
10511045
}
10521046
}
10531047

1048+
/// Appends elements to `Self` from other buffer.
1049+
#[inline]
1050+
unsafe fn append_elements(&mut self, other: *const [T]) {
1051+
let count = (*other).len();
1052+
self.reserve(count);
1053+
let len = self.len();
1054+
ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count);
1055+
self.len += count;
1056+
}
1057+
10541058
/// Create a draining iterator that removes the specified range in the vector
10551059
/// and yields the removed items.
10561060
///
@@ -1681,7 +1685,7 @@ impl<T, I> SpecExtend<T, I> for Vec<T>
16811685
vector
16821686
}
16831687

1684-
fn spec_extend(&mut self, iterator: I) {
1688+
default fn spec_extend(&mut self, iterator: I) {
16851689
// This is the case for a TrustedLen iterator.
16861690
let (low, high) = iterator.size_hint();
16871691
if let Some(high_value) = high {
@@ -1726,6 +1730,13 @@ impl<T> SpecExtend<T, IntoIter<T>> for Vec<T> {
17261730
vector
17271731
}
17281732
}
1733+
1734+
fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
1735+
unsafe {
1736+
self.append_elements(iterator.as_slice() as _);
1737+
}
1738+
iterator.ptr = iterator.end;
1739+
}
17291740
}
17301741

17311742
impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T>

0 commit comments

Comments
 (0)