Use ptr::drop_in_place in VecDeque truncate

This commit is contained in:
Charles Gleason 2019-10-28 17:53:03 -04:00
parent 18c5f4e7f2
commit aa893535c4

View file

@ -856,8 +856,31 @@ impl<T> VecDeque<T> {
/// ```
#[stable(feature = "deque_extras", since = "1.16.0")]
pub fn truncate(&mut self, len: usize) {
for _ in len..self.len() {
self.pop_back();
// Safe because:
//
// * Any slice passed to `drop_in_place` is valid; the second case has
// `len <= front.len()` and returning on `len > self.len()` ensures
// `begin <= back.len()` in the first case
// * The head of the VecDeque is moved before calling `drop_in_place`,
// so no value is dropped twice if `drop_in_place` panics
unsafe {
if len > self.len() {
return;
}
let num_dropped = self.len() - len;
let (front, back) = self.as_mut_slices();
if len > front.len() {
let begin = len - front.len();
let drop_back = back.get_unchecked_mut(begin..) as *mut _;
self.head = self.wrap_sub(self.head, num_dropped);
ptr::drop_in_place(drop_back);
} else {
let drop_back = back as *mut _;
let drop_front = front.get_unchecked_mut(len..) as *mut _;
self.head = self.wrap_sub(self.head, num_dropped);
ptr::drop_in_place(drop_front);
ptr::drop_in_place(drop_back);
}
}
}