use std::{
mem::ManuallyDrop,
ops::{Deref,DerefMut},
ptr::NonNull,
};
use crate::{
marker_type::NonOwningPhantom,
sabi_types::MovePtr,
utils::Transmuter,
};
#[allow(unused_imports)]
use core_extensions::{prelude::*, utils::transmute_ignore_size};
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, StableAbi)]
pub enum CallReferentDrop {
Yes,
No,
}
#[repr(u8)]
#[derive(Debug,Clone,Copy,PartialEq,Eq,StableAbi)]
pub enum Deallocate{
No,
Yes,
}
pub unsafe trait GetPointerKind:Deref+Sized{
type Kind:PointerKindVariant;
const KIND:PointerKind=<Self::Kind as PointerKindVariant>::VALUE;
}
pub trait PointerKindVariant:Sealed{
const VALUE:PointerKind;
}
use self::sealed::Sealed;
mod sealed{
pub trait Sealed{}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash,StableAbi)]
#[repr(u8)]
pub enum PointerKind{
Reference,
MutReference,
SmartPointer
}
#[allow(non_camel_case_types)]
pub struct PK_Reference;
#[allow(non_camel_case_types)]
pub struct PK_MutReference;
#[allow(non_camel_case_types)]
pub struct PK_SmartPointer;
impl Sealed for PK_Reference{}
impl Sealed for PK_MutReference{}
impl Sealed for PK_SmartPointer{}
impl PointerKindVariant for PK_Reference{
const VALUE:PointerKind=PointerKind::Reference;
}
impl PointerKindVariant for PK_MutReference{
const VALUE:PointerKind=PointerKind::MutReference;
}
impl PointerKindVariant for PK_SmartPointer{
const VALUE:PointerKind=PointerKind::SmartPointer;
}
unsafe impl<'a,T> GetPointerKind for &'a T{
type Kind=PK_Reference;
}
unsafe impl<'a,T> GetPointerKind for &'a mut T{
type Kind=PK_MutReference;
}
pub unsafe trait CanTransmuteElement<T>: GetPointerKind {
type TransmutedPtr: Deref<Target = T>;
}
pub trait TransmuteElement{
unsafe fn transmute_element<T>(self) -> <Self as CanTransmuteElement<T>>::TransmutedPtr
where
Self:CanTransmuteElement<T>,
Self::Target:Sized,
{
transmute_ignore_size::<Self, Self::TransmutedPtr>(self)
}
}
impl<This:?Sized> TransmuteElement for This{}
unsafe impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a T {
type TransmutedPtr = &'a O;
}
unsafe impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a mut T {
type TransmutedPtr = &'a mut O;
}
pub unsafe trait OwnedPointer:Sized+DerefMut+GetPointerKind{
unsafe fn get_move_ptr(this:&mut ManuallyDrop<Self>)->MovePtr<'_,Self::Target>
where
Self::Target:Sized;
unsafe fn drop_allocation(this:&mut ManuallyDrop<Self>);
#[inline]
fn with_move_ptr<F,R>(mut this:ManuallyDrop<Self>,f:F)->R
where
F:FnOnce(MovePtr<'_,Self::Target>)->R,
Self::Target:Sized,
{
unsafe{
let ret=f(Self::get_move_ptr(&mut this));
Self::drop_allocation(&mut this);
ret
}
}
#[inline]
fn in_move_ptr<F,R>(self,f:F)->R
where
F:FnOnce(MovePtr<'_,Self::Target>)->R,
Self::Target:Sized,
{
unsafe{
let mut this=ManuallyDrop::new(self);
let ret=f(Self::get_move_ptr(&mut this));
Self::drop_allocation(&mut this);
ret
}
}
}
pub unsafe trait ImmutableRef: Copy {
type Target;
const TARGET: ImmutableRefTarget<Self, Self::Target> = ImmutableRefTarget::new();
#[inline(always)]
fn to_nonnull(self)->NonNull<Self::Target> {
unsafe{ Transmuter{from: self}.to }
}
#[inline(always)]
unsafe fn from_nonnull(from: NonNull<Self::Target>)->Self{
unsafe{ Transmuter{from}.to }
}
#[inline(always)]
fn to_raw_ptr(self)->*const Self::Target {
unsafe{ Transmuter{from: self}.to }
}
#[inline(always)]
unsafe fn from_raw_ptr(from: *const Self::Target)-> Option<Self> {
unsafe{ Transmuter{from}.to }
}
}
pub type ImmutableRefOut<T> = <T as ImmutableRef>::Target;
unsafe impl<'a, T> ImmutableRef for &'a T {
type Target = T;
#[inline(always)]
#[cfg(miri)]
fn to_raw_ptr(self)->*const Self::Target {
self as _
}
#[inline(always)]
#[cfg(miri)]
unsafe fn from_raw_ptr(from: *const Self::Target)-> Option<Self> {
std::mem::transmute(from)
}
}
pub struct ImmutableRefTarget<T, U>(NonOwningPhantom<(T, U)>);
impl<T, U> Copy for ImmutableRefTarget<T, U> {}
impl<T, U> Clone for ImmutableRefTarget<T, U> {
fn clone(&self)->Self{
*self
}
}
impl<T, U> ImmutableRefTarget<T, U> {
#[inline(always)]
const fn new()->Self{
Self(NonOwningPhantom::DEFAULT)
}
}