Guarantee vec.clear/truncate is O(1) for trivial types
This commit is contained in:
parent
74d5c70b17
commit
223600ac2c
1 changed files with 17 additions and 13 deletions
|
@ -685,21 +685,25 @@ impl<T> Vec<T> {
|
||||||
/// [`drain`]: #method.drain
|
/// [`drain`]: #method.drain
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn truncate(&mut self, len: usize) {
|
pub fn truncate(&mut self, len: usize) {
|
||||||
let current_len = self.len;
|
if mem::needs_drop::<T>() {
|
||||||
unsafe {
|
let current_len = self.len;
|
||||||
let mut ptr = self.as_mut_ptr().add(self.len);
|
unsafe {
|
||||||
// Set the final length at the end, keeping in mind that
|
let mut ptr = self.as_mut_ptr().add(self.len);
|
||||||
// dropping an element might panic. Works around a missed
|
// Set the final length at the end, keeping in mind that
|
||||||
// optimization, as seen in the following issue:
|
// dropping an element might panic. Works around a missed
|
||||||
// https://github.com/rust-lang/rust/issues/51802
|
// optimization, as seen in the following issue:
|
||||||
let mut local_len = SetLenOnDrop::new(&mut self.len);
|
// https://github.com/rust-lang/rust/issues/51802
|
||||||
|
let mut local_len = SetLenOnDrop::new(&mut self.len);
|
||||||
|
|
||||||
// drop any extra elements
|
// drop any extra elements
|
||||||
for _ in len..current_len {
|
for _ in len..current_len {
|
||||||
local_len.decrement_len(1);
|
local_len.decrement_len(1);
|
||||||
ptr = ptr.offset(-1);
|
ptr = ptr.offset(-1);
|
||||||
ptr::drop_in_place(ptr);
|
ptr::drop_in_place(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if len <= self.len {
|
||||||
|
self.len = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue