use std::borrow::Cow;
use std::ffi::{CString, OsString};
use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use crate::helper::unsigned::{Succ, Unsigned, Zero};
pub unsafe trait DerefPtr: Deref {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target;
}
unsafe impl<T: ?Sized> DerefPtr for &T {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (*this) as *const T as *mut T }
}
}
unsafe impl<T: ?Sized> DerefPtr for &mut T {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { *this }
}
}
unsafe impl<T: ?Sized> DerefPtr for Box<T> {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (&*this).deref() as *const T as *mut T }
}
}
unsafe impl<T: ?Sized> DerefPtr for Rc<T> {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { Rc::as_ptr(&*this) as *mut T }
}
}
unsafe impl<T: ?Sized> DerefPtr for Arc<T> {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { Arc::as_ptr(&*this) as *mut T }
}
}
unsafe impl<'a, B: ToOwned + ?Sized> DerefPtr for Cow<'a, B> {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (*this).deref() as *const B as *mut B }
}
}
unsafe impl<T> DerefPtr for Vec<T> {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe {
let vec = &*this;
std::ptr::slice_from_raw_parts_mut(vec.as_ptr() as *mut T, vec.len())
}
}
}
unsafe impl DerefPtr for String {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe {
let s = &*this;
std::mem::transmute::<*mut [u8], *mut str>(std::ptr::slice_from_raw_parts_mut(
s.as_ptr() as *mut u8,
s.len(),
))
}
}
}
unsafe impl DerefPtr for OsString {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (&*this).deref() as *const _ as *mut _ }
}
}
unsafe impl DerefPtr for CString {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (&*this).deref() as *const _ as *mut _ }
}
}
unsafe impl DerefPtr for PathBuf {
unsafe fn deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { (&*this).deref() as *const _ as *mut _ }
}
}
pub trait AsDeref<N: Unsigned> {
type Target: ?Sized;
fn as_deref(&self) -> &Self::Target;
unsafe fn as_deref_ptr(this: *mut Self) -> *mut Self::Target;
}
pub trait AsDerefMut<N: Unsigned>: AsDeref<N> {
fn as_deref_mut(&mut self) -> &mut Self::Target;
}
impl<T: ?Sized> AsDeref<Zero> for T {
type Target = T;
fn as_deref(&self) -> &T {
self
}
unsafe fn as_deref_ptr(this: *mut Self) -> *mut Self::Target {
this
}
}
impl<T: ?Sized> AsDerefMut<Zero> for T {
fn as_deref_mut(&mut self) -> &mut T {
self
}
}
impl<T: AsDeref<N, Target: DerefPtr> + ?Sized, N: Unsigned> AsDeref<Succ<N>> for T {
type Target = <T::Target as Deref>::Target;
fn as_deref(&self) -> &Self::Target {
self.as_deref().deref()
}
unsafe fn as_deref_ptr(this: *mut Self) -> *mut Self::Target {
unsafe { DerefPtr::deref_ptr(AsDeref::<N>::as_deref_ptr(this)) }
}
}
impl<T: AsDerefMut<N, Target: DerefMut + DerefPtr> + ?Sized, N: Unsigned> AsDerefMut<Succ<N>> for T {
fn as_deref_mut(&mut self) -> &mut Self::Target {
self.as_deref_mut().deref_mut()
}
}
#[allow(clippy::wrong_self_convention)]
pub trait AsDerefPtrExt {
type Pointee: ?Sized;
unsafe fn as_deref_ptr<D>(self) -> *mut <Self::Pointee as AsDeref<D>>::Target
where
D: Unsigned,
Self::Pointee: AsDeref<D>;
}
impl<T: ?Sized> AsDerefPtrExt for *mut T {
type Pointee = T;
unsafe fn as_deref_ptr<D>(self) -> *mut <T as AsDeref<D>>::Target
where
D: Unsigned,
Self::Pointee: AsDeref<D>,
{
unsafe { AsDeref::<D>::as_deref_ptr(self) }
}
}
impl<T: ?Sized> AsDerefPtrExt for *const T {
type Pointee = T;
unsafe fn as_deref_ptr<D>(self) -> *mut <T as AsDeref<D>>::Target
where
D: Unsigned,
Self::Pointee: AsDeref<D>,
{
unsafe { AsDeref::<D>::as_deref_ptr(self.cast_mut()) }
}
}
pub trait AsDerefCoinductive<N: Unsigned> {
type Target: ?Sized;
fn as_deref_coinductive(&self) -> &Self::Target;
}
pub trait AsDerefMutCoinductive<N: Unsigned>: AsDerefCoinductive<N> {
fn as_deref_mut_coinductive(&mut self) -> &mut Self::Target;
}
impl<T: ?Sized> AsDerefCoinductive<Zero> for T {
type Target = T;
fn as_deref_coinductive(&self) -> &T {
self
}
}
impl<T: ?Sized> AsDerefMutCoinductive<Zero> for T {
fn as_deref_mut_coinductive(&mut self) -> &mut T {
self
}
}
impl<T: Deref<Target: AsDerefCoinductive<N>> + ?Sized, N: Unsigned> AsDerefCoinductive<Succ<N>> for T {
type Target = <T::Target as AsDerefCoinductive<N>>::Target;
fn as_deref_coinductive(&self) -> &Self::Target {
self.deref().as_deref_coinductive()
}
}
impl<T: DerefMut<Target: AsDerefMutCoinductive<N>> + ?Sized, N: Unsigned> AsDerefMutCoinductive<Succ<N>> for T {
fn as_deref_mut_coinductive(&mut self) -> &mut Self::Target {
self.deref_mut().as_deref_mut_coinductive()
}
}