InPlaceDstBufDrop holds onto the allocation before the shrinking happens which means it must deallocate the destination elements but the source allocation.
49 lines
1.4 KiB
Rust
49 lines
1.4 KiB
Rust
use core::marker::PhantomData;
|
|
use core::ptr::{self, drop_in_place};
|
|
use core::slice::{self};
|
|
|
|
use crate::alloc::Global;
|
|
use crate::raw_vec::RawVec;
|
|
|
|
// A helper struct for in-place iteration that drops the destination slice of iteration,
|
|
// i.e. the head. The source slice (the tail) is dropped by IntoIter.
|
|
pub(super) struct InPlaceDrop<T> {
|
|
pub(super) inner: *mut T,
|
|
pub(super) dst: *mut T,
|
|
}
|
|
|
|
impl<T> InPlaceDrop<T> {
|
|
fn len(&self) -> usize {
|
|
unsafe { self.dst.sub_ptr(self.inner) }
|
|
}
|
|
}
|
|
|
|
impl<T> Drop for InPlaceDrop<T> {
|
|
#[inline]
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
ptr::drop_in_place(slice::from_raw_parts_mut(self.inner, self.len()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// A helper struct for in-place collection that drops the destination items together with
|
|
// the source allocation - i.e. before the reallocation happened - to avoid leaking them
|
|
// if some other destructor panics.
|
|
pub(super) struct InPlaceDstDataSrcBufDrop<Src, Dest> {
|
|
pub(super) ptr: *mut Dest,
|
|
pub(super) len: usize,
|
|
pub(super) src_cap: usize,
|
|
pub(super) src: PhantomData<Src>,
|
|
}
|
|
|
|
impl<Src, Dest> Drop for InPlaceDstDataSrcBufDrop<Src, Dest> {
|
|
#[inline]
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
let _drop_allocation =
|
|
RawVec::<Src>::from_raw_parts_in(self.ptr.cast::<Src>(), self.src_cap, Global);
|
|
drop_in_place(core::ptr::slice_from_raw_parts_mut::<Dest>(self.ptr, self.len));
|
|
};
|
|
}
|
|
}
|