pub unsafe trait ROExtRawMutOps<A>: ROExtRawMutAcc {
    // Required methods
    unsafe fn f_write<F>(self, offset: FieldOffset<Self::Target, F, A>, value: F);
    unsafe fn f_copy_from<F>(
        self,
        offset: FieldOffset<Self::Target, F, A>,
        source: *const Self::Target
    );
    unsafe fn f_copy_from_nonoverlapping<F>(
        self,
        offset: FieldOffset<Self::Target, F, A>,
        source: *const Self::Target
    );
    unsafe fn f_replace_raw<F>(
        self,
        offset: FieldOffset<Self::Target, F, A>,
        value: F
    ) -> F;
    unsafe fn f_swap_raw<F>(
        self,
        offset: FieldOffset<Self::Target, F, A>,
        right: *mut Self::Target
    );
    unsafe fn f_swap_nonoverlapping<F>(
        self,
        offset: FieldOffset<Self::Target, F, A>,
        right: *mut Self::Target
    );
}
Expand description

Extension trait for mutable raw pointers to do generic field operations, where the field is determined by a FieldOffset parameter.

Safety

This trait must not to be implemented outside the repr_offset crate.

Alignment

The A type parameter is the Alignment of the field, used to implement methods differently depending on whether the field is Aligned or Unaligned.

Example

This example shows how you can do the equivalent of std::mem::replace in partially initialized structs.

use repr_offset::{
    for_examples::ReprPacked,
    utils::moved,
    ROExtRawMutOps, off,
};

let mut value = ReprPacked {
    a: false,
    b: None,
    c: "",
    d: [0u64; 10],
};

let (a, b) = unsafe{ replace_fields(&mut value, true, Some('!')) };

assert_eq!(moved(a), false);
assert_eq!(moved(value.a), true);

assert_eq!(moved(b), None);
assert_eq!(moved(value.b), Some('!'));

assert_eq!(moved(value.c), "");


/// Replaces the `a` and `b` fields in `this`
///
/// # Safety
///
/// The fields up to and including `b` must be initialized.
unsafe fn replace_fields(
    this: *mut ReprPacked<bool, Option<char>, &'static str, [u64; 10]>,
    a: bool,
    b: Option<char>,
) -> (bool, Option<char>) {
    (
        this.f_replace_raw(off!(a), a),
        this.f_replace_raw(off!(b), b),
    )
}

Required Methods§

source

unsafe fn f_write<F>(self, offset: FieldOffset<Self::Target, F, A>, value: F)

Overwrites the value of a field (determined by offset) from self, without dropping the previous value.

Safety

You must ensure these properties:

  • self must point to an allocated object (this includes the stack) allocated at least up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), self must be an aligned pointer.

  • The field must be writable(if in doubt, all of the pointed-to value).

Example
use repr_offset::{
    for_examples::ReprC,
    utils::moved,
    ROExtRawMutOps, off,
};

let mut value = ReprC {
    a: 0,
    b: None::<u32>,
    c: Vec::new(),
    d: String::new(),
};

let ptr: *mut _ = &mut value;
unsafe{
    ptr.f_write(off!(a), 3);
    ptr.f_write(off!(b), Some(5));
    ptr.f_write(off!(c), vec![8, 13]);
    ptr.f_write(off!(d), "world".to_string());
}

assert_eq!(value.a, 3);
assert_eq!(value.b, Some(5));
assert_eq!(value.c, vec![8, 13]);
assert_eq!(value.d, "world".to_string());
source

unsafe fn f_copy_from<F>( self, offset: FieldOffset<Self::Target, F, A>, source: *const Self::Target )

Copies a field (determined by offset) from source to self.

Safety

You must ensure these properties:

  • self and source must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), both self and source must be aligned pointers.

  • The field must be writable (if in doubt, all of the pointed-to value must be writble).

core::ptr::copy describes what happens when self ànd source overlap.

Example
use repr_offset::{
    for_examples::ReprC,
    ROExtRawMutOps, off,
};

let mut left = ReprC {
    a: 3u128,
    b: Some(5u64),
    c: &[8, 13, 21][..],
    d: (),
};
let right = ReprC {
    a: 55,
    b: None,
    c: &[34, 51, 89][..],
    d: (),
};

let left_ptr: *mut _ = &mut left;
unsafe{
    left_ptr.f_copy_from(off!(a), &right);
    left_ptr.f_copy_from(off!(b), &right);
    left_ptr.f_copy_from(off!(c), &right);
}

assert_eq!(left.a, 55);
assert_eq!(right.a, 55);

assert_eq!(left.b, None);
assert_eq!(right.b, None);

assert_eq!(left.c, &[34, 51, 89][..]);
assert_eq!(right.c, &[34, 51, 89][..]);

source

unsafe fn f_copy_from_nonoverlapping<F>( self, offset: FieldOffset<Self::Target, F, A>, source: *const Self::Target )

Copies a field (determined by offset) from source to self.

Safety

You must ensure these properties:

  • self and source must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), both self and source must be aligned pointers.

  • The field must be writable (if in doubt, all of the pointed-to value must be writble).

  • The field in self and the same field in source must not overlap, (if in doubt, the pointers must not point to overlapping memory).

Example
use repr_offset::{
    for_examples::ReprPacked,
    utils::moved,
    ROExtRawMutOps, off,
};

let mut left = ReprPacked {
    a: false,
    b: None,
    c: "foo",
    d: (),
};
let right = ReprPacked {
    a: true,
    b: Some('?'),
    c: "bar",
    d: (),
};

