use core::{
future::Future,
panic::{RefUnwindSafe, UnwindSafe},
pin::Pin,
task,
};
use super::{PointerDeref, PointerDerefMut, PointerIntoInner, PointerLike, PointerPinUnforgotten};
pub const unsafe fn fn_drop<P: PointerLike>(
) -> impl Fn(*mut ()) + Copy + Send + Sync + UnwindSafe + RefUnwindSafe + Unpin + 'static {
|erased_ptr| drop(unsafe { P::from_ptr(erased_ptr as *mut P::Pointee) })
}
pub const unsafe fn fn_call<P, I, O>(
) -> impl Fn(*const (), I) -> O + Copy + Send + Sync + UnwindSafe + RefUnwindSafe + Unpin + 'static
where
P: PointerDeref,
P::Pointee: Fn(I) -> O,
{
|erased_ptr, input| unsafe { (*(erased_ptr as *const P::Pointee))(input) }
}
pub const unsafe fn fn_call_mut<P, I, O>(
) -> impl Fn(*mut (), I) -> O + Copy + Send + Sync + UnwindSafe + RefUnwindSafe + Unpin + 'static
where
P: PointerDerefMut,
P::Pointee: FnMut(I) -> O,
{
|erased_ptr, input| unsafe { (*(erased_ptr as *mut P::Pointee))(input) }
}
pub const unsafe fn fn_call_once<P, I, O>(
) -> impl Fn(*mut (), I) -> O + Copy + Send + Sync + UnwindSafe + RefUnwindSafe + Unpin + 'static
where
P: PointerIntoInner,
P::Pointee: FnOnce(I) -> O,
{
|erased_ptr, input| (unsafe { P::from_ptr(erased_ptr as *mut P::Pointee) }).into_inner()(input)
}
pub const unsafe fn fn_poll_unforgotten<P, O>(
) -> impl Fn(*mut (), &mut task::Context<'_>) -> task::Poll<O>
+ Copy
+ Send
+ Sync
+ UnwindSafe
+ RefUnwindSafe
+ Unpin
+ 'static
where
P: PointerPinUnforgotten,
P::Pointee: Future<Output = O>,
{
|erased_ptr, cx| unsafe { (Pin::new_unchecked(&mut *(erased_ptr as *mut P::Pointee))).poll(cx) }
}