diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-13 04:21:22 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-13 04:21:22 +0100 |
| commit | 2ca7b7e539b429141028953328ea31db77dbf71a (patch) | |
| tree | be8404e896662fb1f69be29d53f85f933eb43e72 /src/liballoc/collections | |
| parent | 3eeb8d4f2fbae0bb1c587d00b5abeaf938da47f4 (diff) | |
| parent | 164d1a205d21e0bc54b60cb4e9badf27b3883ffd (diff) | |
| download | rust-2ca7b7e539b429141028953328ea31db77dbf71a.tar.gz rust-2ca7b7e539b429141028953328ea31db77dbf71a.zip | |
Rollup merge of #66341 - crgl:vec-deque-extend, r=Amanieu
Match `VecDeque::extend` to `Vec::extend_desugared` Currently, `VecDeque::extend` [does not reserve at all](https://github.com/rust-lang/rust/pull/65069#discussion_r333166522). This implementation still runs a check every iteration of the loop, but should reallocate at most once for the common cases where the `size_hint` lower bound is exact. Further optimizations in the future could improve this for some common cases, but given the complexity of the `Vec::extend` implementation it's not immediately clear that this would be worthwhile.
Diffstat (limited to 'src/liballoc/collections')
| -rw-r--r-- | src/liballoc/collections/vec_deque.rs | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 7795083e058..ebd3f010077 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2809,7 +2809,22 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<A> Extend<A> for VecDeque<A> { fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) { - iter.into_iter().for_each(move |elt| self.push_back(elt)); + // This function should be the moral equivalent of: + // + // for item in iter.into_iter() { + // self.push_back(item); + // } + let mut iter = iter.into_iter(); + while let Some(element) = iter.next() { + if self.len() == self.capacity() { + let (lower, _) = iter.size_hint(); + self.reserve(lower.saturating_add(1)); + } + + let head = self.head; + self.head = self.wrap_add(self.head, 1); + unsafe { self.buffer_write(head, element); } + } } } |
