mirror of
https://git.intege.rs/xlib/x.git
synced 2025-12-06 04:45:02 +00:00
initial
This commit is contained in:
100
src/vso.rs
Normal file
100
src/vso.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
#![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)
|
||||
#[cfg(not(feature="production"))]
|
||||
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>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user