Skip to content

Commit 128b441

Browse files
feat: non-panicking Vec::try_remove
1 parent ebdf2ab commit 128b441

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,6 +2222,53 @@ impl<T, A: Allocator> Vec<T, A> {
22222222
}
22232223
}
22242224

2225+
/// Remove and return the element at position `index` within the vector,
2226+
/// shifting all elements after it to the left, or [`None`] if it does not
2227+
/// exist.
2228+
///
2229+
/// Note: Because this shifts over the remaining elements, it has a
2230+
/// worst-case performance of *O*(*n*). If you'd like to remove
2231+
/// elements from the beginning of the `Vec`, consider using
2232+
/// [`VecDeque::pop_front`] instead.
2233+
///
2234+
/// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
2235+
///
2236+
/// # Examples
2237+
///
2238+
/// ```
2239+
/// let mut v = vec!['a', 'b', 'c'];
2240+
/// assert_eq!(v.try_remove(1), Some('b'));
2241+
/// assert_eq!(v, ['a', 'c']);
2242+
///
2243+
/// assert_eq!(v.try_remove(2), None);
2244+
/// assert_eq!(v, ['a', 'c']);
2245+
/// ```
2246+
#[stable(feature = "vec_try_remove", since = "1.92.0")]
2247+
#[track_caller]
2248+
#[rustc_confusables("delete", "take", "remove")]
2249+
pub fn try_remove(&mut self, index: usize) -> Option<T> {
2250+
let len = self.len();
2251+
if index >= len {
2252+
return None;
2253+
}
2254+
unsafe {
2255+
// infallible
2256+
let ret;
2257+
{
2258+
// the place we are taking from.
2259+
let ptr = self.as_mut_ptr().add(index);
2260+
// copy it out, unsafely having a copy of the value on
2261+
// the stack and in the vector at the same time.
2262+
ret = ptr::read(ptr);
2263+
2264+
// Shift everything down to fill in that spot.
2265+
ptr::copy(ptr.add(1), ptr, len - index - 1);
2266+
}
2267+
self.set_len(len - 1);
2268+
Some(ret)
2269+
}
2270+
}
2271+
22252272
/// Retains only the elements specified by the predicate.
22262273
///
22272274
/// In other words, remove all elements `e` for which `f(&e)` returns `false`.

0 commit comments

Comments
 (0)