about summary refs log tree commit diff
path: root/library/alloc
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev+love@gmail.com>2022-11-20 13:15:59 +0900
committerGitHub <noreply@github.com>2022-11-20 13:15:59 +0900
commit785237d3924d4fb7b23803c964972dce82de2161 (patch)
treec3b5a12cfff05df99d15ec98e86583d3a4045dee /library/alloc
parente69b84204aecf27fe18ada467f78c83b788b80e4 (diff)
parent71bb200225f0164940acc21f1fb647c8155f1706 (diff)
Rollup merge of #104435 - scottmcm:iter-repeat-n, r=thomcc
`VecDeque::resize` should re-use the buffer in the passed-in element

Today it always copies it for *every* appended element, but one of those clones is avoidable.

This adds `iter::repeat_n` (https://github.com/rust-lang/rust/issues/104434) as the primitive needed to do this.  If this PR is acceptable, I'll also use this in `Vec` rather than its custom `ExtendElement` type & infrastructure that is harder to share between multiple different containers:

https://github.com/rust-lang/rust/blob/101e1822c3e54e63996c8aaa014d55716f3937eb/library/alloc/src/vec/mod.rs#L2479-L2492
Diffstat (limited to 'library/alloc')
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs9
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/tests/vec_deque.rs8
3 files changed, 16 insertions, 2 deletions
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 2a57dad89a7..537fe22a4be 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -10,7 +10,7 @@
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{Hash, Hasher};
-use core::iter::{repeat_with, FromIterator};
+use core::iter::{repeat_n, repeat_with, FromIterator};
 use core::marker::PhantomData;
 use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
 use core::ops::{Index, IndexMut, Range, RangeBounds};
@@ -2833,7 +2833,12 @@ impl<T: Clone, A: Allocator> VecDeque<T, A> {
     /// ```
     #[stable(feature = "deque_extras", since = "1.16.0")]
     pub fn resize(&mut self, new_len: usize, value: T) {
-        self.resize_with(new_len, || value.clone());
+        if new_len > self.len() {
+            let extra = new_len - self.len();
+            self.extend(repeat_n(value, extra))
+        } else {
+            self.truncate(new_len);
+        }
     }
 }
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 008926666c1..5e13547abcb 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -124,6 +124,7 @@
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
+#![feature(iter_repeat_n)]
 #![feature(layout_for_ptr)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index 019d73c0b16..c1b9e7af9d8 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -1727,3 +1727,11 @@ fn test_from_zero_sized_vec() {
     let queue = VecDeque::from(v);
     assert_eq!(queue.len(), 100);
 }
+
+#[test]
+fn test_resize_keeps_reserved_space_from_item() {
+    let v = Vec::<i32>::with_capacity(1234);
+    let mut d = VecDeque::new();
+    d.resize(1, v);
+    assert_eq!(d[0].capacity(), 1234);
+}