[][src]Struct corundum::cell::LogRefCell

pub struct LogRefCell<T: PSafe + ?Sized, A: MemPool> { /* fields omitted */ }

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 LogRefCell between threads. To provide thread-safe interior mutability, use Mutex.

PRefCell is an alias name in the pool module for LogRefCell.

Implementations

impl<T: PSafe, A: MemPool> LogRefCell<T, A>[src]

pub fn new(value: T, _j: &Journal<A>) -> Self[src]

Creates a new instance of LogRefCell with the given value

pub fn replace(&self, t: T, j: &Journal<A>) -> T[src]

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::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

Heap::transaction(|j| {
    let cell = Pbox::new(LogRefCell::new(5, j), j);
     
    let old_value = cell.replace(6, j);
    assert_eq!(old_value, 5);
    assert_eq!(*cell.borrow(), 6);
}).unwrap();

pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, j: &Journal<A>, f: F) -> T[src]

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::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

Heap::transaction(|j| {
    let cell = Pbox::new(LogRefCell::new(5, j), j);
     
    let old_value = cell.replace_with(j, |&mut old| old + 1);
    assert_eq!(old_value, 5);
    assert_eq!(*cell.borrow(), 6);
}).unwrap();

pub fn swap(&self, other: &Self, j: &Journal<A>)[src]

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::*;
use corundum::cell::LogRefCell;

let _pool = BuddyAlloc::open_no_root("foo.pool", O_CF);
     
BuddyAlloc::transaction(|j| {
    let c1 = Pbox::new(LogRefCell::new(5i32, j), j);
    let c2 = Pbox::new(LogRefCell::new(10i32, j), j);
    c1.swap(&c2, j);
    assert_eq!(10, c1.take(j));
    assert_eq!(5, c2.take(j));
}).unwrap();

impl<T: PSafe + ?Sized, A: MemPool> LogRefCell<T, A>[src]

pub fn get_mut(&mut self, journal: &Journal<A>) -> &mut T[src]

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::*;
use corundum::cell::LogRefCell;

let _pool = BuddyAlloc::open_no_root("foo.pool", O_CF);
     
BuddyAlloc::transaction(|j| {
    let c1 = Pbox::new(LogRefCell::new(5i32, j), j);
    let c2 = Pbox::new(LogRefCell::new(10i32, j), j);
    c1.swap(&c2, j);
    assert_eq!(10, *c1.borrow());
    assert_eq!(5, *c2.borrow());
}).unwrap();

pub unsafe fn as_mut(&self) -> &mut T[src]

Returns a mutable reference to the underlying data without taking a log

Safety

This function violates borrow rules as it allows multiple mutable references.

Examples

use corundum::default::*;
use corundum::cell::LogRefCell;
 
type P = BuddyAlloc;
 
let root = P::open::<LogRefCell<i32,P>>("foo.pool", O_CF).unwrap();
 
unsafe {
    let mut data = root.as_mut();
    *data = 20;
}
 

pub fn borrow(&self) -> Ref<'_, T, A>[src]

Immutably borrows from an owned value.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

Heap::transaction(|j| {
    let cell = Pbox::new(LogRefCell::new(5, j), j);
     
    assert_eq!(*cell.borrow(), 5);
}).unwrap();

pub fn read(&self) -> T where
    T: Clone
[src]

Returns a clone of the underlying data

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

Heap::transaction(|j| {
    let cell = Pbox::new(LogRefCell::new(5, j), j);
     
    assert_eq!(cell.read(), 5);
}).unwrap();

impl<T: PSafe + Default, A: MemPool> LogRefCell<T, A>[src]

pub fn take(&self, journal: &Journal<A>) -> T[src]

Takes the value of the cell, leaving Default::default() in its place.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogRefCell::new(5, j), j);
    let five = c.take(j);

    assert_eq!(five, 5);
    assert_eq!(*c.borrow(), 0);
}).unwrap();

impl<T: PSafe, A: MemPool> LogRefCell<T, A>[src]

