Guest User

Untitled

a guest
Jan 20th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.54 KB | None | 0 0
  1. use std::ops::Deref;
  2.  
  3. trait StaticCast<T> {
  4. fn static_cast(ptr: *mut Self) -> *mut T;
  5. }
  6.  
  7. fn static_cast<T: StaticCast<U>, U>(ptr: *mut T) -> *mut U {
  8. T::static_cast(ptr)
  9. }
  10.  
  11. struct RawBase(u8);
  12. struct RawDerived(u8);
  13. struct RawDerived2(u8);
  14.  
  15. impl<T> StaticCast<T> for T {
  16. fn static_cast(ptr: *mut T) -> *mut T {
  17. ptr
  18. }
  19. }
  20.  
  21. impl StaticCast<RawBase> for RawDerived {
  22. fn static_cast(ptr: *mut RawDerived) -> *mut RawBase {
  23. (ptr as usize + 2) as _
  24. }
  25. }
  26.  
  27.  
  28. struct BasePtrLike<T: StaticCast<RawBase>>(*mut T);
  29.  
  30. impl<T: StaticCast<RawBase>> Clone for BasePtrLike<T> {
  31. fn clone(&self) -> Self {
  32. BasePtrLike(self.0)
  33. }
  34. }
  35. impl<T: StaticCast<RawBase>> Copy for BasePtrLike<T> {}
  36.  
  37. type BasePtr = BasePtrLike<RawBase>;
  38.  
  39. impl<T: StaticCast<RawBase>> BasePtrLike<T> {
  40. fn f1(self) {
  41. let ptr = static_cast::<T, RawBase>(self.0);
  42. println!("call f1 on {:?}", ptr);
  43. }
  44. }
  45.  
  46. struct DerivedPtrLike<T: StaticCast<RawDerived>>(*mut T);
  47. type DerivedPtr = DerivedPtrLike<RawDerived>;
  48.  
  49. impl<T: StaticCast<RawDerived>> Clone for DerivedPtrLike<T> {
  50. fn clone(&self) -> Self {
  51. DerivedPtrLike(self.0)
  52. }
  53. }
  54. impl<T: StaticCast<RawDerived>> Copy for DerivedPtrLike<T> {}
  55.  
  56. impl<T: StaticCast<RawDerived> + StaticCast<RawBase>> Deref for DerivedPtrLike<T> {
  57. type Target = BasePtrLike<T>;
  58. fn deref(&self) -> &Self::Target {
  59. unsafe { std::mem::transmute::<&Self, &Self::Target>(self) }
  60. }
  61. }
  62.  
  63. struct Derived2PtrLike<T: StaticCast<RawDerived2>>(*mut T);
  64. type Derived2Ptr = Derived2PtrLike<RawDerived2>;
  65.  
  66. impl<T: StaticCast<RawDerived2>> Clone for Derived2PtrLike<T> {
  67. fn clone(&self) -> Self {
  68. Derived2PtrLike(self.0)
  69. }
  70. }
  71. impl<T: StaticCast<RawDerived2>> Copy for Derived2PtrLike<T> {}
  72.  
  73.  
  74. impl Deref for Derived2Ptr {
  75. type Target = DerivedPtrLike<RawDerived2>;
  76. fn deref(&self) -> &Self::Target {
  77. unsafe { std::mem::transmute::<&Derived2Ptr, &Self::Target>(self) }
  78. }
  79. }
  80.  
  81. impl StaticCast<RawDerived> for RawDerived2 {
  82. fn static_cast(ptr: *mut RawDerived2) -> *mut RawDerived {
  83. (ptr as usize + 5) as _
  84. }
  85. }
  86.  
  87. impl StaticCast<RawBase> for RawDerived2 {
  88. fn static_cast(ptr: *mut RawDerived2) -> *mut RawBase {
  89. let ptr = static_cast::<RawDerived2, RawDerived>(ptr);
  90. static_cast::<RawDerived, RawBase>(ptr)
  91. }
  92. }
  93.  
  94.  
  95. fn main() {
  96. let base = BasePtrLike(0x100 as *mut RawBase);
  97. base.f1();
  98.  
  99. let derived = DerivedPtrLike(0x200 as *mut RawDerived);
  100. derived.f1();
  101.  
  102. let derived2 = Derived2PtrLike(0x300 as *mut RawDerived2);
  103. derived2.f1();
  104.  
  105. }
Add Comment
Please, Sign In to add comment