repr_offset::ext

Trait 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§

Source

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);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<S> ROExtRawMutAcc for *mut S

Source§

unsafe fn f_raw_get_mut<F, A>( self, offset: FieldOffset<Self::Target, F, A>, ) -> *mut F

Implementors§