Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![allow(unused, non_upper_case_globals)]
- use std::marker::PhantomData;
- struct Field<Parent, FieldType> {
- offset: usize,
- __: PhantomData<(Parent, FieldType)>
- }
- #[repr(C)]
- struct Foo {
- bar: i32,
- yak: i8,
- hal: u8
- }
- impl Foo {
- const bar: Field<Self, i32> = Field::<Self, i32> { offset: 0, __: PhantomData };
- const yak: Field<Self, i8 > = Field::<Self, i8 > { offset: 4, __: PhantomData };
- const hal: Field<Self, i8 > = Field::<Self, i8 > { offset: 5, __: PhantomData };
- }
- fn main() {
- let x = Foo {
- bar: 20,
- yak: -2,
- hal: 2
- };
- let x_ref = &x;
- let x_field = project(x_ref, Foo::bar);
- println!("{}", x_field);
- let x_field = project(x_ref, Foo::yak);
- println!("{}", x_field);
- let x_field = project(x_ref, Foo::hal);
- println!("{}", x_field);
- }
- trait UnsafeProject<FTy> {
- type Type;
- type Projection;
- unsafe fn project(self, other: Field<Self::Type, FTy>) -> Self::Projection;
- }
- unsafe trait Project<FTy>: UnsafeProject<FTy> {}
- fn project<P, FTy>(p: P, field: Field<P::Type, FTy>) -> P::Projection
- where P: Project<FTy> {
- unsafe {
- p.project(field)
- }
- }
- impl<T, FTy> UnsafeProject<FTy> for *const T {
- type Type = T;
- type Projection = *const FTy;
- unsafe fn project(self, field: Field<T, FTy>) -> *const FTy {
- (self as *const u8)
- .add(field.offset) as *const FTy
- }
- }
- impl<T, FTy> UnsafeProject<FTy> for *mut T {
- type Type = T;
- type Projection = *mut FTy;
- unsafe fn project(self, field: Field<T, FTy>) -> *mut FTy {
- (self as *mut u8)
- .add(field.offset) as *mut FTy
- }
- }
- unsafe impl<'a, T, FTy: 'a> Project<FTy> for &'a T {}
- impl<'a, T, FTy: 'a> UnsafeProject<FTy> for &'a T {
- type Type = T;
- type Projection = &'a FTy;
- unsafe fn project(self, field: Field<T, FTy>) -> &'a FTy {
- &*(self as *const T)
- .project(field)
- }
- }
- unsafe impl<'a, T, FTy: 'a> Project<FTy> for &'a mut T {}
- impl<'a, T, FTy: 'a> UnsafeProject<FTy> for &'a mut T {
- type Type = T;
- type Projection = &'a mut FTy;
- unsafe fn project(self, field: Field<T, FTy>) -> &'a mut FTy {
- &mut *(self as *mut T)
- .project(field)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement