Skip to content

Commit f32d5d9

Browse files
committed
Vec: add remove.
1 parent fedce67 commit f32d5d9

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/vec.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,54 @@ impl<T, const N: usize> Vec<T, N> {
619619

620620
Ok(())
621621
}
622+
623+
/// Removes and returns the element at position `index` within the vector,
624+
/// shifting all elements after it to the left.
625+
///
626+
/// Note: Because this shifts over the remaining elements, it has a
627+
/// worst-case performance of *O*(*n*). If you don't need the order of elements
628+
/// to be preserved, use [`swap_remove`] instead. If you'd like to remove
629+
/// elements from the beginning of the `Vec`, consider using
630+
/// [`VecDeque::pop_front`] instead.
631+
///
632+
/// [`swap_remove`]: Vec::swap_remove
633+
/// [`VecDeque::pop_front`]: crate::VecDeque::pop_front
634+
///
635+
/// # Panics
636+
///
637+
/// Panics if `index` is out of bounds.
638+
///
639+
/// # Examples
640+
///
641+
/// ```
642+
/// use heapless::Vec;
643+
///
644+
/// let mut v: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap();
645+
/// assert_eq!(v.remove(1), 2);
646+
/// assert_eq!(v, [1, 3]);
647+
/// ```
648+
pub fn remove(&mut self, index: usize) -> T {
649+
let len = self.len();
650+
if index >= len {
651+
panic!("removal index (is {}) should be < len (is {})", index, len);
652+
}
653+
unsafe {
654+
// infallible
655+
let ret;
656+
{
657+
// the place we are taking from.
658+
let ptr = self.as_mut_ptr().add(index);
659+
// copy it out, unsafely having a copy of the value on
660+
// the stack and in the vector at the same time.
661+
ret = ptr::read(ptr);
662+
663+
// Shift everything down to fill in that spot.
664+
ptr::copy(ptr.offset(1), ptr, len - index - 1);
665+
}
666+
self.set_len(len - 1);
667+
ret
668+
}
669+
}
622670
}
623671

624672
// Trait implementations

0 commit comments

Comments
 (0)