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)]
26pub struct AbortOnDrop<'a>(pub &'a str);
27
28impl AbortOnDrop<'_> {
29 #[inline(always)]
33 pub fn defuse(self) {
34 std::mem::forget(self);
35 }
36}
37
38impl Drop for AbortOnDrop<'_> {
39 fn drop(&mut self) {
40 eprintln!("FATAL: {} Aborting.", self.0);
41 std::process::abort();
42 }
43}
44
45pub struct EdgeDropGuard<'a, M: Manager> {
47 pub manager: &'a M,
49 edge: ManuallyDrop<M::Edge>,
50}
51
52impl<'a, M: Manager> EdgeDropGuard<'a, M> {
53 #[inline]
55 pub fn new(manager: &'a M, edge: M::Edge) -> Self {
56 Self {
57 manager,
58 edge: ManuallyDrop::new(edge),
59 }
60 }
61
62 #[inline]
64 pub fn into_edge(mut self) -> M::Edge {
65 let edge = unsafe { ManuallyDrop::take(&mut self.edge) };
67 std::mem::forget(self);
68 edge
69 }
70}
71
72impl<'a, M: Manager> Drop for EdgeDropGuard<'a, M> {
73 #[inline]
74 fn drop(&mut self) {
75 self.manager
77 .drop_edge(unsafe { ManuallyDrop::take(&mut self.edge) });
78 }
79}
80
81impl<'a, M: Manager> Deref for EdgeDropGuard<'a, M> {
82 type Target = M::Edge;
83
84 #[inline]
85 fn deref(&self) -> &Self::Target {
86 &self.edge
87 }
88}
89impl<'a, M: Manager> DerefMut for EdgeDropGuard<'a, M> {
90 #[inline]
91 fn deref_mut(&mut self) -> &mut Self::Target {
92 &mut self.edge
93 }
94}
95
96pub struct EdgeVecDropGuard<'a, M: Manager> {
98 pub manager: &'a M,
100 vec: Vec<M::Edge>,
101}
102
103impl<'a, M: Manager> EdgeVecDropGuard<'a, M> {
104 #[inline]
106 pub fn new(manager: &'a M, vec: Vec<M::Edge>) -> Self {
107 Self { manager, vec }
108 }
109
110 #[inline]
112 pub fn into_vec(mut self) -> Vec<M::Edge> {
113 std::mem::take(&mut self.vec)
114 }
115}
116
117impl<'a, M: Manager> Drop for EdgeVecDropGuard<'a, M> {
118 #[inline]
119 fn drop(&mut self) {
120 for e in std::mem::take(&mut self.vec) {
121 self.manager.drop_edge(e);
122 }
123 }
124}
125
126impl<'a, M: Manager> Deref for EdgeVecDropGuard<'a, M> {
127 type Target = Vec<M::Edge>;
128
129 #[inline]
130 fn deref(&self) -> &Self::Target {
131 &self.vec
132 }
133}
134impl<'a, M: Manager> DerefMut for EdgeVecDropGuard<'a, M> {
135 #[inline]
136 fn deref_mut(&mut self) -> &mut Self::Target {
137 &mut self.vec
138 }
139}
140
141pub struct InnerNodeDropGuard<'a, M: Manager> {
143 pub manager: &'a M,
145 node: ManuallyDrop<M::InnerNode>,
146}
147
148impl<'a, M: Manager> InnerNodeDropGuard<'a, M> {
149 #[inline]
151 pub fn new(manager: &'a M, node: M::InnerNode) -> Self {
152 Self {
153 manager,
154 node: ManuallyDrop::new(node),
155 }
156 }
157
158 #[inline]
160 pub fn into_node(mut this: Self) -> M::InnerNode {
161 let node = unsafe { ManuallyDrop::take(&mut this.node) };
163 std::mem::forget(this);
164 node
165 }
166}
167
168impl<'a, M: Manager> Drop for InnerNodeDropGuard<'a, M> {
169 #[inline]
170 fn drop(&mut self) {
171 unsafe { ManuallyDrop::take(&mut self.node) }.drop_with(|e| self.manager.drop_edge(e));
173 }
174}
175
176impl<'a, M: Manager> Deref for InnerNodeDropGuard<'a, M> {
177 type Target = M::InnerNode;
178
179 #[inline]
180 fn deref(&self) -> &Self::Target {
181 &self.node
182 }
183}
184impl<'a, M: Manager> DerefMut for InnerNodeDropGuard<'a, M> {
185 #[inline]
186 fn deref_mut(&mut self) -> &mut Self::Target {
187 &mut self.node
188 }
189}