mirror of
https://git.intege.rs/xlib/x.git
synced 2025-12-05 20:35:01 +00:00
100 lines
2.5 KiB
Rust
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>
|
|
}
|
|
}
|
|
|