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§

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

Object Safety§

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§