1use core::marker::PhantomData;
2use core::ptr::NonNull;
3use core::ptr::{self, drop_in_place};
4use core::slice::{self};
5
6use crate::alloc::Global;
7use 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.
11pub(super) struct InPlaceDrop<T> {
12 pub(super) inner: *mut T,
13 pub(super) dst: *mut T,
14}
15
16impl<T> InPlaceDrop<T> {
17 fn len(&self) -> usize {
18 unsafe { self.dst.sub_ptr(self.inner) }
19 }
20}
21
22impl<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.
34pub(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
41impl<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