1use std::mem::{ManuallyDrop, forget};
5use std::ops::{Deref, DerefMut};
6
7pub(crate) struct ExitGuard<T, F: FnOnce(T)> {
9 drop_callback: ManuallyDrop<(T, F)>,
10}
11
12impl<T, F: FnOnce(T)> ExitGuard<T, F> {
13 #[inline]
15 pub(crate) const fn new(captured: T, drop_callback: F) -> Self {
16 Self {
17 drop_callback: ManuallyDrop::new((captured, drop_callback)),
18 }
19 }
20
21 #[inline]
23 pub(crate) fn forget(mut self) {
24 unsafe {
25 ManuallyDrop::drop(&mut self.drop_callback);
26 }
27 forget(self);
28 }
29}
30
31impl<T, F: FnOnce(T)> Drop for ExitGuard<T, F> {
32 #[inline]
33 fn drop(&mut self) {
34 let (c, f) = unsafe { ManuallyDrop::take(&mut self.drop_callback) };
35 f(c);
36 }
37}
38
39impl<T, F: FnOnce(T)> Deref for ExitGuard<T, F> {
40 type Target = T;
41
42 #[inline]
43 fn deref(&self) -> &Self::Target {
44 &self.drop_callback.0
45 }
46}
47
48impl<T, F: FnOnce(T)> DerefMut for ExitGuard<T, F> {
49 #[inline]
50 fn deref_mut(&mut self) -> &mut Self::Target {
51 &mut self.drop_callback.0
52 }
53}