Trait repr_offset::ext::ROExtAcc
source · pub unsafe trait ROExtAcc: Sized {
// Required methods
fn f_get<F>(&self, offset: FieldOffset<Self, F, Aligned>) -> &F;
fn f_get_mut<F>(&mut self, offset: FieldOffset<Self, F, Aligned>) -> &mut F;
fn f_get_ptr<F, A>(&self, offset: FieldOffset<Self, F, A>) -> *const F;
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<Self, F, A>) -> *mut F;
}
Expand description
Extension trait for (mutable) references to access fields generically,
where the field is determined by a FieldOffset
parameter.
§Safety
This trait must not to be implemented outside the repr_offset
crate.
§Examples
§Unaligned field pointers
Getting raw pointers to all fields in a packed struct.
use repr_offset::{
for_examples::ReprPacked,
ROExtAcc,
off,
};
type This = ReprPacked<u8, Option<usize>, &'static [u16], &'static str>;
let value: This = ReprPacked {
a: 3,
b: Some(5),
c: &[0, 1, 2],
d: "hello",
};
unsafe {
let (a_ptr, b_ptr, c_ptr, d_ptr) = get_field_ptrs(&value);
assert_eq!(a_ptr.read_unaligned(), 3);
assert_eq!(b_ptr.read_unaligned(), Some(5));
assert_eq!(c_ptr.read_unaligned(), &[0, 1, 2]);
assert_eq!(d_ptr.read_unaligned(), "hello");
}
// Note: the mutable version of this function couldn't use `f_get_mut_ptr`,
// it must use `ROExtRawMutAcc::f_raw_get_mut`
fn get_field_ptrs(
this: &This,
) -> (*const u8, *const Option<usize>, *const &'static [u16], *const &'static str) {
(
this.f_get_ptr(off!(a)),
this.f_get_ptr(off!(b)),
this.f_get_ptr(off!(c)),
this.f_get_ptr(off!(d)),
)
}
Required Methods§
sourcefn f_get<F>(&self, offset: FieldOffset<Self, F, Aligned>) -> &F
fn f_get<F>(&self, offset: FieldOffset<Self, F, Aligned>) -> &F
Gets a reference to a field, determined by offset
.
§Example
use repr_offset::{
for_examples::ReprC,
ROExtAcc, off,
};
let value = ReprC {
a: 3,
b: "foo",
c: ReprC {
a: 5,
b: "bar",
c: 8,
d: 13,
},
d: false,
};
assert_eq!(value.f_get(off!(a)), &3);
assert_eq!(value.f_get(off!(c.a)), &5);
assert_eq!(value.f_get(off!(c.b)), &"bar");
sourcefn f_get_mut<F>(&mut self, offset: FieldOffset<Self, F, Aligned>) -> &mut F
fn f_get_mut<F>(&mut self, offset: FieldOffset<Self, F, Aligned>) -> &mut F
Gets a muatble reference to a field, determined by offset
.
§Example
use repr_offset::{
for_examples::{ReprAlign4, ReprC},
ROExtAcc, off,
};
use std::cmp::Ordering;
let mut value = ReprC {
a: 3,
b: Some(5),
c: Ordering::Less,
d: ReprAlign4 {
a: 8,
b: "bar",
c: 13,
d: 21,
},
};
let foo = value.f_get_mut(off!(a));
assert_eq!(foo, &mut 3);
*foo += 100;
assert_eq!(value.a, 103);
let bar = value.f_get_mut(off!(d.a));
assert_eq!(bar, &mut 8);
let baz = value.f_get_mut(off!(d.d));
assert_eq!(baz, &mut 21);
*baz += 300;
assert_eq!(value.d.d, 321);
sourcefn f_get_ptr<F, A>(&self, offset: FieldOffset<Self, F, A>) -> *const F
fn f_get_ptr<F, A>(&self, offset: FieldOffset<Self, F, A>) -> *const F
Gets a const pointer to a field,
the field is determined by offset
.
§Example
use repr_offset::{
for_examples::ReprC,
ROExtAcc, off,
};
let value = ReprC {
a: 3,
b: "foo",
c: ReprC {
a: 5,
b: "bar",
c: 8,
d: 13,
},
d: false,
};
unsafe {
assert_eq!(value.f_get_ptr(off!(a)).read(), 3);
assert_eq!(value.f_get_ptr(off!(c.a)).read(), 5);
assert_eq!(value.f_get_ptr(off!(c.b)).read(), "bar");
}
sourcefn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<Self, F, A>) -> *mut F
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<Self, F, A>) -> *mut F
Gets a mutable pointer to a field, determined by offset
.
§Example
use repr_offset::{
for_examples::{ReprC, ReprPacked},
utils::moved,
ROExtAcc, off,
};
use std::cmp::Ordering;
let mut value = ReprPacked {
a: 3,
b: Some(5),
c: Ordering::Less,
d: ReprC {
a: 8,
b: "bar",
c: 13,
d: 21,
},
};
unsafe {
let foo = value.f_get_mut_ptr(off!(a));
let old_a = foo.read_unaligned();
assert_eq!(old_a, 3);
foo.write_unaligned(old_a + 100);
// the `moved` function prevents the creation of a reference to the packed field.
assert_eq!(moved(value.a), 103);
let baz = value.f_get_mut_ptr(off!(d.d));
let old_dd = baz.read_unaligned();
assert_eq!(old_dd, 21);
baz.write_unaligned(old_dd + 300);
// the `moved` function prevents the creation of a reference to the packed field.
assert_eq!(moved(value.d.d), 321);
}
Object Safety§
This trait is not object safe.