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§
Sourceunsafe fn f_write<F>(self, offset: FieldOffset<Self::Target, F, A>, value: F)
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:
-
selfmust point to an allocated object (this includes the stack) allocated at least up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field),selfmust 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());
Sourceunsafe fn f_copy_from<F>(
self,
offset: FieldOffset<Self::Target, F, A>,
source: *const Self::Target,
)
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:
-
selfandsourcemust point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field), bothselfandsourcemust 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][..]);
Sourceunsafe fn f_copy_from_nonoverlapping<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, )
Copies a field (determined by offset) from source to self.
§Safety
You must ensure these properties:
-
selfandsourcemust point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field), bothselfandsourcemust be aligned pointers. -
The field must be writable (if in doubt, all of the pointed-to value must be writble).
-
The field in
selfand the same field insourcemust 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");
Sourceunsafe fn f_replace_raw<F>(
self,
offset: FieldOffset<Self::Target, F, A>,
value: F,
) -> F
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:
-
selfmust point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field),selfmust 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]);
Sourceunsafe fn f_swap_raw<F>(
self,
offset: FieldOffset<Self::Target, F, A>,
right: *mut Self::Target,
)
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:
-
selfandsourcemust point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field), bothselfandsourcemust be aligned pointers. -
The field in
selfand the same field insourcemust 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][..]);
Sourceunsafe fn f_swap_nonoverlapping<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, )
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:
-
selfandsourcemust point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offsetis aFieldOffset<_, _, Aligned>(because it is for an aligned field), bothselfandsourcemust be aligned pointers. -
The field in
selfand the same field insourcemust be writable (if in doubt, all of the pointed-to value must be writble). -
The field in
selfand the same field insourcemust 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");
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.