#![forbid(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(coerce_unsized, unsize))]
#[cfg(test)]
mod tests;
use core::mem::MaybeUninit;
use core::marker::PhantomData;
#[derive(Debug)]
#[repr(transparent)]
pub struct Out<'a, T: ?Sized>(*mut T, PhantomData<&'a mut T>);
#[inline(always)]
pub fn write<T>(ptr: &mut T, value: T) {
Out::from_mut(ptr).set(value)
}
impl<'a, T> Out<'a, T> {
#[inline(always)]
pub fn from_maybe_uninit(maybe_uninit: &mut MaybeUninit<T>) -> Out<'_, T> {
Out(maybe_uninit.as_mut_ptr(), PhantomData)
}
}
impl<'a, T: ?Sized> Out<'a, T> {
#[inline(always)]
pub fn from_mut(value: &'a mut T) -> Self {
unsafe { Self::from_raw(value) }
}
#[inline(always)]
pub unsafe fn from_raw(ptr: *mut T) -> Out<'a, T> {
Self(ptr, PhantomData)
}
#[inline(always)]
pub fn borrow(&mut self) -> Out<'_, T> { Out(self.0, PhantomData) }
#[inline(always)]
pub fn into_raw(self) -> *mut T { self.0 }
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.0
}
}
impl<'a, T> Out<'a, T> {
pub fn set(&mut self, value: T) { unsafe { std::ptr::write(self.0, value) } }
}
pub trait OutMethod {
#[inline(always)]
fn out(&mut self) -> Out<'_, Self> { Out::from_mut(self) }
}
impl<T: ?Sized> OutMethod for T {}
impl<'a, T: ?Sized> From<&'a mut T> for Out<'a, T> {
#[inline(always)]
fn from(ptr: &'a mut T) -> Self {
Self::from_mut(ptr)
}
}
impl<'a, T> From<&'a mut MaybeUninit<T>> for Out<'a, T> {
#[inline(always)]
fn from(ptr: &'a mut MaybeUninit<T>) -> Self {
Self::from_maybe_uninit(ptr)
}
}
#[cfg(feature = "nightly")]
mod nightly {
use std::ops::CoerceUnsized;
use std::marker::Unsize;
use super::*;
impl<'a, T: Unsize<U>, U: ?Sized> CoerceUnsized<Out<'a, U>> for Out<'a, T> {}
}