let left_ptr: *mut _ = &mut left;
unsafe{
    left_ptr.f_copy_from_nonoverlapping(off!(a), &right);
    left_ptr.f_copy_from_nonoverlapping(off!(b), &right);
    left_ptr.f_copy_from_nonoverlapping(off!(c), &right);
}

assert_eq!(moved(left.a), true);
assert_eq!(moved(right.a), true);

assert_eq!(moved(left.b), Some('?'));
assert_eq!(moved(right.b), Some('?'));

assert_eq!(moved(left.c), "bar");
assert_eq!(moved(right.c), "bar");

source

unsafe fn f_replace_raw<F>( self, offset: FieldOffset<Self::Target, F, A>, value: F ) -> F

Replaces a field (determined by offset) with value, returning the previous value of the field.

Safety

You must ensure these properties:

  • self must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), self must be an aligned pointers.

Example
use repr_offset::{
    for_examples::ReprPacked,
    utils::moved,
    ROExtRawMutOps, off,
};

let mut value = ReprPacked {
    a: 3u128,
    b: Some(5u64),
    c: vec![0, 1],
    d: (),
};

let ptr: *mut _ = &mut value;
unsafe {
    assert_eq!(ptr.f_replace_raw(off!(a), 200), 3);
    assert_eq!(ptr.f_replace_raw(off!(b), None), Some(5));
    assert_eq!(ptr.f_replace_raw(off!(c), vec![2, 3]), vec![0, 1]);
}

assert_eq!(moved(value.a), 200);
assert_eq!(moved(value.b), None);
assert_eq!(moved(value.c), vec![2, 3]);
source

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

Swaps a field (determined by offset) from self with the same field in right.

Safety

You must ensure these properties:

  • self and source must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), both self and source must be aligned pointers.

  • The field in self and the same field in source must be writable (if in doubt, all of the pointed-to value must be writble).

core::ptr::swap describes what happens when self ànd source overlap.

Example
use repr_offset::{
    for_examples::ReprC,
    ROExtRawMutOps, off,
};

let mut left = ReprC {
    a: 3u128,
    b: Some(5u64),
    c: &[8, 13, 21][..],
    d: (),
};
let mut right = ReprC {
    a: 55,
    b: None,
    c: &[34, 51, 89][..],
    d: (),
};

let left_ptr: *mut _ = &mut left;
unsafe{
    left_ptr.f_swap_raw(off!(a), &mut right);
    left_ptr.f_swap_raw(off!(b), &mut right);
    left_ptr.f_swap_raw(off!(c), &mut right);
}

assert_eq!(left.a, 55);
assert_eq!(right.a, 3);

assert_eq!(left.b, None);
assert_eq!(right.b, Some(5));

assert_eq!(left.c, &[34, 51, 89][..]);
assert_eq!(right.c, &[8, 13, 21][..]);

source

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

Swaps a field (determined by offset) from self with the same field in right. self and right must not overlap.

Safety

You must ensure these properties:

  • self and source must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive).

  • If the passed in offset is a FieldOffset<_, _, Aligned> (because it is for an aligned field), both self and source must be aligned pointers.

  • The field in self and the same field in source must be writable (if in doubt, all of the pointed-to value must be writble).

  • The field in self and the same field in source must not overlap, (if in doubt, the pointers must not point to overlapping memory).

Example
use repr_offset::{
    for_examples::ReprPacked,
    utils::moved,
    ROExtRawMutOps, off,
};

let mut left = ReprPacked {
    a: false,
    b: None,
    c: "foo",
    d: (),
};
let mut right = ReprPacked {
    a: true,
    b: Some('?'),
    c: "bar",
    d: (),
};

let left_ptr: *mut _ = &mut left;
unsafe{
    left_ptr.f_swap_nonoverlapping(off!(a), &mut right);
    left_ptr.f_swap_nonoverlapping(off!(b), &mut right);
    left_ptr.f_swap_nonoverlapping(off!(c), &mut right);
}

assert_eq!(moved(left.a), true);
assert_eq!(moved(right.a), false);

assert_eq!(moved(left.b), Some('?'));
assert_eq!(moved(right.b), None);

assert_eq!(moved(left.c), "bar");
assert_eq!(moved(right.c), "foo");

Implementations on Foreign Types§

source§

impl<S> ROExtRawMutOps<Aligned> for *mut S

source§

unsafe fn f_write<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, value: F )

source§

unsafe fn f_copy_from<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, source: *const Self::Target )

source§

unsafe fn f_copy_from_nonoverlapping<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, source: *const Self::Target )

source§

unsafe fn f_replace_raw<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, value: F ) -> F

source§

unsafe fn f_swap_raw<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, right: *mut Self::Target )

source§

unsafe fn f_swap_nonoverlapping<F>( self, offset: FieldOffset<Self::Target, F, Aligned>, right: *mut Self::Target )

source§

impl<S> ROExtRawMutOps<Unaligned> for *mut S

source§

unsafe fn f_write<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, value: F )

source§

unsafe fn f_copy_from<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, source: *const Self::Target )

source§

unsafe fn f_copy_from_nonoverlapping<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, source: *const Self::Target )

source§

unsafe fn f_replace_raw<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, value: F ) -> F

source§

unsafe fn f_swap_raw<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, right: *mut Self::Target )

source§

unsafe fn f_swap_nonoverlapping<F>( self, offset: FieldOffset<Self::Target, F, Unaligned>, right: *mut Self::Target )

Implementors§