oxidd_core/util/
on_drop.rs1use std::mem::ManuallyDrop;
2use std::ops::{Deref, DerefMut};
3
4use crate::Manager;
5
6use crate::util::DropWith;
7
8#[derive(Debug)]
12pub struct OnDrop<'a, T, D: FnOnce(&mut T)>(ManuallyDrop<(&'a mut T, D)>);
13
14impl<'a, T, D: FnOnce(&mut T)> OnDrop<'a, T, D> {
15 #[inline(always)]
17 pub fn new(data: &'a mut T, drop_handler: D) -> Self {
18 Self(ManuallyDrop::new((data, drop_handler)))
19 }
20
21 #[inline(always)]
23 pub fn data(&self) -> &T {
24 self.0 .0
25 }
26
27 #[inline(always)]
29 pub fn data_mut(&mut self) -> &mut T {
30 self.0 .0
31 }
32
33 #[inline(always)]
35 pub fn cancel(mut self) -> (&'a mut T, D) {
36 unsafe { ManuallyDrop::take(&mut self.0) }
38 }
39}
40
41impl<T, D: FnOnce(&mut T)> Drop for OnDrop<'_, T, D> {
42 #[inline(always)]
43 fn drop(&mut self) {
44 let (data, handler) = unsafe { ManuallyDrop::take(&mut self.0) };
46 handler(data)
47 }
48}
49
50#[derive(Debug)]
68pub struct AbortOnDrop<'a>(pub &'a str);
69
70impl AbortOnDrop<'_> {
71 #[inline(always)]
75 pub fn defuse(self) {
76 std::mem::forget(self);
77 }
78}
79
80impl Drop for AbortOnDrop<'_> {
81 fn drop(&mut self) {
82 eprintln!("FATAL: {} Aborting.", self.0);
83 std::process::abort();
84 }
85}
86
87pub struct EdgeDropGuard<'a, M: Manager> {
89 pub manager: &'a M,
91 edge: ManuallyDrop<M::Edge>,
92}
93
94impl<'a, M: Manager> EdgeDropGuard<'a, M> {
95 #[inline]
97 pub fn new(manager: &'a M, edge: M::Edge) -> Self {
98 Self {
99 manager,
100 edge: ManuallyDrop::new(edge),
101 }
102 }
103
104 #[inline]
106 pub fn into_edge(mut self) -> M::Edge {
107 let edge = unsafe { ManuallyDrop::take(&mut self.edge) };
109 std::mem::forget(self);
110 edge
111 }
112}
113
114impl<'a, M: Manager> Drop for EdgeDropGuard<'a, M> {
115 #[inline]
116 fn drop(&mut self) {
117 self.manager
119 .drop_edge(unsafe { ManuallyDrop::take(&mut self.edge) });
120 }
121}
122
123impl<'a, M: Manager> Deref for EdgeDropGuard<'a, M> {
124 type Target = M::Edge;
125
126 #[inline]
127 fn deref(&self) -> &Self::Target {
128 &self.edge
129 }
130}
131impl<'a, M: Manager> DerefMut for EdgeDropGuard<'a, M> {
132 #[inline]
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.edge
135 }
136}
137
138pub struct EdgeVecDropGuard<'a, M: Manager> {
140 pub manager: &'a M,
142 vec: Vec<M::Edge>,
143}
144
145impl<'a, M: Manager> EdgeVecDropGuard<'a, M> {
146 #[inline]
148 pub fn new(manager: &'a M, vec: Vec<M::Edge>) -> Self {
149 Self { manager, vec }
150 }
151
152 #[inline]
154 pub fn into_vec(mut self) -> Vec<M::Edge> {
155 std::mem::take(&mut self.vec)
156 }
157}
158
159impl<'a, M: Manager> Drop for EdgeVecDropGuard<'a, M> {
160 #[inline]
161 fn drop(&mut self) {
162 for e in std::mem::take(&mut self.vec) {
163 self.manager.drop_edge(e);
164 }
165 }
166}
167
168impl<'a, M: Manager> Deref for EdgeVecDropGuard<'a, M> {
169 type Target = Vec<M::Edge>;
170
171 #[inline]
172 fn deref(&self) -> &Self::Target {
173 &self.vec
174 }
175}
176impl<'a, M: Manager> DerefMut for EdgeVecDropGuard<'a, M> {
177 #[inline]
178 fn deref_mut(&mut self) -> &mut Self::Target {
179 &mut self.vec
180 }
181}
182
183pub struct InnerNodeDropGuard<'a, M: Manager> {
185 pub manager: &'a M,
187 node: ManuallyDrop<M::InnerNode>,
188}
189
190impl<'a, M: Manager> InnerNodeDropGuard<'a, M> {
191 #[inline]
193 pub fn new(manager: &'a M, node: M::InnerNode) -> Self {
194 Self {
195 manager,
196 node: ManuallyDrop::new(node),
197 }
198 }
199
200 #[inline]
202 pub fn into_node(mut this: Self) -> M::InnerNode {
203 let node = unsafe { ManuallyDrop::take(&mut this.node) };
205 std::mem::forget(this);
206 node
207 }
208}
209
210impl<'a, M: Manager> Drop for InnerNodeDropGuard<'a, M> {
211 #[inline]
212 fn drop(&mut self) {
213 unsafe { ManuallyDrop::take(&mut self.node) }.drop_with(|e| self.manager.drop_edge(e));
215 }
216}
217
218impl<'a, M: Manager> Deref for InnerNodeDropGuard<'a, M> {
219 type Target = M::InnerNode;
220
221 #[inline]
222 fn deref(&self) -> &Self::Target {
223 &self.node
224 }
225}
226impl<'a, M: Manager> DerefMut for InnerNodeDropGuard<'a, M> {
227 #[inline]
228 fn deref_mut(&mut self) -> &mut Self::Target {
229 &mut self.node
230 }
231}