| 1 | use core::marker::PhantomData; |
| 2 | use core::ptr::{self, NonNull, drop_in_place}; |
| 3 | use core::slice::{self}; |
| 4 | |
| 5 | use crate::alloc::Global; |
| 6 | use crate::raw_vec::RawVec; |
| 7 | |
| 8 | // A helper struct for in-place iteration that drops the destination slice of iteration, |
| 9 | // i.e. the head. The source slice (the tail) is dropped by IntoIter. |
| 10 | pub(super) struct InPlaceDrop<T> { |
| 11 | pub(super) inner: *mut T, |
| 12 | pub(super) dst: *mut T, |
| 13 | } |
| 14 | |
| 15 | impl<T> InPlaceDrop<T> { |
| 16 | fn len(&self) -> usize { |
| 17 | unsafe { self.dst.offset_from_unsigned(self.inner) } |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | impl<T> Drop for InPlaceDrop<T> { |
| 22 | #[inline ] |
| 23 | fn drop(&mut self) { |
| 24 | unsafe { |
| 25 | ptr::drop_in_place(to_drop:slice::from_raw_parts_mut(self.inner, self.len())); |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | // A helper struct for in-place collection that drops the destination items together with |
| 31 | // the source allocation - i.e. before the reallocation happened - to avoid leaking them |
| 32 | // if some other destructor panics. |
| 33 | pub(super) struct InPlaceDstDataSrcBufDrop<Src, Dest> { |
| 34 | pub(super) ptr: NonNull<Dest>, |
| 35 | pub(super) len: usize, |
| 36 | pub(super) src_cap: usize, |
| 37 | pub(super) src: PhantomData<Src>, |
| 38 | } |
| 39 | |
| 40 | impl<Src, Dest> Drop for InPlaceDstDataSrcBufDrop<Src, Dest> { |
| 41 | #[inline ] |
| 42 | fn drop(&mut self) { |
| 43 | unsafe { |
| 44 | let _drop_allocation: RawVec = |
| 45 | RawVec::<Src>::from_nonnull_in(self.ptr.cast::<Src>(), self.src_cap, alloc:Global); |
| 46 | drop_in_place(to_drop:core::ptr::slice_from_raw_parts_mut::<Dest>(self.ptr.as_ptr(), self.len)); |
| 47 | }; |
| 48 | } |
| 49 | } |
| 50 | |