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