use core::marker::PhantomData; use core::ops::Index; #[repr(transparent)] #[derive(Debug)] pub struct Ptr { ptr: *const T, } impl Clone for Ptr { fn clone(&self) -> Self { *self } } impl Copy for Ptr {} impl PartialEq for Ptr { fn eq(&self, other: &Self) -> bool { core::ptr::addr_eq(self.ptr, other.ptr) } } impl Eq for Ptr {} unsafe impl Send for Ptr {} unsafe impl Sync for Ptr {} impl Ptr { pub const fn null() -> Self { Self { ptr: core::ptr::null(), } } pub const fn is_null(self) -> bool { self.ptr.is_null() } pub fn from_raw(ptr: *const T) -> Self { Self { ptr } } pub fn as_raw(self) -> *const T { self.ptr } #[inline(always)] pub unsafe fn as_ref<'a>(self) -> &'a T { debug_assert!(!self.is_null(), "null Ptr dereference"); unsafe { &*self.ptr } } #[inline(always)] pub fn get<'a>(self) -> Option<&'a T> { if self.is_null() { None } else { Some(unsafe { &*self.ptr }) } } #[inline(always)] pub unsafe fn at<'a>(self, index: usize) -> &'a T { debug_assert!(!self.is_null(), "null Ptr array access"); unsafe { &*self.ptr.add(index) } } /// Get element at index, returns None if ptr is null #[inline(always)] pub fn get_at<'a>(self, index: usize) -> Option<&'a T> { if self.is_null() { None } else { Some(unsafe { &*self.ptr.add(index) }) } } /// Offset the pointer, returning a new Ptr #[inline(always)] pub unsafe fn add(self, count: usize) -> Self { Self { ptr: unsafe { self.ptr.add(count) }, } } /// Convert to slice (requires knowing the length) #[inline(always)] pub unsafe fn as_slice<'a>(self, len: usize) -> &'a [T] { debug_assert!(!self.is_null() || len == 0, "null Ptr to non-empty slice"); if len == 0 { &[] } else { unsafe { core::slice::from_raw_parts(self.ptr, len) } } } /// Convert to slice, returns None if null #[inline(always)] pub fn get_slice<'a>(self, len: usize) -> Option<&'a [T]> { if self.is_null() { if len == 0 { Some(&[]) } else { None } } else { Some(unsafe { core::slice::from_raw_parts(self.ptr, len) }) } } } impl core::ops::Deref for Ptr { type Target = T; #[inline(always)] fn deref(&self) -> &T { debug_assert!(!self.is_null(), "Null Ptr dereference"); unsafe { &*self.ptr } } } impl Default for Ptr { fn default() -> Self { Self::null() } } impl From<&T> for Ptr { fn from(r: &T) -> Self { Self { ptr: r as *const T } } } impl From<&[T]> for Ptr { fn from(slice: &[T]) -> Self { Self { ptr: slice.as_ptr(), } } } impl From<*const T> for Ptr { fn from(ptr: *const T) -> Self { Self { ptr } } } impl From> for Ptr { fn from(opt: Option<&T>) -> Self { match opt { Some(r) => Ptr::from(r), None => Ptr::null(), } } }