blob: 6dc56a5b480424b4e625c9b96f3709d9c4d9a9f0 [file] [log] [blame]
use crate::marker::Unpin;
use core::{
fmt,
ops::{Deref, DerefMut},
};
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct Pin<P> {
pointer: P,
}
impl<P: Deref<Target = T>, T: Unpin> Pin<P> {
#[inline(always)]
pub fn new(pointer: P) -> Pin<P> {
unsafe { Pin::new_unchecked(pointer) }
}
}
impl<P: Deref> Pin<P> {
#[inline(always)]
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
Pin { pointer }
}
#[inline(always)]
pub fn as_ref(&self) -> Pin<&P::Target> {
unsafe { Pin::new_unchecked(&*self.pointer) }
}
}
impl<P: DerefMut> Pin<P> {
#[inline(always)]
pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
unsafe { Pin::new_unchecked(&mut *self.pointer) }
}
#[inline(always)]
pub fn set(&mut self, value: P::Target)
where
P::Target: Sized,
{
*(self.pointer) = value;
}
}
impl<'a, T: ?Sized> Pin<&'a T> {
pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>
where
U: ?Sized,
F: FnOnce(&T) -> &U,
{
let pointer = &*self.pointer;
let new_pointer = func(pointer);
Pin::new_unchecked(new_pointer)
}
#[inline(always)]
pub fn get_ref(self) -> &'a T {
self.pointer
}
}
impl<'a, T: ?Sized> Pin<&'a mut T> {
#[inline(always)]
pub fn into_ref(self) -> Pin<&'a T> {
Pin {
pointer: self.pointer,
}
}
#[inline(always)]
pub fn get_mut(self) -> &'a mut T
where
T: Unpin,
{
self.pointer
}
#[inline(always)]
pub unsafe fn get_unchecked_mut(self) -> &'a mut T {
self.pointer
}
pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
where
U: ?Sized,
F: FnOnce(&mut T) -> &mut U,
{
let pointer = Pin::get_unchecked_mut(self);
let new_pointer = func(pointer);
Pin::new_unchecked(new_pointer)
}
}
impl<P: Deref> Deref for Pin<P> {
type Target = P::Target;
fn deref(&self) -> &P::Target {
Pin::get_ref(Pin::as_ref(self))
}
}
impl<P: DerefMut<Target = T>, T: Unpin> DerefMut for Pin<P> {
fn deref_mut(&mut self) -> &mut P::Target {
Pin::get_mut(Pin::as_mut(self))
}
}
impl<P: fmt::Debug> fmt::Debug for Pin<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.pointer, f)
}
}
impl<P: fmt::Display> fmt::Display for Pin<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.pointer, f)
}
}
impl<P: fmt::Pointer> fmt::Pointer for Pin<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&self.pointer, f)
}
}