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