goddamit why is git commit -a so weird

This commit is contained in:
missing 2022-05-17 09:55:19 -05:00 committed by missing
parent f1bb8f9f5b
commit 8f27dc99e7
2 changed files with 220 additions and 0 deletions

50
src/bad_things.rs Normal file
View 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
View 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)
}
}