Trait repr_offset::ext::ROExtRawMutAcc
source · pub unsafe trait ROExtRawMutAcc: ROExtRawAcc {
// Required method
unsafe fn f_raw_get_mut<F, A>(
self,
offset: FieldOffset<Self::Target, F, A>,
) -> *mut F;
}
Expand description
Extension trait for mutable raw pointers 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.
§Example
This example demonstrates how you can get mutable references to the known initialized parts of a struct.
use repr_offset::{
for_examples::ReprC,
tstr::TS,
off,
ROExtRawOps, ROExtRawMutAcc, ROExtRawMutOps,
};
use std::mem::MaybeUninit;
type This = ReprC<u8, Option<usize>, &'static [u16], &'static str>;
let mut uninit = MaybeUninit::<This>::uninit();
unsafe {
let ptr = uninit.as_mut_ptr();
ptr.f_write(off!(a), 3);
ptr.f_write(off!(b), Some(5));
}
{
// Safety: We know that the a and b fields were initialized above.
let (a, b) = unsafe{ get_mut_refs(&mut uninit) };
assert_eq!(*a, 3);
assert_eq!(*b, Some(5));
*a += 100;
*b.as_mut().unwrap() += 200;
}
unsafe {
let ptr = uninit.as_ptr();
assert_eq!(ptr.f_read_copy(off!(a)), 103);
assert_eq!(ptr.f_read_copy(off!(b)), Some(205));
}
/// Gets mutable references to the `a` and `b` fields in `this`
///
/// # Safety
///
/// The fields up to and including `b` must be initialized.
unsafe fn get_mut_refs(this: &mut MaybeUninit<This>) -> (&mut u8, &mut Option<usize>) {
let this = this.as_mut_ptr();
let ptrs = (
this.f_raw_get_mut(off!(a)),
this.f_raw_get_mut(off!(b)),
);
(&mut *ptrs.0, &mut *ptrs.1)
}
Required Methods§
sourceunsafe fn f_raw_get_mut<F, A>(
self,
offset: FieldOffset<Self::Target, F, A>,
) -> *mut F
unsafe fn f_raw_get_mut<F, A>( self, offset: FieldOffset<Self::Target, F, A>, ) -> *mut F
Gets a muatble pointer to a field (determined by offset
) from this mutable pointer.
§Safety
self
must point to some allocated object,
allocated at least up to the field (inclusive).
§Example
use repr_offset::{
for_examples::{ReprC, ReprPacked},
utils::moved,
tstr::TS,
GetPubFieldOffset, FieldType,
ROExtRawMutAcc,
off,
};
use std::mem::MaybeUninit;
type This = ReprPacked<Option<char>, ReprC<u32, u64, String, Vec<u32>>, bool>;
let mut uninit = MaybeUninit::<This>::uninit();
/// Initializes a `This` through a pointer
///
/// # Safety
///
/// You must pass a pointer to allocated (and writable) memory for `This`.
unsafe fn initialize(this: *mut This) {
this.f_raw_get_mut(off!(a)).write_unaligned(None);
this.f_raw_get_mut(off!(b.a)).write_unaligned(3);
this.f_raw_get_mut(off!(b.b)).write_unaligned(5);
this.f_raw_get_mut(off!(b.c)).write_unaligned("8".to_string());
this.f_raw_get_mut(off!(b.d)).write_unaligned(vec![13, 21]);
this.f_raw_get_mut(off!(c)).write_unaligned(false);
}
let value = unsafe{
initialize(uninit.as_mut_ptr());
uninit.assume_init()
};
assert_eq!(moved(value.a), None);
assert_eq!(moved(value.b.a), 3);
assert_eq!(moved(value.b.b), 5);
assert_eq!(moved(value.b.c), "8".to_string());
assert_eq!(moved(value.b.d), vec![13, 21]);
assert_eq!(moved(value.c), false);
Object Safety§
This trait is not object safe.