lv-std 0.0.4

some utils for c and unsafe rust, this is for personal use for now so you can use it but don't expect any regular updates or maintaining
Documentation
use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
use std::any::TypeId;
use std::fmt::Debug;
use std::marker::{PhantomData};
use std::mem::{transmute, transmute_copy};
use std::ops::{Deref, DerefMut};
use std::ptr::copy_nonoverlapping;
use crate::forbid_void;
use crate::unsafe_std::ptrs::into_raw_ptr::IntoRawPtr;
use super::*;


#[repr(transparent)]
#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RawPtr<T: ?Sized> {
    ptr: *mut T,
    _marker: PhantomData<T>,
}

impl<T: Sized> RawPtr<T> {

    const NULL: RawPtr<T> = RawPtr::null();

    #[inline(always)]
    pub const fn null() -> RawPtr<T> {
        Self {
            ptr: 0 as *mut T,
            _marker: PhantomData,
        }
    }




    #[inline(always)]
    pub const unsafe fn index<'a>(self, index: isize) -> &'a T {
        &*self.ptr.offset(index)
    }

    #[inline(always)]
    pub const unsafe fn index_mut<'a>(self, index: isize) -> &'a mut T {
        &mut *self.ptr.offset(index)
    }

    #[inline(always)]
    pub const unsafe fn copy_to(self, other: &mut Self) {
        copy_nonoverlapping(self.ptr, other.ptr, size_of::<T>());
    }

    #[inline(always)]
    pub unsafe fn mem_copy_to<D : IntoRawPtr>(self, other: D, size: usize)
    where <D as IntoRawPtr>::Pointee: 'static
    {
        copy_nonoverlapping(self.ptr, other.to_ptr().cast().ptr, size)
    }

    #[inline(always)]
    pub unsafe fn assign(mut self, value: T) {
        *self.ptr = value;
    }

    #[inline(always)]
    pub unsafe fn assign_cast<D: 'static>(mut self, value: D) {
        forbid_void!(D);
        self.assign(transmute_copy(&value));
    }

    #[inline(always)]
    pub unsafe fn assign_check(mut self, value: T) -> ptr_utils::PtrState {
        if self.ptr.is_null() {
            ptr_utils::PtrState::Null
        }  else {
            *self.ptr = value;
            ptr_utils::PtrState::Val
        }
    }

    #[inline(always)]
    pub const unsafe fn cast_raw<U>(self) -> *mut U {
        transmute(self.ptr)
    }

    #[inline(always)]
    pub const unsafe fn cast_const_raw<U>(mut self) -> *const U {
        transmute(self.ptr)
    }

    #[inline(always)]
    pub const unsafe fn cast<U>(self) -> RawPtr<U> {
        transmute(self)
    }

    #[inline(always)]
    pub unsafe fn alloc() -> RawPtr<T> {
        Self {
            ptr: alloc_zeroed(Layout::new::<T>()) as *mut T,
            _marker: PhantomData,
        }
    }

    #[inline(always)]
    pub unsafe fn calloc(amount: usize) -> RawPtr<T> {
        Self {
            ptr: alloc_zeroed(Layout::array::<T>(amount).unwrap()) as *mut T,
            _marker: PhantomData,
        }
    }

    #[inline(always)]
    pub unsafe fn malloc(size: usize) -> RawPtr<T> {
        Self {
            ptr: alloc(Layout::array::<u8>(size).unwrap()) as *mut T,
            _marker: PhantomData,
        }
    }

    #[inline(always)]
    pub unsafe fn rclone(&self) -> RawPtr<T> {
        unsafe {
            let mut new_ptr = RawPtr::alloc();
            self.to_owned().copy_to(&mut new_ptr);
            new_ptr
        }
    }

}

impl<T: ?Sized> RawPtr<T> {

    #[inline(always)]
    pub const fn new(value: &mut T) -> RawPtr<T> {
        Self {
            ptr: value as *mut T,
            _marker: PhantomData,
        }
    }


    #[inline(always)]
    pub const unsafe fn from_raw(raw: *mut T) -> RawPtr<T> {
        transmute(raw)
    }




    #[inline(always)]
    pub unsafe fn free(self) {
        dealloc(self.ptr as *mut u8, Layout::new::<Self>());
    }




    #[inline(always)]
    pub const fn get_const_raw(self) -> *const T {
        self.ptr as *const T
    }

    #[inline(always)]
    pub const fn is_null(self) -> bool {
        self.ptr.is_null()
    }

    #[inline(always)]
    pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
        self.ptr.as_ref()
    }

    #[inline(always)]
    pub const unsafe fn as_mut<'a>(mut self) -> Option<&'a mut T> {
        self.ptr.as_mut()
    }

    #[inline(always)]
    pub const unsafe fn as_raw(self) -> Option<*mut T> {
        if self.ptr.is_null() {
            None
        } else {
            Some(self.ptr)
        }
    }

    #[inline(always)]
    pub const unsafe fn as_const_raw(self) -> Option<*const T> {
        if self.ptr.is_null() {
            None
        } else {
            Some(self.ptr as  *const T)
        }
    }
    
    /*
    #[inline(always)]
    pub const unsafe fn mut_cast_const(self) -> raw_const_ptr::RawConstPtr<T> {
        transmute(self)
    }
    */



    #[inline(always)]
    pub const unsafe fn cast_ref<'a, U>(self) -> &'a U {
        transmute(self.ptr as *const U)
    }

    #[inline(always)]
    pub const unsafe fn cast_mut<'a, U>(mut self) -> &'a mut U {
        transmute(self.ptr as *mut U)
    }


    #[inline(always)]
    pub const unsafe fn to_owned(&self) -> RawPtr<T> {
        RawPtr::<T>::from_raw(self.ptr)
    }

}

impl<T> Deref for RawPtr<T> {
    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        unsafe { transmute(self.ptr) }
    }
}

impl<T> DerefMut for RawPtr<T> {

    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { transmute(self.ptr) }
    }
}

impl<T: ?Sized> From<*mut T> for RawPtr<T> {

    #[inline(always)]
    fn from(value: *mut T) -> Self {
        unsafe { transmute(value) }
    }
}

impl<T: ?Sized> From<*const T> for RawPtr<T> {

    #[inline(always)]
    fn from(value: *const T) -> Self {
        unsafe { transmute(value) }
    }
}

impl<T: ?Sized> Clone for RawPtr<T> {
    #![allow(useless_deprecated)]
    #[deprecated (since = "0.0.0", note = "this is a blanket impl to allow the copy trait, please refer to the rclone method instead")]
    fn clone(&self) -> Self {
        unsafe {
            unreachable!("this is a blanket impl to allow the copy trait, please refer to the rclone method instead")
        }
    }
}

impl<T: ?Sized> Copy for RawPtr<T> {}
unsafe impl<T: ?Sized> Send for RawPtr<T> {}

#[cfg(test)]
mod tests {

    #[cfg(test)]
    mod ptr {
        use std::fmt::Debug;
        use std::mem::transmute;
        use super::super::*;

        #[test]
        fn new_and_null() {

            let mut x = 32;
            let p_x: RawPtr<i32> = RawPtr::new(&mut x);
            unsafe { assert_eq!(*p_x, 32); }

            let thin_null: *mut () = std::ptr::null_mut();
            let wide_null: *mut dyn Debug = thin_null as *mut dyn Debug;

            let p_null: RawPtr<i32> = RawPtr::NULL;
            unsafe {
                assert_eq!(p_null, transmute(std::ptr::null_mut::<RawPtr<i32>>()));
            }
        }
    }
}