Advertisement
Guest User

Untitled

a guest
May 19th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.25 KB | None | 0 0
  1. #![allow(unused, non_upper_case_globals)]
  2.  
  3. use std::marker::PhantomData;
  4.  
  5. struct Field<Parent, FieldType> {
  6. offset: usize,
  7. __: PhantomData<(Parent, FieldType)>
  8. }
  9.  
  10. #[repr(C)]
  11. struct Foo {
  12. bar: i32,
  13. yak: i8,
  14. hal: u8
  15. }
  16.  
  17. impl Foo {
  18. const bar: Field<Self, i32> = Field::<Self, i32> { offset: 0, __: PhantomData };
  19. const yak: Field<Self, i8 > = Field::<Self, i8 > { offset: 4, __: PhantomData };
  20. const hal: Field<Self, i8 > = Field::<Self, i8 > { offset: 5, __: PhantomData };
  21. }
  22.  
  23. fn main() {
  24. let x = Foo {
  25. bar: 20,
  26. yak: -2,
  27. hal: 2
  28. };
  29.  
  30. let x_ref = &x;
  31.  
  32. let x_field = project(x_ref, Foo::bar);
  33.  
  34. println!("{}", x_field);
  35.  
  36. let x_field = project(x_ref, Foo::yak);
  37.  
  38. println!("{}", x_field);
  39.  
  40. let x_field = project(x_ref, Foo::hal);
  41.  
  42. println!("{}", x_field);
  43.  
  44. }
  45.  
  46. trait UnsafeProject<FTy> {
  47. type Type;
  48. type Projection;
  49.  
  50. unsafe fn project(self, other: Field<Self::Type, FTy>) -> Self::Projection;
  51. }
  52.  
  53. unsafe trait Project<FTy>: UnsafeProject<FTy> {}
  54.  
  55. fn project<P, FTy>(p: P, field: Field<P::Type, FTy>) -> P::Projection
  56. where P: Project<FTy> {
  57. unsafe {
  58. p.project(field)
  59. }
  60. }
  61.  
  62. impl<T, FTy> UnsafeProject<FTy> for *const T {
  63. type Type = T;
  64. type Projection = *const FTy;
  65.  
  66. unsafe fn project(self, field: Field<T, FTy>) -> *const FTy {
  67. (self as *const u8)
  68. .add(field.offset) as *const FTy
  69. }
  70. }
  71.  
  72. impl<T, FTy> UnsafeProject<FTy> for *mut T {
  73. type Type = T;
  74. type Projection = *mut FTy;
  75.  
  76. unsafe fn project(self, field: Field<T, FTy>) -> *mut FTy {
  77. (self as *mut u8)
  78. .add(field.offset) as *mut FTy
  79. }
  80. }
  81.  
  82. unsafe impl<'a, T, FTy: 'a> Project<FTy> for &'a T {}
  83. impl<'a, T, FTy: 'a> UnsafeProject<FTy> for &'a T {
  84. type Type = T;
  85. type Projection = &'a FTy;
  86.  
  87. unsafe fn project(self, field: Field<T, FTy>) -> &'a FTy {
  88. &*(self as *const T)
  89. .project(field)
  90. }
  91. }
  92.  
  93. unsafe impl<'a, T, FTy: 'a> Project<FTy> for &'a mut T {}
  94. impl<'a, T, FTy: 'a> UnsafeProject<FTy> for &'a mut T {
  95. type Type = T;
  96. type Projection = &'a mut FTy;
  97.  
  98. unsafe fn project(self, field: Field<T, FTy>) -> &'a mut FTy {
  99. &mut *(self as *mut T)
  100. .project(field)
  101. }
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement