Expand description
A persistent memory location with safe interior mutability and dynamic borrow checking
This is one of the safe ways to provide interior mutability for pointer wrappers. It takes a log, if it was not already taken, before exposing the mutable reference to the protected data.
To borrow the value immutably, borrow()
can be used. Its
return value is a Ref<T>
. The function
borrow_mut()
returns the inner value wrapped in
RefMut<T>
. The borrowing rules is checked
dynamically when the user tries to borrow the value. It panics if any of
the following situation happens:
- Borrowing the value mutably while it was already borrowed immutably
- Borrowing the value mutably twice
- Borrowing the value immutably while it was already borrowed mutably
It does not implement Sync
, so it is not possible to share PRefCell
between threads. To provide thread-safe interior mutability, use
PMutex
.
PRefCell
is an alias name in the pool module for PRefCell
.
Implementations
sourceimpl<T: PSafe, A: MemPool> PRefCell<T, A>
impl<T: PSafe, A: MemPool> PRefCell<T, A>
sourcepub fn replace(&self, t: T, j: &Journal<A>) -> T
pub fn replace(&self, t: T, j: &Journal<A>) -> T
Replaces the wrapped value with a new one, returning the old value, without deinitializing either one.
This function corresponds to std::mem::replace
.
Panics
Panics if the value is currently borrowed.
Examples
use corundum::alloc::heap::*;
Heap::transaction(|j| {
let cell = Pbox::new(PRefCell::new(5), j);
let old_value = cell.replace(6, j);
assert_eq!(old_value, 5);
assert_eq!(*cell.borrow(), 6);
}).unwrap();
sourcepub fn replace_with<F: FnOnce(&mut T) -> T>(&self, j: &Journal<A>, f: F) -> T
pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, j: &Journal<A>, f: F) -> T
Replaces the wrapped value with a new one computed from f
, returning
the old value, without deinitializing either one.
Panics
Panics if the value is currently borrowed.
Examples
use corundum::alloc::heap::*;
Heap::transaction(|j| {
let cell = Pbox::new(PRefCell::new(5), j);
let old_value = cell.replace_with(j, |&mut old| old + 1);
assert_eq!(old_value, 5);
assert_eq!(*cell.borrow(), 6);
}).unwrap();
sourcepub fn swap(&self, other: &Self, j: &Journal<A>)
pub fn swap(&self, other: &Self, j: &Journal<A>)
Swaps the wrapped value of self
with the wrapped value of other
,
without deinitializing either one.
This function corresponds to std::mem::swap
.
Panics
Panics if the value in either RefCell
is currently borrowed.
Examples
use corundum::default::*;
let _pool = Allocator::open_no_root("foo.pool", O_CF);
Allocator::transaction(|j| {
let c1 = Pbox::new(PRefCell::new(5i32), j);
let c2 = Pbox::new(PRefCell::new(10i32), j);
c1.swap(&c2, j);
assert_eq!(10, c1.take(j));
assert_eq!(5, c2.take(j));
}).unwrap();
sourceimpl<T: PSafe + ?Sized, A: MemPool> PRefCell<T, A>
impl<T: PSafe + ?Sized, A: MemPool> PRefCell<T, A>
sourcepub fn get_mut(&mut self, journal: &Journal<A>) -> &mut T
pub fn get_mut(&mut self, journal: &Journal<A>) -> &mut T
Takes a log and returns a mutable reference to the underlying data.
This call borrows the UnsafeCell
mutably (at compile-time) which
guarantees that we possess the only reference.
Examples
use corundum::default::*;
let _pool = Allocator::open_no_root("foo.pool", O_CF);
Allocator::transaction(|j| {
let c1 = Pbox::new(PRefCell::new(5i32), j);
let c2 = Pbox::new(PRefCell::new(10i32), j);
c1.swap(&c2, j);
assert_eq!(10, *c1.borrow());
assert_eq!(5, *c2.borrow());
}).unwrap();
sourcepub unsafe fn as_mut(&self) -> &mut T
pub unsafe fn as_mut(&self) -> &mut T
Returns a mutable reference to the underlying data without logging
Safety
This function violates borrow rules as it allows multiple mutable references.
Examples
use corundum::default::*;
use corundum::cell::PRefCell;
type P = Allocator;
let root = P::open::<PRefCell<i32,P>>("foo.pool", O_CF).unwrap();
unsafe {
let mut data = root.as_mut();
*data = 20;
}
sourceimpl<T: PSafe + Default, A: MemPool> PRefCell<T, A>
impl<T: PSafe + Default, A: MemPool> PRefCell<T, A>
sourcepub fn take(&self, journal: &Journal<A>) -> T
pub fn take(&self, journal: &Journal<A>) -> T
Takes the value of the cell, leaving Default::default()
in its place.
Examples
use corundum::alloc::heap::*;
Heap::transaction(|j| {
let c = Pbox::new(PRefCell::new(5), j);
let five = c.take(j);
assert_eq!(five, 5);
assert_eq!(*c.borrow(), 0);
}).unwrap();
sourceimpl<T: PSafe, A: MemPool> PRefCell<T, A>
impl<T: PSafe, A: MemPool> PRefCell<T, A>
sourcepub fn borrow_mut(&self, journal: &Journal<A>) -> RefMut<'_, T, A>
pub fn borrow_mut(&self, journal: &Journal<A>) -> RefMut<'_, T, A>
Mutably borrows from an owned value.
It returns a RefMut
type for interior mutability which takes a log of
data when dereferenced mutably. This method requires accessing current
journal which is provided in transaction
.
Examples
use corundum::alloc::heap::*;
use corundum::boxed::Pbox;
let cell=Heap::transaction(|j| {
let cell = Pbox::new(PRefCell::new(5), j);
{
let mut cell = cell.borrow_mut(j);
*cell = 10;
}
assert_eq!(*cell.borrow(), 10);
}).unwrap();
sourcepub unsafe fn as_non_null_mut(&self, journal: &Journal<A>) -> LogNonNull<T, A>
pub unsafe fn as_non_null_mut(&self, journal: &Journal<A>) -> LogNonNull<T, A>
Returns a LogNonNull
pointer to the data
Safety
LogNonNull
does not dynamically check the borrowing rules. Also, it
may outlive the data, leading to a segmentation fault. It is not
recommended to use this function without necessary manual checks.
sourcepub fn as_non_null(&self) -> NonNull<T>
pub fn as_non_null(&self) -> NonNull<T>
Returns a NonNull
pointer to the data
Trait Implementations
sourceimpl<T: PSafe + Ord + ?Sized, A: MemPool> Ord for PRefCell<T, A>
impl<T: PSafe + Ord + ?Sized, A: MemPool> Ord for PRefCell<T, A>
sourceimpl<T: PSafe + PartialOrd + ?Sized, A: MemPool> PartialOrd<PRefCell<T, A>> for PRefCell<T, A>
impl<T: PSafe + PartialOrd + ?Sized, A: MemPool> PartialOrd<PRefCell<T, A>> for PRefCell<T, A>
sourcefn partial_cmp(&self, other: &PRefCell<T, A>) -> Option<Ordering>
fn partial_cmp(&self, other: &PRefCell<T, A>) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
sourcefn lt(&self, other: &PRefCell<T, A>) -> bool
fn lt(&self, other: &PRefCell<T, A>) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
sourcefn le(&self, other: &PRefCell<T, A>) -> bool
fn le(&self, other: &PRefCell<T, A>) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
impl<T: PSafe + Eq + ?Sized, A: MemPool> Eq for PRefCell<T, A>
impl<T: PSafe + ?Sized, A: MemPool> PSafe for PRefCell<T, A>
impl<T: ?Sized, A: MemPool> !PSend for PRefCell<T, A>
impl<T: PSafe + ?Sized, A: MemPool> RefUnwindSafe for PRefCell<T, A>
impl<T: PSafe + ?Sized, A: MemPool> Send for PRefCell<T, A>
Safe to transfer between thread boundaries
impl<T: ?Sized, A: MemPool> !Sync for PRefCell<T, A>
Not safe for thread data sharing
impl<T: PSafe + ?Sized, A: MemPool> TxInSafe for PRefCell<T, A>
impl<T: ?Sized, A: MemPool> !TxOutSafe for PRefCell<T, A>
impl<T: PSafe + ?Sized, A: MemPool> UnwindSafe for PRefCell<T, A>
Auto Trait Implementations
impl<T: ?Sized, A> LooseTxInUnsafe for PRefCell<T, A> where
T: LooseTxInUnsafe,
impl<T: ?Sized, A> Unpin for PRefCell<T, A> where
A: Unpin,
T: Unpin,
impl<T: ?Sized, A> VSafe for PRefCell<T, A> where
A: VSafe,
T: VSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more