Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::ops::Deref;
- trait StaticCast<T> {
- fn static_cast(ptr: *mut Self) -> *mut T;
- }
- fn static_cast<T: StaticCast<U>, U>(ptr: *mut T) -> *mut U {
- T::static_cast(ptr)
- }
- struct RawBase(u8);
- struct RawDerived(u8);
- struct RawDerived2(u8);
- impl<T> StaticCast<T> for T {
- fn static_cast(ptr: *mut T) -> *mut T {
- ptr
- }
- }
- impl StaticCast<RawBase> for RawDerived {
- fn static_cast(ptr: *mut RawDerived) -> *mut RawBase {
- (ptr as usize + 2) as _
- }
- }
- struct BasePtrLike<T: StaticCast<RawBase>>(*mut T);
- impl<T: StaticCast<RawBase>> Clone for BasePtrLike<T> {
- fn clone(&self) -> Self {
- BasePtrLike(self.0)
- }
- }
- impl<T: StaticCast<RawBase>> Copy for BasePtrLike<T> {}
- type BasePtr = BasePtrLike<RawBase>;
- impl<T: StaticCast<RawBase>> BasePtrLike<T> {
- fn f1(self) {
- let ptr = static_cast::<T, RawBase>(self.0);
- println!("call f1 on {:?}", ptr);
- }
- }
- struct DerivedPtrLike<T: StaticCast<RawDerived>>(*mut T);
- type DerivedPtr = DerivedPtrLike<RawDerived>;
- impl<T: StaticCast<RawDerived>> Clone for DerivedPtrLike<T> {
- fn clone(&self) -> Self {
- DerivedPtrLike(self.0)
- }
- }
- impl<T: StaticCast<RawDerived>> Copy for DerivedPtrLike<T> {}
- impl<T: StaticCast<RawDerived> + StaticCast<RawBase>> Deref for DerivedPtrLike<T> {
- type Target = BasePtrLike<T>;
- fn deref(&self) -> &Self::Target {
- unsafe { std::mem::transmute::<&Self, &Self::Target>(self) }
- }
- }
- struct Derived2PtrLike<T: StaticCast<RawDerived2>>(*mut T);
- type Derived2Ptr = Derived2PtrLike<RawDerived2>;
- impl<T: StaticCast<RawDerived2>> Clone for Derived2PtrLike<T> {
- fn clone(&self) -> Self {
- Derived2PtrLike(self.0)
- }
- }
- impl<T: StaticCast<RawDerived2>> Copy for Derived2PtrLike<T> {}
- impl Deref for Derived2Ptr {
- type Target = DerivedPtrLike<RawDerived2>;
- fn deref(&self) -> &Self::Target {
- unsafe { std::mem::transmute::<&Derived2Ptr, &Self::Target>(self) }
- }
- }
- impl StaticCast<RawDerived> for RawDerived2 {
- fn static_cast(ptr: *mut RawDerived2) -> *mut RawDerived {
- (ptr as usize + 5) as _
- }
- }
- impl StaticCast<RawBase> for RawDerived2 {
- fn static_cast(ptr: *mut RawDerived2) -> *mut RawBase {
- let ptr = static_cast::<RawDerived2, RawDerived>(ptr);
- static_cast::<RawDerived, RawBase>(ptr)
- }
- }
- fn main() {
- let base = BasePtrLike(0x100 as *mut RawBase);
- base.f1();
- let derived = DerivedPtrLike(0x200 as *mut RawDerived);
- derived.f1();
- let derived2 = Derived2PtrLike(0x300 as *mut RawDerived2);
- derived2.f1();
- }
Add Comment
Please, Sign In to add comment