#[doc = crate::_tags!(mem)]
#[doc = crate::_doc_location!("sys/mem")]
#[doc = crate::_doc!(vendor: "unsized-stack")]
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FatPtr {
ptr: *const (),
metadata: *const (),
}
impl FatPtr {
pub const fn new<T>(ptr: *const T, metadata: *const ()) -> Self {
Self { ptr: ptr as _, metadata }
}
pub const fn ptr(&self) -> *const () {
self.ptr
}
pub const fn metadata(&self) -> *const () {
self.metadata
}
pub const fn check_valid<T: ?Sized>() {
if size_of::<*const T>() != size_of::<FatPtr>() {
panic!("Type is not valid DST");
}
}
pub const fn to_raw_ptr<T: ?Sized>(fat_ptr: FatPtr) -> *const T {
Self::check_valid::<T>();
unsafe { FatPtrRepr { fat_ptr }.ptr_const }
}
pub const fn from_raw_ptr<T: ?Sized>(fat_ptr: *const T) -> FatPtr {
Self::check_valid::<T>();
unsafe { FatPtrRepr { ptr_const: fat_ptr }.fat_ptr }
}
}
#[repr(C)]
union FatPtrRepr<T: ?Sized> {
pub ptr_const: *const T,
pub fat_ptr: FatPtr,
}
#[cfg(test)]
mod tests {
use super::FatPtr;
#[test]
fn from_raw_ptr() {
let slice: &[usize] = &[0_usize];
let fat_ptr = FatPtr::from_raw_ptr(slice as *const [usize]);
assert_eq!(fat_ptr.metadata(), 1 as *const ());
}
}