Files
x/src/vso.rs
numbers a6ba0f3e40 .
2023-09-19 18:45:27 -04:00

100 lines
2.5 KiB
Rust

#![allow(unused)]
use core::fmt::{Debug, Display, Formatter, UpperHex};
use core::marker::PhantomData;
use core::mem::transmute;
use core::ops::{ControlFlow, Deref, DerefMut, Index, IndexMut};
pub struct VirtualOffset<T, const O: usize>(PhantomData<T>);
impl<T, const O: usize> VirtualOffset<T, O> {
#[inline(always)]
pub(crate) fn vo_as_ptr(&self) -> *mut T {
((self as *const _ as usize) + O) as *mut T
}
#[inline(always)]
pub(crate) fn offset() -> usize {
return O;
}
/// gets a ref to the underlying type
/// just an alias for the deref trait so it doesnt need to be imported
pub fn r#ref(&self) -> &T {
self.deref()
}
}
impl<T, const O: usize> Deref for VirtualOffset<T, O> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { transmute(((self as *const _ as usize) + O) as *const T)}
}
}
impl<T, const O: usize> DerefMut for VirtualOffset<T, O> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { transmute(((self as *mut _ as usize) + O) as *mut T)}
}
}
// ==============================
// Index
// ==============================
impl<I, T: Index<I>, const O: usize> Index<I> for VirtualOffset<T, O> {
type Output = T::Output;
fn index(&self, index: I) -> &Self::Output {
unsafe { &*self.vo_as_ptr() }.index(index)
}
}
impl<I, T: IndexMut<I>, const O: usize> IndexMut<I> for VirtualOffset<T, O> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
unsafe { &mut *self.vo_as_ptr() }.index_mut(index)
}
}
// ==============================
// Display + Debug
// ==============================
// Proxy the Display trait
impl<T: Display, const O: usize> Display for VirtualOffset<T, O> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
// Proxy the UpperHex trait
impl<T: UpperHex, const O: usize> UpperHex for VirtualOffset<T, O> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
// Proxy the Debug trait (in debug builds)
impl<T: Debug, const O: usize> Debug for VirtualOffset<T, O> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
// ==============================
// Macro
// ==============================
#[macro_export]
macro_rules! struct_offset {
($offset:literal, $type:ty) => {
$crate::VirtualOffset<$type, $offset>
}
}