use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use crate::Manager;
use crate::util::DropWith;
#[derive(Debug)]
pub struct OnDrop<'a, T, D: FnOnce(&mut T)>(ManuallyDrop<(&'a mut T, D)>);
impl<'a, T, D: FnOnce(&mut T)> OnDrop<'a, T, D> {
#[inline(always)]
pub fn new(data: &'a mut T, drop_handler: D) -> Self {
Self(ManuallyDrop::new((data, drop_handler)))
}
#[inline(always)]
pub fn data(&self) -> &T {
self.0 .0
}
#[inline(always)]
pub fn data_mut(&mut self) -> &mut T {
self.0 .0
}
#[inline(always)]
pub fn cancel(mut self) -> (&'a mut T, D) {
unsafe { ManuallyDrop::take(&mut self.0) }
}
}
impl<T, D: FnOnce(&mut T)> Drop for OnDrop<'_, T, D> {
#[inline(always)]
fn drop(&mut self) {
let (data, handler) = unsafe { ManuallyDrop::take(&mut self.0) };
handler(data)
}
}
#[derive(Debug)]
pub struct AbortOnDrop<'a>(pub &'a str);
impl AbortOnDrop<'_> {
#[inline(always)]
pub fn defuse(self) {
std::mem::forget(self);
}
}
impl Drop for AbortOnDrop<'_> {
fn drop(&mut self) {
eprintln!("FATAL: {} Aborting.", self.0);
std::process::abort();
}
}
pub struct EdgeDropGuard<'a, M: Manager> {
pub manager: &'a M,
edge: ManuallyDrop<M::Edge>,
}
impl<'a, M: Manager> EdgeDropGuard<'a, M> {
#[inline]
pub fn new(manager: &'a M, edge: M::Edge) -> Self {
Self {
manager,
edge: ManuallyDrop::new(edge),
}
}
#[inline]
pub fn into_edge(mut self) -> M::Edge {
let edge = unsafe { ManuallyDrop::take(&mut self.edge) };
std::mem::forget(self);
edge
}
}
impl<'a, M: Manager> Drop for EdgeDropGuard<'a, M> {
#[inline]
fn drop(&mut self) {
self.manager
.drop_edge(unsafe { ManuallyDrop::take(&mut self.edge) });
}
}
impl<'a, M: Manager> Deref for EdgeDropGuard<'a, M> {
type Target = M::Edge;
#[inline]
fn deref(&self) -> &Self::Target {
&self.edge
}
}
impl<'a, M: Manager> DerefMut for EdgeDropGuard<'a, M> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.edge
}
}
pub struct EdgeVecDropGuard<'a, M: Manager> {
pub manager: &'a M,
vec: Vec<M::Edge>,
}
impl<'a, M: Manager> EdgeVecDropGuard<'a, M> {
#[inline]
pub fn new(manager: &'a M, vec: Vec<M::Edge>) -> Self {
Self { manager, vec }
}
#[inline]
pub fn into_vec(mut self) -> Vec<M::Edge> {
std::mem::take(&mut self.vec)
}
}
impl<'a, M: Manager> Drop for EdgeVecDropGuard<'a, M> {
#[inline]
fn drop(&mut self) {
for e in std::mem::take(&mut self.vec) {
self.manager.drop_edge(e);
}
}
}
impl<'a, M: Manager> Deref for EdgeVecDropGuard<'a, M> {
type Target = Vec<M::Edge>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.vec
}
}
impl<'a, M: Manager> DerefMut for EdgeVecDropGuard<'a, M> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.vec
}
}
pub struct InnerNodeDropGuard<'a, M: Manager> {
pub manager: &'a M,
node: ManuallyDrop<M::InnerNode>,
}
impl<'a, M: Manager> InnerNodeDropGuard<'a, M> {
#[inline]
pub fn new(manager: &'a M, node: M::InnerNode) -> Self {
Self {
manager,
node: ManuallyDrop::new(node),
}
}
#[inline]
pub fn into_node(mut this: Self) -> M::InnerNode {
let node = unsafe { ManuallyDrop::take(&mut this.node) };
std::mem::forget(this);
node
}
}
impl<'a, M: Manager> Drop for InnerNodeDropGuard<'a, M> {
#[inline]
fn drop(&mut self) {
unsafe { ManuallyDrop::take(&mut self.node) }.drop_with(|e| self.manager.drop_edge(e));
}
}
impl<'a, M: Manager> Deref for InnerNodeDropGuard<'a, M> {
type Target = M::InnerNode;
#[inline]
fn deref(&self) -> &Self::Target {
&self.node
}
}
impl<'a, M: Manager> DerefMut for InnerNodeDropGuard<'a, M> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.node
}
}