diff options
| author | bors <bors@rust-lang.org> | 2017-04-20 13:08:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-04-20 13:08:07 +0000 |
| commit | 968ae7babecfc6c62ef9699ff052d9ab00411848 (patch) | |
| tree | 8047c62010017e7f69253113832daef38777176c /src/libcollections/vec.rs | |
| parent | fa6b50fc6282a2c64814b35b16464a22f4ae9265 (diff) | |
| parent | f85a5337ab0f8b492cb8df56a7c2af103010037e (diff) | |
| download | rust-968ae7babecfc6c62ef9699ff052d9ab00411848.tar.gz rust-968ae7babecfc6c62ef9699ff052d9ab00411848.zip | |
Auto merge of #41191 - seanmonstar:spec-extend-vec-intoiter, r=alexcrichton
specialize Extend for Vec with IntoIter Before, `vec.extend(&other_vec)` was quite a bit faster than `vec.extend(other_vec)`. This allows extending by consuming a vec to use the same code as extending from a slice.
Diffstat (limited to 'src/libcollections/vec.rs')
| -rw-r--r-- | src/libcollections/vec.rs | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a3c529f3585..6deb87ae772 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1041,18 +1041,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. /// @@ -1738,7 +1742,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 { @@ -1783,6 +1787,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> |
