rune_alloc/hashbrown/
scopeguard.rs

1// Extracted from the scopeguard crate
2use core::mem::ManuallyDrop;
3use core::ops::{Deref, DerefMut};
4use core::ptr;
5
6pub struct ScopeGuard<T, F>
7where
8    F: FnMut(&mut T),
9{
10    dropfn: F,
11    value: T,
12}
13
14#[inline]
15pub fn guard<T, F>(value: T, dropfn: F) -> ScopeGuard<T, F>
16where
17    F: FnMut(&mut T),
18{
19    ScopeGuard { dropfn, value }
20}
21
22impl<T, F> ScopeGuard<T, F>
23where
24    F: FnMut(&mut T),
25{
26    #[inline]
27    pub fn into_inner(guard: Self) -> T {
28        // Cannot move out of Drop-implementing types, so
29        // ptr::read the value out of a ManuallyDrop<Self>
30        // Don't use mem::forget as that might invalidate value
31        let guard = ManuallyDrop::new(guard);
32        unsafe {
33            let value = ptr::read(&guard.value);
34            // read the closure so that it is dropped
35            let _ = ptr::read(&guard.dropfn);
36            value
37        }
38    }
39}
40
41impl<T, F> Deref for ScopeGuard<T, F>
42where
43    F: FnMut(&mut T),
44{
45    type Target = T;
46    #[inline]
47    fn deref(&self) -> &T {
48        &self.value
49    }
50}
51
52impl<T, F> DerefMut for ScopeGuard<T, F>
53where
54    F: FnMut(&mut T),
55{
56    #[inline]
57    fn deref_mut(&mut self) -> &mut T {
58        &mut self.value
59    }
60}
61
62impl<T, F> Drop for ScopeGuard<T, F>
63where
64    F: FnMut(&mut T),
65{
66    #[inline]
67    fn drop(&mut self) {
68        (self.dropfn)(&mut self.value);
69    }
70}