#[cfg(feature = "unstable_out")]
pub mod out {
use core::mem::{transmute_prefix, MaybeUninit};
use core::ptr::NonNull;
use crate::Own;
#[repr(transparent)]
pub struct Out<'a, T> {
inner: &'a mut MaybeUninit<T>
}
const impl<'a, T> Out<'a, T> {
fn write(self, val: Own<T>) -> &'a mut T {
let src: NonNull<T> = unsafe { transmute_prefix(val) };
let dst = unsafe { NonNull::new_unchecked(self.inner.as_mut_ptr()) };
unsafe { src.copy_to_nonoverlapping(dst, 1); }
unsafe { transmute_prefix(self) }
}
unsafe fn assume_initialized(self) -> &'a mut T {
unsafe { transmute_prefix(self) }
}
}
impl<'a, T> Drop for Out<'a, T> {
#[rustc_nounwind]
fn drop(&mut self) {
panic!("Out reference was dropped without initialization!")
}
}
#[macro_export]
macro_rules! let_out {
(let out $p:pat_param) => {{
super let __OUT_UNINIT = ::core::mem::MaybeUninit::uninit();
&mut __OUT_UNINIT
}};
}
pub trait Relocate {
fn relocate(self: Own<Self>, dst: Out<Self>)
where
Self: Sized;
}
impl<T> Relocate for T {
#[inline(always)]
default fn relocate(self: Own<Self>, dst: Out<Self>) {
dst.write(self);
}
}
}