use core::{
cell::{Cell, UnsafeCell},
mem::{transmute, ManuallyDrop, MaybeUninit},
ptr::read,
};
use crate::{Borrow, Destructure, Move, Restructure};
unsafe impl<T> Destructure for MaybeUninit<T> {
type Underlying = T;
type Destructuring = Move;
fn underlying(&mut self) -> *mut Self::Underlying {
self.as_ptr() as *mut Self::Underlying
}
}
unsafe impl<T, U> Restructure<U> for MaybeUninit<T> {
type Restructured = MaybeUninit<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { read(ptr.cast()) }
}
}
unsafe impl<T> Destructure for &MaybeUninit<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
self.as_ptr() as *mut Self::Underlying
}
}
unsafe impl<'a, T, U: 'a> Restructure<U> for &'a MaybeUninit<T> {
type Restructured = &'a MaybeUninit<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { &*ptr.cast() }
}
}
unsafe impl<T> Destructure for &mut MaybeUninit<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
MaybeUninit::as_mut_ptr(self)
}
}
unsafe impl<'a, T, U: 'a> Restructure<U> for &'a mut MaybeUninit<T> {
type Restructured = &'a mut MaybeUninit<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { &mut *ptr.cast() }
}
}
unsafe impl<T> Destructure for Cell<T> {
type Underlying = T;
type Destructuring = Move;
fn underlying(&mut self) -> *mut Self::Underlying {
self.as_ptr()
}
}
unsafe impl<T, U> Restructure<U> for Cell<T> {
type Restructured = Cell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { read(ptr.cast_const().cast()) }
}
}
unsafe impl<T: ?Sized> Destructure for &Cell<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
self.as_ptr()
}
}
unsafe impl<'a, T: ?Sized, U: 'a + ?Sized> Restructure<U> for &'a Cell<T> {
type Restructured = &'a Cell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *const Cell<U>>(ptr) };
unsafe { &*ptr }
}
}
unsafe impl<T: ?Sized> Destructure for &mut Cell<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
self.as_ptr()
}
}
unsafe impl<'a, T: ?Sized, U: 'a + ?Sized> Restructure<U> for &'a mut Cell<T> {
type Restructured = &'a mut Cell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *mut Cell<U>>(ptr) };
unsafe { &mut *ptr }
}
}
unsafe impl<T> Destructure for UnsafeCell<T> {
type Underlying = T;
type Destructuring = Move;
fn underlying(&mut self) -> *mut Self::Underlying {
self.get()
}
}
unsafe impl<T, U> Restructure<U> for UnsafeCell<T> {
type Restructured = UnsafeCell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { read(ptr.cast()) }
}
}
unsafe impl<T: ?Sized> Destructure for &UnsafeCell<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
self.get()
}
}
unsafe impl<'a, T, U> Restructure<U> for &'a UnsafeCell<T>
where
T: ?Sized,
U: 'a + ?Sized,
{
type Restructured = &'a UnsafeCell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *const UnsafeCell<U>>(ptr) };
unsafe { &*ptr }
}
}
unsafe impl<T: ?Sized> Destructure for &mut UnsafeCell<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
self.get()
}
}
unsafe impl<'a, T, U> Restructure<U> for &'a mut UnsafeCell<T>
where
T: ?Sized,
U: 'a + ?Sized,
{
type Restructured = &'a mut UnsafeCell<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *mut UnsafeCell<U>>(ptr) };
unsafe { &mut *ptr }
}
}
unsafe impl<T> Destructure for ManuallyDrop<T> {
type Underlying = T;
type Destructuring = Move;
fn underlying(&mut self) -> *mut Self::Underlying {
&mut **self as *mut Self::Underlying
}
}
unsafe impl<T, U> Restructure<U> for ManuallyDrop<T> {
type Restructured = ManuallyDrop<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
unsafe { read(ptr.cast()) }
}
}
unsafe impl<T: ?Sized> Destructure for &ManuallyDrop<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
(&***self as *const Self::Underlying).cast_mut()
}
}
unsafe impl<'a, T, U> Restructure<U> for &'a ManuallyDrop<T>
where
T: ?Sized,
U: 'a + ?Sized,
{
type Restructured = &'a ManuallyDrop<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *const ManuallyDrop<U>>(ptr) };
unsafe { &*ptr }
}
}
unsafe impl<T: ?Sized> Destructure for &mut ManuallyDrop<T> {
type Underlying = T;
type Destructuring = Borrow;
fn underlying(&mut self) -> *mut Self::Underlying {
&mut ***self as *mut Self::Underlying
}
}
unsafe impl<'a, T, U> Restructure<U> for &'a mut ManuallyDrop<T>
where
T: ?Sized,
U: 'a + ?Sized,
{
type Restructured = &'a mut ManuallyDrop<U>;
unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
let ptr = unsafe { transmute::<*mut U, *mut ManuallyDrop<U>>(ptr) };
unsafe { &mut *ptr }
}
}