1 | use core::marker::PhantomData; |
2 | use core::ptr::{self, 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.sub_ptr(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: *mut 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_raw_parts_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, self.len)); |
47 | }; |
48 | } |
49 | } |
50 | |