Trait repr_offset::ext::ROExtRawMutOps
source · 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:
-
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 aFieldOffset<_, _, 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());
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:
-
self
andsource
must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offset
is aFieldOffset<_, _, Aligned>
(because it is for an aligned field), bothself
andsource
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][..]);
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:
-
self
andsource
must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offset
is aFieldOffset<_, _, Aligned>
(because it is for an aligned field), bothself
andsource
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 insource
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");
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:
-
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 aFieldOffset<_, _, 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]);
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:
-
self
andsource
must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offset
is aFieldOffset<_, _, Aligned>
(because it is for an aligned field), bothself
andsource
must be aligned pointers. -
The field in
self
and the same field insource
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][..]);
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:
-
self
andsource
must point to an allocated object (this includes the stack) allocated at lest up to the field (inclusive). -
If the passed in
offset
is aFieldOffset<_, _, Aligned>
(because it is for an aligned field), bothself
andsource
must be aligned pointers. -
The field in
self
and the same field insource
must be writable (if in doubt, all of the pointed-to value must be writble). -
The field in
self
and the same field insource
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");