pub fn borrow_mut(&self, journal: &Journal<A>) -> RefMut<'_, T, A>[src]

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::*;
use corundum::boxed::Pbox;
use corundum::cell::LogRefCell;

let cell=Heap::transaction(|j| {
    let cell = Pbox::new(LogRefCell::new(5, j), j);
    {
        let mut cell = cell.borrow_mut(j);
        *cell = 10;
    }
    assert_eq!(*cell.borrow(), 10);
}).unwrap();

pub unsafe fn as_non_null_mut(&self, journal: &Journal<A>) -> LogNonNull<T, A>[src]

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.

pub fn as_non_null(&self) -> NonNull<T>[src]

Returns a NonNull pointer to the data

Trait Implementations

impl<T: PSafe + Debug + ?Sized, A: MemPool> Debug for LogRefCell<T, A>[src]

impl<T: PSafe + Display + ?Sized, A: MemPool> Display for LogRefCell<T, A>[src]

impl<T: PSafe + Eq + ?Sized, A: MemPool> Eq for LogRefCell<T, A>[src]

impl<T: PSafe + Ord + ?Sized, A: MemPool> Ord for LogRefCell<T, A>[src]

impl<T: PSafe + PClone<A>, A: MemPool> PClone<A> for LogRefCell<T, A>[src]

impl<T: PSafe + PClone<A>, A: MemPool> PFrom<Ref<'_, T, A>, A> for LogRefCell<T, A>[src]

pub fn pfrom(other: Ref<'_, T, A>, j: &Journal<A>) -> Self[src]

Crates a new LogRefCell and drops the Ref

After calling this function, the Ref won't be available anymore. It will be possible to borrow the LogRefCell mutably. The new LogRefCell has a new location with the same data.

impl<T: PSafe + PClone<A>, A: MemPool> PFrom<RefMut<'_, T, A>, A> for LogRefCell<T, A>[src]

pub fn pfrom(other: RefMut<'_, T, A>, j: &Journal<A>) -> Self[src]

Crates a new LogRefCell and drops the Ref

After calling this function, the Ref won't be available anymore. It will be possible to borrow the LogRefCell mutably. The new LogRefCell has a new location with the same data.

impl<T: PSafe, A: MemPool> PFrom<T, A> for LogRefCell<T, A>[src]

pub fn pfrom(value: T, j: &Journal<A>) -> Self[src]

Crates a new LogRefCell

impl<T: PSafe + ?Sized, A: MemPool> PSafe for LogRefCell<T, A>[src]

impl<T: PSafe + PartialEq + ?Sized, A: MemPool> PartialEq<LogRefCell<T, A>> for LogRefCell<T, A>[src]

impl<T: PSafe + PartialOrd + ?Sized, A: MemPool> PartialOrd<LogRefCell<T, A>> for LogRefCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> RefUnwindSafe for LogRefCell<T, A>[src]

impl<T: PSafe + RootObj<A>, A: MemPool> RootObj<A> for LogRefCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> Send for LogRefCell<T, A>[src]

Safe to transfer between thread boundaries

impl<T: ?Sized, A: MemPool> !Sync for LogRefCell<T, A>[src]

Not safe for thread data sharing

impl<T: PSafe + ?Sized, A: MemPool> TxInSafe for LogRefCell<T, A>[src]

impl<T: ?Sized, A: MemPool> !TxOutSafe for LogRefCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> UnwindSafe for LogRefCell<T, A>[src]

Auto Trait Implementations

impl<T: ?Sized, A> LooseTxInUnsafe for LogRefCell<T, A> where
    A: LooseTxInUnsafe,
    T: LooseTxInUnsafe
[src]

impl<T: ?Sized, A> Unpin for LogRefCell<T, A> where
    A: Unpin,
    T: Unpin
[src]

impl<T: ?Sized, A> VSafe for LogRefCell<T, A> where
    A: VSafe,
    T: VSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, A> ToString<A> for T where
    T: Display + ?Sized,
    A: MemPool
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,