The source of Vec::split_off
use ptr::copy_nonoverlapping
to split a vector into two:
pub fn split_off(&mut self, at: usize) -> Self
where
A: Clone,
{
#[cold]
#[inline(never)]
fn assert_failed(at: usize, len: usize) -> ! {
panic!("`at` split index (is {at}) should be <= len (is {len})");
}
if at > self.len() {
assert_failed(at, self.len());
}
if at == 0 {
// the new vector can take over the original buffer and avoid the copy
return mem::replace(
self,
Vec::with_capacity_in(self.capacity(), self.allocator().clone()),
);
}
let other_len = self.len - at;
let mut other = Vec::with_capacity_in(other_len, self.allocator().clone());
// Unsafely `set_len` and copy items to `other`.
unsafe {
self.set_len(at);
other.set_len(other_len);
ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());
}
other
}
which assume T
must be Copy
, seems quite strange.
Are there any reason that the split_off
not perform in-place?
Is it something related to the memory allocator?