#![doc = include_str!("../README.md")]
use core::mem;
use std::{hint::unreachable_unchecked, process};
#[inline(always)]
pub unsafe fn extend_ref<'a, T: 'a>(target: &T) -> &'a T {
mem::transmute::<&T, &'a T>(target)
}
#[inline(always)]
pub unsafe fn extend_mut<'a, T: 'a>(target: &mut T) -> &'a mut T {
mem::transmute::<&mut T, &'a mut T>(target)
}
#[doc(hidden)]
#[inline(always)]
pub fn run_abort_guarded<F: FnOnce()>(func: F) -> ! {
struct AbortGuard;
impl Drop for AbortGuard {
fn drop(&mut self) {
process::abort();
}
}
{
let _guard = AbortGuard;
func();
}
unsafe { unreachable_unchecked() }
}
#[macro_export]
macro_rules! ref_extended {
(|$(& $($var: ident)+ ),*| $body: expr) => {
::ref_extended::run_abort_guarded(move || {
$(let ::ref_extended::extract_ref_name!($($var)*) = unsafe { ::ref_extended::extend_lifetime!($($var)*) };)*
{
$body
}
})
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! extract_ref_name {
($name: ident) => {
$name
};
(mut $name: ident) => {
$name
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! extend_lifetime {
($name: ident) => {
::ref_extended::extend_ref(&$name)
};
(mut $name: ident) => {
::ref_extended::extend_mut(&mut $name)
};
}