goddamit why is git commit -a
so weird
This commit is contained in:
parent
f1bb8f9f5b
commit
8f27dc99e7
50
src/bad_things.rs
Normal file
50
src/bad_things.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
// use std::{fmt::Debug, intrinsics::transmute, mem::{transmute_copy, MaybeUninit, ManuallyDrop}, alloc::{dealloc, Layout}, ptr::drop_in_place};
|
||||
|
||||
// trait IsSized {
|
||||
// type SizedRepr;
|
||||
|
||||
// fn is_sized() -> bool;
|
||||
// }
|
||||
|
||||
// impl<T: ?Sized> IsSized for T {
|
||||
// default type SizedRepr = Box<T>;
|
||||
|
||||
// default fn is_sized() -> bool {
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<T> IsSized for T {
|
||||
// type SizedRepr = T;
|
||||
|
||||
// fn is_sized() -> bool {
|
||||
// true
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[repr(transparent)]
|
||||
// struct Item<T: ?Sized>(<T as IsSized>::SizedRepr);
|
||||
|
||||
// impl<T: ?Sized> Item<T> {
|
||||
// fn from_box(v: Box<T>) -> Self {
|
||||
// let ret = if T::is_sized() {
|
||||
// // SAFETY: #[repr(transparent)], and we know its `SizedRepr` is just `T`
|
||||
// unsafe { (&*v as *const _ as *const Self).read() }
|
||||
// let ptr = Box::into_raw(v);
|
||||
// unsafe { dealloc(ptr.cast(), Layout::for_value_raw(ptr)) }
|
||||
// } else {
|
||||
// // SAFETY: #[repr(transparent)], and we know its `SizedRepr` is `Box<T>`
|
||||
// unsafe { (&v as *const _ as *const Self).read() }
|
||||
// mem::forget(v);
|
||||
// };
|
||||
|
||||
// ret
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// pub fn testing() {
|
||||
// dbg!(usize::is_sized());
|
||||
// dbg!(<dyn Debug>::is_sized());
|
||||
// }
|
||||
|
170
src/ptr_ext.rs
Normal file
170
src/ptr_ext.rs
Normal file
|
@ -0,0 +1,170 @@
|
|||
use std::{ptr::{self, Pointee}, mem::size_of_val_raw, alloc::{alloc, Layout}};
|
||||
|
||||
use self::__priv::Sealed;
|
||||
|
||||
mod __priv {
|
||||
pub trait Sealed {}
|
||||
|
||||
impl<T: ?Sized> Sealed for *const T {}
|
||||
impl<T: ?Sized> Sealed for *mut T {}
|
||||
}
|
||||
|
||||
pub trait PtrExt: Sealed {
|
||||
type Pointee: ?Sized;
|
||||
|
||||
fn addr(self) -> usize;
|
||||
|
||||
fn align_up(self, align: usize) -> Self;
|
||||
|
||||
fn with_addr_from<U: ?Sized>(self, addr: *const U) -> Self;
|
||||
|
||||
fn with_addr(self, addr: usize) -> Self;
|
||||
|
||||
unsafe fn get_end(self) -> Self;
|
||||
|
||||
fn add_bytes(self, offset: usize) -> Self;
|
||||
|
||||
fn sub_bytes(self, offset: usize) -> Self;
|
||||
|
||||
unsafe fn copy_bytes_to<U: ?Sized>(self, dest: *mut U, count: usize);
|
||||
|
||||
unsafe fn copy_val_to<U: ?Sized>(self, dest: *mut U);
|
||||
|
||||
unsafe fn read_to_box(self) -> Box<Self::Pointee>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> PtrExt for *const T {
|
||||
type Pointee = T;
|
||||
|
||||
fn addr(self) -> usize {
|
||||
self.to_raw_parts().0 as usize
|
||||
}
|
||||
|
||||
fn align_up(self, align: usize) -> Self {
|
||||
self.with_addr((self.addr() + align - 1) & !(align - 1))
|
||||
}
|
||||
|
||||
fn with_addr_from<U: ?Sized>(self, addr: *const U) -> Self {
|
||||
self.with_addr(addr.addr())
|
||||
}
|
||||
|
||||
fn with_addr(self, addr: usize) -> Self {
|
||||
ptr::from_raw_parts(addr as _, self.to_raw_parts().1)
|
||||
}
|
||||
|
||||
unsafe fn get_end(self) -> Self {
|
||||
self.add_bytes(size_of_val_raw(self))
|
||||
}
|
||||
|
||||
fn add_bytes(self, offset: usize) -> Self {
|
||||
self.with_addr_from(self.cast::<u8>().wrapping_add(offset))
|
||||
}
|
||||
|
||||
fn sub_bytes(self, offset: usize) -> Self {
|
||||
self.with_addr_from(self.cast::<u8>().wrapping_sub(offset))
|
||||
}
|
||||
|
||||
unsafe fn copy_bytes_to<U: ?Sized>(self, dest: *mut U, count: usize) {
|
||||
self.cast::<u8>().copy_to(dest.cast(), count);
|
||||
}
|
||||
|
||||
unsafe fn copy_val_to<U: ?Sized>(self, dest: *mut U) {
|
||||
self.copy_bytes_to(dest, size_of_val_raw(self));
|
||||
}
|
||||
|
||||
unsafe fn read_to_box(self) -> Box<Self::Pointee> {
|
||||
let alloc = alloc(Layout::for_value_raw(self));
|
||||
self.copy_val_to(alloc);
|
||||
Box::from_raw(alloc.with_meta_from(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> PtrExt for *mut T {
|
||||
type Pointee = T;
|
||||
|
||||
fn addr(self) -> usize {
|
||||
self.to_raw_parts().0 as usize
|
||||
}
|
||||
|
||||
fn align_up(self, align: usize) -> Self {
|
||||
self.with_addr((self.addr() + align - 1) & !(align - 1))
|
||||
}
|
||||
|
||||
fn with_addr_from<U: ?Sized>(self, addr: *const U) -> Self {
|
||||
self.with_addr(addr.addr())
|
||||
}
|
||||
|
||||
fn with_addr(self, addr: usize) -> Self {
|
||||
ptr::from_raw_parts_mut(addr as _, self.to_raw_parts().1)
|
||||
}
|
||||
|
||||
unsafe fn get_end(self) -> Self {
|
||||
self.add_bytes(size_of_val_raw(self))
|
||||
}
|
||||
|
||||
fn add_bytes(self, offset: usize) -> Self {
|
||||
self.with_addr_from(self.cast::<u8>().wrapping_add(offset))
|
||||
}
|
||||
|
||||
fn sub_bytes(self, offset: usize) -> Self {
|
||||
self.with_addr_from(self.cast::<u8>().wrapping_sub(offset))
|
||||
}
|
||||
|
||||
unsafe fn copy_bytes_to<U: ?Sized>(self, dest: *mut U, count: usize) {
|
||||
self.cast::<u8>().copy_to(dest.cast(), count);
|
||||
}
|
||||
|
||||
unsafe fn copy_val_to<U: ?Sized>(self, dest: *mut U) {
|
||||
self.copy_bytes_to(dest, size_of_val_raw(self));
|
||||
}
|
||||
|
||||
unsafe fn read_to_box(self) -> Box<Self::Pointee> {
|
||||
let alloc = alloc(Layout::for_value_raw(self));
|
||||
self.copy_val_to(alloc);
|
||||
Box::from_raw(alloc.with_meta_from(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ConstPtrExt: Sealed {
|
||||
fn data_ptr(self) -> *const ();
|
||||
|
||||
fn with_meta<U: ?Sized>(self, meta: <U as Pointee>::Metadata) -> *const U;
|
||||
|
||||
fn with_meta_from<U: ?Sized>(self, ptr: *const U) -> *const U;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> ConstPtrExt for *const T {
|
||||
fn data_ptr(self) -> *const () {
|
||||
self.to_raw_parts().0
|
||||
}
|
||||
|
||||
fn with_meta<U: ?Sized>(self, meta: <U as Pointee>::Metadata) -> *const U {
|
||||
ptr::from_raw_parts(self.data_ptr(), meta)
|
||||
}
|
||||
|
||||
fn with_meta_from<U: ?Sized>(self, ptr: *const U) -> *const U {
|
||||
self.with_meta(ptr.to_raw_parts().1)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MutPtrExt: Sealed {
|
||||
fn data_ptr(self) -> *mut ();
|
||||
|
||||
fn with_meta<U: ?Sized>(self, meta: <U as Pointee>::Metadata) -> *mut U;
|
||||
|
||||
fn with_meta_from<U: ?Sized>(self, ptr: *const U) -> *mut U;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> MutPtrExt for *mut T {
|
||||
fn data_ptr(self) -> *mut () {
|
||||
self.to_raw_parts().0
|
||||
}
|
||||
|
||||
fn with_meta<U: ?Sized>(self, meta: <U as Pointee>::Metadata) -> *mut U {
|
||||
ptr::from_raw_parts_mut(self.data_ptr(), meta)
|
||||
}
|
||||
|
||||
fn with_meta_from<U: ?Sized>(self, ptr: *const U) -> *mut U {
|
||||
self.with_meta(ptr.to_raw_parts().1)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue