pub struct RefMut<'a, T>where
T: ?Sized,{ /* private fields */ }
Expand description
Wrapper for mutably borrowed AtomicCell
that will released lock on drop.
This type can be dereferenced to [&mut T
].
Implements Borrow<T>
, BorrowMut<T>
, AsRef<T>
and AsMut<T>
for convenience.
Implements Debug
, Display
, PartialEq
, PartialOrd
and Hash
by delegating to T
.
Implementations§
§impl<'a, T> RefMut<'a, T>where
T: ?Sized,
impl<'a, T> RefMut<'a, T>where
T: ?Sized,
pub fn new(r: &'a mut T) -> RefMut<'a, T>
pub fn new(r: &'a mut T) -> RefMut<'a, T>
Wraps external reference into RefMut
.
This function’s purpose is to satisfy type requirements
where RefMut
is required but reference does not live in AtomicCell
.
§Examples
use atomicell::RefMut;
let mut value = 42;
let r = RefMut::new(&mut value);
pub fn with_borrow(r: &'a mut T, borrow: AtomicBorrowMut<'a>) -> RefMut<'a, T>
pub fn with_borrow(r: &'a mut T, borrow: AtomicBorrowMut<'a>) -> RefMut<'a, T>
Wraps external reference into RefMut
.
And associates it with provided AtomicBorrowMut
This function is intended to be used by AtomicCell
or other abstractions that use AtomicBorrow
for locking.
§Examples
use core::sync::atomic::AtomicIsize;
use atomicell::{borrow::{AtomicBorrowMut, new_lock}, RefMut};
let counter = new_lock();
let borrow = AtomicBorrowMut::try_new(&counter).unwrap();
let mut value = 42;
let r = RefMut::with_borrow(&mut value, borrow);
assert_eq!(*r, 42);
pub fn into_split(r: RefMut<'a, T>) -> (NonNull<T>, AtomicBorrowMut<'a>)
pub fn into_split(r: RefMut<'a, T>) -> (NonNull<T>, AtomicBorrowMut<'a>)
Splits wrapper into two parts. One is reference to the value and the other is
AtomicBorrowMut
that guards it from being borrowed.
§Safety
User must ensure NonNull
is not dereferenced after AtomicBorrowMut
is dropped.
You must also treat the NonNull
as invariant over T
. This means that any custom
wrapper types you make around the NonNull<T>
must also be invariant over T
. This can
be done by adding a PhantomData<*mut T>
field to the struct.
See the source definition of RefMut
for an example.
§Examples
use atomicell::{AtomicCell, RefMut};
let cell = AtomicCell::new(42);
let r: RefMut<'_, i32> = cell.borrow_mut();
unsafe {
let (r, borrow) = RefMut::into_split(r);
assert_eq!(*r.as_ref(), 42);
assert!(cell.try_borrow().is_none(), "Must not be able to borrow mutably yet");
assert!(cell.try_borrow_mut().is_none(), "Must not be able to borrow mutably yet");
drop(borrow);
assert!(cell.try_borrow_mut().is_some(), "Must be able to borrow mutably now");
}
pub fn map<F, U>(r: RefMut<'a, T>, f: F) -> RefMut<'a, U>
pub fn map<F, U>(r: RefMut<'a, T>, f: F) -> RefMut<'a, U>
Makes a new RefMut
for a component of the borrowed data.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map(…).
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c = AtomicCell::new((5, 'b'));
let b1: RefMut<(u32, char)> = c.borrow_mut();
let b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0);
assert_eq!(*b2, 5)
pub fn filter_map<U, F>(
r: RefMut<'a, T>,
f: F,
) -> Result<RefMut<'a, U>, RefMut<'a, T>>
pub fn filter_map<U, F>( r: RefMut<'a, T>, f: F, ) -> Result<RefMut<'a, U>, RefMut<'a, T>>
Makes a new RefMut
for an optional component of the borrowed data.
The original guard is returned as an Err(..) if the closure returns None.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::filter_map(…).
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c = AtomicCell::new(vec![1, 2, 3]);
{
let b1: RefMut<Vec<u32>> = c.borrow_mut();
let mut b2: Result<RefMut<u32>, _> = RefMut::filter_map(b1, |v| v.get_mut(1));
if let Ok(mut b2) = b2 {
*b2 += 2;
}
}
assert_eq!(*c.borrow(), vec![1, 4, 3]);
pub fn map_split<U, V, F>(
r: RefMut<'a, T>,
f: F,
) -> (RefMut<'a, U>, RefMut<'a, V>)
pub fn map_split<U, V, F>( r: RefMut<'a, T>, f: F, ) -> (RefMut<'a, U>, RefMut<'a, V>)
Splits a RefMut
into multiple RefMut
s for different components of the borrowed data.
The AtomicCell
is already immutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map_split(...)
.
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{RefMut, AtomicCell};
let cell = AtomicCell::new([1, 2, 3, 4]);
let borrow = cell.borrow_mut();
let (begin, end) = RefMut::map_split(borrow, |slice| slice.split_at_mut(2));
assert_eq!(*begin, [1, 2]);
assert_eq!(*end, [3, 4]);
pub fn leak(r: RefMut<'a, T>) -> &'a mut T
pub fn leak(r: RefMut<'a, T>) -> &'a mut T
Convert into a reference to the underlying data.
The underlying AtomicCell
can never be mutably borrowed from again
and will always appear already immutably borrowed.
It is not a good idea to leak more than a constant number of references.
The AtomicCell
can be immutably borrowed again if only a smaller number of leaks have occurred in total.
This is an associated function that needs to be used as RefMut::leak(…).
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let cell = AtomicCell::new(0);
let value = RefMut::leak(cell.borrow_mut());
assert_eq!(*value, 0);
*value = 1;
assert_eq!(*value, 1);
assert!(cell.try_borrow().is_none());
assert!(cell.try_borrow_mut().is_none());
pub fn as_mut<U>(r: RefMut<'a, T>) -> RefMut<'a, U>
pub fn as_mut<U>(r: RefMut<'a, T>) -> RefMut<'a, U>
Converts reference and returns result wrapped in the RefMut
.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map_split(...)
.
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c = AtomicCell::new(String::from("hello"));
let b1: RefMut<String> = c.borrow_mut();
let mut b2: RefMut<str> = RefMut::as_mut(b1);
b2.make_ascii_uppercase();
assert_eq!(*b2, *"HELLO")
pub fn as_deref_mut(r: RefMut<'a, T>) -> RefMut<'a, <T as Deref>::Target>where
T: DerefMut,
pub fn as_deref_mut(r: RefMut<'a, T>) -> RefMut<'a, <T as Deref>::Target>where
T: DerefMut,
Dereferences and returns result wrapped in the RefMut
.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map_split(...)
.
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c = AtomicCell::new(String::from("hello"));
let b1: RefMut<String> = c.borrow_mut();
let mut b2: RefMut<str> = RefMut::as_deref_mut(b1);
b2.make_ascii_uppercase();
assert_eq!(*b2, *"HELLO")
§impl<'a, T> RefMut<'a, Option<T>>
impl<'a, T> RefMut<'a, Option<T>>
pub fn transpose(r: RefMut<'a, Option<T>>) -> Option<RefMut<'a, T>>
pub fn transpose(r: RefMut<'a, Option<T>>) -> Option<RefMut<'a, T>>
Transposes a RefMut
of an Option
into an Option
of a RefMut
.
Releases shared lock of AtomicCell
if the value is None
.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map_split(...)
.
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c = AtomicCell::new(Some(5));
let b1: RefMut<Option<i32>> = c.borrow_mut();
let b2: Option<RefMut<i32>> = RefMut::transpose(b1);
assert!(b2.is_some());
let c = AtomicCell::new(None);
let b1: RefMut<Option<i32>> = c.borrow_mut();
let b2: Option<RefMut<i32>> = RefMut::transpose(b1);
assert!(b2.is_none());
assert!(c.try_borrow_mut().is_some());
§impl<'a, T> RefMut<'a, [T]>
impl<'a, T> RefMut<'a, [T]>
pub fn slice<R>(r: RefMut<'a, [T]>, range: R) -> RefMut<'a, [T]>where
R: RangeBounds<usize>,
pub fn slice<R>(r: RefMut<'a, [T]>, range: R) -> RefMut<'a, [T]>where
R: RangeBounds<usize>,
Makes a new RefMut
for a sub-slice of the borrowed slice.
The AtomicCell
is already mutably borrowed, so this cannot fail.
This is an associated function that needs to be used as RefMut::map(…).
A method would interfere with methods of the same name on the contents of a AtomicCell
used through Deref
.
§Examples
use atomicell::{AtomicCell, RefMut};
let c: &AtomicCell<[i32]> = &AtomicCell::new([1, 2, 3, 4, 5]);
let b1: RefMut<[i32]> = RefMut::as_mut(c.borrow_mut());
let b2: RefMut<[i32]> = RefMut::slice(b1, 2..4);
assert_eq!(*b2, [3, 4])