use core::mem;
pub fn lift<F, R>(root: R, fun: F) -> R
where
F: for<'a> FnOnce(&'a R) -> &'a mut R,
{
let slot = fun(&root) as *mut R;
debug_assert_ne!(slot as *const _, &root as *const _);
mem::replace(unsafe { &mut *slot }, root)
}
pub fn lift_with<F, E, R>(root: R, extra: &E, fun: F) -> R
where
F: for<'a> FnOnce(&'a R, &'a E) -> &'a mut R,
{
let slot = fun(&root, extra) as *mut R;
debug_assert_ne!(slot as *const _, &root as *const _);
mem::replace(unsafe { &mut *slot }, root)
}
pub fn lift_with_mut<F, E, R>(root: R, extra: &mut E, fun: F) -> R
where
F: for<'a> FnOnce(&'a R, &'a mut E) -> &'a mut R,
{
let slot = fun(&root, extra) as *mut R;
debug_assert_ne!(slot as *const _, &root as *const _);
mem::replace(unsafe { &mut *slot }, root)
}