Skip to content

Commit f8249da

Browse files
balt-devbalt-dev
authored andcommitted
Update mod.rs
(cherry picked from commit b48ad8c)
1 parent 55d4364 commit f8249da

File tree

4 files changed

+257
-46
lines changed

4 files changed

+257
-46
lines changed

library/alloc/src/collections/linked_list.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,11 +844,34 @@ impl<T, A: Allocator> LinkedList<T, A> {
844844
/// ```
845845
#[stable(feature = "rust1", since = "1.0.0")]
846846
pub fn push_front(&mut self, elt: T) {
847+
let _ = self.push_front_mut(elt);
848+
}
849+
850+
/// Adds an element first in the list, returning a reference to it.
851+
///
852+
/// This operation should compute in *O*(1) time.
853+
///
854+
/// # Examples
855+
///
856+
/// ```
857+
/// #![feature(push_mut)]
858+
/// use std::collections::LinkedList;
859+
///
860+
/// let mut dl = LinkedList::from([1, 2, 3]);
861+
///
862+
/// let ptr = dl.push_front_mut(2);
863+
/// *ptr += 4;
864+
/// assert_eq!(dl.front().unwrap(), &6);
865+
/// ```
866+
#[unstable(feature = "push_mut", issue = "135974")]
867+
#[must_use = "if you don't need a reference to the value, use LinkedList::push_front instead"]
868+
pub fn push_front_mut(&mut self, elt: T) -> &mut T {
847869
let node = Box::new_in(Node::new(elt), &self.alloc);
848-
let node_ptr = NonNull::from(Box::leak(node));
870+
let mut node_ptr = NonNull::from(Box::leak(node));
849871
// SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc and leaked
850872
unsafe {
851873
self.push_front_node(node_ptr);
874+
&mut node_ptr.as_mut().element
852875
}
853876
}
854877

@@ -893,11 +916,34 @@ impl<T, A: Allocator> LinkedList<T, A> {
893916
#[stable(feature = "rust1", since = "1.0.0")]
894917
#[rustc_confusables("push", "append")]
895918
pub fn push_back(&mut self, elt: T) {
919+
let _ = self.push_back_mut(elt);
920+
}
921+
922+
/// Adds an element to the back of a list, returning a reference to it.
923+
///
924+
/// This operation should compute in *O*(1) time.
925+
///
926+
/// # Examples
927+
///
928+
/// ```
929+
/// #![feature(push_mut)]
930+
/// use std::collections::LinkedList;
931+
///
932+
/// let mut dl = LinkedList::from([1, 2, 3]);
933+
///
934+
/// let ptr = dl.push_back_mut(2);
935+
/// *ptr += 4;
936+
/// assert_eq!(dl.back().unwrap(), &6);
937+
/// ```
938+
#[unstable(feature = "push_mut", issue = "135974")]
939+
#[must_use = "if you don't need a reference to the value, use LinkedList::push_back instead"]
940+
pub fn push_back_mut(&mut self, elt: T) -> &mut T {
896941
let node = Box::new_in(Node::new(elt), &self.alloc);
897-
let node_ptr = NonNull::from(Box::leak(node));
942+
let mut node_ptr = NonNull::from(Box::leak(node));
898943
// SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc and leaked
899944
unsafe {
900945
self.push_back_node(node_ptr);
946+
&mut node_ptr.as_mut().element
901947
}
902948
}
903949

library/alloc/src/collections/vec_deque/mod.rs

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
182182
unsafe { ptr::read(self.ptr().add(off)) }
183183
}
184184

185-
/// Writes an element into the buffer, moving it.
185+
/// Writes an element into the buffer, moving it and returning a pointer to it.
186+
/// # Safety
187+
///
188+
/// May only be called if `off < self.capacity()`.
186189
#[inline]
187-
unsafe fn buffer_write(&mut self, off: usize, value: T) {
190+
unsafe fn buffer_write(&mut self, off: usize, value: T) -> &mut T {
188191
unsafe {
189-
ptr::write(self.ptr().add(off), value);
192+
let ptr = self.ptr().add(off);
193+
ptr::write(ptr, value);
194+
&mut *ptr
190195
}
191196
}
192197

@@ -1888,16 +1893,34 @@ impl<T, A: Allocator> VecDeque<T, A> {
18881893
#[stable(feature = "rust1", since = "1.0.0")]
18891894
#[track_caller]
18901895
pub fn push_front(&mut self, value: T) {
1896+
let _ = self.push_front_mut(value);
1897+
}
1898+
1899+
/// Prepends an element to the deque, returning a reference to it.
1900+
///
1901+
/// # Examples
1902+
///
1903+
/// ```
1904+
/// #![feature(push_mut)]
1905+
/// use std::collections::VecDeque;
1906+
///
1907+
/// let mut d = VecDeque::from([1, 2, 3]);
1908+
/// let x = d.push_front_mut(8);
1909+
/// *x -= 1;
1910+
/// assert_eq!(d.front(), Some(&7));
1911+
/// ```
1912+
#[unstable(feature = "push_mut", issue = "135974")]
1913+
#[track_caller]
1914+
#[must_use = "if you don't need a reference to the value, use VecDeque::push_front instead"]
1915+
pub fn push_front_mut(&mut self, value: T) -> &mut T {
18911916
if self.is_full() {
18921917
self.grow();
18931918
}
18941919

18951920
self.head = self.wrap_sub(self.head, 1);
18961921
self.len += 1;
1897-
1898-
unsafe {
1899-
self.buffer_write(self.head, value);
1900-
}
1922+
// SAFETY: We know that self.head is within range of the deque.
1923+
unsafe { self.buffer_write(self.head, value) }
19011924
}
19021925

19031926
/// Appends an element to the back of the deque.
@@ -1916,12 +1939,33 @@ impl<T, A: Allocator> VecDeque<T, A> {
19161939
#[rustc_confusables("push", "put", "append")]
19171940
#[track_caller]
19181941
pub fn push_back(&mut self, value: T) {
1942+
let _ = self.push_back_mut(value);
1943+
}
1944+
1945+
/// Appends an element to the back of the deque, returning a reference to it.
1946+
///
1947+
/// # Examples
1948+
///
1949+
/// ```
1950+
/// #![feature(push_mut)]
1951+
/// use std::collections::VecDeque;
1952+
///
1953+
/// let mut d = VecDeque::from([1, 2, 3]);
1954+
/// let x = d.push_back_mut(9);
1955+
/// *x += 1;
1956+
/// assert_eq!(d.back(), Some(&10));
1957+
/// ```
1958+
#[unstable(feature = "push_mut", issue = "135974")]
1959+
#[track_caller]
1960+
#[must_use = "if you don't need a reference to the value, use VecDeque::push_back instead"]
1961+
pub fn push_back_mut(&mut self, value: T) -> &mut T {
19191962
if self.is_full() {
19201963
self.grow();
19211964
}
19221965

1923-
unsafe { self.buffer_write(self.to_physical_idx(self.len), value) }
1966+
let len = self.len;
19241967
self.len += 1;
1968+
unsafe { self.buffer_write(self.to_physical_idx(len), value) }
19251969
}
19261970

19271971
#[inline]
@@ -2007,7 +2051,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
20072051
///
20082052
/// # Panics
20092053
///
2010-
/// Panics if `index` is strictly greater than deque's length
2054+
/// Panics if `index` is strictly greater than the deque's length.
20112055
///
20122056
/// # Examples
20132057
///
@@ -2029,7 +2073,38 @@ impl<T, A: Allocator> VecDeque<T, A> {
20292073
#[stable(feature = "deque_extras_15", since = "1.5.0")]
20302074
#[track_caller]
20312075
pub fn insert(&mut self, index: usize, value: T) {
2032-
assert!(index <= self.len(), "index out of bounds");
2076+
let _ = self.insert_mut(index, value);
2077+
}
2078+
2079+
/// Inserts an element at `index` within the deque, shifting all elements
2080+
/// with indices greater than or equal to `index` towards the back,
2081+
/// and returning a reference to it.
2082+
///
2083+
/// Element at index 0 is the front of the queue.
2084+
///
2085+
/// # Panics
2086+
///
2087+
/// Panics if `index` is strictly greater than the deque's length.
2088+
///
2089+
/// # Examples
2090+
///
2091+
/// ```
2092+
/// #![feature(push_mut)]
2093+
/// use std::collections::VecDeque;
2094+
///
2095+
/// let mut vec_deque = VecDeque::from([1, 2, 3]);
2096+
///
2097+
/// let x = vec_deque.insert_mut(1, 5);
2098+
/// *x += 7;
2099+
/// assert_eq!(vec_deque, &[1, 12, 2, 3]);
2100+
/// ```
2101+
#[unstable(feature = "push_mut", issue = "135974")]
2102+
#[track_caller]
2103+
#[must_use = "if you don't need a reference to the value, use VecDeque::insert instead"]
2104+
pub fn insert_mut(&mut self, index: usize, value: T) -> &mut T {
2105+
if core::intrinsics::unlikely(index > self.len) {
2106+
panic!("insertion index (is {index}) should be <= len (is {})", self.len())
2107+
};
20332108
if self.is_full() {
20342109
self.grow();
20352110
}
@@ -2042,16 +2117,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
20422117
unsafe {
20432118
// see `remove()` for explanation why this wrap_copy() call is safe.
20442119
self.wrap_copy(self.to_physical_idx(index), self.to_physical_idx(index + 1), k);
2045-
self.buffer_write(self.to_physical_idx(index), value);
20462120
self.len += 1;
2121+
self.buffer_write(self.to_physical_idx(index), value)
20472122
}
20482123
} else {
20492124
let old_head = self.head;
20502125
self.head = self.wrap_sub(self.head, 1);
20512126
unsafe {
20522127
self.wrap_copy(old_head, self.head, index);
2053-
self.buffer_write(self.to_physical_idx(index), value);
20542128
self.len += 1;
2129+
self.buffer_write(self.to_physical_idx(index), value)
20552130
}
20562131
}
20572132
}

0 commit comments

Comments
 (0)